[gnome-contacts] Store: add contacts in a separate thread.



commit 9c256a5c7917a01f844c43501468c4700a4fcc28
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sun Apr 8 22:50:31 2018 +0200

    Store: add contacts in a separate thread.
    
    This should help with issue #75 by not blocking the main thread anymore
    when adding a huge amount of contacts (which is almost always the case
    when starting Contacts).

 src/contacts-contact-list.vala |  1 +
 src/contacts-store.vala        | 30 +++++++++++++++++++++++-------
 2 files changed, 24 insertions(+), 7 deletions(-)
---
diff --git a/src/contacts-contact-list.vala b/src/contacts-contact-list.vala
index 5a0dd0e..4f75316 100644
--- a/src/contacts-contact-list.vala
+++ b/src/contacts-contact-list.vala
@@ -116,6 +116,7 @@ public class Contacts.ContactList : ListBox {
 
     this.notify["state"].connect (on_ui_state_changed);
 
+    this.sort_on_surname = settings.sort_on_surname;
     settings.changed["sort-on-surname"].connect(() => {
         this.sort_on_surname = settings.sort_on_surname;
         invalidate_sort();
diff --git a/src/contacts-store.vala b/src/contacts-store.vala
index 3b75a88..5b7c715 100644
--- a/src/contacts-store.vala
+++ b/src/contacts-store.vala
@@ -176,10 +176,20 @@ public class Contacts.Store : GLib.Object {
     var replaced_individuals = new HashMap<Individual?, Individual?> ();
     var old_individuals = changes.get_keys();
 
+    // At startup, a mass of contacts are added here: so, do this in a separate thread.
+    var added_individuals = changes[null];
+    if (!added_individuals.is_empty) {
+      new Thread<void*> (null, () => {
+          bulk_add (added_individuals);
+          return null;
+        });
+    }
+
     // Pick best replacements at joins
     foreach (var old_individual in old_individuals) {
       if (old_individual == null)
         continue;
+
       foreach (var new_individual in changes[old_individual]) {
         if (new_individual == null)
           continue;
@@ -202,9 +212,6 @@ public class Contacts.Store : GLib.Object {
           // Removing an old individual.
           var c = Contact.from_individual (old_individual);
           remove (c);
-        } else if (new_individual != null) {
-          // Adding a new individual.
-          add (new Contact (this, new_individual));
         }
       }
 
@@ -231,7 +238,9 @@ public class Contacts.Store : GLib.Object {
           if (i != main_individual) {
             // Already replaced this old_individual, i.e. we're splitting
             // old_individual. We just make this a new one.
-            add (new Contact (this, i));
+            var new_contact = new Contact (this, i);
+            this.contacts.add (new_contact);
+            added (new_contact);
           }
         }
       }
@@ -277,9 +286,16 @@ public class Contacts.Store : GLib.Object {
     return contacts.read_only_view;
   }
 
-  private void add (Contact c) {
-    contacts.add (c);
-    added (c);
+  private void bulk_add (Collection<Individual> indivs) {
+    foreach (var individual in indivs) {
+      var c = new Contact (this, individual);
+      this.contacts.add (c);
+      // Since we do this in a separate thread, use Idle.add.
+      Idle.add (() => {
+          added (c);
+          return false;
+        });
+    }
   }
 
   private void remove (Contact c) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]