# HG changeset patch # User Mark Doliner # Date 1165230851 0 # Node ID f41cd6f78c60d13888af38f702368650d02523f3 # Parent b2b0839f57d05213ae2426dba1c1106bbd460dc3 [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 diff -r b2b0839f57d0 -r f41cd6f78c60 libgaim/protocols/oscar/family_oservice.c --- 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); } /* diff -r b2b0839f57d0 -r f41cd6f78c60 libgaim/protocols/oscar/flap_connection.c --- 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); diff -r b2b0839f57d0 -r f41cd6f78c60 libgaim/protocols/oscar/oscar.h --- 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. */ }; diff -r b2b0839f57d0 -r f41cd6f78c60 libgaim/protocols/oscar/oscar_data.c --- 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; }