changeset 29327:2e3e0801de29

optimization to the oscar prpl to use less memory, care of Shaun Lindsay at Meebo. I suspect this will save a few kilobytes per AIM or ICQ account.
author Mark Doliner <mark@kingant.net>
date Wed, 03 Feb 2010 00:05:22 +0000
parents 89bece95a522
children 0616027add19
files libpurple/protocols/oscar/family_oservice.c libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/oscar.h
diffstat 3 files changed, 32 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/family_oservice.c	Tue Feb 02 23:44:33 2010 +0000
+++ b/libpurple/protocols/oscar/family_oservice.c	Wed Feb 03 00:05:22 2010 +0000
@@ -27,6 +27,24 @@
 
 #include "cipher.h"
 
+/*
+ * Each time we make a FLAP connection to an oscar server the server gives
+ * us a list of rate classes.  Each rate class has different properties for
+ * how frequently we can send SNACs in that rate class before we become
+ * throttled or disconnected.
+ *
+ * The server also gives us a list of every available SNAC and tells us which
+ * rate class it's in.  There are a lot of different SNACs, so this list can be
+ * fairly large.  One important characteristic of these rate classes is that
+ * currently (and since at least 2004) most SNACs are in the same rate class.
+ *
+ * One optimization we can do to save memory is to only keep track of SNACs
+ * that are in classes other than this default rate class.  So if we try to
+ * look up a SNAC and it's not in our hash table then we can assume that it's
+ * in the default rate class.
+ */
+#define OSCAR_DEFAULT_RATECLASS 1
+
 /* Subtype 0x0002 - Client Online */
 void
 aim_srv_clientready(OscarData *od, FlapConnection *conn)
@@ -346,6 +364,9 @@
 
 		rateclass->members = g_hash_table_new(g_direct_hash, g_direct_equal);
 		conn->rateclasses = g_slist_prepend(conn->rateclasses, rateclass);
+
+		if (rateclass->classid == OSCAR_DEFAULT_RATECLASS)
+			conn->default_rateclass = rateclass;
 	}
 	conn->rateclasses = g_slist_reverse(conn->rateclasses);
 
@@ -361,6 +382,15 @@
 		classid = byte_stream_get16(bs);
 		count = byte_stream_get16(bs);
 
+		if (classid == OSCAR_DEFAULT_RATECLASS) {
+			/*
+			 * Don't bother adding these SNACs to the hash table.  See the
+			 * comment for OSCAR_DEFAULT_RATECLASS at the top of this file.
+			 */
+			byte_stream_advance(bs, 4 * count);
+			continue;
+		}
+
 		rateclass = rateclass_find(conn->rateclasses, classid);
 
 		for (j = 0; j < count; j++)
--- a/libpurple/protocols/oscar/flap_connection.c	Tue Feb 02 23:44:33 2010 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Wed Feb 03 00:05:22 2010 +0000
@@ -120,7 +120,7 @@
 			return rateclass;
 	}
 
-	return NULL;
+	return conn->default_rateclass;
 }
 
 /*
--- a/libpurple/protocols/oscar/oscar.h	Tue Feb 02 23:44:33 2010 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Wed Feb 03 00:05:22 2010 +0000
@@ -445,6 +445,7 @@
 	guint16 seqnum_in; /**< The sequence number of most recently received packet. */
 	GSList *groups;
 	GSList *rateclasses; /* Contains nodes of struct rateclass. */
+	struct rateclass *default_rateclass;
 
 	GQueue *queued_snacs; /**< Contains QueuedSnacs. */
 	GQueue *queued_lowpriority_snacs; /**< Contains QueuedSnacs to send only once queued_snacs is empty */