diff --git a/src/datastructures.c b/src/datastructures.c index 451afb94ec39932dfe1f8c58aa82c0777f73b011..99d821f1a93e8fbfa2189a581b6fd59afb367bc7 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 324fcbafc5ef7601fac70ceaea04894b8d46010d..07420681275a989925a08f6c596e3bc4a59202c1 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)