1 /*------------------------------------------------------------------------------
2  *
3  * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4  * The YADIFA TM software product is provided under the BSD 3-clause license:
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  *        * Redistributions of source code must retain the above copyright
11  *          notice, this list of conditions and the following disclaimer.
12  *        * Redistributions in binary form must reproduce the above copyright
13  *          notice, this list of conditions and the following disclaimer in the
14  *          documentation and/or other materials provided with the distribution.
15  *        * Neither the name of EURid nor the names of its contributors may be
16  *          used to endorse or promote products derived from this software
17  *          without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  *------------------------------------------------------------------------------
32  *
33  */
34 
35 /** @defgroup test
36  *  @ingroup test
37  *  @brief skeleton file
38  *
39  * This is a speed test.
40  *
41  * Character case needs to be very fast but
42  * _ the simple "or" formula doesn't work with the extended character set
43  * _ the simple sub,or,add formula doesn't work with the full character set
44  *
45  * So it will probably be done using a lookup table.
46  * Each test covers one method, the first one points to the current choosen method.
47  *
48  * One solution may be better on a different architecture so we may want to try on other CPUs. e.g.: ARM and RISC-V
49  *
50  */
51 
52 #include <dnscore/dnscore.h>
53 #include <ctype.h>
54 #include <dnscore/format.h>
55 
56 #define BENCH_LOOPS 100000
57 #define FQDN_COUNT 12
58 #define LONG_STRING_SIZE 0x1000000
59 
60 static char *names[FQDN_COUNT] =
61 {
62     "www.e.eu.",
63     "www.eu.eu.",
64     "www.ode.eu.",
65     "www.code.eu.",
66     "www.eurid.eu.",
67     "www.yadifa.eu.",
68     "www.zorglub.eu.",
69     "www.mountain.eu.",
70     "www.something.eu.",
71     "www.somethingsomething.eu.",
72     "www.somethingsomethingelse.eu.",
73     "www._#!$*\\0123456789abcdefghijklmnopqrstuvwxyz.eu."
74 };
75 
76 static u8 **fqdns = NULL;
77 
78 static u8 *long_string = NULL;
79 static size_t long_string_size = 0;
80 static u8 *long_string_target = NULL;
81 
test_cases_prepare()82 static void test_cases_prepare()
83 {
84     u8 tmp[MAX_DOMAIN_LENGTH];
85 
86     srand(0);
87 
88     fqdns = malloc(FQDN_COUNT * FQDN_COUNT * sizeof(u8*));
89 
90     if(fqdns == NULL)
91     {
92         exit(2);
93     }
94 
95     for(int i = 0; i < FQDN_COUNT; ++i)
96     {
97         for(int j = 0; j < FQDN_COUNT; ++j)
98         {
99             cstr_to_dnsname(tmp, names[i]);
100 
101             if(j > 0)
102             {
103                 u8 *p = &tmp[0];
104                 for(u8 n = *p++; n != 0; n = *p++)
105                 {
106                     for(u8 k = 0; k < n; ++k)
107                     {
108                         if(rand() & 1)
109                         {
110                             p[k] = tolower(p[k]);
111                         }
112                         else
113                         {
114                             p[k] = toupper(p[k]);
115                         }
116                     }
117                 }
118             }
119 
120             fqdns[i * FQDN_COUNT + j] = dnsname_zdup(tmp);
121         }
122     }
123 
124     long_string = malloc(LONG_STRING_SIZE * 2);
125 
126     if(long_string == NULL)
127     {
128         exit(2);
129     }
130 
131     long_string_target = &long_string[LONG_STRING_SIZE];
132 
133     for(int i = 0; i < LONG_STRING_SIZE; ++i)
134     {
135         long_string[i] = (u8)rand();
136     }
137     long_string[LONG_STRING_SIZE - 1] = '\0';
138     long_string_size = LONG_STRING_SIZE;
139 }
140 
test_cases_equals()141 static void test_cases_equals()
142 {
143     s64 start = timeus();
144 
145     for(int l = 0; l < BENCH_LOOPS; ++l)
146     {
147         for(int i = 0; i < FQDN_COUNT; ++i)
148         {
149             for(int j = 1; j < FQDN_COUNT; ++j)
150             {
151                 u8 *a = fqdns[i * FQDN_COUNT + 0];
152                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
153                 if(!dnsname_equals_ignorecase(a, b))
154                 {
155                     formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
156                     exit(1);
157                 }
158             }
159         }
160     }
161 
162     s64 stop = timeus();
163 
164     formatln("test_cases_equals : time: %lli", stop - start);
165 }
166 
test_cases_equals1()167 static void test_cases_equals1()
168 {
169     s64 start = timeus();
170 
171     for(int l = 0; l < BENCH_LOOPS; ++l)
172     {
173         for(int i = 0; i < FQDN_COUNT; ++i)
174         {
175             for(int j = 1; j < FQDN_COUNT; ++j)
176             {
177                 u8 *a = fqdns[i * FQDN_COUNT + 0];
178                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
179                 if(!dnsname_equals_ignorecase1(a, b))
180                 {
181                     formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
182                     exit(1);
183                 }
184             }
185         }
186     }
187 
188     s64 stop = timeus();
189 
190     formatln("test_cases_equals1: time: %lli", stop - start);
191 }
192 
193 
test_cases_equals2()194 static void test_cases_equals2()
195 {
196     s64 start = timeus();
197 
198     for(int l = 0; l < BENCH_LOOPS; ++l)
199     {
200         for(int i = 0; i < FQDN_COUNT; ++i)
201         {
202             for(int j = 1; j < FQDN_COUNT; ++j)
203             {
204                 u8 *a = fqdns[i * FQDN_COUNT + 0];
205                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
206                 if(!dnsname_equals_ignorecase2(a, b))
207                 {
208                     formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
209                     exit(1);
210                 }
211             }
212         }
213     }
214 
215     s64 stop = timeus();
216 
217     formatln("test_cases_equals2: time: %lli", stop - start);
218 }
219 
test_cases_equals3()220 static void test_cases_equals3()
221 {
222     s64 start = timeus();
223 
224     for(int l = 0; l < BENCH_LOOPS; ++l)
225     {
226         for(int i = 0; i < FQDN_COUNT; ++i)
227         {
228             for(int j = 1; j < FQDN_COUNT; ++j)
229             {
230                 u8 *a = fqdns[i * FQDN_COUNT + 0];
231                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
232                 if(!dnsname_equals_ignorecase3(a, b))
233                 {
234                     formatln("failed to equate %{dnsname} and %{dnsname}", a, b);
235                     exit(1);
236                 }
237             }
238         }
239     }
240 
241     s64 stop = timeus();
242 
243     formatln("test_cases_equals3: time: %lli", stop - start);
244 }
245 
test_label_cases_equals()246 static void test_label_cases_equals()
247 {
248     s64 start = timeus();
249 
250     for(int l = 0; l < BENCH_LOOPS; ++l)
251     {
252         for(int i = 0; i < FQDN_COUNT; ++i)
253         {
254             for(int j = 1; j < FQDN_COUNT; ++j)
255             {
256                 u8 *a = fqdns[i * FQDN_COUNT + 0];
257                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
258                 a += *a + 1;
259                 b += *b + 1;
260                 if(!dnslabel_equals_ignorecase_left(a, b))
261                 {
262                     formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
263                     exit(1);
264                 }
265             }
266         }
267     }
268 
269     s64 stop = timeus();
270 
271     formatln("test_label_cases_equal : time: %lli", stop - start);
272 }
273 
test_label_cases_equals1()274 static void test_label_cases_equals1()
275 {
276     s64 start = timeus();
277 
278     for(int l = 0; l < BENCH_LOOPS; ++l)
279     {
280         for(int i = 0; i < FQDN_COUNT; ++i)
281         {
282             for(int j = 1; j < FQDN_COUNT; ++j)
283             {
284                 u8 *a = fqdns[i * FQDN_COUNT + 0];
285                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
286                 a += *a + 1;
287                 b += *b + 1;
288                 if(!dnslabel_equals_ignorecase_left1(a, b))
289                 {
290                     formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
291                     exit(1);
292                 }
293             }
294         }
295     }
296 
297     s64 stop = timeus();
298 
299     formatln("test_label_cases_equal1: time: %lli", stop - start);
300 }
301 
test_label_cases_equals2()302 static void test_label_cases_equals2()
303 {
304     s64 start = timeus();
305 
306     for(int l = 0; l < BENCH_LOOPS; ++l)
307     {
308         for(int i = 0; i < FQDN_COUNT; ++i)
309         {
310             for(int j = 1; j < FQDN_COUNT; ++j)
311             {
312                 u8 *a = fqdns[i * FQDN_COUNT + 0];
313                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
314                 a += *a + 1;
315                 b += *b + 1;
316                 if(!dnslabel_equals_ignorecase_left2(a, b))
317                 {
318                     formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
319                     exit(1);
320                 }
321             }
322         }
323     }
324 
325     s64 stop = timeus();
326 
327     formatln("test_label_cases_equal2: time: %lli", stop - start);
328 }
329 
test_label_cases_equals3()330 static void test_label_cases_equals3()
331 {
332     s64 start = timeus();
333 
334     for(int l = 0; l < BENCH_LOOPS; ++l)
335     {
336         for(int i = 0; i < FQDN_COUNT; ++i)
337         {
338             for(int j = 1; j < FQDN_COUNT; ++j)
339             {
340                 u8 *a = fqdns[i * FQDN_COUNT + 0];
341                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
342                 a += *a + 1;
343                 b += *b + 1;
344                 if(!dnslabel_equals_ignorecase_left3(a, b))
345                 {
346                     formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
347                     exit(1);
348                 }
349             }
350         }
351     }
352 
353     s64 stop = timeus();
354 
355     formatln("test_label_cases_equal3: time: %lli", stop - start);
356 }
357 
test_label_cases_equals4()358 static void test_label_cases_equals4()
359 {
360     s64 start = timeus();
361 
362     for(int l = 0; l < BENCH_LOOPS; ++l)
363     {
364         for(int i = 0; i < FQDN_COUNT; ++i)
365         {
366             for(int j = 1; j < FQDN_COUNT; ++j)
367             {
368                 u8 *a = fqdns[i * FQDN_COUNT + 0];
369                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
370                 a += *a + 1;
371                 b += *b + 1;
372                 if(!dnslabel_equals_ignorecase_left4(a, b))
373                 {
374                     formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
375                     exit(1);
376                 }
377             }
378         }
379     }
380 
381     s64 stop = timeus();
382 
383     formatln("test_label_cases_equal4: time: %lli", stop - start);
384 }
385 
test_label_cases_equals5()386 static void test_label_cases_equals5()
387 {
388     s64 start = timeus();
389 
390     for(int l = 0; l < BENCH_LOOPS; ++l)
391     {
392         for(int i = 0; i < FQDN_COUNT; ++i)
393         {
394             for(int j = 1; j < FQDN_COUNT; ++j)
395             {
396                 u8 *a = fqdns[i * FQDN_COUNT + 0];
397                 u8 *b = fqdns[i * FQDN_COUNT + j + 0];
398                 a += *a + 1;
399                 b += *b + 1;
400                 if(!dnslabel_equals_ignorecase_left5(a, b))
401                 {
402                     formatln("failed to equate %{dnslabel} and %{dnslabel}", a, b);
403                     exit(1);
404                 }
405             }
406         }
407     }
408 
409     s64 stop = timeus();
410 
411     formatln("test_label_cases_equal5: time: %lli", stop - start);
412 }
413 
test_string_tolower()414 static void test_string_tolower()
415 {
416     s64 start = timeus();
417 
418     for(size_t i = 0; i < long_string_size; ++i)
419     {
420         long_string_target[i] = LOCASE(long_string[i]);
421     }
422 
423     s64 stop = timeus();
424 
425     formatln("test_string_tolower: time: %lli", stop - start);
426 }
427 
test_string_tolower1()428 static void test_string_tolower1()
429 {
430     s64 start = timeus();
431 
432     for(size_t i = 0; i < long_string_size; ++i)
433     {
434         long_string_target[i] = tolower(long_string[i]);
435     }
436 
437     s64 stop = timeus();
438 
439     formatln("test_string_tolower1: time: %lli", stop - start);
440 }
441 
test_string_tolower2()442 static void test_string_tolower2()
443 {
444     s64 start = timeus();
445 
446     for(size_t i = 0; i < long_string_size; ++i)
447     {
448         long_string_target[i] = __LOCASE_TABLE__[long_string[i]];
449     }
450 
451     s64 stop = timeus();
452 
453     formatln("test_string_tolower2: time: %lli", stop - start);
454 }
455 
456 int
main(int argc,char * argv[])457 main(int argc, char *argv[])
458 {
459     (void)argc;
460     (void)argv;
461     /* initializes the core library */
462     dnscore_init();
463 
464     test_cases_prepare();
465 
466     test_cases_equals();
467     test_cases_equals();
468     test_cases_equals1();
469     test_cases_equals1();
470     test_cases_equals2();
471     test_cases_equals2();
472     test_cases_equals3();
473     test_cases_equals3();
474 
475     test_label_cases_equals();
476     test_label_cases_equals();
477     test_label_cases_equals1();
478     test_label_cases_equals1();
479     test_label_cases_equals2();
480     test_label_cases_equals2();
481     test_label_cases_equals3();
482     test_label_cases_equals3();
483     test_label_cases_equals4();
484     test_label_cases_equals4();
485     test_label_cases_equals5();
486     test_label_cases_equals5();
487 
488     test_string_tolower();
489     test_string_tolower();
490     test_string_tolower1();
491     test_string_tolower1();
492     test_string_tolower2();
493     test_string_tolower2();
494 
495     flushout();
496     flusherr();
497     fflush(NULL);
498 
499     dnscore_finalize();
500 
501     return EXIT_SUCCESS;
502 }
503