Home | History | Annotate | Download | only in android
      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