]> git.mdlowis.com Git - archive/carl.git/commitdiff
Added incomplete hashtable implementation
authorMike D. Lowis <mike.lowis@gentex.com>
Wed, 30 Sep 2015 19:38:02 +0000 (15:38 -0400)
committerMike D. Lowis <mike.lowis@gentex.com>
Wed, 30 Sep 2015 19:38:02 +0000 (15:38 -0400)
build.ninja
source/data/hash.c [new file with mode: 0644]
source/data/hash.h [new file with mode: 0644]

index 9556fd5e8654890aa299036c5e859a0c93ad6d5c..4f68f6a1b696637ae2584baaf35e29ebe6f75a0b 100644 (file)
@@ -47,8 +47,9 @@ build source/data/vec.o: cc source/data/vec.c
 build source/data/list.o: cc source/data/list.c
 build source/data/bstree.o: cc source/data/bstree.c
 build source/data/slist.o: cc source/data/slist.c
+build source/data/hash.o: cc source/data/hash.c
 build source/main.o: cc source/main.c
-build libcarl.a: ar source/refcount.o source/utf/runetype/toupper.o source/utf/runetype/tolower.o source/utf/runetype/uppers.o source/utf/runetype/numbers.o source/utf/runetype/symbols.o source/utf/runetype/totitle.o source/utf/runetype/titles.o source/utf/runetype/lowers.o source/utf/runetype/spaces.o source/utf/runetype/punctuation.o source/utf/runetype/alphas.o source/utf/runetype/digits.o source/utf/runetype/controls.o source/utf/runetype/marks.o source/utf/runetype/otherletters.o source/utf/runetype/other.o source/utf/runecmp.o source/utf/runeinrange.o source/utf/chartorune.o source/utf/runetype.o source/utf/runelen.o source/utf/fullrune.o source/utf/runenlen.o source/utf/runetochar.o source/data/vec.o source/data/list.o source/data/bstree.o source/data/slist.o source/main.o
+build libcarl.a: ar source/refcount.o source/utf/runetype/toupper.o source/utf/runetype/tolower.o source/utf/runetype/uppers.o source/utf/runetype/numbers.o source/utf/runetype/symbols.o source/utf/runetype/totitle.o source/utf/runetype/titles.o source/utf/runetype/lowers.o source/utf/runetype/spaces.o source/utf/runetype/punctuation.o source/utf/runetype/alphas.o source/utf/runetype/digits.o source/utf/runetype/controls.o source/utf/runetype/marks.o source/utf/runetype/otherletters.o source/utf/runetype/other.o source/utf/runecmp.o source/utf/runeinrange.o source/utf/chartorune.o source/utf/runetype.o source/utf/runelen.o source/utf/fullrune.o source/utf/runenlen.o source/utf/runetochar.o source/data/vec.o source/data/list.o source/data/bstree.o source/data/slist.o source/data/hash.o source/main.o
 build tests/refcount.o: cc tests/refcount.c
 build tests/utf/test_unicodedata.o: cc tests/utf/test_unicodedata.c
 build tests/data/bstree.o: cc tests/data/bstree.c
diff --git a/source/data/hash.c b/source/data/hash.c
new file mode 100644 (file)
index 0000000..d42475f
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+  @file hash.c
+  @brief See header for details
+  $Revision$
+  $HeadURL$
+  */
+#include <data/hash.h>
+#include <stdlib.h>
+
+#define NUM_PRIMES (sizeof(primes)/sizeof(unsigned int))
+
+static unsigned int Primes[] = {
+    5, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
+    49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
+    12582917, 25165843, 50331653, 100663319, 201326611, 402653189,
+    805306457, 1610612741
+};
+
+static inline unsigned int num_buckets(hash_t* hash) {
+    return Primes[hash->bkt_count];
+}
+
+void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn)
+{
+    hash->size      = 0;
+    hash->bkt_count = 0;
+    hash->hashfn    = hashfn;
+    hash->cmpfn     = cmpfn;
+    hash->delfn     = delfn;
+    hash->buckets   = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash));
+}
+
+void hash_deinit(hash_t* hash)
+{
+    (void)hash;
+}
+
+bool hash_set(hash_t* hash, hash_entry_t* entry)
+{
+    //if (hash->size >= num_buckets(hash))
+    //    rehash(hash);
+    unsigned int hashval = hash->hashfn(entry);
+    unsigned int index   = (hashval % num_buckets(hash));
+    hash_entry_t* parent = NULL;
+    hash_entry_t* node   = hash->buckets[index];
+    //find_entry(&parent, &node, hash);
+
+    if (node != NULL) {
+        if (parent == NULL) {
+            hash_entry_t* deadite = node;
+            node = node->next;
+            hash->delfn(deadite);
+        }
+
+    } else {
+
+    }
+    return true;
+}
+
+hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry)
+{
+    unsigned int hashval = hash->hashfn(entry);
+    unsigned int index   = (hashval % num_buckets(hash));
+    //hash_entry_t* parent = NULL;
+    hash_entry_t* node   = hash->buckets[index];
+    //find_entry(&parent, &node, hashval, entry);
+    return node;
+}
+
+bool hash_del(hash_t* hash, hash_entry_t* entry)
+{
+    (void)hash;
+    (void)entry;
+    return false;
+}
+
+void hash_clr(hash_t* hash)
+{
+    /* Delete all the entries  in the hash */
+    for (unsigned int i = 0; i < num_buckets(hash); i++) {
+        hash_entry_t* node = hash->buckets[0];
+        while (node != NULL) {
+            hash_entry_t* deadite = node;
+            node = node->next;
+            hash->delfn(deadite);
+        }
+    }
+    /* Shrink the buckets array */
+    free(hash->buckets);
+    hash->bkt_count = 0;
+    hash->buckets   = (hash_entry_t**)calloc(sizeof(hash_entry_t*), num_buckets(hash));
+}
+
diff --git a/source/data/hash.h b/source/data/hash.h
new file mode 100644 (file)
index 0000000..e743769
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+  @file hash.h
+  @brief Generic hashtable implementation.
+*/
+#ifndef HASH_H
+#define HASH_H
+
+#include <stddef.h>
+#include <stdbool.h>
+
+typedef struct hash_entry_t {
+    struct hash_entry_t* next;
+} hash_entry_t;
+
+typedef unsigned int (*hash_hashfn_t)(const hash_entry_t* entry);
+
+typedef int (*hash_cmpfn_t)(const hash_entry_t* entry1, const hash_entry_t* entry2);
+
+typedef void (*hash_freefn_t)(hash_entry_t* key);
+
+typedef struct {
+    size_t size;
+    size_t bkt_count;
+    hash_entry_t** buckets;
+    hash_hashfn_t hashfn;
+    hash_cmpfn_t cmpfn;
+    hash_freefn_t delfn;
+} hash_t;
+
+void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn);
+
+void hash_deinit(hash_t* hash);
+
+bool hash_set(hash_t* hash, hash_entry_t* entry);
+
+hash_entry_t* hash_get(hash_t* hash, hash_entry_t* entry);
+
+bool hash_del(hash_t* hash, hash_entry_t* entry);
+
+void hash_clr(hash_t* hash);
+
+#endif /* HASH_H */