92 lines
2.0 KiB
C
92 lines
2.0 KiB
C
#include <hashmap.h>
|
|
#include <string.h>
|
|
|
|
struct hashmap new_map() {
|
|
struct hashmap new;
|
|
|
|
for(int count = 0; count < BUCKET_SIZE; ++count) {
|
|
new.buckets[count] = new_ll();
|
|
}
|
|
|
|
return new;
|
|
}
|
|
|
|
static unsigned int hash_map(const char *str) {
|
|
unsigned int val = 0, high;
|
|
|
|
while (*str) {
|
|
val = ( val << 4 ) + *str++;
|
|
|
|
if((high = val & 0xF0000000) != 0) {
|
|
val ^= high >> 24;
|
|
}
|
|
|
|
val &= ~high;
|
|
}
|
|
|
|
return val % BUCKET_SIZE;
|
|
}
|
|
|
|
void insert_map(struct hashmap *map, const char *key, const void *value) {
|
|
if(key == NULL) {
|
|
return;
|
|
}
|
|
|
|
int index = hash_map(key);
|
|
|
|
for(struct node *iter = map->buckets[index].head; iter != NULL; iter = iter->next) {
|
|
if(strcmp(iter->key, key) == 0) {
|
|
iter->value = value;
|
|
return;
|
|
}
|
|
}
|
|
|
|
insert_ll(&map->buckets[index], key, value);
|
|
}
|
|
|
|
const void *lookup_map(struct hashmap *map, const char *key) {
|
|
if(key == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
int index = hash_map(key);
|
|
|
|
for(struct node *iter = map->buckets[index].head; iter != NULL; iter = iter->next) {
|
|
if(strcmp(iter->key, key) == 0) {
|
|
return iter->value;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int exists_map(struct hashmap *map, const char *key) {
|
|
return lookup_map(map, key) != NULL;
|
|
}
|
|
|
|
const void *remove_map(struct hashmap *map, const char *key) {
|
|
if(key == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
int index = hash_map(key);
|
|
|
|
for(struct node *iter = map->buckets[index].head; iter != NULL; iter = iter->next) {
|
|
if(strcmp(iter->key, key) == 0) {
|
|
const void *value = iter->value;
|
|
remove_ll(&map->buckets[index], iter);
|
|
return value;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void foreach_map(struct hashmap *map, void (*cb)(const char *key, const void *value)) {
|
|
for(int count = 0; count < BUCKET_SIZE; ++count) {
|
|
for(struct node *iter = map->buckets[count].head; iter != NULL; iter = iter->next) {
|
|
cb(iter->key, iter->value);
|
|
}
|
|
}
|
|
}
|