]> begriffs open source - libderp/blob - test/t_hashmap.c
Allow allocator customization at runtime
[libderp] / test / t_hashmap.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "derp/common.h"
6 #include "derp/hashmap.h"
7
8 #ifdef HAVE_BOEHM_GC
9 #include <gc/leak_detector.h>
10 #endif
11
12 int ivals[] = {0,1,2,3,4,5,6,7,8,9};
13
14 unsigned long djb2hash(const void *x)
15 {
16         const char *str = x;
17         unsigned long hash = 5381;
18         int c;
19
20         if (str)
21                 while ( (c = *str++) )
22                         hash = hash * 33 + c;
23         return hash;
24 }
25
26 int main(void)
27 {
28 #ifdef HAVE_BOEHM_GC
29         GC_set_find_leak(1);
30         derp_use_alloc_funcs(GC_malloc, GC_realloc, GC_free);
31 #endif
32
33         hashmap *h = hm_new(0, djb2hash, derp_strcmp, NULL);
34         hm_iter *i;
35         assert(hm_length(h) == 0);
36         assert(hm_is_empty(h));
37         i = hm_iter_begin(h);
38         assert(!hm_iter_next(i));
39         hm_iter_free(i);
40
41         assert(!hm_at(h, "zero"));
42         hm_insert(h, "zero", ivals);
43         assert(hm_length(h) == 1);
44         assert(*(int*)hm_at(h, "zero") == 0);
45
46         /* change it */
47         hm_insert(h, "zero", ivals+1);
48         assert(hm_length(h) == 1);
49         assert(*(int*)hm_at(h, "zero") == 1);
50         /* set it back */
51         hm_insert(h, "zero", ivals);
52         assert(*(int*)hm_at(h, "zero") == 0);
53
54         hm_insert(h, "one", ivals+1);
55         assert(hm_length(h) == 2);
56         assert(*(int*)hm_at(h, "zero") == 0);
57         assert(*(int*)hm_at(h, "one") == 1);
58         assert(!hm_at(h, "flurgle"));
59
60         struct map_pair *p;
61         int n_keys = 0;
62         for (i = hm_iter_begin(h); (p = hm_iter_next(i)); n_keys++)
63                 assert(strcmp((char*)p->k, "zero") == 0 ||
64                        strcmp((char*)p->k, "one") == 0);
65         hm_iter_free(i);
66         assert(n_keys == 2);
67
68         hm_remove(h, "one");
69         assert(!hm_at(h, "one"));
70
71         hm_clear(h);
72         assert(hm_length(h) == 0);
73         assert(!hm_at(h, "zero"));
74
75         /* test for memory leak */
76         hm_dtor(h, derp_free, derp_free, NULL);
77         char *key = malloc(5);
78         int  *val1 = malloc(sizeof *val1),
79              *val2 = malloc(sizeof *val2);
80         strcpy(key, "life");
81         *val1 = 42;
82         *val2 = 13;
83         hm_insert(h, key, val1);
84         hm_insert(h, key, val2);
85
86         hm_free(h);
87
88         /* test iterator when hashmap has only one bucket */
89         hashmap *h1 = hm_new(1, djb2hash, derp_strcmp, NULL);
90         assert(hm_is_empty(h1));
91         hm_insert(h1, "zero", ivals);
92         hm_insert(h1, "one", ivals+1);
93         assert(hm_length(h1) == 2);
94         for (n_keys = 0, i = hm_iter_begin(h1); (p = hm_iter_next(i)); n_keys++)
95                 ;
96         assert(n_keys == 2);
97         hm_iter_free(i);
98         hm_free(h1);
99
100 #ifdef HAVE_BOEHM_GC
101         CHECK_LEAKS();
102 #endif
103         return 0;
104 }