1 /* Tests for hash table routines */
4 #include "lib/mempool.h"
16 #define HASH_NODE struct node1
17 #define HASH_PREFIX(x) test1_##x
18 #define HASH_KEY_ATOMIC key
19 #define HASH_ATOMIC_TYPE int
20 #define HASH_ZERO_FILL
22 #define HASH_GIVE_INIT_DATA
23 static inline void test1_init_data(struct node1 *n)
25 n->data = n->key + 123;
28 #define HASH_WANT_FIND
29 #define HASH_WANT_LOOKUP
30 #define HASH_WANT_REMOVE
32 #include "lib/hashtable.h"
34 static void test1(void)
39 for (i=0; i<1024; i++)
41 struct node1 *n = test1_lookup(i);
42 ASSERT(n->data == i+123);
44 for (i=1; i<1024; i+=2)
46 struct node1 *n = test1_lookup(i);
49 for (i=0; i<1024; i++)
51 struct node1 *n = test1_find(i);
52 if (!n != (i&1) || (n && n->data != i+123))
53 die("Inconsistency at i=%d", i);
56 HASH_FOR_ALL(test1, n)
65 /* TEST 2: external strings */
72 #define HASH_NODE struct node2
73 #define HASH_PREFIX(x) test2_##x
74 #define HASH_KEY_STRING key
76 #define HASH_AUTO_POOL 4096
78 #define HASH_WANT_FIND
81 #include "lib/hashtable.h"
83 static void test2(void)
88 for (i=0; i<1024; i+=2)
91 sprintf(x, "abc%d", i);
92 test2_new(xstrdup(x));
94 for (i=0; i<1024; i++)
98 sprintf(x, "ABC%d", i);
101 die("Inconsistency at i=%d", i);
106 /* TEST 3: internal strings + pools */
108 static struct mempool *pool3;
115 #define HASH_NODE struct node3
116 #define HASH_PREFIX(x) test3_##x
117 #define HASH_KEY_ENDSTRING key
119 #define HASH_WANT_FIND
120 #define HASH_WANT_NEW
122 #define HASH_USE_POOL pool3
124 #include "lib/hashtable.h"
126 static void test3(void)
130 pool3 = mp_new(16384);
132 for (i=0; i<1048576; i+=2)
135 sprintf(x, "abc%d", i);
138 for (i=0; i<1048576; i++)
142 sprintf(x, "abc%d", i);
145 die("Inconsistency at i=%d", i);
150 /* TEST 4: complex keys */
152 #include "lib/hashfunc.h"
160 #define HASH_NODE struct node4
161 #define HASH_PREFIX(x) test4_##x
162 #define HASH_KEY_COMPLEX(x) x host, x port
163 #define HASH_KEY_DECL char *host, int port
165 #define HASH_WANT_CLEANUP
166 #define HASH_WANT_FIND
167 #define HASH_WANT_NEW
168 #define HASH_WANT_LOOKUP
169 #define HASH_WANT_DELETE
170 #define HASH_WANT_REMOVE
172 #define HASH_GIVE_HASHFN
173 static uns test4_hash(char *host, int port)
175 return hash_string_nocase(host) ^ hash_u32(port);
179 static inline int test4_eq(char *host1, int port1, char *host2, int port2)
181 return !strcasecmp(host1,host2) && port1 == port2;
184 #define HASH_GIVE_EXTRA_SIZE
185 static inline uns test4_extra_size(char *host, int port UNUSED)
190 #define HASH_GIVE_INIT_KEY
191 static inline void test4_init_key(struct node4 *n, char *host, int port)
193 strcpy(n->host, host);
197 #include "lib/hashtable.h"
199 static void test4(void)
206 for (i=0; i<1024; i++)
209 sprintf(x, "abc%d", i);
210 n = test4_new(x, i%10);
213 for (i=0; i<1024; i++)
215 sprintf(x, "abc%d", i);
216 n = test4_lookup(x, i%10);
219 for (i=0; i<1024; i++)
222 sprintf(x, "aBc%d", i);
225 n = test4_find(x, i%10);
230 test4_delete(x, i%10);
232 for (i=0; i<1024; i++)
234 sprintf(x, "ABC%d", i);
235 n = test4_find(x, i%10);
236 if (!n != (i&1) || (n && n->data != i))
237 die("Inconsistency at i=%d", i);
243 /* TEST 5: integers again, but this time dynamically */
250 #define HASH_NODE struct node5
251 #define HASH_PREFIX(x) test5_##x
252 #define HASH_KEY_ATOMIC key
253 #define HASH_ATOMIC_TYPE int
254 #define HASH_TABLE_DYNAMIC
258 #define HASH_GIVE_INIT_DATA
259 static inline void test5_init_data(struct test5_table *table UNUSED, struct node5 *n)
261 n->data = n->key + 123;
264 #define HASH_WANT_FIND
265 #define HASH_WANT_NEW
266 #define HASH_WANT_DELETE
268 #include "lib/hashtable.h"
270 static void test5(void)
273 struct test5_table tab;
276 for (i=0; i<1024; i++)
278 struct node5 *n = test5_new(&tab, i);
279 ASSERT(n->data == i+123);
281 for (i=1; i<1024; i+=2)
282 test5_delete(&tab, i);
283 for (i=0; i<1024; i++)
285 struct node5 *n = test5_find(&tab, i);
286 if (!n != (i&1) || (n && n->data != i+123))
287 die("Inconsistency at i=%d", i);
290 HASH_FOR_ALL_DYNAMIC(test5, &tab, n)
298 main(int argc, char **argv)
304 for (int i=1; i<argc; i++)
305 m |= 1 << atol(argv[i]);