summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllison Lortie <desrt@desrt.ca>2016-10-14 11:37:18 +0200
committerAllison Lortie <desrt@desrt.ca>2016-10-14 11:44:48 +0200
commit3ceff8a9ef70a71f236d56afe92067d81d05c16e (patch)
tree13566d3313fecf885ab9b29b470630f15d787705
parent8d3bdbbe6228f88c24e46fa7da64eb8b6f5c9e74 (diff)
downloaddconf-3ceff8a9ef70a71f236d56afe92067d81d05c16e.tar.gz
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.
-rw-r--r--gvdb/gvdb-reader.c42
-rw-r--r--gvdb/gvdb-reader.h9
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);