Annotation of embedaddon/bird2/lib/hash_test.c, revision 1.1.1.1
1.1 misho 1: /*
2: * BIRD Library -- Hash Tests
3: *
4: * (c) 2015 CZ.NIC z.s.p.o.
5: *
6: * Can be freely distributed and used under the terms of the GNU GPL.
7: */
8:
9: #undef LOCAL_DEBUG
10:
11: #include "test/birdtest.h"
12:
13: #include "lib/hash.h"
14:
15: struct test_node {
16: struct test_node *next; /* Hash chain */
17: u32 key;
18: };
19:
20: #define TEST_KEY(n) n->key
21: #define TEST_NEXT(n) n->next
22: #define TEST_EQ(n1,n2) n1 == n2
23: #define TEST_FN(n) (n) ^ u32_hash((n))
24: #define TEST_ORDER 13
25: #define TEST_PARAMS /TEST_ORDER, *2, 2, 2, TEST_ORDER, 20
26: #define TEST_REHASH test_rehash
27:
28: HASH_DEFINE_REHASH_FN(TEST, struct test_node);
29:
30: HASH(struct test_node) hash;
31: struct pool *my_pool;
32:
33: #define MAX_NUM (1 << TEST_ORDER)
34:
35: struct test_node nodes[MAX_NUM];
36:
37: static void
38: print_rate_of_fulfilment(void)
39: {
40: int i;
41: int num_stacked_items = 0;
42:
43: for (i = 0; i < MAX_NUM; i++)
44: if (!hash.data[i])
45: num_stacked_items++;
46:
47: double percent_stacked_items = ((double)num_stacked_items/(double)MAX_NUM)*100.;
48: bt_debug("%d (%.2f %%) chained of %d hashes \n", num_stacked_items, percent_stacked_items, MAX_NUM);
49: }
50:
51: #ifdef LOCAL_DEBUG
52: static void
53: dump_nodes(void)
54: {
55: int i;
56: for (i = 0; i < MAX_NUM; i++)
57: bt_debug("nodes[%3d] is at address %14p has .key %3d, .next %14p \n", i, &nodes[i], nodes[i].key, nodes[i].next);
58: }
59: #endif
60:
61: static void
62: init_hash_(uint order)
63: {
64: resource_init();
65: my_pool = rp_new(&root_pool, "Test pool");
66:
67: HASH_INIT(hash, my_pool, order);
68:
69: int i;
70: for (i = 0; i < MAX_NUM; i++)
71: {
72: nodes[i].key = i;
73: nodes[i].next = NULL;
74: }
75:
76: bt_debug("MAX_NUM %d \n", MAX_NUM);
77: }
78:
79: static void
80: init_hash(void)
81: {
82: init_hash_(TEST_ORDER);
83: }
84:
85: static void
86: validate_filled_hash(void)
87: {
88: int i;
89: struct test_node *node;
90: for (i = 0; i < MAX_NUM; i++)
91: {
92: node = HASH_FIND(hash, TEST, nodes[i].key);
93: bt_assert_msg(node->key == nodes[i].key, "Hash should be filled, to find (%p) the node[%d] (%p) with .key = %u, .next %p", node, i, &nodes[i], nodes[i].key, nodes[i].next);
94: }
95:
96: print_rate_of_fulfilment();
97: }
98:
99: static void
100: validate_empty_hash(void)
101: {
102: int i;
103: struct test_node *node;
104: for (i = 0; i < MAX_NUM; i++)
105: {
106: node = HASH_FIND(hash, TEST, nodes[i].key);
107: bt_assert_msg(node == NULL, "Hash should be empty, to find (%p) the node[%d] (%p) with .key %u, .next %p", node, i, &nodes[i], nodes[i].key, nodes[i].next);
108: }
109: }
110:
111: static void
112: fill_hash(void)
113: {
114: int i;
115: struct test_node *node;
116:
117: for (i = 0; i < MAX_NUM; i++)
118: {
119: nodes[i].key = i;
120: node = &nodes[i];
121: HASH_INSERT(hash, TEST, node);
122: }
123: }
124:
125: static int
126: t_insert_find(void)
127: {
128: init_hash();
129: fill_hash();
130: validate_filled_hash();
131:
132: return 1;
133: }
134:
135: static int
136: t_insert_find_random(void)
137: {
138: init_hash();
139:
140: int i;
141: struct test_node *node;
142: for (i = 0; i < MAX_NUM; i++)
143: {
144: nodes[i].key = bt_random();
145: node = &nodes[i];
146: HASH_INSERT(hash, TEST, node);
147: }
148:
149: validate_filled_hash();
150:
151: return 1;
152: }
153:
154: static int
155: t_insert2_find(void)
156: {
157: init_hash_(1);
158:
159: int i;
160: struct test_node *node;
161: for (i = 0; i < MAX_NUM; i++)
162: {
163: nodes[i].key = i;
164: node = &nodes[i];
165: HASH_INSERT2(hash, TEST, my_pool, node);
166: }
167: bt_assert_msg(hash.order != 1, "The hash should auto-resize from order 2^1. The order of the hash is 2^%u.", hash.order);
168:
169: validate_filled_hash();
170:
171: return 1;
172: }
173:
174: static int
175: t_walk(void)
176: {
177: init_hash();
178: fill_hash();
179:
180: uint i;
181: uint check[MAX_NUM];
182: for (i = 0; i < MAX_NUM; i++)
183: check[i] = 0;
184:
185: HASH_WALK(hash, next, n)
186: {
187: check[n->key]++;
188: }
189: HASH_WALK_END;
190:
191: for (i = 0; i < MAX_NUM; i++)
192: bt_assert(check[i] == 1);
193:
194: return 1;
195: }
196:
197: static int
198: t_walk_delsafe_delete(void)
199: {
200: init_hash();
201: fill_hash();
202:
203: HASH_WALK_DELSAFE(hash, next, n)
204: {
205: HASH_DELETE(hash, TEST, n->key);
206: }
207: HASH_WALK_DELSAFE_END;
208:
209: validate_empty_hash();
210:
211: return 1;
212: }
213:
214: static int
215: t_walk_delsafe_remove(void)
216: {
217: init_hash();
218: fill_hash();
219:
220: HASH_WALK_DELSAFE(hash, next, n)
221: {
222: HASH_REMOVE(hash, TEST, n);
223: }
224: HASH_WALK_DELSAFE_END;
225:
226: validate_empty_hash();
227:
228: return 1;
229: }
230:
231: static int
232: t_walk_delsafe_delete2(void)
233: {
234: init_hash();
235: fill_hash();
236:
237: HASH_WALK_DELSAFE(hash, next, n)
238: {
239: HASH_DELETE2(hash, TEST, my_pool, n->key);
240: }
241: HASH_WALK_DELSAFE_END;
242:
243: validate_empty_hash();
244:
245: return 1;
246: }
247:
248: static int
249: t_walk_delsafe_remove2(void)
250: {
251: init_hash();
252: fill_hash();
253:
254: HASH_WALK_DELSAFE(hash, next, n)
255: {
256: HASH_REMOVE2(hash, TEST, my_pool, n);
257: }
258: HASH_WALK_DELSAFE_END;
259:
260: validate_empty_hash();
261:
262: return 1;
263: }
264:
265: static int
266: t_walk_filter(void)
267: {
268: init_hash();
269: fill_hash();
270:
271: uint i;
272: uint check[MAX_NUM];
273: for (i = 0; i < MAX_NUM; i++)
274: check[i] = 0;
275:
276: HASH_WALK_FILTER(hash, next, n, m)
277: {
278: bt_assert(n == *m);
279: check[n->key]++;
280: }
281: HASH_WALK_FILTER_END;
282:
283: for (i = 0; i < MAX_NUM; i++)
284: bt_assert(check[i] == 1);
285:
286: return 1;
287: }
288:
289: int
290: main(int argc, char *argv[])
291: {
292: bt_init(argc, argv);
293:
294: bt_test_suite(t_insert_find, "HASH_INSERT and HASH_FIND");
295: bt_test_suite(t_insert_find_random, "HASH_INSERT pseudo-random keys and HASH_FIND");
296: bt_test_suite(t_insert2_find, "HASH_INSERT2 and HASH_FIND. HASH_INSERT2 is HASH_INSERT and a smart auto-resize function");
297: bt_test_suite(t_walk, "HASH_WALK");
298: bt_test_suite(t_walk_delsafe_delete, "HASH_WALK_DELSAFE and HASH_DELETE");
299: bt_test_suite(t_walk_delsafe_delete2, "HASH_WALK_DELSAFE and HASH_DELETE2. HASH_DELETE2 is HASH_DELETE and smart auto-resize function");
300: bt_test_suite(t_walk_delsafe_remove, "HASH_WALK_DELSAFE and HASH_REMOVE");
301: bt_test_suite(t_walk_delsafe_remove2, "HASH_WALK_DELSAFE and HASH_REMOVE2. HASH_REMOVE2 is HASH_REMOVE and smart auto-resize function");
302: bt_test_suite(t_walk_filter, "HASH_WALK_FILTER");
303:
304: return bt_exit_value();
305: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>