[gnome-shell] Optimize subsearches
- From: Colin Walters <walters src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-shell] Optimize subsearches
- Date: Fri, 25 Sep 2009 16:16:46 +0000 (UTC)
commit 32ef951fe00e060968bd5fc959399002d6f09491
Author: Colin Walters <walters verbum org>
Date: Wed Sep 23 16:16:38 2009 -0400
Optimize subsearches
This is probably not the biggest optimization that needs to be
made at least for application searching, but we can optimize the
case where we're going from a search of "fi" to "fire" by just
re-searching the list of things we already had that matched "fi"
instead of looping over everything.
https://bugzilla.gnome.org/show_bug.cgi?id=596119
js/ui/genericDisplay.js | 82 +++++++++++++++++++++++++++++++---------------
1 files changed, 55 insertions(+), 27 deletions(-)
---
diff --git a/js/ui/genericDisplay.js b/js/ui/genericDisplay.js
index f8dfc56..df6109f 100644
--- a/js/ui/genericDisplay.js
+++ b/js/ui/genericDisplay.js
@@ -17,6 +17,10 @@ const DND = imports.ui.dnd;
const Link = imports.ui.link;
const Main = imports.ui.main;
+const RedisplayFlags = { NONE: 0,
+ RESET_CONTROLS: 1 << 0,
+ SUBSEARCH: 1 << 1 };
+
const ITEM_DISPLAY_NAME_COLOR = new Clutter.Color();
ITEM_DISPLAY_NAME_COLOR.from_pixel(0xffffffff);
const ITEM_DISPLAY_DESCRIPTION_COLOR = new Clutter.Color();
@@ -357,8 +361,14 @@ GenericDisplay.prototype = {
// Sets the search string and displays the matching items.
setSearch: function(text) {
- this._search = text.toLowerCase();
- this._redisplay(true);
+ let lowertext = text.toLowerCase();
+ let flags = RedisplayFlags.RESET_CONTROLS;
+ if (this._search != '') {
+ if (lowertext.indexOf(this._search) == 0)
+ flags |= RedisplayFlags.SUBSEARCH;
+ }
+ this._search = lowertext;
+ this._redisplay(flags);
},
// Launches the item that is currently selected, closing the Overview
@@ -439,7 +449,7 @@ GenericDisplay.prototype = {
// Load the initial state
load: function() {
- this._redisplay(true);
+ this._redisplay(RedisplayFlags.RESET_CONTROLS);
},
// Should be called when the display is closed
@@ -587,19 +597,23 @@ GenericDisplay.prototype = {
/*
* Updates the displayed items, applying the search string if one exists.
- *
- * resetPage - indicates if the page selection should be reset when displaying the matching results.
- * We reset the page selection when the change in results was initiated by the user by
- * entering a different search criteria or by viewing the results list in a different
- * size mode, but we keep the page selection the same if the results got updated on
- * their own while the user was browsing through the result pages.
+ * @flags: Flags controlling redisplay behavior as follows:
+ * RESET_CONTROLS - indicates if the page selection should be reset when displaying the matching results.
+ * We reset the page selection when the change in results was initiated by the user by
+ * entering a different search criteria or by viewing the results list in a different
+ * size mode, but we keep the page selection the same if the results got updated on
+ * their own while the user was browsing through the result pages.
+ * SUBSEARCH - Indicates that the current _search is a superstring of the previous
+ * one, which implies we only need to re-search through previous results.
*/
- _redisplay: function(resetPage) {
+ _redisplay: function(flags) {
+ let resetPage = flags & RedisplayFlags.RESET_CONTROLS;
+ let isSubSearch = flags & RedisplayFlags.SUBSEARCH;
this._refreshCache();
if (!this._filterActive())
this._setDefaultList();
else
- this._doSearchFilter();
+ this._doSearchFilter(isSubSearch);
if (resetPage)
this._list.page = 0;
@@ -643,35 +657,49 @@ GenericDisplay.prototype = {
//// Private methods ////
- _getSearchMatchedItems: function() {
- let matchedItemsForSearch = {};
+ _getItemSearchScore: function(itemId, terms) {
+ let item = this._allItems[itemId];
+ let score = 0;
+ for (let i = 0; i < terms.length; i++) {
+ let term = terms[i];
+ if (this._isInfoMatching(item, term)) {
+ score++;
+ }
+ }
+ return score;
+ },
+
+ _getSearchMatchedItems: function(isSubSearch) {
// Break the search up into terms, and search for each
// individual term. Keep track of the number of terms
// each item matched.
let terms = this._search.split(/\s+/);
- for (let i = 0; i < terms.length; i++) {
- let term = terms[i];
- for (itemId in this._allItems) {
- let item = this._allItems[itemId];
- if (this._isInfoMatching(item, term)) {
- let count = matchedItemsForSearch[itemId];
- if (!count)
- count = 0;
- count += 1;
- matchedItemsForSearch[itemId] = count;
- }
+ let matchScores = {};
+
+ if (isSubSearch) {
+ for (let i = 0; i < this._matchedItems.length; i++) {
+ let itemId = this._matchedItems[i];
+ let score = this._getItemSearchScore(itemId, terms);
+ if (score > 0)
+ matchScores[itemId] = score;
+ }
+ } else {
+ for (let itemId in this._allItems) {
+ let score = this._getItemSearchScore(itemId, terms);
+ if (score > 0)
+ matchScores[itemId] = score;
}
}
- return matchedItemsForSearch;
+ return matchScores;
},
// Applies the search string to the list of items to find matches,
// and displays the matching items.
- _doSearchFilter: function() {
+ _doSearchFilter: function(isSubSearch) {
let matchedItemsForSearch;
if (this._filterActive()) {
- matchedItemsForSearch = this._getSearchMatchedItems();
+ matchedItemsForSearch = this._getSearchMatchedItems(isSubSearch);
} else {
matchedItemsForSearch = {};
for (let itemId in this._allItems) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]