bonobo-activation cache ...



Hi there,

	This adds a cache to the activation code in bonobo-activation.
Judging by the number of hit messages I get on opening a new window in
Nautilus - this should have a fairly pleasant performance impact.

	May I commit ?

		Michael.

? mjs
? bonobo-activation-0.7.0.tar.gz
? ChangeLog.full
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/bonobo-activation/ChangeLog,v
retrieving revision 1.249
diff -u -p -u -r1.249 ChangeLog
--- ChangeLog	2001/11/29 08:04:38	1.249
+++ ChangeLog	2001/12/18 11:12:26
@@ -1,3 +1,19 @@
+2001-12-18  Michael Meeks  <michael ximian com>
+
+	* test/bonobo-activation-test.c (main): add a more complex
+	nautilus style query.
+
+2001-12-17  Michael Meeks  <michael ximian com>
+
+	* bonobo-activation/bonobo-activation-activate.c
+	(query_cache_equal,query_cache_hash, query_cache_lookup),
+	(query_cache_insert, query_cache_entry_free),
+	(query_cache_clean): impl. a query cache to prune redundant
+	duplicate queries.
+
+	* bonobo-activation/bonobo-activation-server-info.c
+	(Bonobo_ServerInfoList_duplicate): impl.
+
 2001-11-29  Mark McLoughlin  <mark skynet ie>

 	* api-docs/server-xml-reference.sgml: expand desription of
Index: bonobo-activation/bonobo-activation-activate.c
===================================================================
RCS file: /cvs/gnome/bonobo-activation/bonobo-activation/bonobo-activation-activate.c,v
retrieving revision 1.30
diff -u -p -u -r1.30 bonobo-activation-activate.c
--- bonobo-activation/bonobo-activation-activate.c	2001/08/17 22:12:27	1.30
+++ bonobo-activation/bonobo-activation-activate.c	2001/12/18 11:12:28
@@ -29,6 +29,7 @@
 #include <bonobo-activation/bonobo-activation-activate-private.h>
 #include <bonobo-activation/bonobo-activation-id.h>
 #include <bonobo-activation/bonobo-activation-init.h>
+#include <bonobo-activation/bonobo-activation-server-info.h>
 #include <bonobo-activation/bonobo-activation-private.h>
 #include <bonobo-activation/bonobo-activation-shlib.h>
 #include <bonobo-activation/Bonobo_ActivationContext.h>
@@ -98,12 +99,155 @@ bonobo_activation_copy_string_array_to_B
         }
 }

