diff options
| author | Mistivia <i@mistivia.com> | 2025-07-22 15:28:30 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-07-22 15:28:45 +0800 |
| commit | 999fcf0f7655c03265c222cc67617f0f510979bf (patch) | |
| tree | dd51680ffda411239e37460c834a996dc934dc63 /src/hash_table.c | |
| parent | a8764a20f355fd8fb7b03978d754d1cbd48d0a88 (diff) | |
change dir structure
Diffstat (limited to 'src/hash_table.c')
| -rw-r--r-- | src/hash_table.c | 119 |
1 files changed, 0 insertions, 119 deletions
diff --git a/src/hash_table.c b/src/hash_table.c deleted file mode 100644 index bedeb4a..0000000 --- a/src/hash_table.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "hash_table.h" - -#include <stdlib.h> -#include <string.h> - -#include "basic_traits.h" - -#define HTFL_NUL 0 -#define HTFL_VAL 1 -#define HTFL_DEL 2 - -HASH_TABLE_IMPL(String, Int); -HASH_TABLE_IMPL(String, String); -HASH_TABLE_IMPL(String, Double); -HASH_TABLE_IMPL(String, VoidPtr); -HASH_TABLE_IMPL(Int, Int); -HASH_TABLE_IMPL(Int, Double); -HASH_TABLE_IMPL(VoidPtr, Int); -HASH_TABLE_IMPL(VoidPtr, VoidPtr); -HASH_TABLE_IMPL(VoidPtr, String); - - -static void rebuild(HashTable *ht, uint64_t (*hash)(void*), bool (*eq)(void*, void*)) { - HashTable newht; - init_hash_table(&newht, ht->elemsz, ht->size * 6); - void *iter = hash_table_begin(ht); - while (iter != NULL) { - hash_table_insert(&newht, iter, hash, eq); - iter = hash_table_next(ht, iter); - } - free(ht->buf); - free(ht->flagbuf); - *ht = newht; -} - -void init_hash_table(HashTable *ht, int64_t elemsz, int64_t cap) { - if (cap < 16) cap = 16; - ht->buf = malloc(cap * elemsz); - ht->flagbuf = malloc(cap); - memset(ht->buf, 0, cap * elemsz); - memset(ht->flagbuf, 0, cap); - ht->size = 0; - ht->cap = cap; - ht->taken = 0; - ht->elemsz = elemsz; -} - -bool hash_table_insert(HashTable *ht, void *elem, uint64_t (*hash)(void*), bool (*eq)(void*, void*)) { - if (ht->taken + 1 > ht->cap / 2) { - rebuild(ht, hash, eq); - } - ht->taken++; - ht->size++; - int64_t pos = hash(elem) % ht->cap; - while (ht->flagbuf[pos] != HTFL_NUL) { - if (ht->flagbuf[pos] == HTFL_VAL - && eq(ht->buf + pos * ht->elemsz, elem)) { - return false; - } - pos++; - if (pos >= ht->cap) { // arrived end, restart from beginning - pos = 0; - } - } - memcpy(ht->buf + pos * ht->elemsz, elem, ht->elemsz); - ht->flagbuf[pos] = HTFL_VAL; - return true; -} - -void hash_table_remove(HashTable *ht, void * ptr) { - ht->size--; - int64_t pos = (ptr - ht->buf) / ht->elemsz; - ht->flagbuf[pos] = HTFL_DEL; -} - -void *hash_table_ref(HashTable *ht, int64_t pos) { - return ht->buf + pos * ht->elemsz; -} - -void *hash_table_find(HashTable *ht, void *elem, uint64_t (*hash)(void*), bool (*eq)(void*, void*)) { - int64_t pos = hash(elem) % ht->cap; - while (ht->flagbuf[pos] != HTFL_NUL) { - if (ht->flagbuf[pos] == HTFL_VAL - && eq(hash_table_ref(ht, pos), elem)) { - return hash_table_ref(ht, pos); - } - pos++; - if (pos >= ht->cap) { // arrived end, restart from beginning - pos = 0; - } - } - return NULL; -} - -void* hash_table_begin(HashTable *ht) { - if (ht->size <= 0) return NULL; - for (int64_t i = 0; i < ht->cap; i++) { - if (ht->flagbuf[i] == HTFL_VAL) { - return hash_table_ref(ht, i); - } - } - return NULL; -} - -void *hash_table_next(HashTable *ht, void *iter) { - int64_t pos = (iter - ht->buf) / ht->elemsz; - do { - pos++; - if (pos >= ht->cap) { - return NULL; - } - } while (ht->flagbuf[pos] != HTFL_VAL); - return hash_table_ref(ht, pos); -} - -void destroy_hash_table(HashTable *ht) { - free(ht->buf); - free(ht->flagbuf); -} |
