From 70022ae1f64fe026811847d4c69a91f22ccc8b04 Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Fri, 20 May 2016 00:02:49 +0200 Subject: [PATCH] Added basic implementation of hash table. --- src/hashtable-simple.c | 144 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 src/hashtable-simple.c diff --git a/src/hashtable-simple.c b/src/hashtable-simple.c new file mode 100644 index 0000000..7c72149 --- /dev/null +++ b/src/hashtable-simple.c @@ -0,0 +1,144 @@ +#include +#include +#include + +typedef struct hashcell_t { + char key[128]; + void * value; + struct hashcell_t* next; +} HASHCELL; + +typedef struct { + int capacity; + int size; + HASHCELL** data; +} HASHTABLE; + +int hash_of_key(HASHTABLE* hashtable, char * key) { + return 0; +} + +HASHTABLE* hashtable_create(int capacity) { + HASHTABLE * hashtable; + printf("hashtable_create -- %d\n", capacity); + + hashtable = malloc(sizeof(HASHTABLE)); + if (!hashtable) return NULL; + memset(hashtable, 0, sizeof(HASHTABLE)); + + hashtable->data = malloc(capacity * sizeof(HASHCELL*)); + if (!hashtable->data) return NULL; + memset(hashtable->data, 0, capacity * sizeof(HASHCELL*)); + + hashtable->capacity = capacity; + hashtable->size = 0; + + printf("hashtable_create -- done\n"); + return hashtable; +} + +void hashtable_destroy(HASHTABLE* hashtable) { + printf("hashtable_destroy(%p) -- \n", (void*)hashtable); + if (!hashtable) return; + if (!hashtable->data) return; + free(hashtable->data); + free(hashtable); + printf("hashtable_destroy(%p) -- done\n", (void*)hashtable); +} + +void hashtable_rehash(HASHTABLE* hashtable) { + return; +} + +int hashtable_set(HASHTABLE* hashtable, char* key, void * value) { + int idx; + HASHCELL* cell; + + printf("hashtable_set(%s, %p) -- \n", key, (void*)value); + // get position in hashtable + idx = hash_of_key(hashtable, key); + hashtable->size += 1; + + printf("hashtable_set -- search value [%d/%d]\n", idx, hashtable->capacity); + // search value + cell = hashtable->data[idx]; + while(cell) { + if (strcmp(cell->key, key) == 0) { break; } + cell = cell->next; + } + + if (cell) { + // if cell exists, then change inner value + printf("hashtable_set -- update value\n"); + } else { + printf("hashtable_set -- create value\n"); + // create cell & prepend it to the chain + cell = malloc(sizeof(HASHCELL)); + if (!cell) return -1; + memset(cell, 0, sizeof(HASHCELL)); + + cell->next = hashtable->data[idx]; + cell->value = value; + strcpy(cell->key, key); + hashtable->data[idx] = cell; + printf("hashtable_set -- cell@%p{key=%s, value=%p, next=%p}\n", + (void*)cell, + cell->key, + (void*)cell->value, + (void*)cell->next); + } + printf("hashtable_set -- done\n"); + + return 0; +} + +void * hashtable_get(HASHTABLE* hashtable, char* key) { + int idx; + HASHCELL* cell; + printf("hashtable_get(%p, %p) -- \n", hashtable, key); + idx = hash_of_key(hashtable, key); + cell = hashtable->data[idx]; + while(cell) { + printf("hashtable_get(...) -- cell@%p{key=%s, value=%p, next=%p}\n", + (void*)cell, + cell->key, + cell->value, + cell->next); + if (strcmp(cell->key, key) == 0) { break; } + cell = cell->next; + } + if (cell) { + return cell->value; + } else { + printf("hashtable_get(...) -- cell not found\n"); + return NULL; + } +} + +int main(int argc, char** argv) { + HASHTABLE * hashtable; + int x=1, y=2, z=3; + int* value; + + printf("Run !\n"); + hashtable = hashtable_create(1000); + hashtable_destroy(hashtable); + + hashtable = hashtable_create(100); + hashtable_set(hashtable, "alice", &x); + printf("h['alice'] <- %d\n", x); + hashtable_set(hashtable, "bob", &y); + printf("h['bob'] <- %d\n", x); + hashtable_set(hashtable, "charlie", &z); + printf("h['charlie'] <- %d\n", x); + hashtable_set(hashtable, "alice", &y); + value = hashtable_get(hashtable, "alice"); + printf("h['alice'] ? %d\n", *value); + value = hashtable_get(hashtable, "bob"); + printf("h['bob'] ? %d\n", *value); + value = hashtable_get(hashtable, "charlie"); + printf("h['charlie'] ? %d\n", *value); + + return EXIT_SUCCESS; +} +