r22537 - gnucash/branches/2.4/src - [r22190]Since 2.32, GCache is deprecated and should be replaced by GHashTable.

John Ralls jralls at code.gnucash.org
Tue Nov 6 19:24:30 EST 2012


Author: jralls
Date: 2012-11-06 19:24:29 -0500 (Tue, 06 Nov 2012)
New Revision: 22537
Trac: http://svn.gnucash.org/trac/changeset/22537

Added:
   gnucash/branches/2.4/src/libqof/qof/qof-string-cache.c
   gnucash/branches/2.4/src/libqof/qof/qof-string-cache.h
Modified:
   gnucash/branches/2.4/src/app-utils/gnc-component-manager.c
   gnucash/branches/2.4/src/libqof/qof/Makefile.am
   gnucash/branches/2.4/src/libqof/qof/kvp_frame.c
   gnucash/branches/2.4/src/libqof/qof/qof.h
   gnucash/branches/2.4/src/libqof/qof/qofbook.c
   gnucash/branches/2.4/src/libqof/qof/qofutil.c
   gnucash/branches/2.4/src/libqof/qof/qofutil.h
   gnucash/branches/2.4/src/libqof/qof/test/test-qof.c
Log:
[r22190]Since 2.32, GCache is deprecated and should be replaced by GHashTable.

In the new string cache (split out from qofutil.c/.h), the GHashTable has the
string as key and a small heap-allocated guint refcount as data.  The value is
allocated rather than being used by value because there is no way to just
modify the data field of an existing key.  The key would need to be changed at
the same time, which would free the old key value and invalidate all gchar
pointers of objects which have refs to the key.
 (Unit tests removed, they don't work in the 2.4 branch because the testing infrastructure isn't in place.)

