[dconf/wip/proxy: 7/12] gvdb: remove memory allocation from GvdbPath



commit 3ceff8a9ef70a71f236d56afe92067d81d05c16e
Author: Allison Lortie <desrt desrt ca>
Date:   Fri Oct 14 11:37:18 2016 +0200

    gvdb: remove memory allocation from GvdbPath
    
    Modify GvdbPath to never allocate memory.
    
    Previously, if we had fewer split points ('/') than the number of
    pre-allocated items in the arrays in the structure, we would simply use
    them.  At 16, this number is already extremely high, and it's
    implausible to imagine a real case for which this would be insufficient.
    
    This commit simplifies things a bit: if there are more than 16 segments,
    we will just ignore the later ones, except for the final one (ie: the
    complete path).
    
    For the sake of an example, let the limit be 4, rather than 16.  This
    means that you could lock:
    
      /
      /org/
      /org/gnome/
      /org/gnome/app/deeply/nested/key
    
    but not:
    
      /org/gnome/app/
      /org/gnome/app/deeply/
      /org/gnome/app/deeply/nested/
    
    With 16 segments, everything here could be locked, and much more.
    
    In this way, we preserve the previous behaviour of always being able to
    lock a particular individual key of any depth, while introducing
    path-based locks for all reasonable cases, and we avoid memory
    allocations in all cases.

 gvdb/gvdb-reader.c |   42 +++++++-----------------------------------
 gvdb/gvdb-reader.h |    9 ++-------
 2 files changed, 9 insertions(+), 42 deletions(-)
---
diff --git a/gvdb/gvdb-reader.c b/gvdb/gvdb-reader.c
index b675a16..ae18831 100644
--- a/gvdb/gvdb-reader.c
+++ b/gvdb/gvdb-reader.c
@@ -49,28 +49,6 @@ gvdb_path_append_component (GvdbPath    *path,
 {
   guint this_component = path->components++;
 
-  if G_UNLIKELY (path->components % G_N_ELEMENTS (path->my_hashes) == 0)
-    {
-      guint next_size;
-
-      G_STATIC_ASSERT (sizeof path->my_hashes == sizeof path->my_lengths);
-
-      if (path->hashes == path->my_hashes)
-        {
-          /* It's slightly inefficient to do it this way, but
-           * we're already on the slow path, and this simplifies
-           * the code below.
-           */
-          path->hashes = g_memdup (path->hashes, sizeof path->my_hashes);
-          path->lengths = g_memdup (path->lengths, sizeof path->my_lengths);
-        }
-
-      /* 16 → 32 → etc. */
-      next_size = path->components + G_N_ELEMENTS (path->my_hashes);
-      path->hashes = g_renew (guint32, path->hashes, next_size);
-      path->lengths = g_renew (guint, path->lengths, next_size);
-    }
-
   path->hashes[this_component] = hash_value;
   path->lengths[this_component] = length;
 }
@@ -86,8 +64,6 @@ gvdb_path_init (GvdbPath    *path,
 
   path->string = string;
   path->components = 0;
-  path->hashes = path->my_hashes;
-  path->lengths = path->my_lengths;
 
   /* Find all of the separators, creating components, up to including
    * each one.
@@ -97,7 +73,13 @@ gvdb_path_init (GvdbPath    *path,
       hash_value = (hash_value * 33) + ((signed char) string[i]);
       more = TRUE;
 
-      if (string[i] == separator)
+      /* If we have a separator, and if we will not be using the last
+       * item in the array, add a new split point.
+       *
+       * In effect, this always allows locking of individual keys (at
+       * any depth) but only allows locking paths up to a certain depth.
+       */
+      if (string[i] == separator && path->components + 1 < G_N_ELEMENTS (path->hashes))
         {
           gvdb_path_append_component (path, hash_value, i + 1);
           more = FALSE;
@@ -111,16 +93,6 @@ gvdb_path_init (GvdbPath    *path,
     gvdb_path_append_component (path, hash_value, i);
 }
 
-void
-gvdb_path_clear (GvdbPath *path)
-{
-  if (path->hashes != path->my_hashes)
-    g_free (path->hashes);
-
-  if (path->lengths != path->my_lengths)
-    g_free (path->my_lengths);
-}
-
 static const gchar *
 gvdb_table_item_get_key (GvdbTable                   *file,
                          const struct gvdb_hash_item *item,
diff --git a/gvdb/gvdb-reader.h b/gvdb/gvdb-reader.h
index e567a5b..fd76b5e 100644
--- a/gvdb/gvdb-reader.h
+++ b/gvdb/gvdb-reader.h
@@ -28,10 +28,8 @@ typedef struct
 {
   const gchar *string;
   guint        components;
-  guint32     *hashes;
-  guint       *lengths;
-  guint32      my_hashes[16];
-  guint        my_lengths[16];
+  guint32      hashes[16];
+  guint        lengths[16];
 } GvdbPath;
 
 G_BEGIN_DECLS
@@ -42,9 +40,6 @@ void                    gvdb_path_init                                  (GvdbPat
                                                                          gchar         separator);
 
 G_GNUC_INTERNAL
-void                    gvdb_path_clear                                 (GvdbPath     *path);
-
-G_GNUC_INTERNAL
 GvdbTable *             gvdb_table_new_from_bytes                       (GBytes       *bytes,
                                                                          gboolean      trusted,
                                                                          GError      **error);


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