changeset 15106:f41cd6f78c60

[gaim-migrate @ 17892] Use GHashTable and GQueue instead of GSList in a few places in oscar. The speed improvements probably won't be noticeable. 4 files changed, 48 insertions(+), 106 deletions(-) committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 04 Dec 2006 11:14:11 +0000
parents b2b0839f57d0
children 917a50335af3
files libgaim/protocols/oscar/family_oservice.c libgaim/protocols/oscar/flap_connection.c libgaim/protocols/oscar/oscar.h libgaim/protocols/oscar/oscar_data.c
diffstat 4 files changed, 49 insertions(+), 107 deletions(-) [+]
line wrap: on
line diff
--- a/libgaim/protocols/oscar/family_oservice.c	Mon Dec 04 07:47:50 2006 +0000
+++ b/libgaim/protocols/oscar/family_oservice.c	Mon Dec 04 11:14:11 2006 +0000
@@ -278,18 +278,6 @@
 	return NULL;
 }
 
-static void
-rateclass_addpair(struct rateclass *rateclass, guint16 group, guint16 type)
-{
-	struct snacpair *snacpair;
-
-	snacpair = g_new(struct snacpair, 1);
-	snacpair->group = group;
-	snacpair->subtype = type;
-
-	rateclass->members = g_slist_prepend(rateclass->members, snacpair);
-}
-
 /* Subtype 0x0007 - Rate Parameters */
 static int
 rateresp(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
@@ -326,6 +314,7 @@
 		if (mod->version >= 3)
 			byte_stream_getrawbuf(bs, rateclass->unknown, sizeof(rateclass->unknown));
 
+		rateclass->members = g_hash_table_new(g_direct_hash, g_direct_equal);
 		rateclass->last.tv_sec = 0;
 		rateclass->last.tv_usec = 0;
 		conn->rateclasses = g_slist_prepend(conn->rateclasses, rateclass);
@@ -354,9 +343,10 @@
 			subtype = byte_stream_get16(bs);
 
 			if (rateclass != NULL)
-				rateclass_addpair(rateclass, group, subtype);
+				g_hash_table_insert(rateclass->members,
+						GUINT_TO_POINTER((group << 16) + subtype),
+						GUINT_TO_POINTER(TRUE));
 		}
-		rateclass->members = g_slist_reverse(rateclass->members);
 	}
 
 	/*
--- a/libgaim/protocols/oscar/flap_connection.c	Mon Dec 04 07:47:50 2006 +0000
+++ b/libgaim/protocols/oscar/flap_connection.c	Mon Dec 04 11:14:11 2006 +0000
@@ -75,22 +75,18 @@
 static struct rateclass *
 flap_connection_get_rateclass(FlapConnection *conn, guint16 family, guint16 subtype)
 {
-	GSList *tmp1, *tmp2;
+	GSList *tmp1;
+	gconstpointer key;
+
+	key = GUINT_TO_POINTER((family << 16) + subtype);
 
 	for (tmp1 = conn->rateclasses; tmp1 != NULL; tmp1 = tmp1->next)
 	{
 		struct rateclass *rateclass;
 		rateclass = tmp1->data;
 
-		for (tmp2 = rateclass->members; tmp2 != NULL; tmp2 = tmp2->next)
-		{
-			struct snacpair *snacpair;
-			snacpair = tmp2->data;
-			if ((snacpair->group == family) && (snacpair->subtype == subtype))
-			{
-				return rateclass;
-			}
-		}
+		if (g_hash_table_lookup(rateclass->members, key))
+			return rateclass;
 	}
 
 	return NULL;
@@ -119,12 +115,12 @@
 	conn = data;
 	gettimeofday(&now, NULL);
 
-	while (conn->queued_snacs != NULL)
+	while (!g_queue_is_empty(conn->queued_snacs))
 	{
 		QueuedSnac *queued_snac;
 		struct rateclass *rateclass;
 
-		queued_snac = conn->queued_snacs->data;
+		queued_snac = g_queue_peek_head(conn->queued_snacs);
 
 		rateclass = flap_connection_get_rateclass(conn, queued_snac->family, queued_snac->subtype);
 		if (rateclass != NULL)
@@ -144,10 +140,10 @@
 
 		flap_connection_send(conn, queued_snac->frame);
 		g_free(queued_snac);
-		conn->queued_snacs = g_slist_delete_link(conn->queued_snacs, conn->queued_snacs);
+		g_queue_pop_head(conn->queued_snacs);
 	}
 
-	conn->outgoing_timeout = 0;
+	conn->queued_timeout = 0;
 	return FALSE;
 }
 
@@ -179,7 +175,7 @@
 		byte_stream_putbs(&frame->data, data, length);
 	}
 
-	if (conn->outgoing_timeout != 0)
+	if (conn->queued_timeout != 0)
 		enqueue = TRUE;
 	else if ((rateclass = flap_connection_get_rateclass(conn, family, subtype)) != NULL)
 	{
@@ -210,10 +206,10 @@
 		queued_snac->family = family;
 		queued_snac->subtype = subtype;
 		queued_snac->frame = frame;
-		conn->queued_snacs = g_slist_append(conn->queued_snacs, queued_snac);
+		g_queue_push_tail(conn->queued_snacs, queued_snac);
 
-		if (conn->outgoing_timeout == 0)
-			conn->outgoing_timeout = gaim_timeout_add(500, flap_connection_send_queued, conn);
+		if (conn->queued_timeout == 0)
+			conn->queued_timeout = gaim_timeout_add(500, flap_connection_send_queued, conn);
 
 		return;
 	}
@@ -272,6 +268,7 @@
 	conn->fd = -1;
 	conn->subtype = -1;
 	conn->type = type;
+	conn->queued_snacs = g_queue_new();
 
 	od->oscar_connections = g_slist_prepend(od->oscar_connections, conn);
 
@@ -335,13 +332,8 @@
 static void
 flap_connection_destroy_rateclass(struct rateclass *rateclass)
 {
-	while (rateclass->members != NULL)
-	{
-		g_free(rateclass->members->data);
-		rateclass->members = g_slist_delete_link(rateclass->members, rateclass->members);
-	}
-
-	free(rateclass);
+	g_hash_table_destroy(rateclass->members);
+	g_free(rateclass);
 }
 
 /**
@@ -352,8 +344,8 @@
 static void
 flap_frame_destroy(FlapFrame *frame)
 {
-	free(frame->data.data);
-	free(frame);
+	g_free(frame->data.data);
+	g_free(frame);
 }
 
 static gboolean
@@ -423,16 +415,16 @@
 		conn->rateclasses = g_slist_delete_link(conn->rateclasses, conn->rateclasses);
 	}
 
-	while (conn->queued_snacs != NULL)
+	while (!g_queue_is_empty(conn->queued_snacs))
 	{
 		QueuedSnac *queued_snac;
-		queued_snac = conn->queued_snacs->data;
+		queued_snac = g_queue_pop_head(conn->queued_snacs);
 		flap_frame_destroy(queued_snac->frame);
 		g_free(queued_snac);
-		conn->queued_snacs = g_slist_delete_link(conn->queued_snacs, conn->queued_snacs);
 	}
-	if (conn->outgoing_timeout > 0)
-		gaim_timeout_remove(conn->outgoing_timeout);
+	g_queue_free(conn->queued_snacs);
+	if (conn->queued_timeout > 0)
+		gaim_timeout_remove(conn->queued_timeout);
 
 	g_free(conn);
 
--- a/libgaim/protocols/oscar/oscar.h	Mon Dec 04 07:47:50 2006 +0000
+++ b/libgaim/protocols/oscar/oscar.h	Mon Dec 04 11:14:11 2006 +0000
@@ -392,11 +392,9 @@
 	guint16 seqnum; /**< The sequence number of most recent outgoing packet. */
 	GSList *groups;
 	GSList *rateclasses; /* Contains nodes of struct rateclass. */
-	/* TODO: Maybe use a GHashTable for rateclasses */
 
-	GSList *queued_snacs; /**< Contains QueuedSnacs. */
-	guint outgoing_timeout;
-	/* TODO: Maybe use a GQueue for outgoing_snacs */
+	GQueue *queued_snacs; /**< Contains QueuedSnacs. */
+	guint queued_timeout;
 
 	void *internal; /* internal conn-specific libfaim data */
 };
@@ -504,8 +502,7 @@
 		gboolean in_transaction;
 	} ssi;
 
-	/* TODO: Implement this as a HashTable for HUGE speed improvement! */
-	GSList *handlerlist;
+	GHashTable *handlerlist;
 
 	/** A linked list containing FlapConnections. */
 	GSList *oscar_connections;
@@ -578,8 +575,8 @@
 
 void aim_cleansnacs(OscarData *, int maxage);
 
-int oscar_data_addhandler(OscarData *od, guint16 family, guint16 type, aim_rxcallback_t newhandler, guint16 flags);
-void aim_clearhandlers(OscarData *od);
+void oscar_data_addhandler(OscarData *od, guint16 family, guint16 subtype, aim_rxcallback_t newhandler, guint16 flags);
+aim_rxcallback_t aim_callhandler(OscarData *od, guint16 family, guint16 subtype);
 
 /* flap_connection.c */
 FlapConnection *flap_connection_new(OscarData *, int type);
