From: Philip Withnall Date: Mon, 27 Aug 2012 08:59:55 +0000 (+0100) Subject: eds: Batch up emissions of personas-changed while starting up X-Git-Tag: FOLKS_0_7_4_1~41 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3e48d450d35b8c21b407dc481b74b0983507bf1c;p=platform%2Fupstream%2Ffolks.git eds: Batch up emissions of personas-changed while starting up There’s no point in emitting personas-changed multiple times before the EDS persona store has reached quiescence — it just means the individual aggregator has to re-link more personas with each emission. This patch batches up emissions of personas-changed from the EDS persona store until is-quiescent is reached, then notifies about all personas in a single emission. --- diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala index cce55f7..2cd302c 100644 --- a/backends/eds/lib/edsf-persona-store.vala +++ b/backends/eds/lib/edsf-persona-store.vala @@ -46,6 +46,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore private bool _is_prepared = false; private bool _prepare_pending = false; private bool _is_quiescent = false; + private HashSet? _pending_personas = null; /* null before prepare()*/ private E.BookClient? _addressbook = null; /* null before prepare() */ private E.BookClientView? _ebookview = null; /* null before prepare() */ private E.SourceRegistry? _source_registry = null; /* null before prepare() */ @@ -960,6 +961,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore * a quiescent state immediately. */ if (do_initial_query == false && this._is_quiescent == false) { + assert (this._pending_personas == null); /* no initial query */ this._is_quiescent = true; this.notify_property ("is-quiescent"); } @@ -2098,7 +2100,25 @@ public class Edsf.PersonaStore : Folks.PersonaStore private void _contacts_added_cb (GLib.List contacts) { - var added_personas = new HashSet (); + HashSet added_personas; + + /* If the persona store hasn't yet reached quiescence, queue up the + * personas and emit a notification about them later; see + * _contacts_complete_cb() for details. */ + if (this._is_quiescent == false) + { + /* Lazily create pending_personas. */ + if (this._pending_personas == null) + { + this._pending_personas = new HashSet (); + } + + added_personas = this._pending_personas; + } + else + { + added_personas = new HashSet (); + } foreach (E.Contact c in contacts) { @@ -2111,7 +2131,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore } } - if (added_personas.size > 0) + if (added_personas.size > 0 && this._is_quiescent == true) { this._emit_personas_changed (added_personas, null); } @@ -2142,6 +2162,13 @@ public class Edsf.PersonaStore : Folks.PersonaStore { removed_personas.add ((!) persona); this._personas.unset (((!) persona).iid); + + /* Handle the case where a contact is removed before the persona + * store has reached quiescence. */ + if (this._pending_personas != null) + { + this._pending_personas.remove ((!) persona); + } } } @@ -2178,6 +2205,19 @@ public class Edsf.PersonaStore : Folks.PersonaStore return; } + /* Emit a notification about all the personas which were found in the + * initial query. They're queued up in _contacts_added_cb() and only + * emitted here as _contacts_added_cb() may be called many times + * before _contacts_complete_cb() is called. For example, EDS seems to + * like emitting contacts in batches of 16 at the moment. + * Queueing the personas up and emitting a single notification is a + * lot more efficient for the individual aggregator to handle. */ + if (this._pending_personas != null) + { + this._emit_personas_changed (this._pending_personas, null); + this._pending_personas = null; + } + this._is_quiescent = true; this.notify_property ("is-quiescent"); }