Modified: gnucash/branches/2.4/src/app-utils/gnc-component-manager.c
===================================================================
--- gnucash/branches/2.4/src/app-utils/gnc-component-manager.c	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/app-utils/gnc-component-manager.c	2012-11-07 00:24:29 UTC (rev 22537)
@@ -124,7 +124,7 @@
 static gboolean
 destroy_mask_hash_helper (gpointer key, gpointer value, gpointer user_data)
 {
-    qof_util_string_cache_remove (key);
+    qof_string_cache_remove (key);
     g_free (value);
 
     return TRUE;
@@ -241,7 +241,7 @@
     mask = g_hash_table_lookup (cei->event_masks, entity_type);
     if (!mask)
     {
-        char * key = qof_util_string_cache_insert ((gpointer) entity_type);
+        char * key = qof_string_cache_insert ((gpointer) entity_type);
         mask = g_new0 (QofEventId, 1);
         g_hash_table_insert (cei->event_masks, key, mask);
     }

Modified: gnucash/branches/2.4/src/libqof/qof/Makefile.am
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/Makefile.am	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/Makefile.am	2012-11-07 00:24:29 UTC (rev 22537)
@@ -24,6 +24,7 @@
    kvp_frame.c       \
    kvp-util.c        \
    md5.c             \
+   qof-string-cache.c  \
    qofbackend.c      \
    qofclass.c        \
    qofchoice.c       \
@@ -70,6 +71,7 @@
    qofreference.h    \
    qofsession.h      \
    qofsql.h          \
+   qof-string-cache.h  \
    qofutil.h         \
    qofbookmerge.h    \
    qof-gobject.h

Modified: gnucash/branches/2.4/src/libqof/qof/kvp_frame.c
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/kvp_frame.c	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/kvp_frame.c	2012-11-07 00:24:29 UTC (rev 22537)
@@ -32,8 +32,8 @@
 
 #include "qof.h"
 
-/* Note that we keep the keys for this hash table in a GCache
- * (qof_util_string_cache), as it is very likely we will see the
+/* Note that we keep the keys for this hash table in the
+ * qof_string_cache, as it is very likely we will see the
  * same keys over and over again  */
 
 struct _KvpFrame
@@ -108,7 +108,7 @@
 static void
 kvp_frame_delete_worker(gpointer key, gpointer value, gpointer user_data)
 {
-    qof_util_string_cache_remove(key);
+    qof_string_cache_remove(key);
     kvp_value_delete((KvpValue *)value);
 }
 
@@ -143,7 +143,7 @@
 {
     KvpFrame * dest = (KvpFrame *)user_data;
     g_hash_table_insert(dest->hash,
-                        qof_util_string_cache_insert(key),
+                        qof_string_cache_insert(key),
                         (gpointer)kvp_value_copy(value));
 }
 
@@ -184,7 +184,7 @@
     if (key_exists)
     {
         g_hash_table_remove(frame->hash, slot);
-        qof_util_string_cache_remove(orig_key);
+        qof_string_cache_remove(orig_key);
     }
     else
     {
@@ -194,7 +194,7 @@
     if (new_value)
     {
         g_hash_table_insert(frame->hash,
-                            qof_util_string_cache_insert((gpointer) slot),
+                            qof_string_cache_insert((gpointer) slot),
                             new_value);
     }
 

Added: gnucash/branches/2.4/src/libqof/qof/qof-string-cache.c
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qof-string-cache.c	                        (rev 0)
+++ gnucash/branches/2.4/src/libqof/qof/qof-string-cache.c	2012-11-07 00:24:29 UTC (rev 22537)
@@ -0,0 +1,131 @@
+/********************************************************************\
+ * qof-string-cache.c -- QOF string cache functions                 *
+ * Copyright (C) 1997 Robin D. Clark                                *
+ * Copyright (C) 1997-2001,2004 Linas Vepstas <linas at linas.org>     *
+ * Copyright 2006  Neil Williams  <linux at codehelp.co.uk>            *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ *                                                                  *
+ *   Author: Rob Clark (rclark at cs.hmc.edu)                          *
+ *   Author: Linas Vepstas (linas at linas.org)                        *
+ *   Author: Phil Longstaff (phil.longstaff at yahoo.ca)               *
+\********************************************************************/
+
+#include "config.h"
+
+#include <ctype.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include "qof.h"
+
+static QofLogModule log_module = QOF_MOD_UTIL;
+
+/* =================================================================== */
+/* The QOF string cache                                                */
+/*                                                                     */
+/* The cache is a GHashTable where a copy of the string is the key,    */
+/* and a ref count is the value                                        */
+/* =================================================================== */
+
+static GHashTable* qof_string_cache = NULL;
+
+static GHashTable*
+qof_get_string_cache(void)
+{
+    if (!qof_string_cache)
+    {
+        qof_string_cache = g_hash_table_new_full(
+                               g_str_hash,               /* hash_func          */
+                               g_str_equal,              /* key_equal_func     */
+                               g_free,                   /* key_destroy_func   */
+                               g_free);                  /* value_destroy_func */
+    }
+    return qof_string_cache;
+}
+
+void
+qof_string_cache_init(void)
+{
+    (void)qof_get_string_cache();
+}
+
+void
+qof_string_cache_destroy (void)
+{
+    if (qof_string_cache)
+    {
+        g_hash_table_destroy(qof_string_cache);
+    }
+    qof_string_cache = NULL;
+}
+
+/* If the key exists in the cache, check the refcount.  If 1, just
+ * remove the key.  Otherwise, decrement the refcount */
+void
+qof_string_cache_remove(gconstpointer key)
+{
+    if (key)
+    {
+        GHashTable* cache = qof_get_string_cache();
+        gpointer value;
+        gpointer cache_key;
+        if (g_hash_table_lookup_extended(cache, key, &cache_key, &value))
+        {
+            guint* refcount = (guint*)value;
+            if (*refcount == 1)
+            {
+                g_hash_table_remove(cache, key);
+            }
+            else
+            {
+                --(*refcount);
+            }
+        }
+    }
+}
+
+/* If the key exists in the cache, increment the refcount.  Otherwise,
+ * add it with a refcount of 1. */
+gpointer
+qof_string_cache_insert(gconstpointer key)
+{
+    if (key)
+    {
+        GHashTable* cache = qof_get_string_cache();
+        gpointer value;
+        gpointer cache_key;
+        if (g_hash_table_lookup_extended(cache, key, &cache_key, &value))
+        {
+            guint* refcount = (guint*)value;
+            ++(*refcount);
+            return cache_key;
+        }
+        else
+        {
+            gpointer new_key = g_strdup(key);
+            guint* refcount = g_malloc(sizeof(guint));
+            *refcount = 1;
+            g_hash_table_insert(cache, new_key, refcount);
+            return new_key;
+        }
+    }
+    return NULL;
+}
+
+/* ************************ END OF FILE ***************************** */

Added: gnucash/branches/2.4/src/libqof/qof/qof-string-cache.h
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qof-string-cache.h	                        (rev 0)
+++ gnucash/branches/2.4/src/libqof/qof/qof-string-cache.h	2012-11-07 00:24:29 UTC (rev 22537)
@@ -0,0 +1,114 @@
+/********************************************************************\
+ * qof-string-cache.h -- QOF string cache functions                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+/** @addtogroup Utilities
+    @{ */
+/** @file qof-string-cache.h
+    @brief QOF String cache functions
+    @author Copyright (C) 1997 Robin D. Clark <rclark at cs.hmc.edu>
+    @author Copyright (C) 2000 Bill Gribble <grib at billgribble.com>
+    @author Copyright (C) 1997-2002,2004 Linas Vepstas <linas at linas.org>
+    @author Copyright 2006  Neil Williams  <linux at codehelp.co.uk>
+    @author Copyright 2012  Phil Longstaff <phil.longstaff at yahoo.ca>
+*/
+
+#ifndef QOF_STRING_UTIL_H
+#define QOF_STRING_UTIL_H
+
+#if 0
+#include <stddef.h>
+#include "qof.h"
+#include "qoflog.h"
+#include "qofutil.h"
+#include "qofbackend.h"
+#include "qofclass.h"
+#include "qofbook.h"
+#include "qofinstance.h"
+#endif
+
+#define QOF_MOD_UTIL "qof.utilities"
+
+/** The QOF String Cache:
+ *
+ * Many strings used throughout QOF and QOF applications are likely to
+ * be duplicated.
+ *
+ * QOF provides a reference counted cache system for the strings, which
+ * shares strings whenever possible.
+ *
+ * Use qof_string_cache_insert to insert a string into the cache (it
+ * will return a pointer to the cached string).  Basically you should
+ * use this instead of g_strdup.
+ *
+ * Use qof_string_cache_remove (giving it a pointer to a cached
+ * string) if the string is unused.  If this is the last reference to
+ * the string it will be removed from the cache, otherwise it will
+ * just decrement the reference count.  Basically you should use this
+ * instead of g_free.
+ *
+ * Just in case it's not clear: The remove function must NOT be called
+ * for the string you passed INTO the insert function.  It must be
+ * called for the _cached_ string that is _returned_ by the insert
+ * function.
+ *
+ * Note that all the work is done when inserting or removing.  Once
+ * cached the strings are just plain C strings.
+ *
+ * The string cache is demand-created on first use.
+ *
+ **/
+
+/** Initialize the string cache */
+void qof_string_cache_init(void);
+
+/** Destroy the qof_string_cache */
+void qof_string_cache_destroy(void);
+
+/** You can use this function as a destroy notifier for a GHashTable
+   that uses common strings as keys (or values, for that matter.)
+*/
+void qof_string_cache_remove(gconstpointer key);
+
+/** You can use this function with g_hash_table_insert(), for the key
+   (or value), as long as you use the destroy notifier above.
+*/
+gpointer qof_string_cache_insert(gconstpointer key);
+
+#define CACHE_INSERT(str) qof_string_cache_insert((gconstpointer)(str))
+#define CACHE_REMOVE(str) qof_string_cache_remove((str))
+
+/* Replace cached string currently in 'dst' with string in 'src'.
+ * Typical usage:
+ *     void foo_set_name(Foo *f, const char *str) {
+ *        CACHE_REPLACE(f->name, str);
+ *     }
+ * It avoids unnecessary ejection by doing INSERT before REMOVE.
+*/
+#define CACHE_REPLACE(dst, src) do {          \
+        gpointer tmp = CACHE_INSERT((src));   \
+        CACHE_REMOVE((dst));                  \
+        (dst) = tmp;                          \
+    } while (0)
+
+#define QOF_CACHE_NEW(void) qof_string_cache_insert("")
+
+#endif /* QOF_STRING_CACHE_H */
+/** @} */

Modified: gnucash/branches/2.4/src/libqof/qof/qof.h
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qof.h	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/qof.h	2012-11-07 00:24:29 UTC (rev 22537)
@@ -96,5 +96,6 @@
 #include "qofchoice.h"
 #include "qofbookmerge.h"
 #include "qofreference.h"
+#include "qof-string-cache.h"
 
 #endif /* QOF_H_ */

Modified: gnucash/branches/2.4/src/libqof/qof/qofbook.c
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qofbook.c	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/qofbook.c	2012-11-07 00:24:29 UTC (rev 22537)
@@ -67,7 +67,7 @@
 
     book->hash_of_collections = g_hash_table_new_full(
                                     g_str_hash, g_str_equal,
-                                    (GDestroyNotify)qof_util_string_cache_remove,  /* key_destroy_func   */
+                                    (GDestroyNotify)qof_string_cache_remove,  /* key_destroy_func   */
                                     coll_destroy);                            /* value_destroy_func */
 
     qof_instance_init_data (&book->inst, QOF_ID_BOOK, book);
@@ -326,7 +326,7 @@
         col = qof_collection_new (entity_type);
         g_hash_table_insert(
             book->hash_of_collections,
-            qof_util_string_cache_insert((gpointer) entity_type), col);
+            qof_string_cache_insert((gpointer) entity_type), col);
     }
     return col;
 }

