Hash table sizes now must be a power of two (saves a modulus instruction);
authorDavid Given <dg@cowlark.com>
Sat, 17 Dec 2016 09:30:27 +0000 (10:30 +0100)
committerDavid Given <dg@cowlark.com>
Sat, 17 Dec 2016 09:30:27 +0000 (10:30 +0100)
optimise key comparison (if the two keys are identical, we don't need to call
the comparator).

modules/src/data/hashtable.c
modules/src/data/hashtable.h

index 8e43d9e..b76df03 100644 (file)
@@ -64,7 +64,7 @@ void hashtable_rebucket(struct hashtable* ht, unsigned int num_buckets)
                while (old_buckets[i])
                {
                        struct hashnode* hn = old_buckets[i];
-                       uint32_t hash = ht->hashfunction(hn->key) % num_buckets;
+                       uint32_t hash = ht->hashfunction(hn->key) & (num_buckets-1);
 
                        old_buckets[i] = hn->next;
                        hn->next = ht->buckets[hash];
@@ -81,11 +81,21 @@ static struct hashnode** findnodep(struct hashtable* ht, void* key)
     struct hashnode** hnp;
 
     lazy_init(ht);
-    hash = ht->hashfunction(key) % ht->num_buckets;
+    hash = ht->hashfunction(key) & (ht->num_buckets-1);
     hnp = &ht->buckets[hash];
 
-    while (*hnp && !ht->cmpfunction((*hnp)->key, key))
+       for (;;)
+       {
+               void* k;
+
+               if (!*hnp)
+                       break;
+               k = (*hnp)->key;
+               if ((k == key) || ht->cmpfunction(k, key))
+                       break;
+
         hnp = &(*hnp)->next;
+       }
 
     return hnp;
 }
@@ -98,7 +108,7 @@ void* hashtable_put(struct hashtable* ht, void* key, void* value)
     {
                if (ht->size == (ht->num_buckets*2))
                {
-                       hashtable_rebucket(ht, ht->num_buckets*3 + 1);
+                       hashtable_rebucket(ht, ht->num_buckets*4);
                        return hashtable_put(ht, key, value);
                }
 
index 4730411..f5617b3 100644 (file)
@@ -11,7 +11,7 @@ extern bool standard_pointer_comparison_function(void* key1, void* key2);
 
 struct hashtable
 {
-    unsigned int num_buckets;
+    unsigned int num_buckets;  /* power of 2 */
     hashfunction_t* hashfunction;
     cmpfunction_t* cmpfunction;
     struct hashnode** buckets;