@@ -1542,9 +1539,6 @@
 int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, int len);
 int byte_stream_putcaps(ByteStream *bs, guint32 caps);
 
-/* rxhandlers.c */
-aim_rxcallback_t aim_callhandler(OscarData *od, guint16 family, guint16 type);
-
 /*
  * Generic SNAC structure.  Rarely if ever used.
  */
@@ -1571,11 +1565,6 @@
 	guint16 instance;
 };
 
-struct snacpair {
-	guint16 group;
-	guint16 subtype;
-};
-
 struct rateclass {
 	guint16 classid;
 	guint32 windowsize;
@@ -1586,8 +1575,7 @@
 	guint32 current;
 	guint32 max;
 	guint8 unknown[5]; /* only present in versions >= 3 */
-	GSList *members; /* Contains node of struct snacpair */
-	/* TODO: Maybe use a GHashTable for members */
+	GHashTable *members; /* Key is family and subtype, value is TRUE. */
 
 	struct timeval last; /**< The time when we last sent a SNAC of this rate class. */
 };
--- a/libgaim/protocols/oscar/oscar_data.c	Mon Dec 04 07:47:50 2006 +0000
+++ b/libgaim/protocols/oscar/oscar_data.c	Mon Dec 04 11:14:11 2006 +0000
@@ -25,18 +25,11 @@
 struct _SnacHandler
 {
 	guint16 family;
-	guint16 type;
+	guint16 subtype;
 	aim_rxcallback_t handler;
 	guint16 flags;
 };
 
-static void
-oscar_free_buddyinfo(void *data)
-{
-	struct buddyinfo *bi = data;
-	g_free(bi);
-}
-
 /**
  * Allocates a new OscarData and initializes it with default values.
  */
@@ -49,7 +42,8 @@
 
 	aim_initsnachash(od);
 	od->snacid_next = 0x00000001;
-	od->buddyinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, oscar_free_buddyinfo);
+	od->buddyinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+	od->handlerlist = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
 
 	/*
 	 * Register all the modules for this session...
@@ -115,61 +109,39 @@
 		peer_connection_destroy(od->peer_connections->data,
 				OSCAR_DISCONNECT_LOCAL_CLOSED, NULL);
 
-	if (od->handlerlist != NULL)
-		aim_clearhandlers(od);
-
 	aim__shutdownmodules(od);
 
 	g_hash_table_destroy(od->buddyinfo);
+	g_hash_table_destroy(od->handlerlist);
 
 	g_free(od);
 }
 
-int
-oscar_data_addhandler(OscarData *od, guint16 family, guint16 type, aim_rxcallback_t newhandler, guint16 flags)
+void
+oscar_data_addhandler(OscarData *od, guint16 family, guint16 subtype, aim_rxcallback_t newhandler, guint16 flags)
 {
 	SnacHandler *snac_handler;
 
-	gaim_debug_misc("oscar", "Adding handler for %04x/%04x\n", family, type);
+	gaim_debug_misc("oscar", "Adding handler for %04x/%04x\n", family, subtype);
 
 	snac_handler = g_new0(SnacHandler, 1);
 
 	snac_handler->family = family;
-	snac_handler->type = type;
+	snac_handler->subtype = subtype;
 	snac_handler->flags = flags;
 	snac_handler->handler = newhandler;
 
-	od->handlerlist = g_slist_prepend(od->handlerlist, snac_handler);
-
-	return 0;
+	g_hash_table_insert(od->handlerlist,
+			GUINT_TO_POINTER((family << 16) + subtype),
+			snac_handler);
 }
 
-void
-aim_clearhandlers(OscarData *od)
+aim_rxcallback_t
+aim_callhandler(OscarData *od, guint16 family, guint16 subtype)
 {
 	SnacHandler *snac_handler;
 
-	while (od->handlerlist != NULL)
-	{
-		snac_handler = od->handlerlist->data;
-		od->handlerlist = g_slist_remove(od->handlerlist, snac_handler);
-		g_free(snac_handler);
-	}
-	od->handlerlist = NULL;
-}
+	snac_handler = g_hash_table_lookup(od->handlerlist, GUINT_TO_POINTER((family << 16) + subtype));
 
-aim_rxcallback_t
-aim_callhandler(OscarData *od, guint16 family, guint16 type)
-{
-	GSList *cur;
-	SnacHandler *snac_handler;
-
-	for (cur = od->handlerlist; cur != NULL; cur = cur->next)
-	{
-		snac_handler = cur->data;
-		if ((snac_handler->family == family) && (snac_handler->type == type))
-			return snac_handler->handler;
-	}
-
-	return NULL;
+	return snac_handler ? snac_handler->handler : NULL;
 }