Modified: gnucash/branches/2.4/src/libqof/qof/qofutil.c
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qofutil.c	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/qofutil.c	2012-11-07 00:24:29 UTC (rev 22537)
@@ -301,46 +301,7 @@
     return (v && v2) ? g_str_equal(v, v2) : FALSE;
 }
 #endif
-static GCache*
-qof_util_get_string_cache(void)
-{
-    if (!qof_string_cache)
-    {
-        qof_string_cache = g_cache_new(
-                               (GCacheNewFunc) g_strdup, /* value_new_func     */
-                               g_free,                   /* value_destroy_func */
-                               (GCacheDupFunc) g_strdup, /* key_dup_func       */
-                               g_free,                   /* key_destroy_func   */
-                               g_str_hash,               /* hash_key_func      */
-                               g_str_hash,               /* hash_value_func    */
-                               g_str_equal);             /* key_equal_func     */
-    }
-    return qof_string_cache;
-}
 
-void
-qof_util_string_cache_destroy (void)
-{
-    if (qof_string_cache)
-        g_cache_destroy (qof_string_cache);
-    qof_string_cache = NULL;
-}
-
-void
-qof_util_string_cache_remove(gconstpointer key)
-{
-    if (key)
-        g_cache_remove(qof_util_get_string_cache(), key);
-}
-
-gpointer
-qof_util_string_cache_insert(gconstpointer key)
-{
-    if (key)
-        return g_cache_insert(qof_util_get_string_cache(), (gpointer)key);
-    return NULL;
-}
-
 gchar*
 qof_util_param_as_string(QofInstance *ent, QofParam *param)
 {
@@ -522,7 +483,7 @@
 {
     g_type_init();
     qof_log_init();
-    qof_util_get_string_cache ();
+    qof_string_cache_init();
     guid_init ();
     qof_object_initialize ();
     qof_query_init ();
@@ -536,7 +497,7 @@
     qof_object_shutdown ();
     guid_shutdown ();
     qof_finalize_backend_libraries();
-    qof_util_string_cache_destroy ();
+    qof_string_cache_destroy ();
     qof_log_shutdown();
 }
 

Modified: gnucash/branches/2.4/src/libqof/qof/qofutil.h
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/qofutil.h	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/qofutil.h	2012-11-07 00:24:29 UTC (rev 22537)
@@ -288,9 +288,6 @@
 */
 gpointer qof_util_string_cache_insert(gconstpointer key);
 
-#define CACHE_INSERT(str) qof_util_string_cache_insert((gconstpointer)(str))
-#define CACHE_REMOVE(str) qof_util_string_cache_remove((str))
-
 /* Replace cached string currently in 'dst' with string in 'src'.
  * Typical usage:
  *     void foo_set_name(Foo *f, const char *str) {
@@ -304,8 +301,6 @@
         (dst) = tmp;                          \
     } while (0)
 
-#define QOF_CACHE_NEW(void) qof_util_string_cache_insert("")
-
 /** begin_edit
  *
  * @param  inst: an instance of QofInstance

Modified: gnucash/branches/2.4/src/libqof/qof/test/test-qof.c
===================================================================
--- gnucash/branches/2.4/src/libqof/qof/test/test-qof.c	2012-11-07 00:24:20 UTC (rev 22536)
+++ gnucash/branches/2.4/src/libqof/qof/test/test-qof.c	2012-11-07 00:24:29 UTC (rev 22537)
@@ -28,6 +28,7 @@
 extern void test_suite_qofbook();
 extern void test_suite_qofinstance();
 extern void test_suite_qofsession();
+extern void test_suite_qof_string_cache();
 
 int
 main (int   argc,



More information about the gnucash-changes mailing list