summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNiels De Graef <nielsdegraef@gmail.com>2022-08-17 00:14:50 +0200
committerNiels De Graef <nielsdegraef@gmail.com>2022-08-17 01:25:56 +0200
commit7a4aa6227830680ab790e2de314aa7b7e6e15da5 (patch)
tree7837f8bc43914fba2310af06b50c5caea1d39ee9 /src
parent3b343fda88a6f328f5664104c548ee5f5e3b9f44 (diff)
downloadgnome-contacts-7a4aa6227830680ab790e2de314aa7b7e6e15da5.tar.gz
query-filter: Optimize for SimpleQuery
Before this commit, the QueryFilter used a very naive implementation where it would just re-filter all contacts if something change (like a query string). This wasn't of course the most performant thing to do, and after some investigation we found out that on each search bar change, we were using quite some CPU. This commit adds some optimizations by avoiding unnecessary refiltering of contacts where possible. This shaves off quite a few percentages of CPU usage when doing some searching in the side bar.
Diffstat (limited to 'src')
-rw-r--r--src/contacts-query-filter.vala48
1 files changed, 44 insertions, 4 deletions
diff --git a/src/contacts-query-filter.vala b/src/contacts-query-filter.vala
index c563f73..b4459c1 100644
--- a/src/contacts-query-filter.vala
+++ b/src/contacts-query-filter.vala
@@ -28,6 +28,10 @@ public class Contacts.QueryFilter : Gtk.Filter {
public Query query { get; construct; }
+ // if this.query is a SimpleQuery, we can save the query string to enable
+ // some optimizations (see later)
+ private string query_string = "";
+
private uint _min_strength = 0;
public uint min_strength {
get { return this._min_strength; }
@@ -40,20 +44,56 @@ public class Contacts.QueryFilter : Gtk.Filter {
}
}
+ construct {
+ if (this.query is SimpleQuery)
+ this.query_string = ((SimpleQuery) this.query).query_string;
+ this.query.notify.connect (on_query_notify);
+ }
+
public QueryFilter (Query query) {
Object (query: query);
-
- query.notify.connect (on_query_notify);
}
private void on_query_notify (Object object, ParamSpec pspec) {
+ unowned var query = (Query) object;
+
+ // We can optimize a bit in the case of a SimpleQuery
+ if (query is SimpleQuery) {
+ // SimpleQuery notifies its locale changed on a query string update,
+ // even if it didn't change (and we don't support changing it either)
+ if (pspec.get_name () == "query-locale")
+ return;
+
+ // A very common use case is that the user is typing in the search bar.
+ // In case they add a letter, we know the filter will be more strict (and
+ // vice versa)
+ if (pspec.get_name () == "query-string") {
+ var old_query_str = this.query_string;
+ this.query_string = ((SimpleQuery) query).query_string;
+
+ // We shouldn't get a notify for this but in reality we do, so ignore it
+ if (this.query_string == old_query_str)
+ return;
+
+ if (this.query_string.length > old_query_str.length &&
+ this.query_string.index_of (old_query_str) != -1) {
+ this.changed (Gtk.FilterChange.MORE_STRICT);
+ return;
+ }
+ if (this.query_string.length < old_query_str.length &&
+ old_query_str.index_of (this.query_string) != -1) {
+ this.changed (Gtk.FilterChange.LESS_STRICT);
+ return;
+ }
+ }
+ }
+
this.changed (Gtk.FilterChange.DIFFERENT);
}
public override bool match (GLib.Object? item) {
unowned var individual = item as Individual;
- if (individual == null)
- return false;
+ return_val_if_fail (individual != null, false);
return this.query.is_match (individual) > this.min_strength;
}