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