diff options
| author | WormHeamer | 2025-03-01 21:40:24 -0500 | 
|---|---|---|
| committer | WormHeamer | 2025-03-01 21:40:24 -0500 | 
| commit | 20cbe7ee472c416b243541e661e7eb11621a881f (patch) | |
| tree | 62a6a6d4565fc964554aeaec2ce8a6783aff6305 | |
| parent | 9c4420e3ef42a553ded82286988d3cf5d6570ca0 (diff) | |
add ihash
| -rw-r--r-- | ihash.h | 109 | ||||
| -rw-r--r-- | stdwrm.h | 1 | 
2 files changed, 110 insertions, 0 deletions
| @@ -0,0 +1,109 @@ +#ifndef IHASH_H +#define IHASH_H + +#include <stdlib.h> +#include <stdint.h> +#include <ctype.h> + +#include "dynarr.h" +#include "str.h" + +#ifndef IHASH_SLOTS +#define IHASH_SLOTS 8192 +#endif + +typedef uint64_t hash_t; + +typedef struct { +	intptr_t key; +	void *value; +	hash_t hash; +} IntHashEntry; + +typedef struct { +	DYNARR(IntHashEntry) entries; +} IntHashSlot; + +typedef struct { +	IntHashSlot slots[IHASH_SLOTS]; +} IntHashTable; + +hash_t ihash(intptr_t s); +void ihash_init(IntHashTable *h); +void ihash_free(IntHashTable *h); +void *ihash_get(IntHashTable *h, intptr_t key); +void ihash_put(IntHashTable *h, intptr_t key, void *value); +IntHashEntry *ihash_find(IntHashTable *h, intptr_t key); + +#ifdef IHASH_IMPL + +/* murmur64 integer hash */ + +hash_t ihash(intptr_t h) { +	h *= h >> 33; +	h *= 0xff51afd7ed558ccdL; +	h *= h >> 33; +	h *= 0xc4ceb9fe1a85ec53L; +	h *= h >> 33; +	return h; +} + +/* hash table */ + +void ihash_init(IntHashTable *h) { +	*h = (IntHashTable) { 0 }; +} + +void ihash_free(IntHashTable *h) { +	for (unsigned i = 0; i < IHASH_SLOTS; i++) { +		IntHashSlot *s = &h->slots[i]; +		if (!s->entries) continue; +		DA_FREE(s->entries); +	} +} + +static inline int ihash_entry_match(IntHashEntry *h, intptr_t s, hash_t ihash) { +	return s == ihash; +} + +static inline IntHashEntry *ihash_find_hashed(IntHashTable *h, intptr_t key, hash_t k) { +	size_t i = k & (IHASH_SLOTS - 1); +	if (h->slots[i].entries) { +		DA_FOR(h->slots[i].entries, e) { +			if (ihash_entry_match(e, key, k)) { +				return e; +			} +		} +	} +	return NULL; +} + +IntHashEntry *ihash_find(IntHashTable *h, intptr_t key) { +	return ihash_find_hashed(h, key, ihash(key)); +} + +void *ihash_get(IntHashTable *h, intptr_t key) { +	IntHashEntry *e = ihash_find(h, key); +	return e ? e->value : NULL; +} + +void ihash_put(IntHashTable *h, intptr_t key, void *value) { +	hash_t keyh = ihash(key); +	IntHashEntry *e = ihash_find_hashed(h, key, keyh); +	if (e) { +		e->value = value; +	} else { +		hash_t keyi = keyh & (IHASH_SLOTS - 1); +		if (!h->slots[keyi].entries) { +			DA_INIT(h->slots[keyi].entries); +		} +		DA_PUSH(h->slots[keyi].entries, (IntHashEntry) { +			.key = key, +			.value = value, +			.hash = keyh +		}); +	} +} + +#endif +#endif @@ -3,6 +3,7 @@  #ifdef STDWRM_IMPL  #define SHASH_IMPL +#define IHASH_IMPL  #define ZONE_IMPL  #define STR_IMPL  #endif | 
