[tracker] gvdb: Merge upstream changes



commit df58112d63c678f8b713a00d9dc42ce5615414b7
Author: JÃrg Billeter <j bitron ch>
Date:   Tue Dec 13 16:32:54 2011 +0100

    gvdb: Merge upstream changes
    
    This fixes some memory leaks.

 src/gvdb/gvdb-builder.c |   16 +++++++++++++++-
 src/gvdb/gvdb-reader.c  |   37 +++++++++++++++++++++++++++++++------
 src/gvdb/gvdb-reader.h  |    7 ++++++-
 tests/gvdb/gvdb-test.c  |    3 ++-
 4 files changed, 54 insertions(+), 9 deletions(-)
---
diff --git a/src/gvdb/gvdb-builder.c b/src/gvdb/gvdb-builder.c
index fdd0ef4..91adec6 100644
--- a/src/gvdb/gvdb-builder.c
+++ b/src/gvdb/gvdb-builder.c
@@ -24,7 +24,9 @@
 
 #include <glib.h>
 #include <fcntl.h>
+#if !defined(G_OS_WIN32) || !defined(_MSC_VER)
 #include <unistd.h>
+#endif
 #include <string.h>
 
 
@@ -91,7 +93,7 @@ djb_hash (const gchar *key)
   guint32 hash_value = 5381;
 
   while (*key)
-    hash_value = hash_value * 33 + *key++;
+    hash_value = hash_value * 33 + *(signed char *)key++;
 
   return hash_value;
 }
@@ -178,6 +180,14 @@ hash_table_new (gint n_buckets)
 }
 
 static void
+hash_table_free (HashTable *table)
+{
+  g_free (table->buckets);
+
+  g_slice_free (HashTable, table);
+}
+
+static void
 hash_table_insert (gpointer key,
                    gpointer value,
                    gpointer data)
@@ -417,6 +427,8 @@ file_builder_add_hash (FileBuilder         *fb,
           index++;
         }
     }
+
+  hash_table_free (mytable);
 }
 
 static FileBuilder *
@@ -472,6 +484,8 @@ file_builder_serialise (FileBuilder          *fb,
 
       g_string_append_len (result, chunk->data, chunk->size);
       g_free (chunk->data);
+
+      g_slice_free (FileChunk, chunk);
     }
 
   g_queue_free (fb->chunks);
