diff options
Diffstat (limited to 'src/hash_map.c')
-rw-r--r-- | src/hash_map.c | 98 |
1 files changed, 57 insertions, 41 deletions
diff --git a/src/hash_map.c b/src/hash_map.c index b9c3b37..5f80205 100644 --- a/src/hash_map.c +++ b/src/hash_map.c @@ -1,8 +1,8 @@ +#include "hash_map.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> -#include "hash_map.h" #define INITIAL_SIZE (16) #define LOAD_FACTOR_THRESHOLD (0.75) @@ -21,26 +21,16 @@ typedef struct HashMap { static unsigned int hash(const char *key, size_t size) { unsigned int hash_value = 0; - while (*key)hash_value = (hash_value * 31) + *key++; + while (*key) hash_value = (hash_value * 31) + *key++; return hash_value % size; } -hashmap_t hashmap_create(void) { - HashMap *map = (HashMap *)malloc(sizeof(HashMap)); - assert(map); - map->size = INITIAL_SIZE; - map->count = 0; - map->table = (Pair **)calloc(map->size, sizeof(Pair *)); - assert(map->table); - return map; -} - -static void resize(hashmap_t map) { - size_t new_size = ((HashMap*)map)->size * 2; - Pair **new_table = (Pair **)calloc(new_size, sizeof(Pair *)); +static void resize(HashMap *map) { + size_t new_size = map->size * 2; + Pair **new_table = (Pair**)calloc(new_size, sizeof(Pair*)); assert(new_table); - for (size_t i = 0; i < ((HashMap*)map)->size; ++i) { - Pair *pair = ((HashMap*)map)->table[i]; + for (size_t i = 0; i < map->size; ++i) { + Pair *pair = map->table[i]; while (pair) { unsigned int index = hash(pair->key, new_size); Pair *next = pair->next; @@ -49,27 +39,43 @@ static void resize(hashmap_t map) { pair = next; } } - free(((HashMap*)map)->table); - ((HashMap*)map)->table = new_table; - ((HashMap*)map)->size = new_size; + + free(map->table); + map->table = new_table; + map->size = new_size; +} + +HashMap *hashmap_create(void) { + HashMap *map = (HashMap*)malloc(sizeof(HashMap)); + assert(map); + map->size = INITIAL_SIZE; + map->count = 0; + map->table = (Pair**)calloc(map->size, sizeof(Pair*)); + assert(map->table); + return map; } -void hashmap_insert(hashmap_t map, const char *key, int value) { - if ((float)((HashMap*)map)->count / ((HashMap*)map)->size > LOAD_FACTOR_THRESHOLD) resize(((HashMap*)map)); - unsigned int index = hash(key, ((HashMap*)map)->size); - Pair *new_pair = (Pair *)malloc(sizeof(Pair)); +void hashmap_insert(HashMap *map, const char *key, int value) { + int *old_value = hashmap_get(map, key); + if (old_value) { + *old_value = value; + return; + } + if ((float)map->count / map->size > LOAD_FACTOR_THRESHOLD) resize(map); + unsigned int index = hash(key, map->size); + Pair *new_pair = (Pair*)malloc(sizeof(Pair)); assert(new_pair); new_pair->key = strdup(key); assert(new_pair->key); new_pair->value = value; - new_pair->next = ((HashMap*)map)->table[index]; - ((HashMap*)map)->table[index] = new_pair; - ((HashMap*)map)->count++; + new_pair->next = map->table[index]; + map->table[index] = new_pair; + map->count++; } -int *hashmap_get(hashmap_t map, const char *key) { - unsigned int index = hash(key, ((HashMap*)map)->size); - Pair *pair = ((HashMap*)map)->table[index]; +int *hashmap_get(HashMap *map, const char *key) { + unsigned int index = hash(key, map->size); + Pair *pair = map->table[index]; while (pair) { if (strcmp(pair->key, key) == 0) return &pair->value; pair = pair->next; @@ -77,17 +83,17 @@ int *hashmap_get(hashmap_t map, const char *key) { return NULL; } -void hashmap_delete(hashmap_t map, const char *key) { - unsigned int index = hash(key, ((HashMap*)map)->size); - Pair *pair = ((HashMap*)map)->table[index]; +void hashmap_delete(HashMap *map, const char *key) { + unsigned int index = hash(key, map->size); + Pair *pair = map->table[index]; Pair *prev = NULL; while (pair) { if (strcmp(pair->key, key) == 0) { if (prev) prev->next = pair->next; - else ((HashMap*)map)->table[index] = pair->next; + else map->table[index] = pair->next; free(pair->key); free(pair); - ((HashMap*)map)->count--; + map->count--; return; } prev = pair; @@ -95,16 +101,26 @@ void hashmap_delete(hashmap_t map, const char *key) { } } -void hashmap_free(hashmap_t map) { - for (size_t i = 0; i < ((HashMap*)map)->size; ++i) { - Pair *pair = ((HashMap*)map)->table[i]; - while (pair){ +void hashmap_free(HashMap *map) { + for (size_t i = 0; i < map->size; ++i) { + Pair *pair = map->table[i]; + while (pair) { Pair *temp = pair; pair = pair->next; free(temp->key); free(temp); } } - free(((HashMap*)map)->table); - free(((HashMap*)map)); + free(map->table); + free(map); +} + +void hashmap_iterate(HashMap *map, void (*callback)(const char *key, int value)) { + for (size_t i = 0; i < map->size; ++i) { + Pair *pair = map->table[i]; + while (pair) { + callback(pair->key, pair->value); + pair = pair->next; + } + } }
\ No newline at end of file |