8c87e654579bef942a792cb6e5ee9d3201311564
[oweals/u-boot.git] / test / env / hashtable.c
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);