1 #include "hashmap.h"
2 #include <string.h>
3
djb2_hash(const void * str)4 uint32_t djb2_hash(const void *str)
5 {
6 int c;
7 const char *s = str;
8 uint32_t hash = 5381;
9
10 while ((c = *s++))
11 hash = ((hash << 5) + hash) + c;
12 return hash;
13 }
14
hashmap_create(uint32_t (* hash_fct)(const void *),void (* free_fct)(void *),size_t size)15 struct hashmap *hashmap_create(uint32_t(*hash_fct)(const void*),
16 void(*free_fct)(void*), size_t size)
17 {
18 struct hashmap *h = calloc(sizeof(struct hashmap) +
19 sizeof(struct hashmap_entry) * size, 1);
20 h->size = size;
21 h->free = free_fct;
22 h->hash = hash_fct;
23 h->first = h->last = NULL;
24 return h;
25 }
26
hashmap_add(struct hashmap * h,void * data,const void * key)27 void hashmap_add(struct hashmap *h, void *data, const void *key)
28 {
29 uint32_t hash = h->hash(key) % h->size;
30 struct hashmap_entry *e = malloc(sizeof(*e));
31
32 e->data = data;
33 e->key = key;
34 e->next = h->entries[hash];
35 h->entries[hash] = e;
36
37 e->list_prev = NULL;
38 e->list_next = h->first;
39 if (h->first)
40 h->first->list_prev = e;
41 h->first = e;
42 if (!h->last)
43 h->last = e;
44 }
45
hashmap_lookup(struct hashmap * h,const void * key)46 void *hashmap_lookup(struct hashmap *h, const void *key)
47 {
48 struct hashmap_entry *iter;
49 uint32_t hash = h->hash(key) % h->size;
50
51 for (iter = h->entries[hash]; iter; iter = iter->next)
52 if (!strcmp(iter->key, key))
53 return iter->data;
54 return NULL;
55 }
56
hashmap_iter_in_order(struct hashmap * h,struct hashmap_entry ** it)57 void *hashmap_iter_in_order(struct hashmap *h, struct hashmap_entry **it)
58 {
59 *it = *it ? (*it)->list_next : h->first;
60 return *it ? (*it)->data : NULL;
61 }
62
hashmap_free(struct hashmap * h)63 void hashmap_free(struct hashmap *h)
64 {
65 for (size_t i = 0; i < h->size; ++i) {
66 struct hashmap_entry *it = h->entries[i];
67 while (it) {
68 struct hashmap_entry *tmp = it->next;
69 if (h->free)
70 h->free(it->data);
71 free(it);
72 it = tmp;
73 }
74 }
75 free(h);
76 }
77