7 #define DEFAULT_CAPACITY 64
20 void (*key_dtor)(void *);
21 void (*val_dtor)(void *);
22 uint_fast32_t (*hash)(const void *);
23 int (*cmp)(const void *, const void *);
27 hm_new(size_t capacity,
28 uint_fast32_t (*hash)(const void *),
29 int (*cmp)(const void *, const void *),
30 void (*key_dtor)(void *),
31 void (*val_dtor)(void *))
36 capacity = DEFAULT_CAPACITY;
37 hashmap *h = malloc(sizeof *h);
42 .buckets = malloc(capacity * sizeof *h->buckets),
52 for (i = 0; i < capacity; i++)
53 h->buckets[i] = NULL; /* in case allocation fails part-way */
54 for (i = 0; i < capacity; i++)
55 if (!(h->buckets[i] = l_new(NULL))) /* XXX: proper dtor */
71 for (size_t i = 0; i < h->capacity; i++)
72 l_free(h->buckets[i]);
79 hm_length(const hashmap *h)
84 for (n = i = 0; i < h->capacity; i++)
85 n += l_length(h->buckets[i]);
90 hm_is_empty(const hashmap *h)
92 return hm_length(h) == 0;
96 hm_at(const hashmap *h, const void *key)
100 list *bucket = h->buckets[h->hash(key) % h->capacity];
101 list_item *li = l_find(bucket, key, h->cmp);
104 return ((struct pair*)li->data)->v;
108 hm_insert(hashmap *h, void *key, void *val)
112 list *bucket = h->buckets[h->hash(key) % h->capacity];
113 list_item *li = l_find(bucket, key, h->cmp);
116 struct pair *p = (struct pair*)li->data;
117 if (p->v != val && h->val_dtor)
124 struct pair *p = malloc(sizeof *p);
127 *p = (struct pair){.k = key, .v = val};
134 hm_remove(hashmap *h, void *key)
138 list *bucket = h->buckets[h->hash(key) % h->capacity];
139 list_item *li = l_find(bucket, key, h->cmp);
142 l_remove(bucket, li);
143 /* XXX: free li and pair */
152 for (size_t i = 0; i < h->capacity; i++)
153 l_clear(h->buckets[i]);