xref: /openbmc/u-boot/test/env/hashtable.c (revision 2e8560797fc69a34c330a875da4f5d2992452f1e)
1*9dfdbd9fSRoman Kapl // SPDX-License-Identifier: GPL-2.0
2*9dfdbd9fSRoman Kapl /*
3*9dfdbd9fSRoman Kapl  * (C) Copyright 2019
4*9dfdbd9fSRoman Kapl  * Roman Kapl, SYSGO, rka@sysgo.com
5*9dfdbd9fSRoman Kapl  */
6*9dfdbd9fSRoman Kapl 
7*9dfdbd9fSRoman Kapl #include <common.h>
8*9dfdbd9fSRoman Kapl #include <command.h>
9*9dfdbd9fSRoman Kapl #include <search.h>
10*9dfdbd9fSRoman Kapl #include <stdio.h>
11*9dfdbd9fSRoman Kapl #include <test/env.h>
12*9dfdbd9fSRoman Kapl #include <test/ut.h>
13*9dfdbd9fSRoman Kapl 
14*9dfdbd9fSRoman Kapl #define SIZE 32
15*9dfdbd9fSRoman Kapl #define ITERATIONS 10000
16*9dfdbd9fSRoman Kapl 
htab_fill(struct unit_test_state * uts,struct hsearch_data * htab,size_t size)17*9dfdbd9fSRoman Kapl static int htab_fill(struct unit_test_state *uts,
18*9dfdbd9fSRoman Kapl 		     struct hsearch_data *htab, size_t size)
19*9dfdbd9fSRoman Kapl {
20*9dfdbd9fSRoman Kapl 	size_t i;
21*9dfdbd9fSRoman Kapl 	ENTRY item;
22*9dfdbd9fSRoman Kapl 	ENTRY *ritem;
23*9dfdbd9fSRoman Kapl 	char key[20];
24*9dfdbd9fSRoman Kapl 
25*9dfdbd9fSRoman Kapl 	for (i = 0; i < size; i++) {
26*9dfdbd9fSRoman Kapl 		sprintf(key, "%d", (int)i);
27*9dfdbd9fSRoman Kapl 		item.callback = NULL;
28*9dfdbd9fSRoman Kapl 		item.data = key;
29*9dfdbd9fSRoman Kapl 		item.flags = 0;
30*9dfdbd9fSRoman Kapl 		item.key = key;
31*9dfdbd9fSRoman Kapl 		ut_asserteq(1, hsearch_r(item, ENTER, &ritem, htab, 0));
32*9dfdbd9fSRoman Kapl 	}
33*9dfdbd9fSRoman Kapl 
34*9dfdbd9fSRoman Kapl 	return 0;
35*9dfdbd9fSRoman Kapl }
36*9dfdbd9fSRoman Kapl 
htab_check_fill(struct unit_test_state * uts,struct hsearch_data * htab,size_t size)37*9dfdbd9fSRoman Kapl static int htab_check_fill(struct unit_test_state *uts,
38*9dfdbd9fSRoman Kapl 			   struct hsearch_data *htab, size_t size)
39*9dfdbd9fSRoman Kapl {
40*9dfdbd9fSRoman Kapl 	size_t i;
41*9dfdbd9fSRoman Kapl 	ENTRY item;
42*9dfdbd9fSRoman Kapl 	ENTRY *ritem;
43*9dfdbd9fSRoman Kapl 	char key[20];
44*9dfdbd9fSRoman Kapl 
45*9dfdbd9fSRoman Kapl 	for (i = 0; i < size; i++) {
46*9dfdbd9fSRoman Kapl 		sprintf(key, "%d", (int)i);
47*9dfdbd9fSRoman Kapl 		item.callback = NULL;
48*9dfdbd9fSRoman Kapl 		item.flags = 0;
49*9dfdbd9fSRoman Kapl 		item.data = key;
50*9dfdbd9fSRoman Kapl 		item.key = key;
51*9dfdbd9fSRoman Kapl 		hsearch_r(item, FIND, &ritem, htab, 0);
52*9dfdbd9fSRoman Kapl 		ut_assert(ritem);
53*9dfdbd9fSRoman Kapl 		ut_asserteq_str(key, ritem->key);
54*9dfdbd9fSRoman Kapl 		ut_asserteq_str(key, ritem->data);
55*9dfdbd9fSRoman Kapl 	}
56*9dfdbd9fSRoman Kapl 
57*9dfdbd9fSRoman Kapl 	return 0;
58*9dfdbd9fSRoman Kapl }
59*9dfdbd9fSRoman Kapl 
htab_create_delete(struct unit_test_state * uts,struct hsearch_data * htab,size_t iterations)60*9dfdbd9fSRoman Kapl static int htab_create_delete(struct unit_test_state *uts,
61*9dfdbd9fSRoman Kapl 			      struct hsearch_data *htab, size_t iterations)
62*9dfdbd9fSRoman Kapl {
63*9dfdbd9fSRoman Kapl 	size_t i;
64*9dfdbd9fSRoman Kapl 	ENTRY item;
65*9dfdbd9fSRoman Kapl 	ENTRY *ritem;
66*9dfdbd9fSRoman Kapl 	char key[20];
67*9dfdbd9fSRoman Kapl 
68*9dfdbd9fSRoman Kapl 	for (i = 0; i < iterations; i++) {
69*9dfdbd9fSRoman Kapl 		sprintf(key, "cd-%d", (int)i);
70*9dfdbd9fSRoman Kapl 		item.callback = NULL;
71*9dfdbd9fSRoman Kapl 		item.flags = 0;
72*9dfdbd9fSRoman Kapl 		item.data = key;
73*9dfdbd9fSRoman Kapl 		item.key = key;
74*9dfdbd9fSRoman Kapl 		hsearch_r(item, ENTER, &ritem, htab, 0);
75*9dfdbd9fSRoman Kapl 		ritem = NULL;
76*9dfdbd9fSRoman Kapl 
77*9dfdbd9fSRoman Kapl 		hsearch_r(item, FIND, &ritem, htab, 0);
78*9dfdbd9fSRoman Kapl 		ut_assert(ritem);
79*9dfdbd9fSRoman Kapl 		ut_asserteq_str(key, ritem->key);
80*9dfdbd9fSRoman Kapl 		ut_asserteq_str(key, ritem->data);
81*9dfdbd9fSRoman Kapl 
82*9dfdbd9fSRoman Kapl 		ut_asserteq(1, hdelete_r(key, htab, 0));
83*9dfdbd9fSRoman Kapl 	}
84*9dfdbd9fSRoman Kapl 
85*9dfdbd9fSRoman Kapl 	return 0;
86*9dfdbd9fSRoman Kapl }
87*9dfdbd9fSRoman Kapl 
88*9dfdbd9fSRoman Kapl /* Completely fill up the hash table */
env_test_htab_fill(struct unit_test_state * uts)89*9dfdbd9fSRoman Kapl static int env_test_htab_fill(struct unit_test_state *uts)
90*9dfdbd9fSRoman Kapl {
91*9dfdbd9fSRoman Kapl 	struct hsearch_data htab;
92*9dfdbd9fSRoman Kapl 
93*9dfdbd9fSRoman Kapl 	memset(&htab, 0, sizeof(htab));
94*9dfdbd9fSRoman Kapl 	ut_asserteq(1, hcreate_r(SIZE, &htab));
95*9dfdbd9fSRoman Kapl 
96*9dfdbd9fSRoman Kapl 	ut_assertok(htab_fill(uts, &htab, SIZE));
97*9dfdbd9fSRoman Kapl 	ut_assertok(htab_check_fill(uts, &htab, SIZE));
98*9dfdbd9fSRoman Kapl 	ut_asserteq(SIZE, htab.filled);
99*9dfdbd9fSRoman Kapl 
100*9dfdbd9fSRoman Kapl 	hdestroy_r(&htab);
101*9dfdbd9fSRoman Kapl 	return 0;
102*9dfdbd9fSRoman Kapl }
103*9dfdbd9fSRoman Kapl 
104*9dfdbd9fSRoman Kapl ENV_TEST(env_test_htab_fill, 0);
105*9dfdbd9fSRoman Kapl 
106*9dfdbd9fSRoman Kapl /* Fill the hashtable up halfway an repeateadly delete/create elements
107*9dfdbd9fSRoman Kapl  * and check for corruption
108*9dfdbd9fSRoman Kapl  */
env_test_htab_deletes(struct unit_test_state * uts)109*9dfdbd9fSRoman Kapl static int env_test_htab_deletes(struct unit_test_state *uts)
110*9dfdbd9fSRoman Kapl {
111*9dfdbd9fSRoman Kapl 	struct hsearch_data htab;
112*9dfdbd9fSRoman Kapl 
113*9dfdbd9fSRoman Kapl 	memset(&htab, 0, sizeof(htab));
114*9dfdbd9fSRoman Kapl 	ut_asserteq(1, hcreate_r(SIZE, &htab));
115*9dfdbd9fSRoman Kapl 
116*9dfdbd9fSRoman Kapl 	ut_assertok(htab_fill(uts, &htab, SIZE / 2));
117*9dfdbd9fSRoman Kapl 	ut_assertok(htab_create_delete(uts, &htab, ITERATIONS));
118*9dfdbd9fSRoman Kapl 	ut_assertok(htab_check_fill(uts, &htab, SIZE / 2));
119*9dfdbd9fSRoman Kapl 	ut_asserteq(SIZE / 2, htab.filled);
120*9dfdbd9fSRoman Kapl 
121*9dfdbd9fSRoman Kapl 	hdestroy_r(&htab);
122*9dfdbd9fSRoman Kapl 	return 0;
123*9dfdbd9fSRoman Kapl }
124*9dfdbd9fSRoman Kapl 
125*9dfdbd9fSRoman Kapl ENV_TEST(env_test_htab_deletes, 0);
126