htable: add allocator hooks.
[ccan] / ccan / htable / test / run-allocator.c
1 /* Include the C files directly. */
2 #include <ccan/htable/htable.h>
3 #include <ccan/htable/htable.c>
4 #include <ccan/tap/tap.h>
5 #include <stdbool.h>
6 #include <string.h>
7
8 struct htable_with_counters {
9         struct htable ht;
10         size_t num_alloc, num_free;
11 };
12
13 static void *test_alloc(struct htable *ht, size_t len)
14 {
15         ((struct htable_with_counters *)ht)->num_alloc++;
16         return calloc(len, 1);
17 }
18
19         
20 static void test_free(struct htable *ht, void *p)
21 {
22         if (p) {
23                 ((struct htable_with_counters *)ht)->num_free++;
24                 free(p);
25         }
26 }
27
28 static size_t hash(const void *elem, void *unused UNNEEDED)
29 {
30         return *(size_t *)elem;
31 }
32
33 int main(void)
34 {
35         struct htable_with_counters htc;
36         size_t val[] = { 0, 1 };
37
38         htc.num_alloc = htc.num_free = 0;
39         plan_tests(12);
40
41         htable_set_allocator(test_alloc, test_free);
42         htable_init(&htc.ht, hash, NULL);
43         htable_add(&htc.ht, hash(&val[0], NULL), &val[0]);
44         ok1(htc.num_alloc == 1);
45         ok1(htc.num_free == 0);
46         /* Adding another increments, then frees old */
47         htable_add(&htc.ht, hash(&val[1], NULL), &val[1]);
48         ok1(htc.num_alloc == 2);
49         ok1(htc.num_free == 1);
50         htable_clear(&htc.ht);
51         ok1(htc.num_alloc == 2);
52         ok1(htc.num_free == 2);
53
54         /* Should restore defaults */
55         htable_set_allocator(NULL, NULL);
56         ok1(htable_alloc == htable_default_alloc);
57         ok1(htable_free == htable_default_free);
58
59         htable_init(&htc.ht, hash, NULL);
60         htable_add(&htc.ht, hash(&val[0], NULL), &val[0]);
61         ok1(htc.num_alloc == 2);
62         ok1(htc.num_free == 2);
63         htable_add(&htc.ht, hash(&val[1], NULL), &val[1]);
64         ok1(htc.num_alloc == 2);
65         ok1(htc.num_free == 2);
66         htable_clear(&htc.ht);
67
68         /* This exits depending on whether all tests passed */
69         return exit_status();
70 }