VirtualBox

source: vbox/trunk/src/libs/libxml2-2.13.2/testdict.c@ 106165

最後變更 在這個檔案從106165是 105420,由 vboxsync 提交於 4 月 前

libxml2-2.12.6: Applied and adjusted our libxml2 changes to 2.12.6. bugref:10730

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette