diff options
| author | Carson Fleming <[email protected]> | 2026-02-14 02:53:37 -0500 |
|---|---|---|
| committer | Carson Fleming <[email protected]> | 2026-02-14 02:53:37 -0500 |
| commit | 9ef0abf7ab5266f6b58c0e55bbe9dd9038bc7f6e (patch) | |
| tree | 54abfa548d7aae56c1ace1a72bce8581570b5fd2 /map.c | |
| parent | 1a08245d480b8a18fcbc80efd8602cdb90d6ed5e (diff) | |
| download | safec-9ef0abf7ab5266f6b58c0e55bbe9dd9038bc7f6e.tar.gz | |
more like dangerousc.org atp
Diffstat (limited to 'map.c')
| -rw-r--r-- | map.c | 147 |
1 files changed, 0 insertions, 147 deletions
@@ -3,18 +3,6 @@ #include <stdlib.h> #define DEFAULT_CAPACITY 16 -#define TOMBSTONE_VAL ((void*)-1) - -size_t hash_bytes(const void* start, size_t size) { - size_t hash = 0; - const char* raw_data = start; - for (size_t i = 0; i < size; i++) { - hash = (hash << 5) - hash + raw_data[i]; - } - return hash; -} - -/* MAPS */ void map_init( map_t* map, @@ -195,138 +183,3 @@ void map_foreach_readwrite( free(keys); free(vals); } - -/* SETS */ - -void set_init( - set_t* set, - hash_func_t hash_func, - eq_func_t eq_func, - double load_limit -) { - set_init_capacity(set, hash_func, eq_func, load_limit, DEFAULT_CAPACITY); -} - -void set_init_capacity( - set_t* set, - hash_func_t hash_func, - eq_func_t eq_func, - double load_limit, - size_t capacity -) { - set->hash_func = hash_func; - set->eq_func = eq_func; - set->load_limit = load_limit; - set->size = 0; - set->__num_buckets = capacity / load_limit + 1; - set->__buckets = calloc(set->__num_buckets, sizeof(void*)); - - if (set->__buckets == NULL) - crash("Out of memory allocating %ld hash buckets\n", set->__num_buckets); -} - -void set_destroy(set_t* set) { - free(set->__buckets); -} - -static size_t fetch_set_idx( - const set_t* set, - const void* key, - bool fetch_tombstones -) { - if (key == NULL || key == TOMBSTONE_VAL) - crash("safec sets do not support non-address keys: %p.\n", key); - size_t base = set->hash_func(key) % set->__num_buckets; - size_t idx = base, i = 0, offset = 0; - - for (;;) { - void* cur = set->__buckets[idx]; - if (cur == NULL || (fetch_tombstones && cur == TOMBSTONE_VAL) - || (cur != TOMBSTONE_VAL && set->eq_func(key, cur))) - return idx; - if (offset >= set->__num_buckets) return set->__num_buckets; - i++; - offset = i * i; - idx = (base + offset) % set->__num_buckets; - } -} - -bool set_contains(const set_t* set, const void* key) { - size_t idx = fetch_set_idx(set, key, false); - return idx < set->__num_buckets && set->__buckets[idx] != NULL; -} - -void* set_get(const set_t* set, const void* key) { - return set_get_or_default(set, key, NULL); -} - -void* set_get_or_default(const set_t* set, const void* key, void* default_key) { - size_t idx = fetch_set_idx(set, key, false); - if (idx >= set->__num_buckets) return default_key; - void* found = set->__buckets[idx]; - return found == NULL ? default_key : found; -} - -static void rehash_set(set_t* set) { - size_t old_num_buckets = set->__num_buckets; - void** old_buckets = set->__buckets; - set->__num_buckets <<= 1; - set->__buckets = calloc(set->__num_buckets, sizeof(void*)); - if (set->__buckets == NULL) - crash( - "Out of memory allocating %ld hash buckets\n", set->__num_buckets); - - for (size_t i = 0; i < old_num_buckets; i++) { - void* key = old_buckets[i]; - if (key == NULL) continue; - size_t idx = fetch_set_idx(set, key, true); - if (idx >= set->__num_buckets) - crash( - "Set failed rehashing, likely due to bad hash function.\n"); - set->__buckets[idx] = key; - } - free(old_buckets); -} - -static size_t fetch_set_idx_rehashing(set_t* set, void* key) { - size_t idx = fetch_set_idx(set, key, true); - if ((double) ++set->size / set->__num_buckets > set->load_limit - || idx >= set->__num_buckets) { - rehash_set(set); - idx = fetch_set_idx(set, key, true); - if (idx >= set->__num_buckets) - crash( - "Set still full after rehashing, " - "likely due to bad hash function.\n"); - } - return idx; -} - -void* set_add(set_t* set, void* key) { - size_t idx = fetch_set_idx_rehashing(set, key); - void* old_key = set->__buckets[idx]; - if (old_key != NULL) return old_key; - set->__buckets[idx] = key; - return key; -} - -void set_put(set_t* set, void* key) { - size_t idx = fetch_set_idx_rehashing(set, key); - set->__buckets[idx] = key; -} - -void* set_remove(set_t* set, const void* key) { - size_t idx = fetch_set_idx(set, key, false); - void* old_key = set->__buckets[idx]; - if (old_key != NULL) set->size--; - set->__buckets[idx] = TOMBSTONE_VAL; - return old_key; -} - -void set_foreach(set_t* set, set_foreach_func_t foreach_func, void* data) { - for (size_t i = 0; i < set->__num_buckets; i++) { - void* key = set->__buckets[i]; - if (key == NULL || key == TOMBSTONE_VAL) continue; - foreach_func(key, data); - } -} |
