strmap: new module for ordered map of strings using a critbit tree.
[ccan] / ccan / strmap / test / run-order.c
1 #include <ccan/strmap/strmap.h>
2 #include <ccan/strmap/strmap.c>
3 #include <ccan/tap/tap.h>
4 #include <stdio.h>
5
6 #define NUM 1000
7
8 static bool in_order(const char *member, char *value, unsigned int *count)
9 {
10         int i = atoi(member);
11         ok1(i == atoi(value));
12         ok1(*count == i);
13         (*count)++;
14         return false;
15 }
16
17 static bool in_order_by_2(const char *member, char *value, unsigned int *count)
18 {
19         int i = atoi(member);
20         ok1(i == atoi(value));
21         ok1(*count == i);
22         (*count) += 2;
23         return false;
24 }
25
26 static bool dump(const char *member, char *value, bool *ok)
27 {
28         diag("%s=>%s", member, value);
29         if (value != member + 1)
30                 *ok = false;
31         return false;
32 }
33
34 int main(void)
35 {
36         struct strmap_charp {
37                 STRMAP_MEMBERS(char *);
38         } map;
39         unsigned int i;
40         char *str[NUM];
41         bool dump_ok;
42
43         plan_tests(1 + NUM * 4 + 3 * NUM);
44         strmap_init(&map);
45
46         for (i = 0; i < NUM; i++) {
47                 char template[10];
48                 sprintf(template, "%08u", i);
49                 str[i] = strdup(template);
50         }
51
52         for (i = 0; i < NUM; i++)
53                 strmap_add(&map, str[i], str[i]+1);
54
55         dump_ok = true;
56         strmap_iterate(&map, dump, &dump_ok);
57         ok1(dump_ok);
58
59         /* Iterate. */
60         i = 0;
61         strmap_iterate(&map, in_order, &i);
62
63         /* Preserve order after deletion. */
64         for (i = 0; i < NUM; i += 2) {
65                 char *v;
66                 ok1(strmap_del(&map, str[i], &v) == str[i]);
67                 ok1(v == str[i] + 1);
68         }
69
70         i = 1;
71         strmap_iterate(&map, in_order_by_2, &i);
72
73         for (i = 1; i < NUM; i += 2) {
74                 char *v;
75                 ok1(strmap_del(&map, str[i], &v) == str[i]);
76                 ok1(v == str[i] + 1);
77         }
78
79         /* empty traverse. */
80         strmap_iterate(&map, in_order_by_2, (unsigned int *)NULL);
81
82         /* insert backwards, should be fine. */
83         for (i = 0; i < NUM; i++)
84                 strmap_add(&map, str[NUM-1-i], str[NUM-1-i]+1);
85
86         i = 0;
87         strmap_iterate(&map, in_order, &i);
88
89         strmap_clear(&map);
90
91         for (i = 0; i < NUM; i++)
92                 free(str[i]);
93
94         /* This exits depending on whether all tests passed */
95         return exit_status();
96 }