bonobo-activation cache ...
- From: Michael Meeks <michael ximian com>
- To: Maciej Stachowiak <mjs eazel com>, Darin Adler <darin eazel com>
- Cc: <gnome-components-list gnome org>
- Subject: bonobo-activation cache ...
- Date: Tue, 18 Dec 2001 06:23:33 -0500 (EST)
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]