/** * hashtable.c - A basic hashtable implementation * */ #include #include #include "llist.h" #include "hashtable.h" #define SIZE 128 typedef struct { void* key; void* data; } HTEntry; /** * Simple hash function used */ int hash(char* key, int ht_size) { int h = 0; // basic modulo hash for (size_t i = 0; i < strlen(key); i++) { h = (31 * h + key[i]) % ht_size; } return h; } /** * Compare function for searching a bucket */ int compare(void* data, void* arg) { char* key = arg; HTEntry* entry = data; return strcmp(entry->key, key); } /** * Delete HT entry from bucket */ int delete_entry(void* data, void* arg) { (void) arg; HTEntry* entry = data; free(entry); return 0; } /** * Create a new hashtable */ HT* ht_create(void) { HT* ht = malloc(sizeof(HT)); ht->size = SIZE; ht->entries = 0; ht->store = malloc(ht->size * sizeof(LL*)); for (int i = 0; i < ht->size; i++) { ht->store[i] = ll_create(); } return ht; } /** * Add a new key value pair to a hashtable */ int ht_put(HT* ht, char* key, void* data) { int addr = hash(key, ht->size); LL* bucket = ht->store[addr]; HTEntry* entry = malloc(sizeof(HTEntry)); entry->key = strdup(key); entry->data = data; ll_push(bucket, entry); ht->entries++; return 0; } /** * Get a value from a hashtable with a key */ void* ht_get(HT* ht, char* key) { int addr = hash(key, ht->size); LL* bucket = ht->store[addr]; HTEntry* entry = ll_search(bucket, compare, (void*) key); if (entry == NULL) { return NULL; } return entry->data; } /** * Delete a key value pair from a hashtable */ void* ht_delete(HT* ht, char* key) { int addr = hash(key, ht->size); LL* bucket = ht->store[addr]; HTEntry* entry = ll_delete(bucket, compare, key); if (entry == NULL) { return NULL; } ht->entries--; return entry->data; } /** * Destroy/free an entire hashtable */ int ht_free(HT* ht) { for (int i = 0; i < ht->size; i++) { LL* bucket = ht->store[i]; ll_loop(bucket, delete_entry, NULL); ll_free(bucket); } free(ht); return 0; }