[folks] eds: Support lazy initialisation of properties
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] eds: Support lazy initialisation of properties
- Date: Tue, 28 Aug 2012 21:04:03 +0000 (UTC)
commit 57f84d50f5fcaf3bf821d368a7ff309bc2edb3d2
Author: Philip Withnall <philip tecnocode co uk>
Date: Mon Aug 27 10:13:19 2012 +0100
eds: Support lazy initialisation of properties
See commit 303547fec56e416f57f73643e2afb7bb4e4a8a7f. This adds support for
lazy initialisation of multi-valued properties to the EDS backend.
backends/eds/lib/edsf-persona.vala | 275 ++++++++++++++++++++++++++----------
1 files changed, 198 insertions(+), 77 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index f757f7d..3acd098 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -149,22 +149,8 @@ public class Edsf.Persona : Folks.Persona,
"local-ids",
"web-service-addresses" };
- private HashSet<PhoneFieldDetails> _phone_numbers;
- private Set<PhoneFieldDetails> _phone_numbers_ro;
- private HashSet<EmailFieldDetails> _email_addresses;
- private Set<EmailFieldDetails> _email_addresses_ro;
- private HashSet<NoteFieldDetails> _notes;
- private Set<NoteFieldDetails> _notes_ro;
private static HashTable<string, E.ContactField>? _im_eds_map = null;
- private HashSet<PostalAddressFieldDetails> _postal_addresses;
- private Set<PostalAddressFieldDetails> _postal_addresses_ro;
-
- private HashSet<string> _local_ids;
- private Set<string> _local_ids_ro;
-
- private HashMultiMap<string, WebServiceFieldDetails> _web_service_addresses;
-
private bool _is_favourite;
private E.Contact _contact; /* should be set on construct */
@@ -178,6 +164,11 @@ public class Edsf.Persona : Folks.Persona,
construct { this._contact = value; }
}
+ /* NOTE: Other properties support lazy initialisation, but
+ * web-service-addresses doesn't as it's a linkable property, so always has to
+ * be loaded anyway. */
+ private HashMultiMap<string, WebServiceFieldDetails> _web_service_addresses;
+
/**
* { inheritDoc}
*/
@@ -201,6 +192,11 @@ public class Edsf.Persona : Folks.Persona,
web_service_addresses);
}
+ /* NOTE: Other properties support lazy initialisation, but local-ids doesn't
+ * as it's a linkable property, so always has to be loaded anyway. */
+ private HashSet<string> _local_ids = new HashSet<string> ();
+ private Set<string> _local_ids_ro;
+
/**
* IDs used to link { link Edsf.Persona}s.
*/
@@ -229,6 +225,9 @@ public class Edsf.Persona : Folks.Persona,
yield ((Edsf.PersonaStore) this.store)._set_local_ids (this, local_ids);
}
+ private HashSet<PostalAddressFieldDetails>? _postal_addresses = null;
+ private Set<PostalAddressFieldDetails>? _postal_addresses_ro = null;
+
/**
* The postal addresses of the contact.
*
@@ -239,7 +238,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<PostalAddressFieldDetails> postal_addresses
{
- get { return this._postal_addresses_ro; }
+ get
+ {
+ this._update_addresses (true);
+ return this._postal_addresses_ro;
+ }
set { this.change_postal_addresses.begin (value); }
}
@@ -255,6 +258,9 @@ public class Edsf.Persona : Folks.Persona,
postal_addresses);
}
+ private HashSet<PhoneFieldDetails>? _phone_numbers = null;
+ private Set<PhoneFieldDetails>? _phone_numbers_ro = null;
+
/**
* { inheritDoc}
*
@@ -263,7 +269,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<PhoneFieldDetails> phone_numbers
{
- get { return this._phone_numbers_ro; }
+ get
+ {
+ this._update_phones (true);
+ return this._phone_numbers_ro;
+ }
set { this.change_phone_numbers.begin (value); }
}
@@ -278,6 +288,9 @@ public class Edsf.Persona : Folks.Persona,
yield ((Edsf.PersonaStore) this.store)._set_phones (this, phone_numbers);
}
+ private HashSet<EmailFieldDetails>? _email_addresses = null;
+ private Set<EmailFieldDetails>? _email_addresses_ro = null;
+
/**
* { inheritDoc}
*
@@ -286,7 +299,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<EmailFieldDetails> email_addresses
{
- get { return this._email_addresses_ro; }
+ get
+ {
+ this._update_emails (true);
+ return this._email_addresses_ro;
+ }
set { this.change_email_addresses.begin (value); }
}
@@ -302,6 +319,9 @@ public class Edsf.Persona : Folks.Persona,
email_addresses);
}
+ private HashSet<NoteFieldDetails>? _notes = null;
+ private Set<NoteFieldDetails>? _notes_ro = null;
+
/**
* { inheritDoc}
*
@@ -310,7 +330,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<NoteFieldDetails> notes
{
- get { return this._notes_ro; }
+ get
+ {
+ this._update_notes (true);
+ return this._notes_ro;
+ }
set { this.change_notes.begin (value); }
}
@@ -471,8 +495,8 @@ public class Edsf.Persona : Folks.Persona,
yield ((Edsf.PersonaStore) this.store)._set_gender (this, gender);
}
- private HashSet<UrlFieldDetails> _urls;
- private Set<UrlFieldDetails> _urls_ro;
+ private HashSet<UrlFieldDetails>? _urls = null;
+ private Set<UrlFieldDetails>? _urls_ro = null;
/**
* { inheritDoc}
*
@@ -481,7 +505,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<UrlFieldDetails> urls
{
- get { return this._urls_ro; }
+ get
+ {
+ this._update_urls (true);
+ return this._urls_ro;
+ }
set { this.change_urls.begin (value); }
}
@@ -495,6 +523,8 @@ public class Edsf.Persona : Folks.Persona,
yield ((Edsf.PersonaStore) this.store)._set_urls (this, urls);
}
+ /* NOTE: Other properties support lazy initialisation, but im-addresses
+ * doesn't as it's a linkable property, so always has to be loaded anyway. */
private HashMultiMap<string, ImFieldDetails> _im_addresses =
new HashMultiMap<string, ImFieldDetails> (null, null,
(GLib.HashFunc) ImFieldDetails.hash,
@@ -523,8 +553,8 @@ public class Edsf.Persona : Folks.Persona,
yield ((Edsf.PersonaStore) this.store)._set_im_fds (this, im_addresses);
}
- private HashSet<string> _groups;
- private Set<string> _groups_ro;
+ private HashSet<string>? _groups = null;
+ private Set<string>? _groups_ro = null;
/**
* { inheritDoc}
@@ -534,7 +564,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<string> groups
{
- get { return this._groups_ro; }
+ get
+ {
+ this._update_groups (true);
+ return this._groups_ro;
+ }
set { this.change_groups.begin (value); }
}
@@ -546,16 +580,19 @@ public class Edsf.Persona : Folks.Persona,
public async void change_group (string group, bool is_member)
throws GLib.Error
{
+ /* NOTE: This method specifically accesses this.groups rather than
+ * this._groups, so that lazy loading is guaranteed to happen if
+ * necessary. */
/* Nothing to do? */
- if ((is_member == true && this._groups.contains (group) == true) ||
- (is_member == false && this._groups.contains (group) == false))
+ if ((is_member == true && this.groups.contains (group) == true) ||
+ (is_member == false && this.groups.contains (group) == false))
{
return;
}
/* Replace the current set of groups with a modified one. */
var new_groups = new HashSet<string> ();
- foreach (var category_name in this._groups)
+ foreach (var category_name in this.groups)
{
new_groups.add (category_name);
}
@@ -625,8 +662,8 @@ public class Edsf.Persona : Folks.Persona,
bday);
}
- private HashSet<RoleFieldDetails> _roles;
- private Set<RoleFieldDetails> _roles_ro;
+ private HashSet<RoleFieldDetails>? _roles = null;
+ private Set<RoleFieldDetails>? _roles_ro = null;
/**
* { inheritDoc}
@@ -636,7 +673,11 @@ public class Edsf.Persona : Folks.Persona,
[CCode (notify = false)]
public Set<RoleFieldDetails> roles
{
- get { return this._roles_ro; }
+ get
+ {
+ this._update_roles (true);
+ return this._roles_ro;
+ }
set { this.change_roles.begin (value); }
}
@@ -790,39 +831,12 @@ public class Edsf.Persona : Folks.Persona,
debug ("Creating new Edsf.Persona with IID '%s'", this.iid);
this._gender = Gender.UNSPECIFIED;
- this._phone_numbers = new HashSet<PhoneFieldDetails> (
- (GLib.HashFunc) PhoneFieldDetails.hash,
- (GLib.EqualFunc) PhoneFieldDetails.equal);
- this._phone_numbers_ro = this._phone_numbers.read_only_view;
- this._email_addresses = new HashSet<EmailFieldDetails> (
- (GLib.HashFunc) EmailFieldDetails.hash,
- (GLib.EqualFunc) EmailFieldDetails.equal);
- this._email_addresses_ro = this._email_addresses.read_only_view;
- this._notes = new HashSet<NoteFieldDetails> (
- (GLib.HashFunc) NoteFieldDetails.hash,
- (GLib.EqualFunc) NoteFieldDetails.equal);
- this._notes_ro = this._notes.read_only_view;
- this._urls = new HashSet<UrlFieldDetails> (
- (GLib.HashFunc) UrlFieldDetails.hash,
- (GLib.EqualFunc) UrlFieldDetails.equal);
- this._urls_ro = this._urls.read_only_view;
- this._postal_addresses = new HashSet<PostalAddressFieldDetails> (
- (GLib.HashFunc) PostalAddressFieldDetails.hash,
- (GLib.EqualFunc) PostalAddressFieldDetails.equal);
- this._postal_addresses_ro = this._postal_addresses.read_only_view;
- this._local_ids = new HashSet<string> ();
this._local_ids_ro = this._local_ids.read_only_view;
this._web_service_addresses =
new HashMultiMap<string, WebServiceFieldDetails> (
null, null,
(GLib.HashFunc) WebServiceFieldDetails.hash,
(GLib.EqualFunc) WebServiceFieldDetails.equal);
- this._groups = new HashSet<string> ();
- this._groups_ro = this._groups.read_only_view;
- this._roles = new HashSet<RoleFieldDetails> (
- (GLib.HashFunc) RoleFieldDetails.hash,
- (GLib.EqualFunc) RoleFieldDetails.equal);
- this._roles_ro = this._roles.read_only_view;
this._anti_links = new HashSet<string> ();
this._anti_links_ro = this._anti_links.read_only_view;
@@ -895,10 +909,10 @@ public class Edsf.Persona : Folks.Persona,
this._update_names ();
this._update_avatar ();
- this._update_urls ();
- this._update_phones ();
- this._update_addresses ();
- this._update_emails ();
+ this._update_urls (false);
+ this._update_phones (false);
+ this._update_addresses (false);
+ this._update_emails (false);
/* Note: because we assume certain e-mail addresses
* (@gmail, @msn, etc) to also be IM IDs we /must/
@@ -906,13 +920,13 @@ public class Edsf.Persona : Folks.Persona,
*/
this._update_im_addresses ();
- this._update_groups ();
- this._update_notes ();
+ this._update_groups (false);
+ this._update_notes (false);
this._update_local_ids ();
this._update_web_services_addresses ();
this._update_gender ();
this._update_birthday ();
- this._update_roles ();
+ this._update_roles (false);
this._update_favourite ();
this._update_anti_links ();
@@ -1005,8 +1019,23 @@ public class Edsf.Persona : Folks.Persona,
}
}
- private void _update_roles ()
+ private void _update_roles (bool create_if_not_exist)
{
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for roles. */
+ if (this._roles == null && create_if_not_exist == false)
+ {
+ this.notify_property ("roles");
+ return;
+ }
+ else if (this._roles == null)
+ {
+ this._roles = new HashSet<RoleFieldDetails> (
+ (GLib.HashFunc) RoleFieldDetails.hash,
+ (GLib.EqualFunc) RoleFieldDetails.equal);
+ this._roles_ro = this._roles.read_only_view;
+ }
+
var new_roles = new HashSet<RoleFieldDetails> (
(GLib.HashFunc) RoleFieldDetails.hash,
(GLib.EqualFunc) RoleFieldDetails.equal);
@@ -1159,8 +1188,23 @@ public class Edsf.Persona : Folks.Persona,
}
}
- private void _update_emails ()
+ private void _update_emails (bool create_if_not_exist)
{
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for e-mail addresses. */
+ if (this._email_addresses == null && create_if_not_exist == false)
+ {
+ this.notify_property ("email-addresses");
+ return;
+ }
+ else if (this._email_addresses == null)
+ {
+ this._email_addresses = new HashSet<EmailFieldDetails> (
+ (GLib.HashFunc) EmailFieldDetails.hash,
+ (GLib.EqualFunc) EmailFieldDetails.equal);
+ this._email_addresses_ro = this._email_addresses.read_only_view;
+ }
+
var new_email_addresses = new HashSet<EmailFieldDetails> (
(GLib.HashFunc) EmailFieldDetails.hash,
(GLib.EqualFunc) EmailFieldDetails.equal);
@@ -1188,8 +1232,23 @@ public class Edsf.Persona : Folks.Persona,
}
}
- private void _update_notes ()
+ private void _update_notes (bool create_if_not_exist)
{
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for notes. */
+ if (this._notes == null && create_if_not_exist == false)
+ {
+ this.notify_property ("notes");
+ return;
+ }
+ else if (this._notes == null)
+ {
+ this._notes = new HashSet<NoteFieldDetails> (
+ (GLib.HashFunc) NoteFieldDetails.hash,
+ (GLib.EqualFunc) NoteFieldDetails.equal);
+ this._notes_ro = this._notes.read_only_view;
+ }
+
var new_notes = new HashSet<NoteFieldDetails> (
(GLib.HashFunc) NoteFieldDetails.hash,
(GLib.EqualFunc) NoteFieldDetails.equal);
@@ -1350,9 +1409,26 @@ public class Edsf.Persona : Folks.Persona,
}
}
- private void _update_urls ()
+ private void _update_urls (bool create_if_not_exist)
{
- var new_urls = new HashSet<UrlFieldDetails> ();
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for URIs. */
+ if (this._urls == null && create_if_not_exist == false)
+ {
+ this.notify_property ("urls");
+ return;
+ }
+ else if (this._urls == null)
+ {
+ this._urls = new HashSet<UrlFieldDetails> (
+ (GLib.HashFunc) UrlFieldDetails.hash,
+ (GLib.EqualFunc) UrlFieldDetails.equal);
+ this._urls_ro = this._urls.read_only_view;
+ }
+
+ var new_urls = new HashSet<UrlFieldDetails> (
+ (GLib.HashFunc) UrlFieldDetails.hash,
+ (GLib.EqualFunc) UrlFieldDetails.equal);
/* First we get the standard Evo urls.. */
foreach (var mapping in Persona._url_properties)
@@ -1444,6 +1520,10 @@ public class Edsf.Persona : Folks.Persona,
* who don't actually use GMail or MSN addresses for IM).
*
* See bgo#657142
+ *
+ * NOTE: The public property name (this.email_addresses, as opposed to
+ * this._email_addresses) is used here to ensure the values are
+ * lazy-loaded correctly.
*/
foreach (var email in this.email_addresses)
{
@@ -1495,8 +1575,21 @@ public class Edsf.Persona : Folks.Persona,
}
}
- private void _update_groups ()
+ private void _update_groups (bool create_if_not_exist)
{
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for groups. */
+ if (this._groups == null && create_if_not_exist == false)
+ {
+ this.notify_property ("groups");
+ return;
+ }
+ else if (this._groups == null)
+ {
+ this._groups = new HashSet<string> ();
+ this._groups_ro = this._groups.read_only_view;
+ }
+
var category_names =
this._contact.get<GLib.List<string>> (E.ContactField.CATEGORY_LIST);
var new_categories = new HashSet<string> ();
@@ -1638,8 +1731,23 @@ public class Edsf.Persona : Folks.Persona,
return retval;
}
- private void _update_phones ()
+ private void _update_phones (bool create_if_not_exist)
{
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for phone numbers. */
+ if (this._phone_numbers == null && create_if_not_exist == false)
+ {
+ this.notify_property ("phone-numbers");
+ return;
+ }
+ else if (this._phone_numbers == null)
+ {
+ this._phone_numbers = new HashSet<PhoneFieldDetails> (
+ (GLib.HashFunc) PhoneFieldDetails.hash,
+ (GLib.EqualFunc) PhoneFieldDetails.equal);
+ this._phone_numbers_ro = this._phone_numbers.read_only_view;
+ }
+
var new_phone_numbers = new HashSet<PhoneFieldDetails> (
(GLib.HashFunc) PhoneFieldDetails.hash,
(GLib.EqualFunc) PhoneFieldDetails.equal);
@@ -1727,11 +1835,26 @@ public class Edsf.Persona : Folks.Persona,
* are the same and if so instantiate only one PostalAddress
* (with the given types).
*/
- private void _update_addresses ()
+ private void _update_addresses (bool create_if_not_exist)
{
+ /* See the comments in Folks.Individual about the lazy instantiation
+ * strategy for addresses. */
+ if (this._postal_addresses == null && create_if_not_exist == false)
+ {
+ this.notify_property ("postal-addresses");
+ return;
+ }
+ else if (this._postal_addresses == null)
+ {
+ this._postal_addresses = new HashSet<PostalAddressFieldDetails> (
+ (GLib.HashFunc) PostalAddressFieldDetails.hash,
+ (GLib.EqualFunc) PostalAddressFieldDetails.equal);
+ this._postal_addresses_ro = this._postal_addresses.read_only_view;
+ }
+
var new_postal_addresses = new HashSet<PostalAddressFieldDetails> (
- (GLib.HashFunc) PhoneFieldDetails.hash,
- (GLib.EqualFunc) PhoneFieldDetails.equal);
+ (GLib.HashFunc) PostalAddressFieldDetails.hash,
+ (GLib.EqualFunc) PostalAddressFieldDetails.equal);
var attrs = this.contact.get_attributes (E.ContactField.ADDRESS);
foreach (unowned E.VCardAttribute attr in attrs)
@@ -1753,10 +1876,8 @@ public class Edsf.Persona : Folks.Persona,
{
this._postal_addresses = new_postal_addresses;
this._postal_addresses_ro = new_postal_addresses.read_only_view;
- this.notify_property ("phone-numbers");
+ this.notify_property ("postal-addresses");
}
-
- this.notify_property ("postal-addresses");
}
private void _update_local_ids ()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]