1
// @(#) $Revision: 4.20 $ $Source: /judy/test/manual/Judy1LTime.c $
2
//=======================================================================
3
// This program measures the performance of a Judy1 and JudyL Array.
5
// Douglas L. Baskins (8/2001) doug@sourcejudy.com
6
//=======================================================================
8
#include <unistd.h> // sbrk()
9
#include <stdlib.h> // exit()
10
#include <stdio.h> // printf()
11
#include <math.h> // pow()
12
#include <sys/time.h> // gettimeofday()
13
#include <Judy.h> // for Judy macros J*()
15
#ifdef NOINLINE /* this is the 21st century? */
16
#define _INLINE_ static
18
#define _INLINE_ inline
22
//=======================================================================
24
//=======================================================================
26
// cc -static -O3 Judy1LTime.c -lJudy -lm
28
// the -static is for a little better performace on some platforms
30
// if optional high-resolution timers are desired:
32
// cc -static -O3 -DJU_LINUX_IA32 Judy1LTime.c -lJudy -lm
36
//=======================================================================
37
// T I M I N G M A C R O S
38
//=======================================================================
39
// if your machine is one of the supported types in the following header
40
// file then uncomment this corresponding to what the header file says.
41
// This will give very high timing resolution.
43
// #define JU_xxxxxxx 1 // read timeit.h
44
// #define JU_LINUX_IA32 1 // I.E. IA32 Linux
46
// #include "timeit.h" // optional for high resolution times
48
double DeltaUSec; // Global for remembering delta times
52
// Note: I have found some Linux systems (2.4.18-6mdk) have bugs in the
53
// gettimeofday() routine. Sometimes the difference of two consective calls
54
// returns a negative ~2840 microseconds instead of 0 or 1. If you use the
55
// above #include "timeit.h" and compile with timeit.c and use
56
// -DJU_LINUX_IA32, that problem will be eliminated. This is because for
57
// delta times less than .1 sec, the hardware free running timer is used
58
// instead of gettimeofday(). I have found the negative time problem
59
// appears about 40-50 times per second with numerous gettimeofday() calls.
60
// You should just ignore negative times output.
62
#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T
64
#define STARTTm(T) gettimeofday(&__TVBeg_##T, NULL)
68
gettimeofday(&__TVEnd_##T, NULL); \
69
(D) = (double)(__TVEnd_##T.tv_sec - __TVBeg_##T.tv_sec) * 1E6 + \
70
((double)(__TVEnd_##T.tv_usec - __TVBeg_##T.tv_usec)); \
75
//=======================================================================
76
// M E M O R Y S I Z E M A C R O S
77
//=======================================================================
78
// Most mallocs have mallinfo()
79
// However, the size is an int, so just about worthless in 64 bit
80
// machines with more than 4Gb ram. But needed on 32 bit machines
81
// that have more than a 1Gbyte of memory, because malloc stops
82
// using sbrk() about at that time (runs out of heap -- use mmap()).
84
// un-define this if your malloc has mallinfo(); see above
92
#include <malloc.h> // mallinfo()
94
struct mallinfo malStart;
96
#define STARTmem malStart = mallinfo() /* works with some mallocs */
99
struct mallinfo malEnd = mallinfo(); \
100
/* strange little dance from signed to unsigned to double */ \
101
unsigned int _un_int = malEnd.arena - malStart.arena; \
102
DeltaMem = _un_int; /* to double */ \
107
// this usually works for machines with less than 1-2Gb RAM.
108
// (it does not include memory ACQUIRED by mmap())
112
#define STARTmem (malStart = (char *)sbrk(0))
115
char *malEnd = (char *)sbrk(0); \
116
DeltaMem = malEnd - malStart; \
121
//=======================================================================
123
// Common macro to handle a failure
124
#define FAILURE(STR, UL) \
126
printf( "Error: %s %lu, file='%s', 'function='%s', line %d\n", \
127
STR, UL, __FILE__, __FUNCTI0N__, __LINE__); \
128
fprintf(stderr, "Error: %s %lu, file='%s', 'function='%s', line %d\n", \
129
STR, UL, __FILE__, __FUNCTI0N__, __LINE__); \
133
// Interations without improvement
134
// Minimum of 2 loops, maximum of 1000000
136
#define MAXLOOPS 1000000
138
// Maximum or 10 loops with no improvement
141
// Structure to keep track of times
142
typedef struct MEASUREMENTS_STRUCT
148
// Specify prototypes for each test routine
149
int NextNumb(Word_t *PNumber, double *PDNumb, double DMult,
152
Word_t TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elems);
154
Word_t TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elems);
156
int TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elems);
158
Word_t TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elems);
160
int TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elems);
162
Word_t TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elems);
164
int TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elems);
166
Word_t TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex,
169
Word_t TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex,
172
//=======================================================================
173
// These are LFSF feedback taps for bitwidths of 10..64 sized numbers.
174
// Tested with Seed=0xc1fc to 35 billion numbers
175
//=======================================================================
177
Word_t StartSeed = 0xc1fc; // default beginning number
180
Word_t MagicList[] = {
181
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0..9
207
0x145f9, // 35 following tested with Seed=0xc1fc to 35 billion numbers
239
// Routine to "mirror" the input data word
243
// BIT REVERSAL, Ron Gutman in Dr. Dobb's Journal, #316, Sept 2000, pp133-136
247
word = ((word & 0x00000000ffffffff) << 32) |
248
((word & 0xffffffff00000000) >> 32);
249
word = ((word & 0x0000ffff0000ffff) << 16) |
250
((word & 0xffff0000ffff0000) >> 16);
251
word = ((word & 0x00ff00ff00ff00ff) << 8) |
252
((word & 0xff00ff00ff00ff00) >> 8);
253
word = ((word & 0x0f0f0f0f0f0f0f0f) << 4) |
254
((word & 0xf0f0f0f0f0f0f0f0) >> 4);
255
word = ((word & 0x3333333333333333) << 2) |
256
((word & 0xcccccccccccccccc) >> 2);
257
word = ((word & 0x5555555555555555) << 1) |
258
((word & 0xaaaaaaaaaaaaaaaa) >> 1);
259
#else // not __LP64__
260
word = ((word & 0x0000ffff) << 16) | ((word & 0xffff0000) >> 16);
261
word = ((word & 0x00ff00ff) << 8) | ((word & 0xff00ff00) >> 8);
262
word = ((word & 0x0f0f0f0f) << 4) | ((word & 0xf0f0f0f0) >> 4);
263
word = ((word & 0x33333333) << 2) | ((word & 0xcccccccc) >> 2);
264
word = ((word & 0x55555555) << 1) | ((word & 0xaaaaaaaa) >> 1);
265
#endif // not __LP64__
270
double DeltaUSec1 = 0.0; // Global for measuring delta times
271
double DeltaUSecL = 0.0; // Global for measuring delta times
273
Word_t J1Flag = 0; // time Judy1
274
Word_t JLFlag = 0; // time JudyL
275
Word_t dFlag = 0; // time Judy1Unset JudyLDel
276
Word_t vFlag = 0; // time Searching
277
Word_t CFlag = 0; // time Counting
278
Word_t IFlag = 0; // time duplicate inserts/sets
279
Word_t DFlag = 0; // bit reverse the data stream
280
Word_t lFlag = 0; // do not do multi-insert tests
281
Word_t aFlag = 0; // output active memory in array
282
Word_t SkipN = 0; // default == Random skip
283
Word_t TValues = 100000; // Maximum retrieve tests for timing
284
Word_t nElms = 1000000; // Max population of arrays
285
Word_t ErrorFlag = 0;
286
Word_t PtsPdec = 40; // measurement points per decade
288
// Stuff for LFSR (pseudo random number generator)
289
Word_t RandomBit = ~0UL / 2 + 1;
290
Word_t BValue = sizeof(Word_t) * 8;
293
// for error routines -- notice misspelling, name conflicts with some compilers
295
#define __FUNCTI0N__ "Random"
297
_INLINE_ Word_t // so INLINING compilers get to look at it.
298
Random(Word_t newseed)
300
if (newseed & RandomBit)
309
newseed &= RandomBit * 2 - 1;
310
if (newseed == FirstSeed)
311
FAILURE("LFSR failed", newseed);
315
_INLINE_ Word_t // so INLINING compilers get to look at it.
316
GetNextIndex(Word_t Index)
321
Index = Random(Index);
327
#define __FUNCTI0N__ "main"
330
main(int argc, char *argv[])
332
// Names of Judy Arrays
333
void *J1 = NULL; // Judy1
334
void *JL = NULL; // JudyL
336
TIMER_vars(tm1); // declare timer variables
337
Word_t Count1, CountL;
343
Word_t PtsPdec = 40; // points per decade
344
Word_t Groups; // Number of measurement groups
353
//============================================================
354
// PARSE INPUT PARAMETERS
355
//============================================================
357
while ((c = getopt(argc, argv, "n:S:T:P:b:B:dDC1LvIla")) != -1)
361
case 'n': // Max population of arrays
362
nElms = strtoul(optarg, NULL, 0); // Size of Linear Array
364
FAILURE("No tests: -n", nElms);
366
// Check if more than a trillion (64 bit only)
367
if ((double)nElms > 1e12)
368
FAILURE("Too many Indexes=", nElms);
371
case 'S': // Step Size, 0 == Random
372
SkipN = strtoul(optarg, NULL, 0);
375
case 'T': // Maximum retrieve tests for timing
376
TValues = strtoul(optarg, NULL, 0);
379
case 'P': // measurement points per decade
380
PtsPdec = strtoul(optarg, NULL, 0);
383
case 'b': // May not work past 35 bits if changed
384
StartSeed = strtoul(optarg, NULL, 0);
387
case 'B': // expanse of data points (random only)
388
BValue = strtoul(optarg, NULL, 0);
391
(MagicList[BValue] == 0) || (BValue > (sizeof(Word_t) * 8)))
394
printf("\nIllegal number of random bits of %lu !!!\n",
400
vFlag = 1; // time Searching
403
case '1': // time Judy1
407
case 'L': // time JudyL
411
case 'd': // time Judy1Unset JudyLDel
415
case 'D': // bit reverse the data stream
419
case 'C': // time Counting
423
case 'I': // time duplicate insert/set
427
case 'l': // do not loop in tests
431
case 'a': // output active memory in Judy array
443
printf("\n%s -n# -P# -S# -B# -T# -b # -DCpdI\n\n", argv[0]);
445
printf("-n <#> number of indexes used in tests\n");
446
printf("-P <#> number measurement points per decade\n");
447
printf("-S <#> index skip amount, 0 = random\n");
448
printf("-B <#> # bits (10..%d) in random number generator\n",
449
(int)sizeof(Word_t) * 8);
450
printf("-L time JudyL\n");
451
printf("-1 time Judy1\n");
452
printf("-I time DUPLICATE Ins/Set times\n");
453
printf("-C time JudyCount tests\n");
454
printf("-v time Judy Search tests\n");
455
printf("-d time JudyDel/Unset instead of JudyFreeArray\n");
456
printf("-l do not loop on same Indexes\n");
457
printf("-T <#> max number indexes in read times - 0 == MAX\n");
463
// If none, then both
464
if (!JLFlag && !J1Flag)
467
// Set number of Random bits in LFSR
468
RandomBit = 1UL << (BValue - 1);
469
Magic = MagicList[BValue];
471
if (nElms > ((RandomBit - 2) * 2))
474
("# Number = -n%lu of Indexes reduced to max expanse of Random numbers\n",
476
nElms = ((RandomBit - 2) * 2);
479
printf("# TITLE %s -n%lu -S%lu -T%lu -B%lu -P%lu",
480
argv[0], nElms, SkipN, TValues, BValue, PtsPdec);
499
if (sizeof(Word_t) == 8)
500
printf("#%s 64 Bit version\n", argv[0]);
501
else if (sizeof(Word_t) == 4)
502
printf("#%s 32 Bit version\n", argv[0]);
504
printf("# XLABEL Population\n");
505
printf("# YLABEL Microseconds / Index\n");
507
//============================================================
508
// CALCULATE NUMBER OF MEASUREMENT GROUPS
509
//============================================================
511
// Calculate Multiplier for number of points per decade
512
Mult = pow(10.0, 1.0 / (double)PtsPdec);
515
Word_t numb, prevnumb;
517
// Count number of measurements needed (10K max)
519
for (Groups = 2; Groups < 10000; Groups++)
520
if (NextNumb(&numb, &sum, Mult, nElms))
523
// Get memory for measurements
524
Pms = (Pms_t) calloc(Groups, sizeof(ms_t));
526
// Now calculate number of Indexes for each measurement point
529
for (grp = 0; grp < Groups; grp++)
531
Pms[grp].ms_delta = numb - prevnumb;
534
NextNumb(&numb, &sum, Mult, nElms);
536
} // Groups = number of sizes
538
//============================================================
539
// PRINT HEADER TO PERFORMANCE TIMERS
540
//============================================================
542
printf("# COLHEAD 1 Population\n");
543
printf("# COLHEAD 2 Measurments\n");
544
printf("# COLHEAD 3 J1S\n");
545
printf("# COLHEAD 4 JLI\n");
546
printf("# COLHEAD 5 J1T\n");
547
printf("# COLHEAD 6 JLG\n");
552
printf("# COLHEAD %d J1S-dup\n", Col++);
553
printf("# COLHEAD %d JLI-dup\n", Col++);
557
printf("# COLHEAD %d J1C\n", Col++);
558
printf("# COLHEAD %d JLC\n", Col++);
562
printf("# COLHEAD %d J1N\n", Col++);
563
printf("# COLHEAD %d JLN\n", Col++);
564
printf("# COLHEAD %d J1P\n", Col++);
565
printf("# COLHEAD %d JLP\n", Col++);
566
printf("# COLHEAD %d J1NE\n", Col++);
567
printf("# COLHEAD %d JLNE\n", Col++);
568
printf("# COLHEAD %d J1PE\n", Col++);
569
printf("# COLHEAD %d JLPE\n", Col++);
573
printf("# COLHEAD %d J1U\n", Col++);
574
printf("# COLHEAD %d JLD\n", Col++);
576
printf("# COLHEAD %d J1MU/I\n", Col++);
577
printf("# COLHEAD %d JLMU/I\n", Col++);
580
printf("# COLHEAD %d J1MA/I\n", Col++);
581
printf("# COLHEAD %d JLMA/I\n", Col++);
583
printf("# COLHEAD %d HEAP/I\n", Col++);
585
printf("# %s\n", Judy1MallocSizes);
586
printf("# %s\n", JudyLMallocSizes);
588
printf("# Pop1 Measmts J1S JLI J1T JLG");
591
printf(" dupJ1S dupJLI");
597
printf(" J1N JLN J1P JLP J1NE JLNE J1PE JLPE");
602
printf(" J1MU/I JLMU/I");
605
printf(" J1MA/I JLMA/I");
612
//============================================================
613
// BEGIN TESTS AT EACH GROUP SIZE
614
//============================================================
616
// Get the kicker to test the LFSR
617
FirstSeed = Seed = StartSeed & (RandomBit * 2 - 1);
620
for (Pop1 = grp = 0; grp < Groups; grp++)
622
Word_t LowIndex, HighIndex;
626
Delta = Pms[grp].ms_delta;
629
NewSeed = TestJudyIns(&J1, &JL, Seed, Delta);
631
// Accumulate the Total population of arrays
635
// Only test the maximum of TValues if not zero
637
Meas = (Pop1 < TValues) ? Pop1 : TValues;
639
printf("%10lu %9lu", Pop1, Meas);
640
printf(" %6.3f", DeltaUSec1);
641
printf(" %6.3f", DeltaUSecL);
645
LowIndex = TestJudyGet(J1, JL, FirstSeed, Meas);
646
printf(" %6.3f", DeltaUSec1);
647
printf(" %6.3f", DeltaUSecL);
649
// Test J1T, JLI - duplicates
653
LowIndex = TestJudyDup(&J1, &JL, FirstSeed, Meas);
654
printf(" %6.3f", DeltaUSec1);
655
printf(" %6.3f", DeltaUSecL);
659
TestJudyCount(J1, JL, LowIndex, Meas);
660
printf(" %6.3f", DeltaUSec1);
661
printf(" %6.3f", DeltaUSecL);
666
HighIndex = TestJudyNext(J1, JL, LowIndex, Meas);
667
printf(" %6.3f", DeltaUSec1);
668
printf(" %6.3f", DeltaUSecL);
671
TestJudyPrev(J1, JL, HighIndex, Meas);
672
printf(" %6.3f", DeltaUSec1);
673
printf(" %6.3f", DeltaUSecL);
676
TestJudyNextEmpty(J1, JL, LowIndex, Meas);
677
printf(" %6.3f", DeltaUSec1);
678
printf(" %6.3f", DeltaUSecL);
681
TestJudyPrevEmpty(J1, JL, HighIndex, Meas);
682
printf(" %6.3f", DeltaUSec1);
683
printf(" %6.3f", DeltaUSecL);
689
TestJudyDel(&J1, &JL, FirstSeed, Meas);
690
printf(" %6.3f", DeltaUSec1);
691
printf(" %6.3f", DeltaUSecL);
694
TestJudyIns(&J1, &JL, FirstSeed, Meas);
697
// Advance Index number set
700
// Print the number of bytes used per Index
701
printf(" %6.3f", (double)Judy1MemUsed(J1) / (double)Pop1);
702
printf(" %6.3f", (double)JudyLMemUsed(JL) / (double)Pop1);
705
printf(" %6.3f", (double)Judy1MemActive(J1) / (double)Pop1);
706
printf(" %6.3f", (double)JudyLMemActive(JL) / (double)Pop1);
710
printf(" %6.3f", DeltaMem / (double)Pop1);
712
fflush(NULL); // assure data gets to file in case malloc fail
715
JLC(CountL, JL, 0, -1); // get the counts
716
J1C(Count1, J1, 0, -1);
718
if (JLFlag && J1Flag)
720
if (CountL != Count1)
721
FAILURE("Judy1/LCount not equal", Count1);
727
J1FA(Bytes, J1); // Free the Judy1 Array
728
ENDTm(DeltaUSec1, tm1);
729
DeltaUSec1 /= (double)Count1;
731
printf("# Judy1FreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n",
732
Count1, (double)Bytes / (double)Count1, DeltaUSec1);
738
JLFA(Bytes, JL); // Free the JudyL Array
739
ENDTm(DeltaUSecL, tm1);
740
DeltaUSecL /= (double)CountL;
742
printf("# JudyLFreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n",
743
CountL, (double)Bytes / (double)CountL, DeltaUSecL);
749
#define __FUNCTI0N__ "TestJudyIns"
752
TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elements)
754
TIMER_vars(tm1); // declare timer variables
767
Loops = (MAXLOOPS / Elements) + MINLOOPS;
778
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
782
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
784
Seed1 = GetNextIndex(Seed1);
787
TstIndex = Swizzle(Seed1);
791
J1U(Rc, *J1, TstIndex);
796
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
798
Seed1 = GetNextIndex(Seed1);
801
TstIndex = Swizzle(Seed1);
805
J1S(Rc, *J1, TstIndex);
807
FAILURE("Judy1Set failed - DUP Index at", elm);
809
ENDTm(DeltaUSec1, tm1);
811
if (DDel > DeltaUSec1)
822
DeltaUSec1 = DDel / (double)Elements;
829
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
833
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
835
Seed1 = GetNextIndex(Seed1);
838
TstIndex = Swizzle(Seed1);
842
JLD(Rc, *JL, TstIndex);
847
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
849
Seed1 = GetNextIndex(Seed1);
852
TstIndex = Swizzle(Seed1);
856
JLI(PValue, *JL, TstIndex);
857
if (*PValue == TstIndex)
858
FAILURE("JudyLIns failed - DUP Index", TstIndex);
860
*PValue = TstIndex; // save Index in Value
862
ENDTm(DeltaUSecL, tm1);
863
DeltaUSecL /= Elements;
865
if (DDel > DeltaUSecL)
877
return (Seed1); // New seed
881
#define __FUNCTI0N__ "TestJudyDup"
884
TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elements)
886
TIMER_vars(tm1); // declare timer variables
887
Word_t LowIndex = ~0UL;
899
Loops = (MAXLOOPS / Elements) + MINLOOPS;
904
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
907
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
909
Seed1 = GetNextIndex(Seed1);
912
TstIndex = Swizzle(Seed1);
916
if (TstIndex < LowIndex)
919
J1S(Rc, *J1, TstIndex);
921
FAILURE("Judy1Test Rc != 0", (Word_t)Rc);
923
ENDTm(DeltaUSec1, tm1);
925
if (DDel > DeltaUSec1)
936
DeltaUSec1 = DDel / (double)Elements;
944
for (DDel = 1e40, lp = 0; lp < Loops; lp++)
947
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
949
Seed1 = GetNextIndex(Seed1);
952
TstIndex = Swizzle(Seed1);
956
if (TstIndex < LowIndex)
959
JLI(PValue, *JL, TstIndex);
960
if (PValue == (Word_t *)NULL)
961
FAILURE("JudyLGet ret PValue = NULL", 0L);
962
if (*PValue != TstIndex)
963
FAILURE("JudyLGet ret wrong Value at", elm);
965
ENDTm(DeltaUSecL, tm1);
967
if (DDel > DeltaUSecL)
978
DeltaUSecL = DDel / (double)Elements;
985
#define __FUNCTI0N__ "TestJudyGet"
988
TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elements)
990
TIMER_vars(tm1); // declare timer variables
991
Word_t LowIndex = ~0UL;
1003
Loops = (MAXLOOPS / Elements) + MINLOOPS;
1008
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1011
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
1013
Seed1 = GetNextIndex(Seed1);
1016
TstIndex = Swizzle(Seed1);
1020
if (TstIndex < LowIndex)
1021
LowIndex = TstIndex;
1023
J1T(Rc, J1, TstIndex);
1025
FAILURE("Judy1Test Rc != 1", (Word_t)Rc);
1027
ENDTm(DeltaUSec1, tm1);
1029
if (DDel > DeltaUSec1)
1040
DeltaUSec1 = DDel / (double)Elements;
1048
for (DDel = 1e40, lp = 0; lp < Loops; lp++)
1051
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
1053
Seed1 = GetNextIndex(Seed1);
1056
TstIndex = Swizzle(Seed1);
1060
if (TstIndex < LowIndex)
1061
LowIndex = TstIndex;
1063
JLG(PValue, JL, TstIndex);
1064
if (PValue == (Word_t *)NULL)
1065
FAILURE("JudyLGet ret PValue = NULL", 0L);
1066
if (*PValue != TstIndex)
1067
FAILURE("JudyLGet ret wrong Value at", elm);
1069
ENDTm(DeltaUSecL, tm1);
1071
if (DDel > DeltaUSecL)
1082
DeltaUSecL = DDel / (double)Elements;
1089
#define __FUNCTI0N__ "TestJudyCount"
1092
TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements)
1094
TIMER_vars(tm1); // declare timer variables
1096
Word_t Count1, CountL;
1097
Word_t TstIndex = LowIndex;
1105
Loops = (MAXLOOPS / Elements) + MINLOOPS;
1109
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1111
TstIndex = LowIndex;
1113
for (elm = 0; elm < Elements; elm++)
1115
J1C(Count1, J1, LowIndex, TstIndex);
1117
if (Count1 != (elm + 1))
1118
FAILURE("J1C at", elm);
1120
J1N(Rc, J1, TstIndex);
1122
ENDTm(DeltaUSec1, tm1);
1124
if (DDel > DeltaUSec1)
1135
DeltaUSec1 = DDel / (double)Elements;
1140
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1142
TstIndex = LowIndex;
1144
for (elm = 0; elm < Elements; elm++)
1148
JLC(CountL, JL, LowIndex, TstIndex);
1150
if (CountL != (elm + 1))
1151
FAILURE("JLC at", elm);
1153
JLN(PValue, JL, TstIndex);
1155
ENDTm(DeltaUSecL, tm1);
1157
if (DDel > DeltaUSecL)
1168
DeltaUSecL = DDel / (double)Elements;
1175
#define __FUNCTI0N__ "TestJudyNext"
1178
TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements)
1180
TIMER_vars(tm1); // declare timer variables
1189
Loops = (MAXLOOPS / Elements) + MINLOOPS;
1193
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1199
J1F(Rc, J1, Jindex);
1201
for (elm = 0; elm < Elements; elm++)
1204
FAILURE("Judy1Next Rc != 1 =", (Word_t)Rc);
1206
J1N(Rc, J1, Jindex); // Get next one
1208
ENDTm(DeltaUSec1, tm1);
1210
if (DDel > DeltaUSec1)
1221
DeltaUSec1 = DDel / (double)Elements;
1226
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1230
// Get an Index low enough for Elements
1234
JLF(PValue, JL, Jindex);
1236
for (elm = 0; elm < Elements; elm++)
1239
FAILURE("JudyLNext ret NULL PValue at", elm);
1241
JLN(PValue, JL, Jindex); // Get next one
1243
ENDTm(DeltaUSecL, tm1);
1245
if (DDel > DeltaUSecL)
1256
DeltaUSecL = DDel / (double)Elements;
1259
// perhaps a check should be done here -- if I knew what to expect.
1260
return (Jindex); // return last one
1264
#define __FUNCTI0N__ "TestJudyPrev"
1267
TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements)
1269
TIMER_vars(tm1); // declare timer variables
1277
Loops = (MAXLOOPS / Elements) + MINLOOPS;
1281
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1283
Word_t J1index = HighIndex;
1287
J1L(Rc, J1, J1index);
1289
for (elm = 0; elm < Elements; elm++)
1292
FAILURE("Judy1Prev Rc != 1 =", (Word_t)Rc);
1294
J1P(Rc, J1, J1index); // Get previous one
1296
ENDTm(DeltaUSec1, tm1);
1298
if (DDel > DeltaUSec1)
1309
DeltaUSec1 = DDel / (double)Elements;
1314
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1317
Word_t JLindex = HighIndex;
1320
JLL(PValue, JL, JLindex);
1322
for (elm = 0; elm < Elements; elm++)
1325
FAILURE("JudyLPrev ret NULL PValue at", elm);
1327
JLP(PValue, JL, JLindex); // Get previous one
1329
ENDTm(DeltaUSecL, tm1);
1331
if (DDel > DeltaUSecL)
1342
DeltaUSecL = DDel / (double)Elements;
1345
// perhaps a check should be done here -- if I knew what to expect.
1350
#define __FUNCTI0N__ "TestJudyNextEmpty"
1352
// Returns number of consecutive Indexes
1354
TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements)
1356
TIMER_vars(tm1); // declare timer variables
1363
int Rc; // Return code
1365
Loops = (MAXLOOPS / Elements) + MINLOOPS;
1369
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1371
Word_t Seed1 = LowIndex;
1374
for (elm = 0; elm < Elements; elm++)
1379
// Find next Empty Index, J1index is modified by J1NE
1380
J1NE(Rc, J1, J1index); // Rc = Judy1NextEmpty(J1, &J1index,PJE0)
1383
FAILURE("Judy1NextEmpty Rcode != 1 =", (Word_t)Rc);
1385
Seed1 = GetNextIndex(Seed1);
1387
ENDTm(DeltaUSec1, tm1);
1389
if (DDel > DeltaUSec1)
1400
DeltaUSec1 = DDel / (double)Elements;
1405
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1407
Word_t Seed1 = LowIndex;
1410
for (elm = 0; elm < Elements; elm++)
1415
// Find next Empty Index, JLindex is modified by JLNE
1416
JLNE(Rc, JL, JLindex); // Rc = JudyLNextEmpty(JL, &JLindex,PJE0)
1419
FAILURE("JudyLNextEmpty Rcode != 1 =", (Word_t)Rc);
1421
Seed1 = GetNextIndex(Seed1);
1423
ENDTm(DeltaUSecL, tm1);
1425
if (DDel > DeltaUSecL)
1436
DeltaUSecL = DDel / (double)Elements;
1442
// Routine to time and test JudyPrevEmpty routines
1445
#define __FUNCTI0N__ "TestJudyPrevEmpty"
1448
TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements)
1450
TIMER_vars(tm1); // declare timer variables
1459
Loops = (MAXLOOPS / Elements) + MINLOOPS;
1463
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1465
Word_t Seed1 = HighIndex;
1468
for (elm = 0; elm < Elements; elm++)
1473
J1PE(Rc, J1, J1index); // Rc = Judy1PrevEmpty(J1, &J1index,PJE0)
1476
FAILURE("Judy1PrevEmpty Rc != 1 =", (Word_t)Rc);
1478
Seed1 = GetNextIndex(Seed1);
1480
ENDTm(DeltaUSec1, tm1);
1482
if (DDel > DeltaUSec1)
1493
DeltaUSec1 = DDel / (double)Elements;
1498
for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
1500
Word_t Seed1 = HighIndex;
1503
for (elm = 0; elm < Elements; elm++)
1508
// Find next Empty Index, JLindex is modified by JLPE
1509
JLPE(Rc, JL, JLindex); // Rc = JudyLPrevEmpty(JL, &JLindex,PJE0)
1512
FAILURE("JudyLPrevEmpty Rcode != 1 =", (Word_t)Rc);
1514
Seed1 = GetNextIndex(Seed1);
1516
ENDTm(DeltaUSecL, tm1);
1518
if (DDel > DeltaUSecL)
1529
DeltaUSecL = DDel / (double)Elements;
1536
#define __FUNCTI0N__ "TestJudyDel"
1539
TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elements)
1541
TIMER_vars(tm1); // declare timer variables
1550
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
1552
Seed1 = GetNextIndex(Seed1);
1555
TstIndex = Swizzle(Seed1);
1559
J1U(Rc, *J1, TstIndex);
1561
FAILURE("Judy1Unset ret Rcode != 1", (Word_t)Rc);
1563
ENDTm(DeltaUSec1, tm1);
1564
DeltaUSec1 /= Elements;
1570
for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
1572
Seed1 = GetNextIndex(Seed1);
1575
TstIndex = Swizzle(Seed1);
1579
JLD(Rc, *JL, TstIndex);
1581
FAILURE("JudyLDel ret Rcode != 1", (Word_t)Rc);
1583
ENDTm(DeltaUSecL, tm1);
1584
DeltaUSecL /= Elements;
1589
// Routine to get next size of Indexes
1590
int // return 1 if last number
1591
NextNumb(Word_t *PNumber, // pointer to returned next number
1592
double *PDNumb, // Temp double of above
1593
double DMult, // Multiplier
1594
Word_t MaxNumb) // Max number to return
1599
Word_t PrevNumb = *PNumber;
1601
// Verify integer number increased
1602
for (num = 0; num < 1000; num++)
1607
// Return it in integer format
1608
*PNumber = (Word_t)(*PDNumb + 0.5);
1610
if (*PNumber != PrevNumb)
1614
// Verify it did not exceed max number
1615
if ((*PDNumb + 0.5) > (double)MaxNumb)
1617
// it did, so return max
1619
return (1); // flag it
1621
return (0); // more available