Re: Implementing Batch Requests in GConf



Title: Re: Implementing Batch Requests in GConf

Okay, I've hacked together a very rough patch that will do negative
caching on GConf entries. This means if it doesn't find a key in cache
that should've been covered by a previous add_dir, it will consider that
authoritative and not do a roundtrip to the server. This drastically
reduces the total number of roundtrips during Gnome login.

This is definitely not intended for inclusion, I'm just looking for
feedback.

-Ryan

diff -u gconf-orig/gconf2-2.18.0.1/gconf/gconf-client.c gconf-negative-cache/gconf2-2.18.0.1/gconf/gconf-client.c
--- gconf-orig/gconf2-2.18.0.1/gconf/gconf-client.c	2007-03-02 14:10:13.000000000 -0800
+++ gconf-negative-cache/gconf2-2.18.0.1/gconf/gconf-client.c	2007-04-24 12:52:47.000000000 -0700
@@ -233,6 +233,7 @@
   client->error_mode = GCONF_CLIENT_HANDLE_UNRETURNED;
   client->dir_hash = g_hash_table_new (g_str_hash, g_str_equal);
   client->cache_hash = g_hash_table_new (g_str_hash, g_str_equal);
+  client->cache_complete = TRUE;
   /* We create the listeners only if they're actually used */
   client->listeners = NULL;
   client->notify_list = NULL;
@@ -808,7 +809,8 @@
   
   g_hash_table_foreach_remove (client->cache_hash, (GHRFunc)clear_cache_foreach,
                                client);
-
+  
+  client->cache_complete = FALSE;
   g_assert (g_hash_table_size(client->cache_hash) == 0);
 }
 
@@ -1223,7 +1225,8 @@
     {
       trace ("%s was in the client-side cache\n", key);
       
-      g_assert (entry != NULL);
+      if (entry == NULL)
+        return NULL; 
       
       if (gconf_entry_get_is_default (entry) && !use_default)
         return NULL;
@@ -1957,6 +1960,26 @@
     }
 }
 
+typedef struct {
+  gboolean is_added;
+  char *dirname;
+} DirIsAddedData;
+
+
+static void
+foreach_dir_is_added(gpointer key, gpointer value, gpointer dir_data_pointer)
+{
+  DirIsAddedData *dir_data = dir_data_pointer;
+
+  if (dir_data->is_added == TRUE)
+    return;
+
+  if (gconf_key_is_below (key, dir_data->dirname))
+  {
+    dir_data->is_added = TRUE;
+  }
+}
+
 static gboolean
 gconf_client_lookup (GConfClient *client,
                      const char  *key,
@@ -1970,7 +1993,22 @@
   entry = g_hash_table_lookup (client->cache_hash, key);
 
   *entryp = entry;
-      
+ 
+  if (!entry && client->cache_complete)
+  {
+    DirIsAddedData dir_data;
+    
+    dir_data.dirname = key;
+    dir_data.is_added = FALSE;
+
+    g_hash_table_foreach(client->dir_hash, foreach_dir_is_added, &dir_data);
+    if (dir_data.is_added)
+    {
+      trace ("Negative cache hit on %s\n", key);
+      return TRUE;
+    }
+  }
+
   return entry != NULL;
 }
 
diff -u gconf-orig/gconf2-2.18.0.1/gconf/gconf-client.h gconf-negative-cache/gconf2-2.18.0.1/gconf/gconf-client.h
--- gconf-orig/gconf2-2.18.0.1/gconf/gconf-client.h	2007-03-02 14:10:13.000000000 -0800
+++ gconf-negative-cache/gconf2-2.18.0.1/gconf/gconf-client.h	2007-04-24 09:23:22.000000000 -0700
@@ -101,7 +101,7 @@
   guint notify_handler;
   int pending_notify_count;
   gpointer pad1;
-  int pad2;  
+  gboolean cache_complete;  
 };
 
 struct _GConfClientClass


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