diff libpurple/blist.c @ 27645:36aa9ed8cd39

Use a hash table for looking up PurpleGroup:s. Apparently Aman "tmm1" Gupta has a lot of groups in his buddy list, so he wrote this patch. committer: Paul Aurich <paul@darkrain42.org>
author aman@tmm1.net
date Thu, 16 Jul 2009 04:40:08 +0000
parents c7812bda30f1
children b84f51988365
line wrap: on
line diff
--- a/libpurple/blist.c	Thu Jul 16 03:55:24 2009 +0000
+++ b/libpurple/blist.c	Thu Jul 16 04:40:08 2009 +0000
@@ -48,6 +48,12 @@
  */
 static GHashTable *buddies_cache = NULL;
 
+/**
+ * A hash table used for efficient lookups of groups by name.
+ * UTF-8 collate-key => PurpleGroup*.
+ */
+static GHashTable *groups_cache = NULL;
+
 static guint          save_timer = 0;
 static gboolean       blist_loaded = FALSE;
 
@@ -704,6 +710,10 @@
 	buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal,
 					 NULL, (GDestroyNotify)g_hash_table_destroy);
 
+	groups_cache = g_hash_table_new_full((GHashFunc)g_str_hash,
+					 (GEqualFunc)g_str_equal,
+					 (GDestroyNotify)g_free, NULL);
+
 	for (account = purple_accounts_get_all(); account != NULL; account = account->next)
 	{
 		purple_blist_buddies_cache_add_account(account->data);
@@ -1203,6 +1213,7 @@
 	} else {
 		/* A simple rename */
 		PurpleBlistNode *cnode, *bnode;
+		gchar* key;
 
 		/* Build a GList of all buddies in this group */
 		for (cnode = ((PurpleBlistNode *)source)->child; cnode != NULL; cnode = cnode->next) {
@@ -1213,6 +1224,13 @@
 
 		old_name = source->name;
 		source->name = new_name;
+
+		key = g_utf8_collate_key(old_name, -1);
+		g_hash_table_remove(groups_cache, key);
+		g_free(key);
+
+		key = g_utf8_collate_key(new_name, -1);
+		g_hash_table_insert(groups_cache, key, source);
 	}
 
 	/* Save our changes */
@@ -1946,6 +1964,7 @@
 {
 	PurpleBlistUiOps *ops;
 	PurpleBlistNode *gnode = (PurpleBlistNode*)group;
+	gchar* key;
 
 	g_return_if_fail(group != NULL);
 	g_return_if_fail(PURPLE_BLIST_NODE_IS_GROUP((PurpleBlistNode *)group));
@@ -1989,6 +2008,9 @@
 		purplebuddylist->root = gnode;
 	}
 
+	key = g_utf8_collate_key(group->name, -1);
+	g_hash_table_insert(groups_cache, key, group);
+
 	purple_blist_schedule_save();
 
 	if (ops && ops->update) {
@@ -2174,6 +2196,7 @@
 	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
 	PurpleBlistNode *node;
 	GList *l;
+	gchar* key;
 
 	g_return_if_fail(group != NULL);
 
@@ -2191,6 +2214,10 @@
 	if (node->next)
 		node->next->prev = node->prev;
 
+	key = g_utf8_collate_key(group->name, -1);
+	g_hash_table_remove(groups_cache, key);
+	g_free(key);
+
 	purple_blist_schedule_save();
 
 	/* Update the UI */
@@ -2427,17 +2454,17 @@
 
 PurpleGroup *purple_find_group(const char *name)
 {
-	PurpleBlistNode *node;
+	gchar* key;
+	PurpleGroup *group;
 
 	g_return_val_if_fail(purplebuddylist != NULL, NULL);
 	g_return_val_if_fail((name != NULL) && (*name != '\0'), NULL);
 
-	for (node = purplebuddylist->root; node != NULL; node = node->next) {
-		if (!purple_utf8_strcasecmp(((PurpleGroup *)node)->name, name))
-			return (PurpleGroup *)node;
-	}
-
-	return NULL;
+	key = g_utf8_collate_key(name, -1);
+	group = g_hash_table_lookup(groups_cache, key);
+	g_free(key);
+
+	return group;
 }
 
 PurpleChat *
@@ -3117,6 +3144,10 @@
 
 	g_hash_table_destroy(purplebuddylist->buddies);
 	g_hash_table_destroy(buddies_cache);
+	g_hash_table_destroy(groups_cache);
+
+	buddies_cache = NULL;
+	groups_cache = NULL;
 
 	PURPLE_DBUS_UNREGISTER_POINTER(purplebuddylist);
 	g_free(purplebuddylist);