Re: [Nautilus-list] Cacheing bonobo ui xml



On Tue, 21 Aug 2001, Alex Larsson wrote:

> Here is a dirty patch that caches the result of bonobo_ui_util_new_ui so 
> that multiple parsing and fixups of the same file is avoided. This wastes 
> a bit memory (haven't measured how much) but speeds up e.g. opening a new 
> window in nautilus. I got about 9% speedup on open new window in nautilus.
> 
> Comments?

Got some comments from michael on irc, so here is a new and improved 
version. This one seems to give 15% (This is measured using strace from 
nautilus_application_create_window() to fm_directory_view_end_loading()). 
This one also uses less memory.

Index: bonobo-ui-util.c
===================================================================
RCS file: /cvs/gnome/bonobo/bonobo/bonobo-ui-util.c,v
retrieving revision 1.42
diff -u -p -r1.42 bonobo-ui-util.c
--- bonobo-ui-util.c	2001/04/15 16:12:32	1.42
+++ bonobo-ui-util.c	2001/08/21 22:19:11
@@ -1186,7 +1186,6 @@ bonobo_ui_util_fixup_icons (BonoboUINode
 		bonobo_ui_util_fixup_icons (l);
 }
 
-
 /**
  * bonobo_ui_util_new_ui:
  * @component: The component help callback should be on
@@ -1222,6 +1221,35 @@ bonobo_ui_util_new_ui (BonoboUIComponent
 	return node;
 }
 
+typedef struct {
+	const char *file_name;
+	const char *app_datadir;
+	const char *app_name;
+	const char *tree;
+} BonoboUINodeCacheEntry;
+
+static guint
+node_hash (gconstpointer key)
+{
+	BonoboUINodeCacheEntry *entry = (BonoboUINodeCacheEntry *)key;
+	/* Ignore the app_datadir in the hash, since that 
+	   is also in file_name (always?) */
+	return g_str_hash (entry->file_name) ^ g_str_hash (entry->app_name);
+}
+
+static gint
+node_equal (gconstpointer a,
+	    gconstpointer b)
+{
+	BonoboUINodeCacheEntry *entry_a = (BonoboUINodeCacheEntry *)a;
+	BonoboUINodeCacheEntry *entry_b = (BonoboUINodeCacheEntry *)b;
+
+	return (strcmp (entry_a->file_name, entry_b->file_name) == 0) &&
+		(strcmp (entry_a->app_name, entry_b->app_name) == 0) &&
+		(strcmp (entry_a->app_datadir, entry_b->app_datadir) == 0);
+}
+
+
 /**
  * bonobo_ui_util_set_ui:
  * @component: the component
@@ -1241,7 +1269,15 @@ bonobo_ui_util_set_ui (BonoboUIComponent
 		       const char        *app_name)
 {
 	char *fname;
-	BonoboUINode *ui;
+	const char *ui;
+	static GHashTable *loaded_node_cache = NULL;
+	BonoboUINodeCacheEntry entry, *cached;
+	BonoboUINode *node;
+	
+	if (loaded_node_cache == NULL) {
+		loaded_node_cache = g_hash_table_new (node_hash,
+						      node_equal);
+	}
 
 	if (bonobo_ui_component_get_container (component) == CORBA_OBJECT_NIL) {
 		g_warning ("Component must be associated with a container first "
@@ -1254,16 +1290,36 @@ bonobo_ui_util_set_ui (BonoboUIComponent
 		g_warning ("Can't find '%s' to load ui from", file_name);
 		return;
 	}
+
+
+	/* FIXME: May want to stat the file to see if it changed? */
+	entry.file_name = file_name;
+	entry.app_datadir = app_datadir;
+	entry.app_name = app_name;
 	
-	ui = bonobo_ui_util_new_ui (component, fname, app_datadir, app_name);
+	cached = g_hash_table_lookup (loaded_node_cache, &entry);
+	if (cached) {
+		ui = cached->tree;
+	} else {
+		node = bonobo_ui_util_new_ui (component, fname, app_datadir, app_name);
+		ui = bonobo_ui_node_to_string (node, TRUE);
+		bonobo_ui_node_free (node);
+		
+		cached = g_new (BonoboUINodeCacheEntry, 1);
+		
+		cached->file_name = g_strdup (file_name);
+		cached->app_datadir = g_strdup (app_datadir);
+		cached->app_name = g_strdup (app_name);
+		cached->tree = ui;
+		
+		g_hash_table_insert (loaded_node_cache,
+				     cached, cached);
+	}
 	
 	if (ui)
-		bonobo_ui_component_set_tree (
-			component, "/", ui, NULL);
+		bonobo_ui_component_set (component, "/", ui, NULL);
 	
 	g_free (fname);
-	bonobo_ui_node_free (ui);
-	/* FIXME: we could be caching the tree here */
 }
 
 /*






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