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