aboutsummaryrefslogtreecommitdiff
path: root/src/hash_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hash_map.c')
-rw-r--r--src/hash_map.c98
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