misc: hash-table wrapper
authorDavid Herrmann <dh.herrmann@googlemail.com>
Fri, 30 Mar 2012 16:30:55 +0000 (18:30 +0200)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Fri, 30 Mar 2012 16:42:12 +0000 (18:42 +0200)
We want to move away from glib eventually. Until then, we use a simple
wrapper around the hash-table functions so we need to change a single
place only.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
src/misc.c
src/misc.h

index 5ee1e92..5afe470 100644 (file)
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include "log.h"
 #include "misc.h"
 
+#define LOG_SUBSYSTEM "misc"
+
 #define RING_SIZE 512
 
 struct ring_entry {
@@ -266,3 +269,89 @@ void kmscon_hook_call(struct kmscon_hook *hook, void *parent, void *arg)
                        hook->cur_entry = hook->cur_entry->next;
        }
 }
+
+/* Hash Tables
+ * This is currently a wrapper around the GHashTable glib object. We should
+ * replace this with an own hash-table to avoid glib dependency. However, I
+ * currently don't have the time so we use glib.
+ * TODO: Write an own hash-table implementation!
+ */
+
+#include <glib.h>
+
+struct kmscon_hashtable {
+       GHashTable *tbl;
+};
+
+unsigned int kmscon_direct_hash(const void *data)
+{
+       return g_direct_hash(data);
+}
+
+int kmscon_direct_equal(const void *data1, const void *data2)
+{
+       return g_direct_equal(data1, data2);
+}
+
+int kmscon_hashtable_new(struct kmscon_hashtable **out,
+                               kmscon_hash_cb hash_cb,
+                               kmscon_equal_cb equal_cb,
+                               kmscon_free_cb free_key,
+                               kmscon_free_cb free_value)
+{
+       struct kmscon_hashtable *tbl;
+
+       if (!out || !hash_cb || !equal_cb)
+               return -EINVAL;
+
+       tbl = malloc(sizeof(*tbl));
+       if (!tbl)
+               return -ENOMEM;
+       memset(tbl, 0, sizeof(*tbl));
+
+       tbl->tbl = g_hash_table_new_full(hash_cb, equal_cb,
+                                               free_key, free_value);
+       if (!tbl->tbl) {
+               log_err("cannot allocate GHashTable");
+               free(tbl);
+               return -ENOMEM;
+       }
+
+       *out = tbl;
+       return 0;
+}
+
+void kmscon_hashtable_free(struct kmscon_hashtable *tbl)
+{
+       if (!tbl)
+               return;
+
+       g_hash_table_unref(tbl->tbl);
+}
+
+int kmscon_hashtable_insert(struct kmscon_hashtable *tbl, void *key,
+                               void *data)
+{
+       if (!tbl)
+               return -EINVAL;
+
+       g_hash_table_insert(tbl->tbl, key, data);
+       return 0;
+}
+
+bool kmscon_hashtable_find(struct kmscon_hashtable *tbl, void **out, void *key)
+{
+       void *val;
+       gboolean res;
+
+       if (!tbl)
+               return -EINVAL;
+
+       res = g_hash_table_lookup_extended(tbl->tbl, key, NULL, &val);
+       if (res != TRUE)
+               return false;
+
+       if (out)
+               *out = val;
+       return true;
+}
index 80b17e4..97fb6c5 100644 (file)
@@ -35,6 +35,8 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
+/* ring buffer for arbitrary byte-streams */
+
 struct kmscon_ring;
 
 int kmscon_ring_new(struct kmscon_ring **out);
@@ -45,6 +47,8 @@ int kmscon_ring_write(struct kmscon_ring *ring, const char *val, size_t len);
 const char *kmscon_ring_peek(struct kmscon_ring *ring, size_t *len);
 void kmscon_ring_drop(struct kmscon_ring *ring, size_t len);
 
+/* callback hooks */
+
 struct kmscon_hook;
 typedef void (*kmscon_hook_cb) (void *parent, void *arg, void *data);
 
@@ -58,4 +62,25 @@ void kmscon_hook_call(struct kmscon_hook *hook, void *parent, void *arg);
 #define kmscon_hook_rm_cast(hook, cb, data) \
        kmscon_hook_rm((hook), (kmscon_hook_cb)(cb), (data))
 
+/* hash-tables */
+
+struct kmscon_hashtable;
+
+typedef unsigned int (*kmscon_hash_cb) (const void *data);
+typedef int (*kmscon_equal_cb) (const void *data1, const void *data2);
+typedef void (*kmscon_free_cb) (void *data);
+
+unsigned int kmscon_direct_hash(const void *data);
+int kmscon_direct_equal(const void *data1, const void *data2);
+
+int kmscon_hashtable_new(struct kmscon_hashtable **out,
+                               kmscon_hash_cb hash_cb,
+                               kmscon_equal_cb equal_cb,
+                               kmscon_free_cb free_key,
+                               kmscon_free_cb free_value);
+void kmscon_hashtable_free(struct kmscon_hashtable *tbl);
+int kmscon_hashtable_insert(struct kmscon_hashtable *tbl, void *key,
+                               void *data);
+bool kmscon_hashtable_find(struct kmscon_hashtable *tbl, void **out, void *key);
+
 #endif /* KMSCON_MISC_H */