pidgin.next.minor: 3e6702b7: conversation: O(1) purple_conv_chat_cb_f...
darkrain42 at pidgin.im
darkrain42 at pidgin.im
Mon Jun 20 01:25:43 EDT 2011
----------------------------------------------------------------------
Revision: 3e6702b7af65c9e35d8aa1352d619c5408eeeee0
Parent: 2cfab48d6f33829b3a29bd711c9648bf0ac75fb9
Author: darkrain42 at pidgin.im
Date: 06/20/11 01:24:30
Branch: im.pidgin.pidgin.next.minor
URL: http://d.pidgin.im/viewmtn/revision/info/3e6702b7af65c9e35d8aa1352d619c5408eeeee0
Changelog:
conversation: O(1) purple_conv_chat_cb_find
I also deprecated what seems like a useless function. The
ui_data is to implement constant-time lookups for the room
list in Pidgin.
Changes against parent 2cfab48d6f33829b3a29bd711c9648bf0ac75fb9
patched ChangeLog.API
patched libpurple/conversation.c
patched libpurple/conversation.h
-------------- next part --------------
============================================================
--- libpurple/conversation.c 5d997f74639ed482eeb33a121b140ba6d52d4ce3
+++ libpurple/conversation.c 9ee548f6040abb5ae9b23fa821067990f2efee3f
@@ -70,6 +70,25 @@ static void _purple_conversations_hconv_
g_free(hc);
}
+static guint _purple_conversation_user_hash(gconstpointer data)
+{
+ const gchar *name = data;
+ gchar *casefold, *collated;
+ guint hash;
+
+ casefold = g_utf8_casefold(name, -1);
+ collated = g_utf8_collate_key(casefold, -1);
+ hash = g_str_hash(collated);
+ g_free(collated);
+ g_free(casefold);
+ return hash;
+}
+
+static gboolean _purple_conversation_user_equal(gconstpointer a, gconstpointer b)
+{
+ return !purple_utf8_strcasecmp(a, b);
+}
+
void
purple_conversations_set_ui_ops(PurpleConversationUiOps *ops)
{
@@ -393,6 +412,10 @@ purple_conversation_new(PurpleConversati
conv->u.chat = g_new0(PurpleConvChat, 1);
conv->u.chat->conv = conv;
+ conv->u.chat->user_hash_func = _purple_conversation_user_hash;
+ conv->u.chat->user_eq_func = _purple_conversation_user_equal;
+ conv->u.chat->users = g_hash_table_new_full(_purple_conversation_user_hash,
+ _purple_conversation_user_equal, NULL, NULL);
PURPLE_DBUS_REGISTER_POINTER(conv->u.chat, PurpleConvChat);
chats = g_list_prepend(chats, conv);
@@ -547,6 +570,8 @@ purple_conversation_destroy(PurpleConver
conv->u.im = NULL;
}
else if (conv->type == PURPLE_CONV_TYPE_CHAT) {
+ g_hash_table_destroy(conv->u.chat->users);
+ conv->u.chat->users = NULL;
g_list_foreach(conv->u.chat->in_room, (GFunc)purple_conv_chat_cb_destroy, NULL);
g_list_free(conv->u.chat->in_room);
@@ -1677,10 +1702,10 @@ purple_conv_chat_add_users(PurpleConvCha
cbuddy = purple_conv_chat_cb_new(user, alias, flag);
cbuddy->buddy = purple_find_buddy(conv->account, user) != NULL;
- /* This seems dumb. Why should we set users thousands of times? */
- purple_conv_chat_set_users(chat,
- g_list_prepend(chat->in_room, cbuddy));
+ chat->in_room = g_list_prepend(chat->in_room, cbuddy);
+ g_hash_table_replace(chat->users, cbuddy->name, cbuddy);
+
cbuddies = g_list_prepend(cbuddies, cbuddy);
if (!quiet && new_arrivals) {
@@ -1771,17 +1796,18 @@ purple_conv_chat_rename_user(PurpleConvC
flags = purple_conv_chat_user_get_flags(chat, old_user);
cb = purple_conv_chat_cb_new(new_user, new_alias, flags);
cb->buddy = purple_find_buddy(conv->account, new_user) != NULL;
- purple_conv_chat_set_users(chat,
- g_list_prepend(chat->in_room, cb));
+ chat->in_room = g_list_prepend(chat->in_room, cb);
+ g_hash_table_replace(chat->users, cb->name, cb);
+
if (ops != NULL && ops->chat_rename_user != NULL)
ops->chat_rename_user(conv, old_user, new_user, new_alias);
cb = purple_conv_chat_cb_find(chat, old_user);
if (cb) {
- purple_conv_chat_set_users(chat,
- g_list_remove(chat->in_room, cb));
+ chat->in_room = g_list_remove(chat->in_room, cb);
+ g_hash_table_remove(chat->users, cb->name);
purple_conv_chat_cb_destroy(cb);
}
@@ -1874,8 +1900,8 @@ purple_conv_chat_remove_users(PurpleConv
cb = purple_conv_chat_cb_find(chat, user);
if (cb) {
- purple_conv_chat_set_users(chat,
- g_list_remove(chat->in_room, cb));
+ chat->in_room = g_list_remove(chat->in_room, cb);
+ g_hash_table_remove(chat->users, cb);
purple_conv_chat_cb_destroy(cb);
}
@@ -1943,6 +1969,8 @@ purple_conv_chat_clear_users(PurpleConvC
g_list_free(names);
}
+ g_hash_table_remove_all(chat->users);
+
for (l = users; l; l = l->next)
{
PurpleConvChatBuddy *cb = l->data;
@@ -1956,7 +1984,7 @@ purple_conv_chat_clear_users(PurpleConvC
}
g_list_free(users);
- purple_conv_chat_set_users(chat, NULL);
+ chat->in_room = NULL;
}
@@ -2146,19 +2174,10 @@ purple_conv_chat_cb_find(PurpleConvChat
PurpleConvChatBuddy *
purple_conv_chat_cb_find(PurpleConvChat *chat, const char *name)
{
- GList *l;
- PurpleConvChatBuddy *cb = NULL;
-
g_return_val_if_fail(chat != NULL, NULL);
g_return_val_if_fail(name != NULL, NULL);
- for (l = purple_conv_chat_get_users(chat); l; l = l->next) {
- cb = l->data;
- if (!g_utf8_collate(cb->name, name))
- return cb;
- }
-
- return NULL;
+ return g_hash_table_lookup(chat->users, name);
}
void
============================================================
--- libpurple/conversation.h 1b5c4abc64bc9456e7f4d60bf23713f150e1da94
+++ libpurple/conversation.h 4fc61f2537f22c89cb7420fa8224e638eeb3864e
@@ -271,7 +271,9 @@ struct _PurpleConvChat
{
PurpleConversation *conv; /**< The parent conversation. */
- GList *in_room; /**< The users in the room. */
+ GList *in_room; /**< The users in the room.
+ * @deprecated Will be removed in 3.0.0
+ */
GList *ignored; /**< Ignored users. */
char *who; /**< The person who set the topic. */
char *topic; /**< The topic. */
@@ -279,6 +281,19 @@ struct _PurpleConvChat
char *nick; /**< Your nick in this chat. */
gboolean left; /**< We left the chat and kept the window open */
+ GHashTable *users; /**< Hash table of the users in the room.
+ * @since 2.9.0
+ */
+ GHashFunc user_hash_func; /**< Function used to hash entries into
+ * the users hash. Defaults to a
+ * case-insensitive collation function.
+ * @since 2.9.0
+ */
+ GEqualFunc user_eq_func; /**< Function used for equality in the
+ * users hash. Defaults to a wrapper
+ * around purple_utf8_strcasecmp.
+ * @since 2.9.0
+ */
};
/**
@@ -304,6 +319,7 @@ struct _PurpleConvChatBuddy
GHashTable *attributes; /**< A hash table of attributes about the user, such as
* real name, user at host, etc.
*/
+ gpointer ui_data; /** < The UI can put whatever it wants here. */
};
/**
@@ -1065,6 +1081,8 @@ PurpleConversation *purple_conv_chat_get
* @param users The list of users.
*
* @return The list passed.
+ *
+ * @deprecated This function will be removed in 3.0.0. You shouldn't be using it anyway.
*/
GList *purple_conv_chat_set_users(PurpleConvChat *chat, GList *users);
============================================================
--- ChangeLog.API 94479f9df0b0926fd66f8b8c8bf2aa6e1b617dc3
+++ ChangeLog.API b664bc9be9035c5e4378f63bc4c0b3bc643d3ab8
@@ -1,7 +1,18 @@ version 2.9.0 (MM/DD/YYYY):
Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
version 2.9.0 (MM/DD/YYYY):
+ libpurple:
+ Added:
+ * Hash table and equivalence function to PurpleConvChat struct,
+ which makes purple_conv_chat_cb_find O(1). The equivalence
+ function should only be set by a prpl, and must only be set
+ before any occupants are in the room.
+ * ui_data opaque pointer to PurpleConvChatBuddy struct.
+ Deprecated:
+ * purple_conv_chat_set_users
+ * PurpleConvChat in_room list
+
version 2.8.0 (06/07/2011):
libpurple:
Added:
More information about the Commits
mailing list