diff --git a/src/gvdb/gvdb-reader.c b/src/gvdb/gvdb-reader.c
index fb23393..57816af 100644
--- a/src/gvdb/gvdb-reader.c
+++ b/src/gvdb/gvdb-reader.c
@@ -87,7 +87,6 @@ gvdb_table_setup_root (GvdbTable                 *file,
 {
   const struct gvdb_hash_header *header;
   guint32 n_bloom_words;
-  guint32 bloom_shift;
   guint32 n_buckets;
   gsize size;
 
@@ -100,7 +99,6 @@ gvdb_table_setup_root (GvdbTable                 *file,
 
   n_bloom_words = guint32_from_le (header->n_bloom_words);
   n_buckets = guint32_from_le (header->n_buckets);
-  bloom_shift = n_bloom_words >> 27;
   n_bloom_words &= (1u << 27) - 1;
 
   if G_UNLIKELY (n_bloom_words * sizeof (guint32_le) > size)
@@ -230,7 +228,7 @@ gvdb_table_check_name (GvdbTable             *file,
     return FALSE;
 
   parent = guint32_from_le (item->parent);
-  if (key_length == 0 && parent == -1)
+  if (key_length == 0 && parent == 0xffffffffu)
     return TRUE;
 
   if G_LIKELY (parent < file->n_hash_items && this_size > 0)
@@ -256,7 +254,7 @@ gvdb_table_lookup (GvdbTable   *file,
     return NULL;
 
   for (key_length = 0; key[key_length]; key_length++)
-    hash_value = (hash_value * 33) + key[key_length];
+    hash_value = (hash_value * 33) + ((signed char *) key)[key_length];
 
   if (!gvdb_table_bloom_filter (file, hash_value))
     return NULL;
@@ -340,7 +338,7 @@ gvdb_table_list (GvdbTable   *file,
   const guint32_le *list;
   gchar **strv;
   guint length;
-  gint i;
+  guint i;
 
   if ((item = gvdb_table_lookup (file, key, 'L')) == NULL)
     return NULL;
@@ -574,6 +572,30 @@ gvdb_table_is_valid (GvdbTable *table)
   return !!*table->data;
 }
 
+/**
+ * gvdb_table_walk:
+ * @table: a #GvdbTable
+ * @key: a key corresponding to a list
+ * @open_func: the #GvdbWalkOpenFunc
+ * @value_func: the #GvdbWalkValueFunc
+ * @close_func: the #GvdbWalkCloseFunc
+ * @user_data: data to pass to the callbacks
+ *
+ * Looks up the list at @key and iterate over the items in it.
+ *
+ * First, @open_func is called to signal that we are starting to iterate over
+ * the list.  Then the list is iterated.  When all items in the list have been
+ * iterated over, the @close_func is called.
+ *
+ * When iterating, if a given item in the list is a value then @value_func is
+ * called.
+ *
+ * If a given item in the list is itself a list then @open_func is called.  If
+ * that function returns %TRUE then the walk begins iterating the items in the
+ * sublist, until there are no more items, at which point a matching
+ * @close_func call is made.  If @open_func returns %FALSE then no iteration of
+ * the sublist occurs and no corresponding @close_func call is made.
+ **/
 void
 gvdb_table_walk (GvdbTable         *table,
                  const gchar       *key,
@@ -585,16 +607,18 @@ gvdb_table_walk (GvdbTable         *table,
   const struct gvdb_hash_item *item;
   const guint32_le *pointers[64];
   const guint32_le *enders[64];
+  gsize name_lengths[64];
   gint index = 0;
 
   item = gvdb_table_lookup (table, key, 'L');
+  name_lengths[0] = 0;
   pointers[0] = NULL;
   enders[0] = NULL;
   goto start_here;
 
   while (index)
     {
-      close_func (user_data);
+      close_func (name_lengths[index], user_data);
       index--;
 
       while (pointers[index] < enders[index])
@@ -621,6 +645,7 @@ gvdb_table_walk (GvdbTable         *table,
                                                  &pointers[index],
                                                  &length);
                       enders[index] = pointers[index] + length;
+                      name_lengths[index] = name_len;
                     }
                 }
               else if (item->type == 'v')
diff --git a/src/gvdb/gvdb-reader.h b/src/gvdb/gvdb-reader.h
index 9f302c0..e6921e9 100644
--- a/src/gvdb/gvdb-reader.h
+++ b/src/gvdb/gvdb-reader.h
@@ -26,6 +26,8 @@
 
 typedef struct _GvdbTable GvdbTable;
 
+G_BEGIN_DECLS
+
 G_GNUC_INTERNAL
 GvdbTable *             gvdb_table_new                                  (const gchar  *filename,
                                                                          gboolean      trusted,
@@ -62,8 +64,10 @@ typedef void          (*GvdbWalkValueFunc)                              (const g
 typedef gboolean      (*GvdbWalkOpenFunc)                               (const gchar       *name,
                                                                          gsize              name_len,
                                                                          gpointer           user_data);
-typedef void          (*GvdbWalkCloseFunc)                              (gpointer           user_data);
+typedef void          (*GvdbWalkCloseFunc)                              (gsize              name_len,
+                                                                         gpointer           user_data);
 
+G_GNUC_INTERNAL
 void                    gvdb_table_walk                                 (GvdbTable         *table,
                                                                          const gchar       *key,
                                                                          GvdbWalkOpenFunc   open_func,
@@ -71,5 +75,6 @@ void                    gvdb_table_walk                                 (GvdbTab
                                                                          GvdbWalkCloseFunc  close_func,
                                                                          gpointer           user_data);
 
+G_END_DECLS
 
 #endif /* __gvdb_reader_h__ */
diff --git a/tests/gvdb/gvdb-test.c b/tests/gvdb/gvdb-test.c
index 2d4730d..14f8da2 100644
--- a/tests/gvdb/gvdb-test.c
+++ b/tests/gvdb/gvdb-test.c
@@ -29,7 +29,8 @@ walk_open_cb (G_GNUC_UNUSED const gchar *name,
 }
 
 void
-walk_close_cb (G_GNUC_UNUSED gpointer user_data)
+walk_close_cb (G_GNUC_UNUSED gsize name_len,
+               G_GNUC_UNUSED gpointer user_data)
 {
 }
 



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