]> git.mdlowis.com Git - archive/carl.git/commitdiff
Added some hash functions to the hashtable interface
authorMike D. Lowis <mike.lowis@gentex.com>
Thu, 1 Oct 2015 20:01:56 +0000 (16:01 -0400)
committerMike D. Lowis <mike.lowis@gentex.com>
Thu, 1 Oct 2015 20:01:56 +0000 (16:01 -0400)
source/data/hash.c
source/data/hash.h
tests/data/hash.c

index 7fadd122a7c0ec3116a6a5173a82fd590d8dd29e..67388b52875a89a50308b82c0438ec61eabf19f0 100644 (file)
@@ -53,6 +53,37 @@ static void rehash(hash_t* hash)
     }
 }
 
+uint32_t hash_bytes(uint8_t* key, size_t len)
+{
+    uint32_t a=31415u, b=27183u, hash;
+    for (hash=0; len > 0; key++, len--, a*=b)
+        hash = (a * hash) + *key;
+    return hash32(hash);
+}
+
+uint64_t hash64(uint64_t key)
+{
+    key = (~key) + (key << 21); // key = (key << 21) - key - 1;
+    key = key ^ (key >> 24);
+    key = (key + (key << 3)) + (key << 8); // key * 265
+    key = key ^ (key >> 14);
+    key = (key + (key << 2)) + (key << 4); // key * 21
+    key = key ^ (key >> 28);
+    key = key + (key << 31);
+    return key;
+}
+
+uint32_t hash32(uint32_t key)
+{
+   key = (key+0x7ed55d16) + (key<<12);
+   key = (key^0xc761c23c) ^ (key>>19);
+   key = (key+0x165667b1) + (key<<5);
+   key = (key+0xd3a2646c) ^ (key<<9);
+   key = (key+0xfd7046c5) + (key<<3);
+   key = (key^0xb55a4f09) ^ (key>>16);
+   return key;
+}
+
 void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn)
 {
     hash->size      = 0;
index 0c9f54f3852815e338a071004c6ae35cf97d6cd4..f720b57a6d26264bf3c543df1cca1922dd38f835 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <stddef.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 typedef struct hash_entry_t {
     unsigned int hash;
@@ -28,6 +29,12 @@ typedef struct {
     hash_freefn_t delfn;
 } hash_t;
 
+uint32_t hash_bytes(uint8_t* key, size_t len);
+
+uint64_t hash64(uint64_t key);
+
+uint32_t hash32(uint32_t a);
+
 void hash_init(hash_t* hash, hash_hashfn_t hashfn, hash_cmpfn_t cmpfn, hash_freefn_t delfn);
 
 void hash_deinit(hash_t* hash);
index e77a43fdbbd0649670b7f96f640837db17fbcc51..522afd932bf0cba92b96d41b312ac88ab0adac30 100644 (file)
@@ -5,6 +5,8 @@
 #include <data/hash.h>
 #include <carl.h>
 
+static const uint Num_Iterations = 1000000;
+
 typedef struct {
     hash_entry_t link;
     uint val;
@@ -34,10 +36,9 @@ static void delete_func(hash_entry_t* entry)
 TEST_SUITE(Hash) {
     TEST(Verify sequential hash inserts and lookups)
     {
-        uint maxval = 1000000;
         hash_t hash;
         hash_init(&hash, hash_func, compare_func, delete_func);
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t* entry = (int_node_t*)malloc(sizeof(int_node_t));
             entry->val = i;
@@ -45,7 +46,7 @@ TEST_SUITE(Hash) {
             CHECK(i+1 == hash_size(&hash));
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
         }
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t search = { .val = i };
             hash_entry_t* entry = hash_get(&hash, &(search.link));
@@ -59,10 +60,9 @@ TEST_SUITE(Hash) {
 
     TEST(Verify ping pong hash inserts and lookups)
     {
-        uint maxval = 1000000;
         hash_t hash;
         hash_init(&hash, hash_func, compare_func, delete_func);
-        for (uint i = 0; i < (maxval/2); i++) {
+        for (uint i = 0; i < (Num_Iterations/2); i++) {
             /* Insert the lower number */
             int_node_t* entry = (int_node_t*)malloc(sizeof(int_node_t));
             entry->val = i;
@@ -70,11 +70,11 @@ TEST_SUITE(Hash) {
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
             /* Insert the higher number */
             entry = (int_node_t*)malloc(sizeof(int_node_t));
-            entry->val = maxval - i;
+            entry->val = Num_Iterations - i;
             hash_set(&hash, &(entry->link));
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
         }
-        for (uint i = 0; i < (maxval/2); i++)
+        for (uint i = 0; i < (Num_Iterations/2); i++)
         {
             /* Find the lower number */
             int_node_t search = { .val = i };
@@ -83,7 +83,7 @@ TEST_SUITE(Hash) {
             CHECK(entry != NULL);
             CHECK(search.val == ientry->val);
             /* Find the higher number */
-            search.val = maxval-i;
+            search.val = Num_Iterations-i;
             entry = hash_get(&hash, &(search.link));
             ientry = container_of(entry, int_node_t, link);
             CHECK(entry != NULL);
@@ -108,10 +108,9 @@ TEST_SUITE(Hash) {
 
     TEST(Verify sequential inserts and deletions)
     {
-        uint maxval = 1000000;
         hash_t hash;
         hash_init(&hash, hash_func, compare_func, delete_func);
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t* entry = (int_node_t*)malloc(sizeof(int_node_t));
             entry->val = i;
@@ -119,43 +118,41 @@ TEST_SUITE(Hash) {
             CHECK(i+1 == hash_size(&hash));
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
         }
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t search = { .val = i };
             CHECK(hash_del(&hash, &(search.link)));
-            CHECK((maxval - (i+1)) == hash_size(&hash));
+            CHECK((Num_Iterations - (i+1)) == hash_size(&hash));
         }
         hash_deinit(&hash);
     }
 
     TEST(Verify reverse inserts and deletions)
     {
-        uint maxval = 1000000;
         hash_t hash;
         hash_init(&hash, hash_func, compare_func, delete_func);
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t* entry = (int_node_t*)malloc(sizeof(int_node_t));
-            entry->val = maxval - i;
+            entry->val = Num_Iterations - i;
             hash_set(&hash, &(entry->link));
             CHECK(i+1 == hash_size(&hash));
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
         }
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t search = { .val = i+1 };
             CHECK(hash_del(&hash, &(search.link)));
-            CHECK((maxval - (i+1)) == hash_size(&hash));
+            CHECK((Num_Iterations - (i+1)) == hash_size(&hash));
         }
         hash_deinit(&hash);
     }
 
     TEST(Verify ping pong hash inserts and deletions)
     {
-        uint maxval = 1000000;
         hash_t hash;
         hash_init(&hash, hash_func, compare_func, delete_func);
-        for (uint i = 0; i < (maxval/2); i++) {
+        for (uint i = 0; i < (Num_Iterations/2); i++) {
             /* Insert the lower number */
             int_node_t* entry = (int_node_t*)malloc(sizeof(int_node_t));
             entry->val = i;
@@ -163,11 +160,11 @@ TEST_SUITE(Hash) {
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
             /* Insert the higher number */
             entry = (int_node_t*)malloc(sizeof(int_node_t));
-            entry->val = maxval - i;
+            entry->val = Num_Iterations - i;
             hash_set(&hash, &(entry->link));
             CHECK(&(entry->link) == hash_get(&hash, &(entry->link)));
         }
-        for (uint i = 0; i < maxval; i++)
+        for (uint i = 0; i < Num_Iterations; i++)
         {
             int_node_t search = { .val = i };
             if (hash_get(&hash, &(search.link)))