blob: 3c3cbf73ca9078d14c8f72f34da7263bacab3a39 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifdef CLIB_UNIX
Dave Barachc3799992016-08-15 11:12:27 -040017#include <unistd.h>
18#include <stdlib.h>
19#include <stdio.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070020#endif
21
22#include <vppinfra/slist.h>
23
Dave Barachc3799992016-08-15 11:12:27 -040024typedef struct
25{
Ed Warnickecb9cada2015-12-08 15:45:58 -070026 u32 *random_pool;
27 u32 seed;
28 u32 iter;
29 u32 verbose;
30 f64 branching_factor;
31 clib_slist_t slist;
32} test_main_t;
33
34test_main_t test_main;
35
36#define foreach_simple_test \
37_(2) \
38_(4) \
39_(3) \
Dave Barachc3799992016-08-15 11:12:27 -040040_(1)
Ed Warnickecb9cada2015-12-08 15:45:58 -070041
42
Dave Barachc3799992016-08-15 11:12:27 -040043void
44run_test (test_main_t * tm)
Ed Warnickecb9cada2015-12-08 15:45:58 -070045{
46 int i;
Dave Barachc3799992016-08-15 11:12:27 -040047 u32 *tv;
Ed Warnickecb9cada2015-12-08 15:45:58 -070048 u32 ncompares;
49 u64 total_compares = 0;
50
Dave Barachc3799992016-08-15 11:12:27 -040051 if (1)
52 {
53 /*
54 * Add a bunch of random numbers to the skip-list,
55 * sorting them.
56 */
57 for (i = 0; i < tm->iter; i++)
58 {
59 pool_get (tm->random_pool, tv);
60 *tv = random_u32 (&tm->seed);
61 clib_slist_add (&tm->slist, tv, tv - tm->random_pool);
62 }
63 /* make sure we can find each one */
64 for (i = 0; i < tm->iter; i++)
65 {
66 u32 search_result;
67 tv = pool_elt_at_index (tm->random_pool, i);
Ed Warnickecb9cada2015-12-08 15:45:58 -070068
Dave Barachc3799992016-08-15 11:12:27 -040069 search_result = clib_slist_search (&tm->slist, tv, &ncompares);
70 ASSERT (search_result == i);
Ed Warnickecb9cada2015-12-08 15:45:58 -070071
Dave Barachc3799992016-08-15 11:12:27 -040072 total_compares += ncompares;
73 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070074
Dave Barachc3799992016-08-15 11:12:27 -040075 fformat (stdout, "%.2f avg compares/search\n",
76 (f64) total_compares / (f64) i);
Ed Warnickecb9cada2015-12-08 15:45:58 -070077
Dave Barachc3799992016-08-15 11:12:27 -040078 fformat (stdout, "%U\n", format_slist, &tm->slist,
79 tm->iter < 1000 /* verbose */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -070080
Dave Barachc3799992016-08-15 11:12:27 -040081 /* delete half of them */
82 for (i = tm->iter / 2; i < tm->iter; i++)
83 {
84 tv = pool_elt_at_index (tm->random_pool, i);
85 (void) clib_slist_del (&tm->slist, tv);
86 }
Ed Warnickecb9cada2015-12-08 15:45:58 -070087
Dave Barachc3799992016-08-15 11:12:27 -040088 /* make sure we can find the set we should find, and no others */
89 for (i = 0; i < tm->iter; i++)
90 {
91 u32 search_result;
92 tv = pool_elt_at_index (tm->random_pool, i);
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
Dave Barachc3799992016-08-15 11:12:27 -040094 search_result = clib_slist_search (&tm->slist, tv, &ncompares);
95 if (i >= tm->iter / 2)
96 ASSERT (search_result == (u32) ~ 0);
97 else
98 ASSERT (search_result == i);
Ed Warnickecb9cada2015-12-08 15:45:58 -070099
Dave Barachc3799992016-08-15 11:12:27 -0400100 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700101
Dave Barachc3799992016-08-15 11:12:27 -0400102 fformat (stdout, "%U\n", format_slist, &tm->slist,
103 tm->iter < 1000 /* verbose */ );
104
105 /* delete the rest */
106 for (i = 0; i < tm->iter; i++)
107 {
108 tv = pool_elt_at_index (tm->random_pool, i);
109
110 (void) clib_slist_del (&tm->slist, tv);
111 }
112
113 fformat (stdout, "%U\n", format_slist, &tm->slist,
114 tm->iter < 1000 /* verbose */ );
115 }
116 else
117 {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700118
119#define _(n) \
120 do { \
121 pool_get (tm->random_pool, tv); \
122 *tv = n; \
123 clib_slist_add (&tm->slist, tv, tv - tm->random_pool); \
124 fformat(stdout, "%U\n", format_slist, &tm->slist, 1 /* verbose */); \
125 } while (0);
Dave Barachc3799992016-08-15 11:12:27 -0400126 foreach_simple_test;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700127#undef _
Dave Barachc3799992016-08-15 11:12:27 -0400128 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700129
130 return;
131}
132
Dave Barachc3799992016-08-15 11:12:27 -0400133word
134test_compare (void *key, u32 elt_index)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135{
Dave Barachc3799992016-08-15 11:12:27 -0400136 u32 *k = (u32 *) key;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700137 u32 elt = test_main.random_pool[elt_index];
138
139 if (*k < elt)
140 return -1;
141 if (*k > elt)
142 return 1;
143 return 0;
144}
145
Dave Barachc3799992016-08-15 11:12:27 -0400146u8 *
147test_format (u8 * s, va_list * args)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700148{
149 u32 elt_index = va_arg (*args, u32);
150 u32 elt = test_main.random_pool[elt_index];
151
152 return format (s, "%u", elt);
153}
154
Dave Barachc3799992016-08-15 11:12:27 -0400155void
156initialize_slist (test_main_t * tm)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157{
158 clib_slist_init (&tm->slist, tm->branching_factor,
Dave Barachc3799992016-08-15 11:12:27 -0400159 test_compare, test_format);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700160}
161
Dave Barachc3799992016-08-15 11:12:27 -0400162int
163test_slist_main (unformat_input_t * input)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700164{
165 test_main_t *tm = &test_main;
166 u32 tmp;
167
168 tm->seed = 0xbabeb00b;
Florin Corase10e3722016-04-13 00:05:27 +0200169 tm->iter = 100000;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700170 tm->verbose = 1;
171 tm->branching_factor = 1.0 / 5.0;
172
173 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
174 {
175 if (unformat (input, "seed %d", &tm->seed))
Dave Barachc3799992016-08-15 11:12:27 -0400176 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700177 else if (unformat (input, "iter %d", &tm->iter))
Dave Barachc3799992016-08-15 11:12:27 -0400178 continue;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179 else if (unformat (input, "verbose"))
Dave Barachc3799992016-08-15 11:12:27 -0400180 tm->verbose = 1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181 else if (unformat (input, "branch %d", &tmp))
Dave Barachc3799992016-08-15 11:12:27 -0400182 {
183 if (tmp > 0)
184 tm->branching_factor = 1.0 / (f64) tmp;
185 else
186 fformat (stderr, "warning: branch = 0, ignored\n");
187 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700188 else
Dave Barachc3799992016-08-15 11:12:27 -0400189 {
190 clib_error ("unknown input `%U'", format_unformat_error, input);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700191 goto usage;
Dave Barachc3799992016-08-15 11:12:27 -0400192 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700193 }
194 initialize_slist (tm);
195 run_test (tm);
196
197 return 0;
198
Dave Barachc3799992016-08-15 11:12:27 -0400199usage:
200 fformat (stderr, "usage: test_slist seed <seed> iter <iter> [verbose]\n");
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201 return 1;
Dave Barachc3799992016-08-15 11:12:27 -0400202
Ed Warnickecb9cada2015-12-08 15:45:58 -0700203}
204
205#ifdef CLIB_UNIX
Dave Barachc3799992016-08-15 11:12:27 -0400206int
207main (int argc, char *argv[])
Ed Warnickecb9cada2015-12-08 15:45:58 -0700208{
209 unformat_input_t i;
210 int ret;
211
Dave Barachc3799992016-08-15 11:12:27 -0400212 clib_mem_init (0, (u64) 4 << 30);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700213
214 unformat_init_command_line (&i, argv);
215 ret = test_slist_main (&i);
216 unformat_free (&i);
217
218 return ret;
219}
220#endif /* CLIB_UNIX */
Dave Barachc3799992016-08-15 11:12:27 -0400221
222/*
223 * fd.io coding-style-patch-verification: ON
224 *
225 * Local Variables:
226 * eval: (c-set-style "gnu")
227 * End:
228 */