+/*
+ * FIXME: in theory it is nice to be able to add components
+ * and for them to be automaticaly registered; this cache
+ * militates against this. We need a callback mechanism from
+ * the daemon to allow flushing.
+ *
+ * Also - these query results tend to be fairly huge; we
+ * should probably be pruning the strings based on locale
+ * at the server side.
+ */
+
+/* Limit of the number of cached queries */
+#define QUERY_CACHE_MAX 32
+
+static GHashTable *query_cache = NULL;
+
+typedef struct {
+	char  *query;
+	char **sort_criteria;
+
+	Bonobo_ServerInfoList *list;
+} CacheEntry;
+
+static void
+query_cache_entry_free (gpointer data)
+{
+        CacheEntry *entry = data;
+
+/*      g_warning ("Blowing item %p", entry); */
+
+        g_free (entry->query);
+        g_strfreev (entry->sort_criteria);
+        CORBA_free (entry->list);
+        g_free (entry);
+}
+
+static gboolean
+query_cache_clean (gpointer  key,
+                   gpointer  value,
+                   gpointer  user_data)
+{
+        int *a = user_data;
+        /* Blow half the elements */
+        return (*a)++ % 2;
+}
+
+static gboolean
+query_cache_equal (gconstpointer a, gconstpointer b)
+{
+	int i;
+	char **strsa, **strsb;
+	const CacheEntry *entrya = a;
+	const CacheEntry *entryb = b;
+
+	if (strcmp (entrya->query, entryb->query))
+		return FALSE;
+
+	strsa = entrya->sort_criteria;
+	strsb = entryb->sort_criteria;
+
+	if (!strsa && !strsb)
+		return TRUE;
+
+	if (!strsa || !strsb)
+		return FALSE;
+
+	for (i = 0; strsa [i] && strsb [i]; i++)
+		if (strcmp (strsa [i], strsb [i]))
+			return FALSE;
+
+	if (strsa [i] || strsb [i])
+		return FALSE;
+
+	return TRUE;
+}
+
+static guint
+query_cache_hash (gconstpointer a)
+{
+	guint hash, i;
+	char **strs;
+	const CacheEntry *entry = a;
+
+	hash = g_str_hash (entry->query);
+	strs = entry->sort_criteria;
+
+	for (i = 0; strs && strs [i]; i++)
+		hash ^= g_str_hash (strs [i]);
+
+	return hash;
+}
+
+static Bonobo_ServerInfoList *
+query_cache_lookup (char         *query,
+		    char * const *sort_criteria)
+{
+	CacheEntry  fake;
+	CacheEntry *entry;
+
+	if (!query_cache) {
+		query_cache = g_hash_table_new_full (
+			query_cache_hash,
+                        query_cache_equal,
+                        query_cache_entry_free,
+                        NULL);
+		return NULL;
+	}
+
+	fake.query = query;
+	fake.sort_criteria = (char **) sort_criteria;
+
+	if ((entry = g_hash_table_lookup (query_cache, &fake))) {
+/*		g_warning ("\n\n ---  Hit (%p)  ---\n\n\n", entry->list); */
+		return Bonobo_ServerInfoList_duplicate (entry->list);
+	} else {
+/*		g_warning ("Miss '%s'", query); */
+		return NULL;
+	}
+}
+
+static void
+query_cache_insert (const char   *query,
+		    char * const *sort_criteria,
+		    Bonobo_ServerInfoList *list)
+{
+        int idx = 0;
+	CacheEntry *entry = g_new (CacheEntry, 1);
+
+        if (g_hash_table_size (query_cache) > QUERY_CACHE_MAX) {
+                g_hash_table_foreach_remove (
+                        query_cache, query_cache_clean, &idx);
+        }
+
+	entry->query = g_strdup (query);
+	entry->sort_criteria = g_strdupv ((char **) sort_criteria);
+	entry->list = Bonobo_ServerInfoList_duplicate (list);
+
+	g_hash_table_insert (query_cache, entry, entry);
+
+/*	g_warning ("Query cache size now %d",
+                g_hash_table_size (query_cache)); */
+}
+
 /**
  * bonobo_activation_query:
  * @requirements: query string.
  * @selection_order: sort criterion for returned list.
  * @ev: a %CORBA_Environment structure which will contain
- *      the CORBA exception status of the operation.
+ *      the CORBA exception status of the operation, or NULL
  *
  * Executes the @requirements query on the bonobo-activation-server.
  * The result is sorted according to @selection_order.
@@ -112,17 +256,17 @@ bonobo_activation_copy_string_array_to_B
  *
  * Return value: the list of servers matching the requirements.
  */
-
 Bonobo_ServerInfoList *
-bonobo_activation_query (const char *requirements, char *const *selection_order,
-	   CORBA_Environment * ev)
+bonobo_activation_query (const char   *requirements,
+                         char * const *selection_order,
+                         CORBA_Environment *ev)
 {
 	Bonobo_StringList selorder;
 	Bonobo_ServerInfoList *res;
 	CORBA_Environment myev;
 	Bonobo_ActivationContext ac;
         char *ext_requirements;
-
+        char *query_requirements;

 	g_return_val_if_fail (requirements, CORBA_OBJECT_NIL);
 	ac = bonobo_activation_activation_context_get ();
@@ -130,30 +274,40 @@ bonobo_activation_query (const char *req

         ext_requirements = bonobo_activation_maybe_add_test_requirements (requirements);

+        if (ext_requirements == NULL) {
+                query_requirements = (char *) requirements;
+        } else {
+                query_requirements = (char *) ext_requirements;
+        }
+
 	if (!ev) {
 		ev = &myev;
 		CORBA_exception_init (&myev);
 	}

-        bonobo_activation_copy_string_array_to_Bonobo_StringList (selection_order, &selorder);
+	res = query_cache_lookup (query_requirements, selection_order);

-        if (ext_requirements == NULL) {
-                res = Bonobo_ActivationContext_query (ac, (char *) requirements,
-                                                      &selorder, bonobo_activation_context_get (), ev);
-        } else {
-                res = Bonobo_ActivationContext_query (ac, (char *) ext_requirements,
-                                                      &selorder, bonobo_activation_context_get (), ev);
+        if (!res) {
+                bonobo_activation_copy_string_array_to_Bonobo_StringList (selection_order, &selorder);
+
+                res = Bonobo_ActivationContext_query (
+                        ac, query_requirements,
+                        &selorder, bonobo_activation_context_get (), ev);
+
+                if (ev->_major != CORBA_NO_EXCEPTION) {
+                        res = NULL;
+                }
+
+                query_cache_insert (query_requirements, selection_order, res);
         }

         if (ext_requirements != NULL) {
                 g_free (ext_requirements);
         }
-
-	if (ev->_major != CORBA_NO_EXCEPTION)
-		res = NULL;

-	if (ev == &myev)
+	if (ev == &myev) {
 		CORBA_exception_free (&myev);
+        }

 	return res;
 }
Index: bonobo-activation/bonobo-activation-server-info.c
===================================================================
RCS file: /cvs/gnome/bonobo-activation/bonobo-activation/bonobo-activation-server-info.c,v
retrieving revision 1.16
diff -u -p -u -r1.16 bonobo-activation-server-info.c
--- bonobo-activation/bonobo-activation-server-info.c	2001/07/31 16:52:01	1.16
+++ bonobo-activation/bonobo-activation-server-info.c	2001/12/18 11:12:28
@@ -196,4 +196,8 @@ Bonobo_ServerInfo_duplicate (const Bonob
 	return copy;
 }

-
+Bonobo_ServerInfoList *
+Bonobo_ServerInfoList_duplicate (const Bonobo_ServerInfoList *original)
+{
+        return ORBit_copy_value (original, TC_Bonobo_ServerInfoList);
+}
Index: bonobo-activation/bonobo-activation-server-info.h
===================================================================
RCS file: /cvs/gnome/bonobo-activation/bonobo-activation/bonobo-activation-server-info.h,v
retrieving revision 1.5
diff -u -p -u -r1.5 bonobo-activation-server-info.h
--- bonobo-activation/bonobo-activation-server-info.h	2001/08/18 00:19:02	1.5
+++ bonobo-activation/bonobo-activation-server-info.h	2001/12/18 11:12:28
@@ -44,6 +44,7 @@ void                       CORBA_sequenc
 void                       Bonobo_ServerInfo_copy              (Bonobo_ServerInfo                      *copy,
                                                                 const Bonobo_ServerInfo                *original);
 Bonobo_ServerInfo         *Bonobo_ServerInfo_duplicate         (const Bonobo_ServerInfo                *original);
+Bonobo_ServerInfoList     *Bonobo_ServerInfoList_duplicate     (const Bonobo_ServerInfoList            *original);

 G_END_DECLS

Index: test/bonobo-activation-test.c
===================================================================
RCS file: /cvs/gnome/bonobo-activation/test/bonobo-activation-test.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 bonobo-activation-test.c
--- test/bonobo-activation-test.c	2001/11/15 23:32:56	1.24
+++ test/bonobo-activation-test.c	2001/12/18 11:12:29
@@ -113,7 +113,9 @@ main (int argc, char *argv[])
 	CORBA_Object obj;
 	CORBA_Environment ev;
         Bonobo_ServerInfoList *info;
-        char *sort_by[2];
+        char *sort_by[4];
+        char *query;
+        int   i;

 	CORBA_exception_init (&ev);
 	bonobo_activation_init (argc, argv);
@@ -124,25 +126,49 @@ main (int argc, char *argv[])
                 "'OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058',"
                 "'OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c',"
                 "'OAFIID:nautilus_music_view:9456b5d2-60a8-407f-a56e-d561e1821391'])";
-        sort_by[1] = NULL;
-
-        info = bonobo_activation_query (
-                "(bonobo:supported_mime_types.has_one (['x-directory/normal',"
-                "                                       'x-directory/*', '*']) AND "
-                "has (['OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058',"
-                "      'OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c',"
-                "      'OAFIID:nautilus_music_view:9456b5d2-60a8-407f-a56e-d561e1821391'], iid) ) ",
-                sort_by, &ev);
-
+        sort_by[1] = "iid != 'OAFIID:nautilus_content_loser:95901458-c68b-43aa-aaca-870ced11062d'";
+        sort_by[2] = "iid != 'OAFIID:nautilus_sample_content_view:45c746bc-7d64-4346-90d5-6410463b43ae'";
+        sort_by[3] = NULL;
+
+        query = "( (((repo_ids.has_all (['IDL:Bonobo/Control:1.0',"
+                "'IDL:Nautilus/View:1.0']) OR (repo_ids.has_one "
+                "(['IDL:Bonobo/Control:1.0','IDL:Bonobo/Embeddable:1.0']) AND "
+                "repo_ids.has_one (['IDL:Bonobo/PersistStream:1.0', "
+                "'IDL:Bonobo/ProgressiveDataSink:1.0', "
+                "'IDL:Bonobo/PersistFile:1.0']))) AND (bonobo:supported_mime_types.defined () OR "
+                "bonobo:supported_uri_schemes.defined () OR "
+                "bonobo:additional_uri_schemes.defined ()) AND "
+                "(((NOT bonobo:supported_mime_types.defined () OR "
+                "bonobo:supported_mime_types.has ('x-directory/normal') OR "
+                "bonobo:supported_mime_types.has ('x-directory/*') OR "
+                "bonobo:supported_mime_types.has ('*/*')) AND "
+                "(NOT bonobo:supported_uri_schemes.defined () OR "
+                "bonobo:supported_uri_schemes.has ('file') OR "
+                "bonobo:supported_uri_schemes.has ('*'))) OR "
+                "(bonobo:additional_uri_schemes.has ('file') OR "
+                "bonobo:additional_uri_schemes.has ('*'))) AND "
+                "nautilus:view_as_name.defined ()) OR false) AND "
+                "(has (['OAFIID:nautilus_file_manager_icon_view:42681b21-d5ca-4837-87d2-394d88ecc058', "
+                "'OAFIID:nautilus_file_manager_list_view:521e489d-0662-4ad7-ac3a-832deabe111c'], iid)) ) AND "
+                "(NOT test_only.defined() OR NOT test_only)";
+
+
+        for (i = 0; i < 100; i++) {
+                info = bonobo_activation_query (query, sort_by, &ev);
+
+                if (ev._major == CORBA_NO_EXCEPTION) {
+                        CORBA_free (info);
+                } else {
+                        fprintf (stderr, "Test of query failed '%s'\n",
+                                 bonobo_activation_exception_id (&ev));
+                }
+        }
         if (ev._major == CORBA_NO_EXCEPTION) {
-                fprintf (stderr, "Query passed\n");
                 passed++;
-                CORBA_free (info);
-        } else
-                fprintf (stderr, "Test of query failed\n");
+        }

 	obj = bonobo_activation_activate ("repo_ids.has('IDL:Empty:1.0')", NULL, 0, NULL,
-                            &ev);
+                                          &ev);
         if (test_object (obj, &ev, "by query")) {
                 passed += test_empty (obj, &ev, "by query");
         }

-- 
 mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]