[patch] GCache



Hi,

here's a patch to GCache which does the following:

- use GDestroyNotify instead of GCacheDestroyFunc.
- remove GCacheDestroyFuncs from the GCache struct
  and use the extended GHash API instead.
- add g_cache_remove_by_key() function. I found this
  function to be very useful in a number of applications.

This change is not completely backwards-compatible:
While GCacheDestroyFunc could be typedef'd to 
GDestroyNotify to retain backward compatibility, the
behaviour of g_cache_destroy() changes with this patch.
In GLib-1.2, calling g_cache_destroy() did not free the
memory allocated for keys and values in the cache. 
Since the user explicitely specified functions to manage
the memory allocated by the GCache, it should IMHO use
these to clean up after itself on destruction.

Most users of GCache will expect it to behave the new way
or don't call g_cache_destroy() at all since they keep
the cache for the application's lifetime. For that reason,
I do not expect this change to break existing code, but
I'd like to hear your comments. If you like the change, 
I'll also move the documentation into gcache.c before
committing.


Salut, Sven


Index: gcache.c
===================================================================
RCS file: /cvs/gnome/glib/gcache.c,v
retrieving revision 1.10
diff -u -r1.10 gcache.c
--- gcache.c	2000/10/30 14:34:52	1.10
+++ gcache.c	2001/05/14 11:42:36
@@ -46,15 +46,9 @@
   /* Called to create a value from a key */
   GCacheNewFunc value_new_func;
 
-  /* Called to destroy a value */
-  GCacheDestroyFunc value_destroy_func;
-
   /* Called to duplicate a key */
   GCacheDupFunc key_dup_func;
 
-  /* Called to destroy a key */
-  GCacheDestroyFunc key_destroy_func;
-
   /* Associates keys with nodes */
   GHashTable *key_table;
 
@@ -71,13 +65,13 @@
 G_LOCK_DEFINE_STATIC (node_mem_chunk);
 
 GCache*
-g_cache_new (GCacheNewFunc      value_new_func,
-	     GCacheDestroyFunc  value_destroy_func,
-	     GCacheDupFunc      key_dup_func,
-	     GCacheDestroyFunc  key_destroy_func,
-	     GHashFunc          hash_key_func,
-	     GHashFunc          hash_value_func,
-	     GEqualFunc         key_equal_func)
+g_cache_new (GCacheNewFunc   value_new_func,
+	     GDestroyNotify  value_destroy_func,
+	     GCacheDupFunc   key_dup_func,
+	     GDestroyNotify  key_destroy_func,
+	     GHashFunc       hash_key_func,
+	     GHashFunc       hash_value_func,
+	     GEqualFunc      key_equal_func)
 {
   GRealCache *cache;
 
@@ -91,11 +85,15 @@
 
   cache = g_new (GRealCache, 1);
   cache->value_new_func = value_new_func;
-  cache->value_destroy_func = value_destroy_func;
   cache->key_dup_func = key_dup_func;
-  cache->key_destroy_func = key_destroy_func;
-  cache->key_table = g_hash_table_new (hash_key_func, key_equal_func);
-  cache->value_table = g_hash_table_new (hash_value_func, NULL);
+  cache->key_table = g_hash_table_new_full (hash_key_func, 
+                                            key_equal_func,
+                                            key_destroy_func,
+                                            NULL);
+  cache->value_table = g_hash_table_new_full (hash_value_func, 
+                                              NULL,
+                                              value_destroy_func,
+                                              NULL);
 
   return (GCache*) cache;
 }
@@ -108,8 +106,8 @@
   g_return_if_fail (cache != NULL);
 
   rcache = (GRealCache*) cache;
-  g_hash_table_destroy (rcache->key_table);
   g_hash_table_destroy (rcache->value_table);
+  g_hash_table_destroy (rcache->key_table);
   g_free (rcache);
 }
 
@@ -147,7 +145,6 @@
 		gconstpointer  value)
 {
   GRealCache *rcache;
-  GCacheNode *node;
   gpointer key;
 
   g_return_if_fail (cache != NULL);
@@ -155,18 +152,30 @@
   rcache = (GRealCache*) cache;
 
   key = g_hash_table_lookup (rcache->value_table, value);
-  node = g_hash_table_lookup (rcache->key_table, key);
+  g_cache_remove_by_key (cache, key);
+}
 
-  g_return_if_fail (node != NULL);
+void
+g_cache_remove_by_key (GCache   *cache,
+                       gpointer  key)
+{
+  GRealCache *rcache;
+  GCacheNode *node;
+  gpointer    orig_key;
+
+  g_return_if_fail (cache != NULL);
 
+  rcache = (GRealCache*) cache;
+
+  if (!g_hash_table_lookup_extended (rcache->key_table, 
+                                     key, &orig_key, (gpointer *) &node))
+    return;
+
   node->ref_count -= 1;
   if (node->ref_count == 0)
     {
-      g_hash_table_remove (rcache->value_table, value);
-      g_hash_table_remove (rcache->key_table, key);
-
-      (* rcache->key_destroy_func) (key);
-      (* rcache->value_destroy_func) (node->value);
+      g_hash_table_remove (rcache->value_table, node->value);
+      g_hash_table_remove (rcache->key_table, orig_key);
       g_cache_node_destroy (node);
     }
 }
@@ -209,8 +218,9 @@
 
   G_LOCK (node_mem_chunk);
   if (!node_mem_chunk)
-    node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
-				      1024, G_ALLOC_AND_FREE);
+    node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", 
+                                      sizeof (GCacheNode), 1024, 
+                                      G_ALLOC_AND_FREE);
 
   node = g_chunk_new (GCacheNode, node_mem_chunk);
   G_UNLOCK (node_mem_chunk);
Index: gcache.h
===================================================================
RCS file: /cvs/gnome/glib/gcache.h,v
retrieving revision 1.2
diff -u -r1.2 gcache.h
--- gcache.h	2000/10/30 14:34:52	1.2
+++ gcache.h	2001/05/14 11:42:36
@@ -35,14 +35,13 @@
 
 typedef gpointer        (*GCacheNewFunc)        (gpointer       key);
 typedef gpointer        (*GCacheDupFunc)        (gpointer       value);
-typedef void            (*GCacheDestroyFunc)    (gpointer       value);
 
 /* Caches
  */
 GCache*  g_cache_new           (GCacheNewFunc      value_new_func,
-                                GCacheDestroyFunc  value_destroy_func,
+                                GDestroyNotify     value_destroy_func,
                                 GCacheDupFunc      key_dup_func,
-                                GCacheDestroyFunc  key_destroy_func,
+                                GDestroyNotify     key_destroy_func,
                                 GHashFunc          hash_key_func,
                                 GHashFunc          hash_value_func,
                                 GEqualFunc         key_equal_func);
@@ -51,6 +50,8 @@
                                 gpointer           key);
 void     g_cache_remove        (GCache            *cache,
                                 gconstpointer      value);
+void     g_cache_remove_by_key (GCache            *cache,
+                                gpointer           key);
 void     g_cache_key_foreach   (GCache            *cache,
                                 GHFunc             func,
                                 gpointer           user_data);




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