#include "ht.h" #include #include unsigned int ht_default_hash_func(void* data){ const unsigned int fnv_prime = 16777619; const unsigned int fnv_offset_basis = 2166136261; unsigned int hash; char* string; hash = fnv_offset_basis; string = data; while (*string) { hash = hash * fnv_prime; hash = hash ^ (*(string++)); } return hash; } int ht_default_cmp_func(void* a, void* b){ return strcmp(a, b) == 0; } void* ht_default_copy_func(void* from) { void* copy = malloc(sizeof(char) * (strlen(from) + 1)); if(copy) { strcpy(copy, from); } return copy; } void ht_default_free_func(void* data){ free(data); } void ht_init(ht* ht){ ht->cmp_func = ht_default_cmp_func; ht->copy_func = ht_default_copy_func; ht->free_func = ht_default_free_func; ht->hash_func = ht_default_hash_func; memset(ht->data, 0, sizeof(ht->data)); } void ht_free(ht* ht){ int index = 0; for(; index < LIBDS_HT_SIZE; index++){ ht_node* head = ht->data[index]; while(head){ ht_node* to_delete = head; head = head->next; ht->free_func(to_delete->key); free(to_delete); } } } libds_result ht_put(ht* ht, void* key, void* data){ libds_result result = SUCCESS; ht_node* new_node = NULL; unsigned int key_int = ht->hash_func(key) % LIBDS_HT_SIZE; new_node = malloc(sizeof(*new_node)); if(new_node) { new_node->data = data; new_node->key = ht->copy_func(key); if(new_node->key == NULL){ result = MALLOC; } } else { result = MALLOC; } if(result != SUCCESS) { if(new_node) { free(new_node); new_node = NULL; } } else { new_node->next = ht->data[key_int]; ht->data[key_int] = new_node; } return result; } void* ht_get(ht* ht, void* key) { void* data = NULL; ht_node* search_node; unsigned int key_int = ht->hash_func(key) % LIBDS_HT_SIZE; search_node = ht->data[key_int]; while(search_node && data == NULL){ if(ht->cmp_func(search_node->key, key)) { data = search_node->data; } search_node = search_node->next; } return data; } void ht_remove(ht* ht, void* key){ ht_node** search_ptr; unsigned int key_int = ht->hash_func(key) % LIBDS_HT_SIZE; search_ptr = &ht->data[key_int]; while(*search_ptr){ if(ht->cmp_func((*search_ptr)->key, key)){ ht_node* to_delete = *search_ptr; *search_ptr = (*search_ptr)->next; ht->free_func(to_delete->key); free(to_delete); } else { search_ptr = &(*search_ptr)->next; } } } int ht_foreach(ht* ht, void* data, compare_func compare, foreach_func foreach, ...){ int index = 0; int return_code = 0; va_list args; for(; index < LIBDS_HT_SIZE && return_code == 0; index++){ ht_node* search_node = ht->data[index]; while(search_node && return_code == 0){ if(compare(data, search_node->data)) { va_start(args, foreach); return_code = foreach(search_node->data, args); va_end(args); } search_node = search_node->next; } } return return_code; }