From 3c946d0a54ef321f995d9112d5265d28dc262a3b Mon Sep 17 00:00:00 2001 From: Nathan Fisher Date: Sat, 12 Aug 2023 11:13:02 -0400 Subject: [PATCH] Add hashmap `deinit` and `get` functions --- hmap.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 8 deletions(-) diff --git a/hmap.c b/hmap.c index b4342f8..1dafb92 100644 --- a/hmap.c +++ b/hmap.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -70,7 +71,7 @@ typedef struct { hmap_node *buckets; } hmap; -hmap_node* hmap_insert(hmap * map, void *key, size_t keysize, void *data); +void* hmap_insert(hmap * map, void *key, void *data); hmap_node* hmap_node_init(void *key, size_t keysize, void *data) { hmap_node *node; @@ -85,11 +86,20 @@ hmap_node* hmap_node_init(void *key, size_t keysize, void *data) { return node; } -void* hmap_node_attach(hmap_node *root, hmap_node *leaf) { +void hmap_node_deinit(hmap_node *node) { + hmap_node *current = node; + while (current != NULL) { + current = node->next; + free(node); + node = current; + } +} + +void* hmap_node_attach(hmap_node *root, hmap_node *leaf, size_t keysize) { void *ret = NULL; while (1) { - if (root->key == leaf->key) { + if (memcmp(root->key, leaf->key, keysize) == 0) { ret = root->data; root->data = leaf->data; return ret; @@ -104,6 +114,21 @@ void* hmap_node_attach(hmap_node *root, hmap_node *leaf) { // todo } +void* hmap_node_search(hmap_node *root, void *key, size_t keysize) { + void *ret = NULL; + + while (1) { + if (memcmp(root->key, key, keysize) == 0) { + ret = root->data; + return ret; + } else if (root->next == NULL) { + return NULL; + } else { + root = root->next; + } + } +} + hmap* hmap_init(size_t keysize) { hmap* map; @@ -120,6 +145,18 @@ hmap* hmap_init(size_t keysize) { return map; } +void hmap_deinit(hmap *map) { + int i; + + for (i = 0; i < map->capacity; i++) { + if (map->buckets[i].next != NULL) { + hmap_node_deinit(map->buckets[i].next); + } + } + free(map->buckets); + free(map); +} + int hmap_expand(hmap *map) { hmap_node *old; hmap_node *new; @@ -133,7 +170,7 @@ int hmap_expand(hmap *map) { for (i = 0; i < map->capacity; i++) { current = &old[i]; while (current->key != NULL) { - hmap_insert(map, current->key, map->keysize, current->data); + hmap_insert(map, current->key, current->data); current = current->next; } } @@ -141,7 +178,7 @@ int hmap_expand(hmap *map) { return 0; } -hmap_node* hmap_insert(hmap * map, void *key, size_t keysize, void *data) { +void* hmap_insert(hmap *map, void *key, void *data) { hmap_node *node; size_t idx; hmap_node *ret = NULL; @@ -149,14 +186,28 @@ hmap_node* hmap_insert(hmap * map, void *key, size_t keysize, void *data) { if (map->len >= map->capacity / 2) { if (hmap_expand(map)) return NULL; } - node = hmap_node_init(key, keysize, data); + node = hmap_node_init(key, map->keysize, data); if (node == NULL) return NULL; idx = node->hash % map->capacity; if (map->buckets[idx].key == NULL) { map->buckets[idx] = *node; } else { - ret = hmap_node_attach(&map->buckets[idx], node); + ret = hmap_node_attach(&map->buckets[idx], node, map->keysize); } - // todo + map->len += 1; + if (ret == NULL) + return NULL; + else + return ret->data; +} + +void* hmap_get(hmap *map, void *key) { + uint64_t hash; + size_t idx; + void *ret; + + hash = hash_fnv1a_64(key, map->keysize); + idx = hash % map->capacity; + ret = hmap_node_search(&map->buckets[idx], key, map->keysize); return ret; }