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