diff options
author | Allison Lortie <desrt@desrt.ca> | 2016-10-14 11:37:18 +0200 |
---|---|---|
committer | Allison Lortie <desrt@desrt.ca> | 2016-10-14 11:44:48 +0200 |
commit | 3ceff8a9ef70a71f236d56afe92067d81d05c16e (patch) | |
tree | 13566d3313fecf885ab9b29b470630f15d787705 | |
parent | 8d3bdbbe6228f88c24e46fa7da64eb8b6f5c9e74 (diff) | |
download | dconf-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.c | 42 | ||||
-rw-r--r-- | 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); |