Re: bonobo-activation cache ...



On 18Dec2001 06:23AM (-0500), Michael Meeks wrote:
> 
> 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 ?

There's two things that need to be addressed.

1) Have you measured the performance improvement from this change? If
it's very small it may not be worth coming up with a solution for
issue 2 below:

2) The cache needs to be invalidated when new .server files are
installed. bonobo-activation-server picks these up automatically, and
before we added this feature, people got horribly confused by the fact
that new or updated components would not show up. You can just flush
the caches when bonobo-activation-server rereads the directory of
.server files, which it stats periodically to detect new files.

 - Maciej

 
> 		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
> 
> _______________________________________________
> gnome-components-list mailing list
> gnome-components-list gnome org
> http://mail.gnome.org/mailman/listinfo/gnome-components-list



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