From 3788c90161e6ba7cc2c0f4db81b799fcb0d21a85 Mon Sep 17 00:00:00 2001 From: Andrea Shepard <andrea@special-circumstanc.es> Date: Sat, 11 Jan 2020 17:46:42 +0000 Subject: [PATCH] Implement precomputed-hash versions of hash table functions --- src/datastructures.c | 30 ++++++++++++++++++++++++++---- src/internal.h | 23 ++++++++++++++--------- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/datastructures.c b/src/datastructures.c index 451afb94..99d821f1 100644 --- a/src/datastructures.c +++ b/src/datastructures.c @@ -149,13 +149,14 @@ HHashTable* h_hashtable_new(HArena *arena, HEqualFunc equalFunc, HHashFunc hashF return ht; } -void* h_hashtable_get(const HHashTable* ht, const void* key) { - HHashValue hashval = ht->hashFunc(key); +void * h_hashtable_get_precomp(const HHashTable *ht, const void *key, + HHashValue hashval) { + HHashTableEntry *hte = NULL; + #ifdef CONSISTENCY_CHECK assert((ht->capacity & (ht->capacity - 1)) == 0); // capacity is a power of 2 #endif - HHashTableEntry *hte = NULL; for (hte = &ht->contents[hashval & (ht->capacity - 1)]; hte != NULL; hte = hte->next) { @@ -169,9 +170,16 @@ void* h_hashtable_get(const HHashTable* ht, const void* key) { return hte->value; } } + return NULL; } +void * h_hashtable_get(const HHashTable *ht, const void *key) { + HHashValue hashval = ht->hashFunc(key); + + return h_hashtable_get_precomp(ht, key, hashval); +} + void h_hashtable_put_raw(HHashTable* ht, HHashTableEntry* new_entry); void h_hashtable_ensure_capacity(HHashTable* ht, size_t n) { @@ -197,7 +205,21 @@ void h_hashtable_ensure_capacity(HHashTable* ht, size_t n) { //h_arena_free(ht->arena, old_contents); } -void h_hashtable_put(HHashTable* ht, const void* key, void* value) { +void h_hashtable_put_precomp(HHashTable *ht, const void *key, void *value, + HHashValue hashval) { + HHashTableEntry entry = { + .key = key, + .value = value, + .hashval = hashval + }; + + /* Rebalance if necessary */ + h_hashtable_ensure_capacity(ht, ht->used + 1); + /* Insert it */ + h_hashtable_put_raw(ht, &entry); +} + +void h_hashtable_put(HHashTable *ht, const void *key, void *value) { // # Start with a rebalancing h_hashtable_ensure_capacity(ht, ht->used + 1); diff --git a/src/internal.h b/src/internal.h index 324fcbaf..07420681 100644 --- a/src/internal.h +++ b/src/internal.h @@ -367,16 +367,21 @@ HSlist* h_slist_remove_all(HSlist *slist, const void* item); void h_slist_free(HSlist *slist); static inline bool h_slist_empty(const HSlist *sl) { return (sl->head == NULL); } -HHashTable* h_hashtable_new(HArena *arena, HEqualFunc equalFunc, HHashFunc hashFunc); -void* h_hashtable_get(const HHashTable* ht, const void* key); -void h_hashtable_put(HHashTable* ht, const void* key, void* value); -void h_hashtable_update(HHashTable* dst, const HHashTable *src); -void h_hashtable_merge(void *(*combine)(void *v1, const void *v2), +HHashTable* h_hashtable_new(HArena *arena, HEqualFunc equalFunc, + HHashFunc hashFunc); +void * h_hashtable_get_precomp(const HHashTable *ht, const void *key, + HHashValue hashval); +void * h_hashtable_get(const HHashTable *ht, const void *key); +void h_hashtable_put_precomp(HHashTable *ht, const void *key, + void *value, HHashValue hashval); +void h_hashtable_put(HHashTable *ht, const void *key, void *value); +void h_hashtable_update(HHashTable *dst, const HHashTable *src); +void h_hashtable_merge(void *(*combine)(void *v1, const void *v2), HHashTable *dst, const HHashTable *src); -int h_hashtable_present(const HHashTable* ht, const void* key); -void h_hashtable_del(HHashTable* ht, const void* key); -void h_hashtable_free(HHashTable* ht); -static inline bool h_hashtable_empty(const HHashTable* ht) { return (ht->used == 0); } +int h_hashtable_present(const HHashTable *ht, const void *key); +void h_hashtable_del(HHashTable *ht, const void *key); +void h_hashtable_free(HHashTable *ht); +static inline bool h_hashtable_empty(const HHashTable *ht) { return (ht->used == 0); } typedef HHashTable HHashSet; #define h_hashset_new(a,eq,hash) h_hashtable_new(a,eq,hash) -- GitLab