#include #include #include #include "hashtable.h" typedef struct _Set { uint64_t key; void* data; } Set; typedef struct _Hashtable { uint32_t size; HashFunc hash; EqualFunc compare; Set** sets; } Hashtable; static uint32_t hash_table_index(Hashtable* ht, const void* key) { return (ht->hash(key) % ht->size); } Hashtable* hash_table_create(HashFunc hf, EqualFunc ef) { return hash_table_create_full(hf, ef, TABLESIZE); } Hashtable* hash_table_create_full(HashFunc hf, EqualFunc ef, uint32_t size) { Hashtable* ht = malloc(sizeof(*ht)); ht->size = size; ht->hash = hf; ht->compare = ef; ht->sets = calloc(sizeof(Set*), ht->size); return ht; } void hash_table_destroy(Hashtable* ht) { for (uint32_t i = 0; i < ht->size; i++) { if (ht->sets[i] != NULL) { Set* tmp = ht->sets[i]; if (tmp != NULL) { Set* set = tmp; free(set->data); free(set); } ht->sets[i] = NULL; } } hash_table_print(ht); free(ht->sets); free(ht); } void hash_table_print(Hashtable* ht) { printf("Start Table\n"); for (uint32_t i = 0; i < ht->size; i++) { if (ht->sets[i] == NULL) { //printf("\t%i\t---\n", i); } else { printf("\t%i\t\n", i); Set* tmp = ht->sets[i]; if (tmp != NULL) { printf("\"%ju\" - (%p)", tmp->key, tmp->data); } printf("\n"); } } printf("End Table\n"); } bool hash_table_insert(Hashtable* ht, const void* key, void* obj) { if (key == NULL || obj == NULL || ht == NULL) return false; // implement chaning void* found = hash_table_lookup(ht, key); if (found != NULL) { printf("[%s:%s] - %s: Missing chaining\n", (const char*) found, (const char*) key, (const char*) obj); return false; } uint32_t index = hash_table_index(ht, key); Set* set = malloc(sizeof(*set)); set->data = obj; set->key = index; ht->sets[index] = set; return true; } void* hash_table_lookup(Hashtable* ht, const void* key) { if (key == NULL || ht == NULL) return false; uint64_t index = hash_table_index(ht, key); Set* set = ht->sets[index]; if (set == NULL) return NULL; //printf("find: %p -> found: %p\n", key, set->data); if (ht->compare(set->data, key)) return set->data; else return NULL; } void* hash_table_delete(Hashtable* ht, const void* key) { if (key == NULL || ht == NULL) return false; uint64_t index = hash_table_index(ht, key); Set* tmp = ht->sets[index]; if (tmp != NULL && ht->compare((void*)tmp->key, (void*)index) == false) return NULL; // just in case if (tmp == NULL) return NULL; void* result = tmp->data; free(tmp); return result; } uint64_t int_hash(const void* key) { return *(uint64_t*) key; } uint64_t str_hash(const void* key) { const signed char* p; uint64_t h = 5381; for (p = key; *p != '\0'; p++) { h = (h << 5) + h + *p; } return h; } uint64_t ptr_hash(const void* key) { return (uint64_t)key; } bool int_equal(const void* a, const void* b) { return *((const int*) a) == *((const int*) b); } bool str_equal(const void* a, const void* b) { const char *string1 = (const char*) a; const char *string2 = (const char*) b; return strcmp (string1, string2) == 0; } bool ptr_equal(const void* a, const void* b) { return a == b; }