1 /* Tests for hash table routines */
4 #include "ucw/mempool.h"
10 /* TEST 1: integers */
17 #define HASH_NODE struct node1
18 #define HASH_PREFIX(x) test1_##x
19 #define HASH_KEY_ATOMIC key
20 #define HASH_ATOMIC_TYPE int
21 #define HASH_ZERO_FILL
23 #define HASH_GIVE_INIT_DATA
24 static inline void test1_init_data(struct node1 *n)
26 n->data = n->key + 123;
29 #define HASH_WANT_FIND
30 #define HASH_WANT_LOOKUP
31 #define HASH_WANT_REMOVE
33 #include "ucw/hashtable.h"
35 static void test1(void)
40 for (i=0; i<1024; i++)
42 struct node1 *n = test1_lookup(i);
43 ASSERT(n->data == i+123);
45 for (i=1; i<1024; i+=2)
47 struct node1 *n = test1_lookup(i);
50 for (i=0; i<1024; i++)
52 struct node1 *n = test1_find(i);
53 if (!n != (i&1) || (n && n->data != i+123))
54 die("Inconsistency at i=%d", i);
57 HASH_FOR_ALL(test1, n)
66 /* TEST 2: external strings */
73 #define HASH_NODE struct node2
74 #define HASH_PREFIX(x) test2_##x
75 #define HASH_KEY_STRING key
77 #define HASH_AUTO_POOL 4096
79 #define HASH_WANT_FIND
82 #include "ucw/hashtable.h"
84 static void test2(void)
89 for (i=0; i<1024; i+=2)
92 sprintf(x, "abc%d", i);
93 test2_new(xstrdup(x));
95 for (i=0; i<1024; i++)
99 sprintf(x, "ABC%d", i);
102 die("Inconsistency at i=%d", i);
107 /* TEST 3: internal strings + pools */
109 static struct mempool *pool3;
116 #define HASH_NODE struct node3
117 #define HASH_PREFIX(x) test3_##x
118 #define HASH_KEY_ENDSTRING key
120 #define HASH_WANT_FIND
121 #define HASH_WANT_NEW
123 #define HASH_USE_POOL pool3
125 #include "ucw/hashtable.h"
127 static void test3(void)
131 pool3 = mp_new(16384);
133 for (i=0; i<1048576; i+=2)
136 sprintf(x, "abc%d", i);
139 for (i=0; i<1048576; i++)
143 sprintf(x, "abc%d", i);
146 die("Inconsistency at i=%d", i);
151 /* TEST 4: complex keys */
153 #include "ucw/hashfunc.h"
161 #define HASH_NODE struct node4
162 #define HASH_PREFIX(x) test4_##x
163 #define HASH_KEY_COMPLEX(x) x host, x port
164 #define HASH_KEY_DECL char *host, int port
166 #define HASH_WANT_CLEANUP
167 #define HASH_WANT_FIND
168 #define HASH_WANT_NEW
169 #define HASH_WANT_LOOKUP
170 #define HASH_WANT_DELETE
171 #define HASH_WANT_REMOVE
173 #define HASH_GIVE_HASHFN
174 static uns test4_hash(char *host, int port)
176 return hash_string_nocase(host) ^ hash_u32(port);
180 static inline int test4_eq(char *host1, int port1, char *host2, int port2)
182 return !strcasecmp(host1,host2) && port1 == port2;
185 #define HASH_GIVE_EXTRA_SIZE
186 static inline uns test4_extra_size(char *host, int port UNUSED)
191 #define HASH_GIVE_INIT_KEY
192 static inline void test4_init_key(struct node4 *n, char *host, int port)
194 strcpy(n->host, host);
198 #include "ucw/hashtable.h"
200 static void test4(void)
207 for (i=0; i<1024; i++)
210 sprintf(x, "abc%d", i);
211 n = test4_new(x, i%10);
214 for (i=0; i<1024; i++)
216 sprintf(x, "abc%d", i);
217 n = test4_lookup(x, i%10);
220 for (i=0; i<1024; i++)
223 sprintf(x, "aBc%d", i);
226 n = test4_find(x, i%10);
231 test4_delete(x, i%10);
233 for (i=0; i<1024; i++)
235 sprintf(x, "ABC%d", i);
236 n = test4_find(x, i%10);
237 if (!n != (i&1) || (n && n->data != i))
238 die("Inconsistency at i=%d", i);
244 /* TEST 5: integers again, but this time dynamically */
251 #define HASH_NODE struct node5
252 #define HASH_PREFIX(x) test5_##x
253 #define HASH_KEY_ATOMIC key
254 #define HASH_ATOMIC_TYPE int
255 #define HASH_TABLE_DYNAMIC
259 #define HASH_GIVE_INIT_DATA
260 static inline void test5_init_data(struct test5_table *table UNUSED, struct node5 *n)
262 n->data = n->key + 123;
265 #define HASH_WANT_FIND
266 #define HASH_WANT_NEW
267 #define HASH_WANT_DELETE
269 #include "ucw/hashtable.h"
271 static void test5(void)
274 struct test5_table tab;
277 for (i=0; i<1024; i++)
279 struct node5 *n = test5_new(&tab, i);
280 ASSERT(n->data == i+123);
282 for (i=1; i<1024; i+=2)
283 test5_delete(&tab, i);
284 for (i=0; i<1024; i++)
286 struct node5 *n = test5_find(&tab, i);
287 if (!n != (i&1) || (n && n->data != i+123))
288 die("Inconsistency at i=%d", i);
291 HASH_FOR_ALL_DYNAMIC(test5, &tab, n)
299 main(int argc, char **argv)
305 for (int i=1; i<argc; i++)
306 m |= 1 << atol(argv[i]);