#include #include #include #include #include #include "hash.h" static uint64_t hashtable_hash(const char *key) { #define FNV_OFFSET 14695981039346656037UL #define FNV_PRIME 1099511628211UL uint64_t hash = FNV_OFFSET; for (const char *p = key; *p; p++) { hash ^= (uint64_t)(unsigned char)(*p); hash *= FNV_PRIME; } return hash; } void hashtable_init (HashTable *t, size_t capacity) { memset(t, 0, sizeof(*t)); t->capacity = capacity; t->buckets = malloc(t->capacity * sizeof(*t->buckets)); for (int i = 0; i < t->capacity; i++) { t->buckets[i] = NULL; } } void hashtable_deinit (HashTable *t) { for (int i = 0; i < t->capacity; i++) { if (t->buckets[i] != NULL) { if (t->buckets[i]->key != NULL) { free((void *)t->buckets[i]->key); } free(t->buckets[i]); } } free(t->buckets); } HashEntry * hashtable_new (const char *key, void *value, size_t sz) { HashEntry *e = malloc(sizeof(*e)); e->key = malloc(strlen(key)+1); e->value = malloc(sz); e->sz = sz; strcpy((char*)e->key, key); memcpy(e->value, value, e->sz); return e; } void * hashtable_get (HashTable *t, const char *key) { uint64_t hash = hashtable_hash(key); size_t index = (size_t)(hash % t->capacity); for (int i = index; i < t->capacity; i++) { if (t->buckets[i] != NULL && t->buckets[i]->key != NULL && strcmp(t->buckets[i]->key, key) == 0) { return t->buckets[i]->value; } } return NULL; } bool hashtable_check (HashTable *t, const char *key) { return hashtable_get(t, key) != NULL; } void hashtable_set (HashTable *t, const char *key, void *value, size_t sz) { uint64_t hash = hashtable_hash(key); size_t index = (size_t)(hash % t->capacity); for (int i = index; i < t->capacity; i++) { if (t->buckets[i] == NULL) { HashEntry *e = hashtable_new(key, value, sz); t->buckets[i] = e; break; } else if (t->buckets[i] != NULL && t->buckets[i]->key != NULL && strcmp(t->buckets[i]->key, key) == 0) { t->buckets[i]->sz = sz; t->buckets[i]->value = value; break; } } } bool hashtable_delete (HashTable *t, const char *key) { uint64_t hash = hashtable_hash(key); size_t index = (size_t)(hash % t->capacity); for (int i = index; i < t->capacity; i++) { if (t->buckets[i] != NULL && t->buckets[i]->key != NULL && strcmp(t->buckets[i]->key, key) == 0) { HashEntry *e = t->buckets[i]; free((void*)e->key); free((void*)e->value); free((void*)e); t->buckets[i] = NULL; return true; } } return false; }