VirtualBox

source: vbox/trunk/src/libs/libxml2-2.12.6/testdict.c

Last change on this file was 104106, checked in by vboxsync, 8 weeks ago

libxml2-2.9.14: Applied and adjusted our libxml2 changes to 2.9.14. bugref:10640

  • Property svn:eol-style set to native
File size: 20.8 KB
Line 
1#include <stdlib.h>
2#include <string.h>
3#include <libxml/parser.h>
4#include <libxml/dict.h>
5
6
7/**** dictionary tests ****/
8
9#ifdef __clang__
10 #define ATTRIBUTE_NO_SANITIZE_INTEGER \
11 __attribute__ ((no_sanitize("unsigned-integer-overflow"))) \
12 __attribute__ ((no_sanitize("unsigned-shift-base")))
13#else
14 #define ATTRIBUTE_NO_SANITIZE_INTEGER
15#endif
16
17/* #define WITH_PRINT */
18
19static const char *seeds1[] = {
20 "a", "b", "c",
21 "d", "e", "f",
22 "g", "h", "i",
23 "j", "k", "l",
24
25 NULL
26};
27
28static const char *seeds2[] = {
29 "m", "n", "o",
30 "p", "q", "r",
31 "s", "t", "u",
32 "v", "w", "x",
33
34 NULL
35};
36
37#define NB_STRINGS_MAX 100000
38#define NB_STRINGS_NS 10000
39#define NB_STRINGS_PREFIX (NB_STRINGS_NS / 20)
40#define NB_STRINGS_MIN 10
41
42static xmlChar **strings1;
43static xmlChar **strings2;
44static const xmlChar **test1;
45static const xmlChar **test2;
46static int nbErrors = 0;
47
48static void
49fill_string_pool(xmlChar **strings, const char **seeds) {
50 int i, j, k;
51 int start_ns = NB_STRINGS_MAX - NB_STRINGS_NS;
52
53 /*
54 * That's a bit nasty but the output is fine and it doesn't take hours
55 * there is a small but sufficient number of duplicates, and we have
56 * ":xxx" and full QNames in the last NB_STRINGS_NS values
57 */
58 for (i = 0; seeds[i] != NULL; i++) {
59 strings[i] = xmlStrdup((const xmlChar *) seeds[i]);
60 if (strings[i] == NULL) {
61 fprintf(stderr, "Out of memory while generating strings\n");
62 exit(1);
63 }
64 }
65 for (j = 0, k = 0; i < start_ns; i++) {
66 strings[i] = xmlStrncatNew(strings[j], strings[k], -1);
67 if (strings[i] == NULL) {
68 fprintf(stderr, "Out of memory while generating strings\n");
69 exit(1);
70 }
71 if (xmlStrlen(strings[i]) > 30) {
72 fprintf(stderr, "### %s %s\n", strings[start_ns+j], strings[k]);
73 abort();
74 }
75 j++;
76 if (j >= 50) {
77 j = 0;
78 k++;
79 }
80 }
81 for (j = 0, k = 0; (j < NB_STRINGS_PREFIX) && (i < NB_STRINGS_MAX);
82 i++, j++) {
83 strings[i] = xmlStrncatNew(strings[k], (const xmlChar *) ":", -1);
84 if (strings[i] == NULL) {
85 fprintf(stderr, "Out of memory while generating strings\n");
86 exit(1);
87 }
88 k += 1;
89 if (k >= start_ns) k = 0;
90 }
91 for (j = 0, k = 0; i < NB_STRINGS_MAX; i++) {
92 strings[i] = xmlStrncatNew(strings[start_ns+j], strings[k], -1);
93 if (strings[i] == NULL) {
94 fprintf(stderr, "Out of memory while generating strings\n");
95 exit(1);
96 }
97 j++;
98 if (j >= NB_STRINGS_PREFIX) j = 0;
99 k += 5;
100 if (k >= start_ns) k = 0;
101 }
102}
103
104#ifdef WITH_PRINT
105static void print_strings(void) {
106 int i;
107
108 for (i = 0; i < NB_STRINGS_MAX;i++) {
109 printf("%s\n", strings1[i]);
110 }
111 for (i = 0; i < NB_STRINGS_MAX;i++) {
112 printf("%s\n", strings2[i]);
113 }
114}
115#endif
116
117static void clean_strings(void) {
118 int i;
119
120 for (i = 0; i < NB_STRINGS_MAX; i++) {
121 if (strings1[i] != NULL) /* really should not happen */
122 xmlFree(strings1[i]);
123 }
124 for (i = 0; i < NB_STRINGS_MAX; i++) {
125 if (strings2[i] != NULL) /* really should not happen */
126 xmlFree(strings2[i]);
127 }
128}
129
130/*
131 * This tests the sub-dictionary support
132 */
133static int
134test_subdict(xmlDictPtr parent) {
135 int i, j;
136 xmlDictPtr dict;
137 int ret = 0;
138 xmlChar prefix[40];
139 xmlChar *cur, *pref;
140 const xmlChar *tmp;
141
142 dict = xmlDictCreateSub(parent);
143 if (dict == NULL) {
144 fprintf(stderr, "Out of memory while creating sub-dictionary\n");
145 exit(1);
146 }
147 /* Cast to avoid buggy warning on MSVC. */
148 memset((void *) test2, 0, sizeof(test2));
149
150 /*
151 * Fill in NB_STRINGS_MIN, at this point the dictionary should not grow
152 * and we allocate all those doing the fast key computations
153 * All the strings are based on a different seeds subset so we know
154 * they are allocated in the main dictionary, not coming from the parent
155 */
156 for (i = 0;i < NB_STRINGS_MIN;i++) {
157 test2[i] = xmlDictLookup(dict, strings2[i], -1);
158 if (test2[i] == NULL) {
159 fprintf(stderr, "Failed lookup for '%s'\n", strings2[i]);
160 ret = 1;
161 nbErrors++;
162 }
163 }
164 j = NB_STRINGS_MAX - NB_STRINGS_NS;
165 /* ":foo" like strings2 */
166 for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
167 test2[j] = xmlDictLookup(dict, strings2[j], xmlStrlen(strings2[j]));
168 if (test2[j] == NULL) {
169 fprintf(stderr, "Failed lookup for '%s'\n", strings2[j]);
170 ret = 1;
171 nbErrors++;
172 }
173 }
174 /* "a:foo" like strings2 */
175 j = NB_STRINGS_MAX - NB_STRINGS_MIN;
176 for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
177 test2[j] = xmlDictLookup(dict, strings2[j], xmlStrlen(strings2[j]));
178 if (test2[j] == NULL) {
179 fprintf(stderr, "Failed lookup for '%s'\n", strings2[j]);
180 ret = 1;
181 nbErrors++;
182 }
183 }
184
185 /*
186 * At this point allocate all the strings
187 * the dictionary will grow in the process, reallocate more string tables
188 * and switch to the better key generator
189 */
190 for (i = 0;i < NB_STRINGS_MAX;i++) {
191 if (test2[i] != NULL)
192 continue;
193 test2[i] = xmlDictLookup(dict, strings2[i], -1);
194 if (test2[i] == NULL) {
195 fprintf(stderr, "Failed lookup for '%s'\n", strings2[i]);
196 ret = 1;
197 nbErrors++;
198 }
199 }
200
201 /*
202 * Now we can start to test things, first that all strings2 belongs to
203 * the dict, and that none of them was actually allocated in the parent
204 */
205 for (i = 0;i < NB_STRINGS_MAX;i++) {
206 if (!xmlDictOwns(dict, test2[i])) {
207 fprintf(stderr, "Failed ownership failure for '%s'\n",
208 strings2[i]);
209 ret = 1;
210 nbErrors++;
211 }
212 if (xmlDictOwns(parent, test2[i])) {
213 fprintf(stderr, "Failed parent ownership failure for '%s'\n",
214 strings2[i]);
215 ret = 1;
216 nbErrors++;
217 }
218 }
219
220 /*
221 * Also verify that all strings from the parent are seen from the subdict
222 */
223 for (i = 0;i < NB_STRINGS_MAX;i++) {
224 if (!xmlDictOwns(dict, test1[i])) {
225 fprintf(stderr, "Failed sub-ownership failure for '%s'\n",
226 strings1[i]);
227 ret = 1;
228 nbErrors++;
229 }
230 }
231
232 /*
233 * Then that another lookup to the string in sub will return the same
234 */
235 for (i = 0;i < NB_STRINGS_MAX;i++) {
236 if (xmlDictLookup(dict, strings2[i], -1) != test2[i]) {
237 fprintf(stderr, "Failed re-lookup check for %d, '%s'\n",
238 i, strings2[i]);
239 ret = 1;
240 nbErrors++;
241 }
242 }
243 /*
244 * But also that any lookup for a string in the parent will be provided
245 * as in the parent
246 */
247 for (i = 0;i < NB_STRINGS_MAX;i++) {
248 if (xmlDictLookup(dict, strings1[i], -1) != test1[i]) {
249 fprintf(stderr, "Failed parent string lookup check for %d, '%s'\n",
250 i, strings1[i]);
251 ret = 1;
252 nbErrors++;
253 }
254 }
255
256 /*
257 * check the QName lookups
258 */
259 for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) {
260 cur = strings2[i];
261 pref = &prefix[0];
262 while (*cur != ':') *pref++ = *cur++;
263 cur++;
264 *pref = 0;
265 tmp = xmlDictQLookup(dict, &prefix[0], cur);
266 if (tmp != test2[i]) {
267 fprintf(stderr, "Failed lookup check for '%s':'%s'\n",
268 &prefix[0], cur);
269 ret = 1;
270 nbErrors++;
271 }
272 }
273 /*
274 * check the QName lookups for strings from the parent
275 */
276 for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) {
277 cur = strings1[i];
278 pref = &prefix[0];
279 while (*cur != ':') *pref++ = *cur++;
280 cur++;
281 *pref = 0;
282 tmp = xmlDictQLookup(dict, &prefix[0], cur);
283 if (xmlDictQLookup(dict, &prefix[0], cur) != test1[i]) {
284 fprintf(stderr, "Failed parent lookup check for '%s':'%s'\n",
285 &prefix[0], cur);
286 ret = 1;
287 nbErrors++;
288 }
289 }
290
291 xmlDictFree(dict);
292 return(ret);
293}
294
295/*
296 * Test a single dictionary
297 */
298static int
299test_dict(xmlDict *dict) {
300 int i, j;
301 int ret = 0;
302 xmlChar prefix[40];
303 xmlChar *cur, *pref;
304 const xmlChar *tmp;
305
306 /* Cast to avoid buggy warning on MSVC. */
307 memset((void *) test1, 0, sizeof(test1));
308
309 /*
310 * Fill in NB_STRINGS_MIN, at this point the dictionary should not grow
311 * and we allocate all those doing the fast key computations
312 */
313 for (i = 0;i < NB_STRINGS_MIN;i++) {
314 test1[i] = xmlDictLookup(dict, strings1[i], -1);
315 if (test1[i] == NULL) {
316 fprintf(stderr, "Failed lookup for '%s'\n", strings1[i]);
317 ret = 1;
318 nbErrors++;
319 }
320 }
321 j = NB_STRINGS_MAX - NB_STRINGS_NS;
322 /* ":foo" like strings1 */
323 for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
324 test1[j] = xmlDictLookup(dict, strings1[j], xmlStrlen(strings1[j]));
325 if (test1[j] == NULL) {
326 fprintf(stderr, "Failed lookup for '%s'\n", strings1[j]);
327 ret = 1;
328 nbErrors++;
329 }
330 }
331 /* "a:foo" like strings1 */
332 j = NB_STRINGS_MAX - NB_STRINGS_MIN;
333 for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
334 test1[j] = xmlDictLookup(dict, strings1[j], xmlStrlen(strings1[j]));
335 if (test1[j] == NULL) {
336 fprintf(stderr, "Failed lookup for '%s'\n", strings1[j]);
337 ret = 1;
338 nbErrors++;
339 }
340 }
341
342 /*
343 * At this point allocate all the strings
344 * the dictionary will grow in the process, reallocate more string tables
345 * and switch to the better key generator
346 */
347 for (i = 0;i < NB_STRINGS_MAX;i++) {
348 if (test1[i] != NULL)
349 continue;
350 test1[i] = xmlDictLookup(dict, strings1[i], -1);
351 if (test1[i] == NULL) {
352 fprintf(stderr, "Failed lookup for '%s'\n", strings1[i]);
353 ret = 1;
354 nbErrors++;
355 }
356 }
357
358 /*
359 * Now we can start to test things, first that all strings1 belongs to
360 * the dict
361 */
362 for (i = 0;i < NB_STRINGS_MAX;i++) {
363 if (!xmlDictOwns(dict, test1[i])) {
364 fprintf(stderr, "Failed ownership failure for '%s'\n",
365 strings1[i]);
366 ret = 1;
367 nbErrors++;
368 }
369 }
370
371 /*
372 * Then that another lookup to the string will return the same
373 */
374 for (i = 0;i < NB_STRINGS_MAX;i++) {
375 if (xmlDictLookup(dict, strings1[i], -1) != test1[i]) {
376 fprintf(stderr, "Failed re-lookup check for %d, '%s'\n",
377 i, strings1[i]);
378 ret = 1;
379 nbErrors++;
380 }
381 }
382
383 /*
384 * More complex, check the QName lookups
385 */
386 for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) {
387 cur = strings1[i];
388 pref = &prefix[0];
389 while (*cur != ':') *pref++ = *cur++;
390 cur++;
391 *pref = 0;
392 tmp = xmlDictQLookup(dict, &prefix[0], cur);
393 if (tmp != test1[i]) {
394 fprintf(stderr, "Failed lookup check for '%s':'%s'\n",
395 &prefix[0], cur);
396 ret = 1;
397 nbErrors++;
398 }
399 }
400
401 return(ret);
402}
403
404static int
405testall_dict(void) {
406 xmlDictPtr dict;
407 int ret = 0;
408
409 strings1 = xmlMalloc(NB_STRINGS_MAX * sizeof(strings1[0]));
410 memset(strings1, 0, NB_STRINGS_MAX * sizeof(strings1[0]));
411 strings2 = xmlMalloc(NB_STRINGS_MAX * sizeof(strings2[0]));
412 memset(strings2, 0, NB_STRINGS_MAX * sizeof(strings2[0]));
413 test1 = xmlMalloc(NB_STRINGS_MAX * sizeof(test1[0]));
414 memset(test1, 0, NB_STRINGS_MAX * sizeof(test1[0]));
415 test2 = xmlMalloc(NB_STRINGS_MAX * sizeof(test2[0]));
416 memset(test2, 0, NB_STRINGS_MAX * sizeof(test2[0]));
417
418 fill_string_pool(strings1, seeds1);
419 fill_string_pool(strings2, seeds2);
420#ifdef WITH_PRINT
421 print_strings();
422#endif
423
424 dict = xmlDictCreate();
425 if (dict == NULL) {
426 fprintf(stderr, "Out of memory while creating dictionary\n");
427 exit(1);
428 }
429 if (test_dict(dict) != 0) {
430 ret = 1;
431 }
432 if (test_subdict(dict) != 0) {
433 ret = 1;
434 }
435 xmlDictFree(dict);
436
437 clean_strings();
438 xmlFree(strings1);
439 xmlFree(strings2);
440 xmlFree(test1);
441 xmlFree(test2);
442
443 return ret;
444}
445
446
447/**** Hash table tests ****/
448
449static unsigned
450rng_state[2] = { 123, 456 };
451
452#define HASH_ROL(x,n) ((x) << (n) | ((x) & 0xFFFFFFFF) >> (32 - (n)))
453
454ATTRIBUTE_NO_SANITIZE_INTEGER
455static unsigned
456my_rand(unsigned max) {
457 unsigned s0 = rng_state[0];
458 unsigned s1 = rng_state[1];
459 unsigned result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
460
461 s1 ^= s0;
462 rng_state[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
463 rng_state[1] = HASH_ROL(s1, 13);
464
465 return((result & 0xFFFFFFFF) % max);
466}
467
468static xmlChar *
469gen_random_string(xmlChar id) {
470 unsigned size = my_rand(64) + 1;
471 unsigned id_pos = my_rand(size);
472 size_t j;
473
474 xmlChar *str = xmlMalloc(size + 1);
475 for (j = 0; j < size; j++) {
476 str[j] = 'a' + my_rand(26);
477 }
478 str[id_pos] = id;
479 str[size] = 0;
480
481 /* Generate QName in 75% of cases */
482 if (size > 3 && my_rand(4) > 0) {
483 unsigned colon_pos = my_rand(size - 3) + 1;
484
485 if (colon_pos >= id_pos)
486 colon_pos++;
487 str[colon_pos] = ':';
488 }
489
490 return str;
491}
492
493typedef struct {
494 xmlChar **strings;
495 size_t num_entries;
496 size_t num_keys;
497 size_t num_strings;
498 size_t index;
499 xmlChar id;
500} StringPool;
501
502static StringPool *
503pool_new(size_t num_entries, size_t num_keys, xmlChar id) {
504 StringPool *ret;
505 size_t num_strings;
506
507 ret = xmlMalloc(sizeof(*ret));
508 ret->num_entries = num_entries;
509 ret->num_keys = num_keys;
510 num_strings = num_entries * num_keys;
511 ret->strings = xmlMalloc(num_strings * sizeof(ret->strings[0]));
512 memset(ret->strings, 0, num_strings * sizeof(ret->strings[0]));
513 ret->num_strings = num_strings;
514 ret->index = 0;
515 ret->id = id;
516
517 return ret;
518}
519
520static void
521pool_free(StringPool *pool) {
522 size_t i;
523
524 for (i = 0; i < pool->num_strings; i++) {
525 xmlFree(pool->strings[i]);
526 }
527 xmlFree(pool->strings);
528 xmlFree(pool);
529}
530
531static int
532pool_done(StringPool *pool) {
533 return pool->index >= pool->num_strings;
534}
535
536static void
537pool_reset(StringPool *pool) {
538 pool->index = 0;
539}
540
541static int
542pool_bulk_insert(StringPool *pool, xmlHashTablePtr hash, size_t num) {
543 size_t i, j;
544 int ret = 0;
545
546 for (i = pool->index, j = 0; i < pool->num_strings && j < num; j++) {
547 xmlChar *str[3];
548 size_t k;
549
550 while (1) {
551 xmlChar tmp_key[1];
552 int res;
553
554 for (k = 0; k < pool->num_keys; k++)
555 str[k] = gen_random_string(pool->id);
556
557 switch (pool->num_keys) {
558 case 1:
559 res = xmlHashAddEntry(hash, str[0], tmp_key);
560 if (res == 0 &&
561 xmlHashUpdateEntry(hash, str[0], str[0], NULL) != 0)
562 ret = -1;
563 break;
564 case 2:
565 res = xmlHashAddEntry2(hash, str[0], str[1], tmp_key);
566 if (res == 0 &&
567 xmlHashUpdateEntry2(hash, str[0], str[1], str[0],
568 NULL) != 0)
569 ret = -1;
570 break;
571 case 3:
572 res = xmlHashAddEntry3(hash, str[0], str[1], str[2],
573 tmp_key);
574 if (res == 0 &&
575 xmlHashUpdateEntry3(hash, str[0], str[1], str[2],
576 str[0], NULL) != 0)
577 ret = -1;
578 break;
579 }
580
581 if (res == 0)
582 break;
583 for (k = 0; k < pool->num_keys; k++)
584 xmlFree(str[k]);
585 }
586
587 for (k = 0; k < pool->num_keys; k++)
588 pool->strings[i++] = str[k];
589 }
590
591 pool->index = i;
592 return ret;
593}
594
595static xmlChar *
596hash_qlookup(xmlHashTable *hash, xmlChar **names, size_t num_keys) {
597 xmlChar *prefix[3];
598 const xmlChar *local[3];
599 xmlChar *res;
600 size_t i;
601
602 for (i = 0; i < 3; ++i) {
603 if (i >= num_keys) {
604 prefix[i] = NULL;
605 local[i] = NULL;
606 } else {
607 const xmlChar *name = names[i];
608 const xmlChar *colon = BAD_CAST strchr((const char *) name, ':');
609
610 if (colon == NULL) {
611 prefix[i] = NULL;
612 local[i] = name;
613 } else {
614 prefix[i] = xmlStrndup(name, colon - name);
615 local[i] = &colon[1];
616 }
617 }
618 }
619
620 res = xmlHashQLookup3(hash, prefix[0], local[0], prefix[1], local[1],
621 prefix[2], local[2]);
622
623 for (i = 0; i < 3; ++i)
624 xmlFree(prefix[i]);
625
626 return res;
627}
628
629static int
630pool_bulk_lookup(StringPool *pool, xmlHashTablePtr hash, size_t num,
631 int existing) {
632 size_t i, j;
633 int ret = 0;
634
635 for (i = pool->index, j = 0; i < pool->num_strings && j < num; j++) {
636 xmlChar **str = &pool->strings[i];
637 int q;
638
639 for (q = 0; q < 2; q++) {
640 xmlChar *res = NULL;
641
642 if (q) {
643 res = hash_qlookup(hash, str, pool->num_keys);
644 } else {
645 switch (pool->num_keys) {
646 case 1:
647 res = xmlHashLookup(hash, str[0]);
648 break;
649 case 2:
650 res = xmlHashLookup2(hash, str[0], str[1]);
651 break;
652 case 3:
653 res = xmlHashLookup3(hash, str[0], str[1], str[2]);
654 break;
655 }
656 }
657
658 if (existing) {
659 if (res != str[0])
660 ret = -1;
661 } else {
662 if (res != NULL)
663 ret = -1;
664 }
665 }
666
667 i += pool->num_keys;
668 }
669
670 pool->index = i;
671 return ret;
672}
673
674static int
675pool_bulk_remove(StringPool *pool, xmlHashTablePtr hash, size_t num) {
676 size_t i, j;
677 int ret = 0;
678
679 for (i = pool->index, j = 0; i < pool->num_strings && j < num; j++) {
680 xmlChar **str = &pool->strings[i];
681 int res = -1;
682
683 switch (pool->num_keys) {
684 case 1:
685 res = xmlHashRemoveEntry(hash, str[0], NULL);
686 break;
687 case 2:
688 res = xmlHashRemoveEntry2(hash, str[0], str[1], NULL);
689 break;
690 case 3:
691 res = xmlHashRemoveEntry3(hash, str[0], str[1], str[2], NULL);
692 break;
693 }
694
695 if (res != 0)
696 ret = -1;
697
698 i += pool->num_keys;
699 }
700
701 pool->index = i;
702 return ret;
703}
704
705static int
706test_hash(size_t num_entries, size_t num_keys, int use_dict) {
707 xmlDict *dict = NULL;
708 xmlHashTable *hash;
709 StringPool *pool1, *pool2;
710 int ret = 0;
711
712 if (use_dict) {
713 dict = xmlDictCreate();
714 hash = xmlHashCreateDict(0, dict);
715 } else {
716 hash = xmlHashCreate(0);
717 }
718 pool1 = pool_new(num_entries, num_keys, '1');
719 pool2 = pool_new(num_entries, num_keys, '2');
720
721 /* Insert all strings from pool2 and about half of pool1. */
722 while (!pool_done(pool2)) {
723 if (pool_bulk_insert(pool1, hash, my_rand(50)) != 0) {
724 fprintf(stderr, "pool1: hash insert failed\n");
725 ret = 1;
726 }
727 if (pool_bulk_insert(pool2, hash, my_rand(100)) != 0) {
728 fprintf(stderr, "pool1: hash insert failed\n");
729 ret = 1;
730 }
731 }
732
733 /* Check existing entries */
734 pool_reset(pool2);
735 if (pool_bulk_lookup(pool2, hash, pool2->num_entries, 1) != 0) {
736 fprintf(stderr, "pool2: hash lookup failed\n");
737 ret = 1;
738 }
739
740 /* Remove all strings from pool2 and insert the rest of pool1. */
741 pool_reset(pool2);
742 while (!pool_done(pool1) || !pool_done(pool2)) {
743 if (pool_bulk_insert(pool1, hash, my_rand(50)) != 0) {
744 fprintf(stderr, "pool1: hash insert failed\n");
745 ret = 1;
746 }
747 if (pool_bulk_remove(pool2, hash, my_rand(100)) != 0) {
748 fprintf(stderr, "pool2: hash remove failed\n");
749 ret = 1;
750 }
751 }
752
753 /* Check existing entries */
754 pool_reset(pool1);
755 if (pool_bulk_lookup(pool1, hash, pool1->num_entries, 1) != 0) {
756 fprintf(stderr, "pool1: hash lookup failed\n");
757 ret = 1;
758 }
759
760 /* Check removed entries */
761 pool_reset(pool2);
762 if (pool_bulk_lookup(pool2, hash, pool2->num_entries, 0) != 0) {
763 fprintf(stderr, "pool2: hash lookup succeeded unexpectedly\n");
764 ret = 1;
765 }
766
767 pool_free(pool1);
768 pool_free(pool2);
769 xmlHashFree(hash, NULL);
770 xmlDictFree(dict);
771
772 return ret;
773}
774
775static int
776testall_hash(void) {
777 size_t num_keys;
778
779 for (num_keys = 1; num_keys <= 3; num_keys++) {
780 size_t num_strings;
781 size_t max_strings = num_keys == 1 ? 100000 : 1000;
782
783 for (num_strings = 10; num_strings <= max_strings; num_strings *= 10) {
784 size_t reps, i;
785
786 reps = 1000 / num_strings;
787 if (reps == 0)
788 reps = 1;
789
790 for (i = 0; i < reps; i++) {
791 if (test_hash(num_strings, num_keys, /* use_dict */ 0) != 0)
792 return(1);
793 }
794
795 if (test_hash(num_strings, num_keys, /* use_dict */ 1) != 0)
796 return(1);
797 }
798 }
799
800 return(0);
801}
802
803
804/**** main ****/
805
806int
807main(void) {
808 int ret = 0;
809
810 LIBXML_TEST_VERSION
811
812 if (testall_dict() != 0) {
813 fprintf(stderr, "dictionary tests failed\n");
814 ret = 1;
815 }
816 if (testall_hash() != 0) {
817 fprintf(stderr, "hash tests failed\n");
818 ret = 1;
819 }
820
821 xmlCleanupParser();
822 return(ret);
823}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use