xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/ckh.c (revision 7bdf38e5b7a28439665f2fdeff81e36913eef7dd)
1a0698ed9Schristos #include "test/jemalloc_test.h"
2a0698ed9Schristos 
3a0698ed9Schristos TEST_BEGIN(test_new_delete) {
4a0698ed9Schristos 	tsd_t *tsd;
5a0698ed9Schristos 	ckh_t ckh;
6a0698ed9Schristos 
7a0698ed9Schristos 	tsd = tsd_fetch();
8a0698ed9Schristos 
9*7bdf38e5Schristos 	expect_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
10a0698ed9Schristos 	    ckh_string_keycomp), "Unexpected ckh_new() error");
11a0698ed9Schristos 	ckh_delete(tsd, &ckh);
12a0698ed9Schristos 
13*7bdf38e5Schristos 	expect_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash,
14a0698ed9Schristos 	    ckh_pointer_keycomp), "Unexpected ckh_new() error");
15a0698ed9Schristos 	ckh_delete(tsd, &ckh);
16a0698ed9Schristos }
17a0698ed9Schristos TEST_END
18a0698ed9Schristos 
19a0698ed9Schristos TEST_BEGIN(test_count_insert_search_remove) {
20a0698ed9Schristos 	tsd_t *tsd;
21a0698ed9Schristos 	ckh_t ckh;
22a0698ed9Schristos 	const char *strs[] = {
23a0698ed9Schristos 	    "a string",
24a0698ed9Schristos 	    "A string",
25a0698ed9Schristos 	    "a string.",
26a0698ed9Schristos 	    "A string."
27a0698ed9Schristos 	};
28a0698ed9Schristos 	const char *missing = "A string not in the hash table.";
29a0698ed9Schristos 	size_t i;
30a0698ed9Schristos 
31a0698ed9Schristos 	tsd = tsd_fetch();
32a0698ed9Schristos 
33*7bdf38e5Schristos 	expect_false(ckh_new(tsd, &ckh, 2, ckh_string_hash,
34a0698ed9Schristos 	    ckh_string_keycomp), "Unexpected ckh_new() error");
35*7bdf38e5Schristos 	expect_zu_eq(ckh_count(&ckh), 0,
36a0698ed9Schristos 	    "ckh_count() should return %zu, but it returned %zu", ZU(0),
37a0698ed9Schristos 	    ckh_count(&ckh));
38a0698ed9Schristos 
39a0698ed9Schristos 	/* Insert. */
40a0698ed9Schristos 	for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
41a0698ed9Schristos 		ckh_insert(tsd, &ckh, strs[i], strs[i]);
42*7bdf38e5Schristos 		expect_zu_eq(ckh_count(&ckh), i+1,
43a0698ed9Schristos 		    "ckh_count() should return %zu, but it returned %zu", i+1,
44a0698ed9Schristos 		    ckh_count(&ckh));
45a0698ed9Schristos 	}
46a0698ed9Schristos 
47a0698ed9Schristos 	/* Search. */
48a0698ed9Schristos 	for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
49a0698ed9Schristos 		union {
50a0698ed9Schristos 			void *p;
51a0698ed9Schristos 			const char *s;
52a0698ed9Schristos 		} k, v;
53a0698ed9Schristos 		void **kp, **vp;
54a0698ed9Schristos 		const char *ks, *vs;
55a0698ed9Schristos 
56a0698ed9Schristos 		kp = (i & 1) ? &k.p : NULL;
57a0698ed9Schristos 		vp = (i & 2) ? &v.p : NULL;
58a0698ed9Schristos 		k.p = NULL;
59a0698ed9Schristos 		v.p = NULL;
60*7bdf38e5Schristos 		expect_false(ckh_search(&ckh, strs[i], kp, vp),
61a0698ed9Schristos 		    "Unexpected ckh_search() error");
62a0698ed9Schristos 
63a0698ed9Schristos 		ks = (i & 1) ? strs[i] : (const char *)NULL;
64a0698ed9Schristos 		vs = (i & 2) ? strs[i] : (const char *)NULL;
65*7bdf38e5Schristos 		expect_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu",
66a0698ed9Schristos 		    i);
67*7bdf38e5Schristos 		expect_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu",
68a0698ed9Schristos 		    i);
69a0698ed9Schristos 	}
70*7bdf38e5Schristos 	expect_true(ckh_search(&ckh, missing, NULL, NULL),
71a0698ed9Schristos 	    "Unexpected ckh_search() success");
72a0698ed9Schristos 
73a0698ed9Schristos 	/* Remove. */
74a0698ed9Schristos 	for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) {
75a0698ed9Schristos 		union {
76a0698ed9Schristos 			void *p;
77a0698ed9Schristos 			const char *s;
78a0698ed9Schristos 		} k, v;
79a0698ed9Schristos 		void **kp, **vp;
80a0698ed9Schristos 		const char *ks, *vs;
81a0698ed9Schristos 
82a0698ed9Schristos 		kp = (i & 1) ? &k.p : NULL;
83a0698ed9Schristos 		vp = (i & 2) ? &v.p : NULL;
84a0698ed9Schristos 		k.p = NULL;
85a0698ed9Schristos 		v.p = NULL;
86*7bdf38e5Schristos 		expect_false(ckh_remove(tsd, &ckh, strs[i], kp, vp),
87a0698ed9Schristos 		    "Unexpected ckh_remove() error");
88a0698ed9Schristos 
89a0698ed9Schristos 		ks = (i & 1) ? strs[i] : (const char *)NULL;
90a0698ed9Schristos 		vs = (i & 2) ? strs[i] : (const char *)NULL;
91*7bdf38e5Schristos 		expect_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu",
92a0698ed9Schristos 		    i);
93*7bdf38e5Schristos 		expect_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu",
94a0698ed9Schristos 		    i);
95*7bdf38e5Schristos 		expect_zu_eq(ckh_count(&ckh),
96a0698ed9Schristos 		    sizeof(strs)/sizeof(const char *) - i - 1,
97a0698ed9Schristos 		    "ckh_count() should return %zu, but it returned %zu",
98a0698ed9Schristos 		        sizeof(strs)/sizeof(const char *) - i - 1,
99a0698ed9Schristos 		    ckh_count(&ckh));
100a0698ed9Schristos 	}
101a0698ed9Schristos 
102a0698ed9Schristos 	ckh_delete(tsd, &ckh);
103a0698ed9Schristos }
104a0698ed9Schristos TEST_END
105a0698ed9Schristos 
106a0698ed9Schristos TEST_BEGIN(test_insert_iter_remove) {
107a0698ed9Schristos #define NITEMS ZU(1000)
108a0698ed9Schristos 	tsd_t *tsd;
109a0698ed9Schristos 	ckh_t ckh;
110a0698ed9Schristos 	void **p[NITEMS];
111a0698ed9Schristos 	void *q, *r;
112a0698ed9Schristos 	size_t i;
113a0698ed9Schristos 
114a0698ed9Schristos 	tsd = tsd_fetch();
115a0698ed9Schristos 
116*7bdf38e5Schristos 	expect_false(ckh_new(tsd, &ckh, 2, ckh_pointer_hash,
117a0698ed9Schristos 	    ckh_pointer_keycomp), "Unexpected ckh_new() error");
118a0698ed9Schristos 
119a0698ed9Schristos 	for (i = 0; i < NITEMS; i++) {
120a0698ed9Schristos 		p[i] = mallocx(i+1, 0);
121*7bdf38e5Schristos 		expect_ptr_not_null(p[i], "Unexpected mallocx() failure");
122a0698ed9Schristos 	}
123a0698ed9Schristos 
124a0698ed9Schristos 	for (i = 0; i < NITEMS; i++) {
125a0698ed9Schristos 		size_t j;
126a0698ed9Schristos 
127a0698ed9Schristos 		for (j = i; j < NITEMS; j++) {
128*7bdf38e5Schristos 			expect_false(ckh_insert(tsd, &ckh, p[j], p[j]),
129a0698ed9Schristos 			    "Unexpected ckh_insert() failure");
130*7bdf38e5Schristos 			expect_false(ckh_search(&ckh, p[j], &q, &r),
131a0698ed9Schristos 			    "Unexpected ckh_search() failure");
132*7bdf38e5Schristos 			expect_ptr_eq(p[j], q, "Key pointer mismatch");
133*7bdf38e5Schristos 			expect_ptr_eq(p[j], r, "Value pointer mismatch");
134a0698ed9Schristos 		}
135a0698ed9Schristos 
136*7bdf38e5Schristos 		expect_zu_eq(ckh_count(&ckh), NITEMS,
137a0698ed9Schristos 		    "ckh_count() should return %zu, but it returned %zu",
138a0698ed9Schristos 		    NITEMS, ckh_count(&ckh));
139a0698ed9Schristos 
140a0698ed9Schristos 		for (j = i + 1; j < NITEMS; j++) {
141*7bdf38e5Schristos 			expect_false(ckh_search(&ckh, p[j], NULL, NULL),
142a0698ed9Schristos 			    "Unexpected ckh_search() failure");
143*7bdf38e5Schristos 			expect_false(ckh_remove(tsd, &ckh, p[j], &q, &r),
144a0698ed9Schristos 			    "Unexpected ckh_remove() failure");
145*7bdf38e5Schristos 			expect_ptr_eq(p[j], q, "Key pointer mismatch");
146*7bdf38e5Schristos 			expect_ptr_eq(p[j], r, "Value pointer mismatch");
147*7bdf38e5Schristos 			expect_true(ckh_search(&ckh, p[j], NULL, NULL),
148a0698ed9Schristos 			    "Unexpected ckh_search() success");
149*7bdf38e5Schristos 			expect_true(ckh_remove(tsd, &ckh, p[j], &q, &r),
150a0698ed9Schristos 			    "Unexpected ckh_remove() success");
151a0698ed9Schristos 		}
152a0698ed9Schristos 
153a0698ed9Schristos 		{
154a0698ed9Schristos 			bool seen[NITEMS];
155a0698ed9Schristos 			size_t tabind;
156a0698ed9Schristos 
157a0698ed9Schristos 			memset(seen, 0, sizeof(seen));
158a0698ed9Schristos 
159a0698ed9Schristos 			for (tabind = 0; !ckh_iter(&ckh, &tabind, &q, &r);) {
160a0698ed9Schristos 				size_t k;
161a0698ed9Schristos 
162*7bdf38e5Schristos 				expect_ptr_eq(q, r, "Key and val not equal");
163a0698ed9Schristos 
164a0698ed9Schristos 				for (k = 0; k < NITEMS; k++) {
165a0698ed9Schristos 					if (p[k] == q) {
166*7bdf38e5Schristos 						expect_false(seen[k],
167a0698ed9Schristos 						    "Item %zu already seen", k);
168a0698ed9Schristos 						seen[k] = true;
169a0698ed9Schristos 						break;
170a0698ed9Schristos 					}
171a0698ed9Schristos 				}
172a0698ed9Schristos 			}
173a0698ed9Schristos 
174a0698ed9Schristos 			for (j = 0; j < i + 1; j++) {
175*7bdf38e5Schristos 				expect_true(seen[j], "Item %zu not seen", j);
176a0698ed9Schristos 			}
177a0698ed9Schristos 			for (; j < NITEMS; j++) {
178*7bdf38e5Schristos 				expect_false(seen[j], "Item %zu seen", j);
179a0698ed9Schristos 			}
180a0698ed9Schristos 		}
181a0698ed9Schristos 	}
182a0698ed9Schristos 
183a0698ed9Schristos 	for (i = 0; i < NITEMS; i++) {
184*7bdf38e5Schristos 		expect_false(ckh_search(&ckh, p[i], NULL, NULL),
185a0698ed9Schristos 		    "Unexpected ckh_search() failure");
186*7bdf38e5Schristos 		expect_false(ckh_remove(tsd, &ckh, p[i], &q, &r),
187a0698ed9Schristos 		    "Unexpected ckh_remove() failure");
188*7bdf38e5Schristos 		expect_ptr_eq(p[i], q, "Key pointer mismatch");
189*7bdf38e5Schristos 		expect_ptr_eq(p[i], r, "Value pointer mismatch");
190*7bdf38e5Schristos 		expect_true(ckh_search(&ckh, p[i], NULL, NULL),
191a0698ed9Schristos 		    "Unexpected ckh_search() success");
192*7bdf38e5Schristos 		expect_true(ckh_remove(tsd, &ckh, p[i], &q, &r),
193a0698ed9Schristos 		    "Unexpected ckh_remove() success");
194a0698ed9Schristos 		dallocx(p[i], 0);
195a0698ed9Schristos 	}
196a0698ed9Schristos 
197*7bdf38e5Schristos 	expect_zu_eq(ckh_count(&ckh), 0,
198a0698ed9Schristos 	    "ckh_count() should return %zu, but it returned %zu",
199a0698ed9Schristos 	    ZU(0), ckh_count(&ckh));
200a0698ed9Schristos 	ckh_delete(tsd, &ckh);
201a0698ed9Schristos #undef NITEMS
202a0698ed9Schristos }
203a0698ed9Schristos TEST_END
204a0698ed9Schristos 
205a0698ed9Schristos int
206a0698ed9Schristos main(void) {
207a0698ed9Schristos 	return test(
208a0698ed9Schristos 	    test_new_delete,
209a0698ed9Schristos 	    test_count_insert_search_remove,
210a0698ed9Schristos 	    test_insert_iter_remove);
211a0698ed9Schristos }
212