Reorganize source tree to use single autotools instance
[vpp.git] / src / vppinfra / test_pfhash.c
1 /*
2   Copyright (c) 2013 Cisco and/or its affiliates.
3
4   * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include <vppinfra/pfhash.h>
18 #include <vppinfra/format.h>
19 #include <vppinfra/random.h>
20
21 #if defined(CLIB_HAVE_VEC128) && ! defined (__ALTIVEC__)
22
23 int verbose = 0;
24
25 always_inline u8 *
26 random_aligned_string (u32 * seed, uword len)
27 {
28   u8 *alphabet = (u8 *) "abcdefghijklmnopqrstuvwxyz";
29   u8 *s = 0;
30   word i;
31
32   vec_resize_aligned (s, len, 16);
33   for (i = 0; i < len; i++)
34     s[i] = alphabet[random_u32 (seed) % 26];
35
36   return s;
37 }
38
39 void exit (int);
40
41 int
42 test_pfhash_main (unformat_input_t * input)
43 {
44   u32 seed = 0xdeaddabe;
45   int i, iter;
46   u32 nkeys = 4;
47   u32 niter = 1;
48   u32 nbuckets = 1;
49   u32 bucket;
50   u32 sizes[3] = { 16, 8, 4 }, this_size, size;
51   u8 **keys = 0;
52   pfhash_t _rec, *p = &_rec;
53
54   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
55     {
56       if (unformat (input, "seed %d", &seed))
57         ;
58       else if (unformat (input, "niter %d", &niter))
59         ;
60       else if (unformat (input, "nkeys %d", &nkeys))
61         ;
62       else if (unformat (input, "nbuckets %d", &nbuckets))
63         ;
64       else if (unformat (input, "verbose %d", &verbose))
65         ;
66       else if (unformat (input, "verbose"))
67         verbose = 1;
68       else
69         clib_error ("unknown input `%U'", format_unformat_error, input);
70     }
71
72   vec_validate (keys, nkeys - 1);
73
74   for (i = 0; i < nkeys; i++)
75     {
76       int j, k;
77
78     again:
79       keys[i] = random_aligned_string (&seed, 16);
80       for (j = 0; j < (i - 1); j++)
81         {
82           /* Make sure we don't have a dup key in the min key size */
83           for (k = 0; k < 4; k++)
84             {
85               if (keys[i][k] != keys[j][k])
86                 goto check_next_key;
87             }
88           vec_free (keys[i]);
89           goto again;
90         check_next_key:
91           ;
92         }
93     }
94
95   /* test 8 byte key, 8 byte value case separately */
96
97   for (size = 8; size < 9; size++)
98     {
99       this_size = 8;
100
101       fformat (stdout, "%d-byte key 8 byte value test\n", this_size);
102
103       pfhash_init (p, "test", 8 /* key size */ , 8 /* value size */ ,
104                    nbuckets + 1);
105
106       for (iter = 0; iter < niter; iter++)
107         {
108           bucket = 0;
109           for (i = 0; i < nkeys; i++)
110             {
111               bucket = (i % nbuckets) + 1;
112               pfhash_set (p, bucket, keys[i],
113                           (void *) (u64) 0x100000000ULL + i + 1);
114             }
115
116           for (i = 0; i < nkeys; i++)
117             {
118               bucket = (i % nbuckets) + 1;
119               if (pfhash_get (p, bucket, keys[i])
120                   != (u64) 0x100000000ULL + i + 1)
121                 {
122                   clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
123                   (void) pfhash_get (p, bucket, keys[i]);
124                 }
125             }
126
127           /* test inline functions */
128           for (i = 0; i < nkeys; i++)
129             {
130               u32 bucket_contents;
131               u64 value = 0xdeadbeef;
132               bucket = (i % nbuckets) + 1;
133
134               pfhash_prefetch_bucket (p, bucket);
135               bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
136
137               value = pfhash_search_kv_8v8 (p, bucket_contents,
138                                             (u64 *) keys[i]);
139               if (value != (u64) 0x100000000ULL + i + 1)
140                 clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
141             }
142
143           if (verbose)
144             fformat (stdout, "%U\n", format_pfhash, p, verbose > 1);
145
146           for (i = 0; i < nkeys; i++)
147             {
148               bucket = (i % nbuckets) + 1;
149               pfhash_unset (p, bucket, keys[i]);
150             }
151
152           for (i = 0; i < nkeys; i++)
153             {
154               bucket = (i % nbuckets) + 1;
155               if (pfhash_get (p, bucket, keys[i]) != (u64) ~ 0)
156                 {
157                   clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
158                   (void) pfhash_get (p, bucket, keys[i]);
159                 }
160             }
161           /* test inline functions */
162           for (i = 0; i < nkeys; i++)
163             {
164               u32 bucket_contents;
165               u64 value = 0xdeadbeef;
166               bucket = (i % nbuckets) + 1;
167
168               pfhash_prefetch_bucket (p, bucket);
169               bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
170
171               value = pfhash_search_kv_8v8 (p, bucket_contents,
172                                             (u64 *) keys[i]);
173
174               if (value != (u64) ~ 0)
175                 clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
176             }
177         }
178       pfhash_free (p);
179     }
180
181   /* test other cases */
182
183   for (size = 0; size < ARRAY_LEN (sizes); size++)
184     {
185       this_size = sizes[size];
186
187       fformat (stdout, "%d-byte key test\n", this_size);
188
189       pfhash_init (p, "test", this_size, 4 /* value size */ , nbuckets + 1);
190
191       for (iter = 0; iter < niter; iter++)
192         {
193           bucket = 0;
194           for (i = 0; i < nkeys; i++)
195             {
196               bucket = (i % nbuckets) + 1;
197               pfhash_set (p, bucket, keys[i], (void *) (u64) i + 1);
198             }
199
200           for (i = 0; i < nkeys; i++)
201             {
202               bucket = (i % nbuckets) + 1;
203               if (pfhash_get (p, bucket, keys[i]) != i + 1)
204                 {
205                   clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
206                   (void) pfhash_get (p, bucket, keys[i]);
207                 }
208             }
209
210           /* test inline functions */
211           for (i = 0; i < nkeys; i++)
212             {
213               u32 bucket_contents;
214               u32 value = 0xdeadbeef;
215               bucket = (i % nbuckets) + 1;
216
217               pfhash_prefetch_bucket (p, bucket);
218               bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
219               switch (p->key_size)
220                 {
221                 case 16:
222                   value =
223                     pfhash_search_kv_16 (p, bucket_contents,
224                                          (u32x4 *) keys[i]);
225                   break;
226                 case 8:
227                   value =
228                     pfhash_search_kv_8 (p, bucket_contents, (u64 *) keys[i]);
229                   break;
230                 case 4:
231                   value =
232                     pfhash_search_kv_4 (p, bucket_contents, (u32 *) keys[i]);
233                   break;
234                 }
235
236               if (value != (i + 1))
237                 clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
238             }
239
240           if (verbose)
241             fformat (stdout, "%U\n", format_pfhash, p, verbose > 1);
242
243           for (i = 0; i < nkeys; i++)
244             {
245               bucket = (i % nbuckets) + 1;
246               pfhash_unset (p, bucket, keys[i]);
247             }
248
249           for (i = 0; i < nkeys; i++)
250             {
251               bucket = (i % nbuckets) + 1;
252               if (pfhash_get (p, bucket, keys[i]) != (u64) ~ 0)
253                 {
254                   clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
255                   (void) pfhash_get (p, bucket, keys[i]);
256                 }
257             }
258           /* test inline functions */
259           for (i = 0; i < nkeys; i++)
260             {
261               u32 bucket_contents;
262               u32 value = 0xdeadbeef;
263               bucket = (i % nbuckets) + 1;
264
265               pfhash_prefetch_bucket (p, bucket);
266               bucket_contents = pfhash_read_bucket_prefetch_kv (p, bucket);
267               switch (p->key_size)
268                 {
269                 case 16:
270                   value =
271                     pfhash_search_kv_16 (p, bucket_contents,
272                                          (u32x4 *) keys[i]);
273                   break;
274                 case 8:
275                   value =
276                     pfhash_search_kv_8 (p, bucket_contents, (u64 *) keys[i]);
277                   break;
278                 case 4:
279                   value =
280                     pfhash_search_kv_4 (p, bucket_contents, (u32 *) keys[i]);
281                   break;
282                 }
283               if (value != (u32) ~ 0)
284                 clib_warning ("key %d bucket %d lookup FAIL\n", i, bucket);
285             }
286         }
287       pfhash_free (p);
288     }
289
290   exit (0);
291 }
292 #else
293 int
294 test_pfhash_main (unformat_input_t * input)
295 {
296   clib_warning ("MMX unit not available");
297   return 0;
298 }
299 #endif
300
301 #ifdef CLIB_UNIX
302 int
303 main (int argc, char *argv[])
304 {
305   unformat_input_t i;
306   int ret;
307
308   unformat_init_command_line (&i, argv);
309   ret = test_pfhash_main (&i);
310   unformat_free (&i);
311
312   return ret;
313 }
314 #endif /* CLIB_UNIX */
315
316 /*
317  * fd.io coding-style-patch-verification: ON
318  *
319  * Local Variables:
320  * eval: (c-set-style "gnu")
321  * End:
322  */