1 #include "hashmap.h" 2 #include <string.h> 3 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 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 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 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 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 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