Alien-Judy

 view release on metacpan or  search on metacpan

src/judy-1.0.5/test/Judy1LTime.c  view on Meta::CPAN

// @(#) $Revision: 4.20 $ $Source: /judy/test/manual/Judy1LTime.c $
//=======================================================================
//      This program measures the performance of a Judy1 and JudyL Array.
//                      -by- 
//      Douglas L. Baskins (8/2001)  doug@sourcejudy.com
//=======================================================================

#include <unistd.h>             // sbrk()
#include <stdlib.h>             // exit()
#include <stdio.h>              // printf()
#include <math.h>               // pow()
#include <sys/time.h>           // gettimeofday()
#include <Judy.h>               // for Judy macros J*()

#ifdef NOINLINE                 /* this is the 21st century? */
#define _INLINE_ static
#else
#define _INLINE_ inline
#endif


//=======================================================================
//      C O M P I L E D:
//=======================================================================
//
//      cc -static -O3 Judy1LTime.c -lJudy -lm
//
//  the -static is for a little better performace on some platforms
//
//  if optional high-resolution timers are desired:
//
//      cc -static -O3 -DJU_LINUX_IA32 Judy1LTime.c -lJudy -lm
//
//  and read below:
//  
//=======================================================================
//      T I M I N G   M A C R O S
//=======================================================================
// if your machine is one of the supported types in the following header
// file then uncomment this corresponding to what the header file says.
// This will give very high timing resolution.
//
// #define JU_xxxxxxx 1         // read timeit.h
// #define JU_LINUX_IA32 1      // I.E. IA32 Linux
//
#include "timeit.h"             // optional for high resolution times

double    DeltaUSec;            // Global for remembering delta times

#ifndef _TIMEIT_H

// Note: I have found some Linux systems (2.4.18-6mdk) have bugs in the 
// gettimeofday() routine.  Sometimes the difference of two consective calls 
// returns a negative ~2840 microseconds instead of 0 or 1.  If you use the 
// above #include "timeit.h" and compile with timeit.c and use 
// -DJU_LINUX_IA32, that problem will be eliminated.  This is because for 
// delta times less than .1 sec, the hardware free running timer is used 
// instead of gettimeofday().  I have found the negative time problem
// appears about 40-50 times per second with numerous gettimeofday() calls.
// You should just ignore negative times output.

#define TIMER_vars(T) struct timeval __TVBeg_##T, __TVEnd_##T

#define STARTTm(T) gettimeofday(&__TVBeg_##T, NULL)

#define ENDTm(D,T)                                                      \
{                                                                       \
    gettimeofday(&__TVEnd_##T, NULL);                                   \
    (D) = (double)(__TVEnd_##T.tv_sec  - __TVBeg_##T.tv_sec) * 1E6 +    \
         ((double)(__TVEnd_##T.tv_usec - __TVBeg_##T.tv_usec));         \
}

#endif // _TIMEIT_H

//=======================================================================
//      M E M O R Y   S I Z E   M A C R O S
//=======================================================================
//      Most mallocs have mallinfo()
//      However, the size is an int, so just about worthless in 64 bit
//      machines with more than 4Gb ram.  But needed on 32 bit machines 
//      that have more than a 1Gbyte of memory, because malloc stops
//      using sbrk() about at that time (runs out of heap -- use mmap()).

// un-define this if your malloc has mallinfo(); see above

#define NOMALLINFO 1

double    DeltaMem;

#ifndef NOMALLINFO

#include <malloc.h>             // mallinfo()

struct mallinfo malStart;

#define STARTmem malStart = mallinfo() /* works with some mallocs */
#define ENDmem                                                  \
{                                                               \
    struct mallinfo malEnd = mallinfo();                        \
/* strange little dance from signed to unsigned to double */    \
    unsigned int _un_int = malEnd.arena - malStart.arena;       \
    DeltaMem = _un_int;      /* to double */                    \
}

#else // MALLINFO

// this usually works for machines with less than 1-2Gb RAM.
// (it does not include memory ACQUIRED by mmap())

char     *malStart;

#define STARTmem (malStart = (char *)sbrk(0))
#define ENDmem                                                  \
{                                                               \
    char  *malEnd =  (char *)sbrk(0);                           \
    DeltaMem = malEnd - malStart;                               \
}

src/judy-1.0.5/test/Judy1LTime.c  view on Meta::CPAN

Word_t    vFlag = 0;            // time Searching 
Word_t    CFlag = 0;            // time Counting
Word_t    IFlag = 0;            // time duplicate inserts/sets
Word_t    DFlag = 0;            // bit reverse the data stream
Word_t    lFlag = 0;            // do not do multi-insert tests
Word_t    aFlag = 0;            // output active memory in array
Word_t    SkipN = 0;            // default == Random skip
Word_t    TValues = 100000;     // Maximum retrieve tests for timing
Word_t    nElms = 1000000;      // Max population of arrays
Word_t    ErrorFlag = 0;
Word_t    PtsPdec = 40;         // measurement points per decade

// Stuff for LFSR (pseudo random number generator)
Word_t    RandomBit = ~0UL / 2 + 1;
Word_t    BValue = sizeof(Word_t) * 8;
Word_t    Magic;

// for error routines -- notice misspelling, name conflicts with some compilers 
#undef __FUNCTI0N__
#define __FUNCTI0N__ "Random"

_INLINE_ Word_t                 // so INLINING compilers get to look at it.
Random(Word_t newseed)
{
    if (newseed & RandomBit)
    {
        newseed += newseed;
        newseed ^= Magic;
    }
    else
    {
        newseed += newseed;
    }
    newseed &= RandomBit * 2 - 1;
    if (newseed == FirstSeed)
        FAILURE("LFSR failed", newseed);
    return (newseed);
}

_INLINE_ Word_t                 // so INLINING compilers get to look at it.
GetNextIndex(Word_t Index)
{
    if (SkipN)
        Index += SkipN;
    else
        Index = Random(Index);

    return (Index);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "main"

int
main(int argc, char *argv[])
{
//  Names of Judy Arrays
    void     *J1 = NULL;        // Judy1
    void     *JL = NULL;        // JudyL

    TIMER_vars(tm1);            // declare timer variables
    Word_t    Count1, CountL;
    Word_t    Bytes;

    double    Mult;
    Pms_t     Pms;
    Word_t    Seed;
    Word_t    PtsPdec = 40;     // points per decade
    Word_t    Groups;           // Number of measurement groups
    Word_t    grp;
    Word_t    Pop1;
    Word_t    Meas;
    int       Col;

    int       c;
    extern char *optarg;

//============================================================
// PARSE INPUT PARAMETERS
//============================================================

    while ((c = getopt(argc, argv, "n:S:T:P:b:B:dDC1LvIla")) != -1)
    {
        switch (c)
        {
        case 'n':              // Max population of arrays
            nElms = strtoul(optarg, NULL, 0); // Size of Linear Array
            if (nElms == 0)
                FAILURE("No tests: -n", nElms);

//          Check if more than a trillion (64 bit only)
            if ((double)nElms > 1e12)
                FAILURE("Too many Indexes=", nElms);
            break;

        case 'S':              // Step Size, 0 == Random
            SkipN = strtoul(optarg, NULL, 0);
            break;

        case 'T':              // Maximum retrieve tests for timing 
            TValues = strtoul(optarg, NULL, 0);
            break;

        case 'P':              // measurement points per decade
            PtsPdec = strtoul(optarg, NULL, 0);
            break;

        case 'b':              // May not work past 35 bits if changed
            StartSeed = strtoul(optarg, NULL, 0);
            break;

        case 'B':              // expanse of data points (random only)
            BValue = strtoul(optarg, NULL, 0);
            if ((BValue > 64)
                ||
                (MagicList[BValue] == 0) || (BValue > (sizeof(Word_t) * 8)))
            {
                ErrorFlag++;
                printf("\nIllegal number of random bits of %lu !!!\n",
                       BValue);
            }

src/judy-1.0.5/test/Judy1LTime.c  view on Meta::CPAN

            TestJudyIns(&J1, &JL, FirstSeed, Meas);
        }

//      Advance Index number set
        Seed = NewSeed;

//      Print the number of bytes used per Index
        printf(" %6.3f", (double)Judy1MemUsed(J1) / (double)Pop1);
        printf(" %6.3f", (double)JudyLMemUsed(JL) / (double)Pop1);
        if (aFlag)
        {
            printf(" %6.3f", (double)Judy1MemActive(J1) / (double)Pop1);
            printf(" %6.3f", (double)JudyLMemActive(JL) / (double)Pop1);
        }

        ENDmem;
        printf(" %6.3f", DeltaMem / (double)Pop1);
        printf("\n");
        fflush(NULL);           // assure data gets to file in case malloc fail
    }

    JLC(CountL, JL, 0, -1);     // get the counts
    J1C(Count1, J1, 0, -1);

    if (JLFlag && J1Flag)
    {
        if (CountL != Count1)
            FAILURE("Judy1/LCount not equal", Count1);
    }

    if (Count1)
    {
        STARTTm(tm1);
        J1FA(Bytes, J1);        // Free the Judy1 Array
        ENDTm(DeltaUSec1, tm1);
        DeltaUSec1 /= (double)Count1;

        printf("# Judy1FreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n",
               Count1, (double)Bytes / (double)Count1, DeltaUSec1);
    }

    if (CountL)
    {
        STARTTm(tm1);
        JLFA(Bytes, JL);        // Free the JudyL Array
        ENDTm(DeltaUSecL, tm1);
        DeltaUSecL /= (double)CountL;

        printf("# JudyLFreeArray: %lu, %0.3f bytes/Index, %0.3f USec/Index\n",
               CountL, (double)Bytes / (double)CountL, DeltaUSecL);
    }
    exit(0);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyIns"

Word_t
TestJudyIns(void **J1, void **JL, Word_t Seed, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    TstIndex;
    Word_t    elm;
    Word_t   *PValue;
    Word_t    Seed1 = 0;
    int       Rc;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;

    if (Elements < 100)
        Loops = (MAXLOOPS / Elements) + MINLOOPS;
    else
        Loops = 1;

    if (lFlag)
        Loops = 1;

//  Judy1Set timings

    if (J1Flag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            if (lp != 0)
            {
                for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
                {
                    Seed1 = GetNextIndex(Seed1);

                    if (DFlag)
                        TstIndex = Swizzle(Seed1);
                    else
                        TstIndex = Seed1;

                    J1U(Rc, *J1, TstIndex);
                }
            }

            STARTTm(tm1);
            for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
            {
                Seed1 = GetNextIndex(Seed1);

                if (DFlag)
                    TstIndex = Swizzle(Seed1);
                else
                    TstIndex = Seed1;

                J1S(Rc, *J1, TstIndex);
                if (Rc == 0)
                    FAILURE("Judy1Set failed - DUP Index at", elm);
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;

src/judy-1.0.5/test/Judy1LTime.c  view on Meta::CPAN


    if (JLFlag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            if (lp != 0)
            {
                for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
                {
                    Seed1 = GetNextIndex(Seed1);

                    if (DFlag)
                        TstIndex = Swizzle(Seed1);
                    else
                        TstIndex = Seed1;

                    JLD(Rc, *JL, TstIndex);
                }
            }

            STARTTm(tm1);
            for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
            {
                Seed1 = GetNextIndex(Seed1);

                if (DFlag)
                    TstIndex = Swizzle(Seed1);
                else
                    TstIndex = Seed1;

                JLI(PValue, *JL, TstIndex);
                if (*PValue == TstIndex)
                    FAILURE("JudyLIns failed - DUP Index", TstIndex);

                *PValue = TstIndex; // save Index in Value
            }
            ENDTm(DeltaUSecL, tm1);
            DeltaUSecL /= Elements;

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
    }
    return (Seed1);             // New seed
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyDup"

Word_t
TestJudyDup(void **J1, void **JL, Word_t Seed, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    LowIndex = ~0UL;
    Word_t    TstIndex;
    Word_t    elm;
    Word_t   *PValue;
    Word_t    Seed1;
    int       Rc;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        LowIndex = ~0UL;
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            STARTTm(tm1);
            for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
            {
                Seed1 = GetNextIndex(Seed1);

                if (DFlag)
                    TstIndex = Swizzle(Seed1);
                else
                    TstIndex = Seed1;

                if (TstIndex < LowIndex)
                    LowIndex = TstIndex;

                J1S(Rc, *J1, TstIndex);
                if (Rc != 0)
                    FAILURE("Judy1Test Rc != 0", (Word_t)Rc);
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    icnt = ICNT;

    if (JLFlag)
    {
        LowIndex = ~0UL;
        for (DDel = 1e40, lp = 0; lp < Loops; lp++)
        {
            STARTTm(tm1);
            for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
            {
                Seed1 = GetNextIndex(Seed1);

                if (DFlag)
                    TstIndex = Swizzle(Seed1);
                else
                    TstIndex = Seed1;

                if (TstIndex < LowIndex)
                    LowIndex = TstIndex;

                JLI(PValue, *JL, TstIndex);
                if (PValue == (Word_t *)NULL)
                    FAILURE("JudyLGet ret PValue = NULL", 0L);
                if (*PValue != TstIndex)
                    FAILURE("JudyLGet ret wrong Value at", elm);
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

    return (LowIndex);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyGet"

Word_t
TestJudyGet(void *J1, void *JL, Word_t Seed, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    LowIndex = ~0UL;
    Word_t    TstIndex;
    Word_t    elm;
    Word_t   *PValue;
    Word_t    Seed1;
    int       Rc;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        LowIndex = ~0UL;
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            STARTTm(tm1);
            for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
            {
                Seed1 = GetNextIndex(Seed1);

                if (DFlag)
                    TstIndex = Swizzle(Seed1);
                else
                    TstIndex = Seed1;

                if (TstIndex < LowIndex)
                    LowIndex = TstIndex;

                J1T(Rc, J1, TstIndex);
                if (Rc != 1)
                    FAILURE("Judy1Test Rc != 1", (Word_t)Rc);
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    icnt = ICNT;

    if (JLFlag)
    {
        LowIndex = ~0UL;
        for (DDel = 1e40, lp = 0; lp < Loops; lp++)
        {
            STARTTm(tm1);
            for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
            {
                Seed1 = GetNextIndex(Seed1);

                if (DFlag)
                    TstIndex = Swizzle(Seed1);
                else
                    TstIndex = Seed1;

                if (TstIndex < LowIndex)
                    LowIndex = TstIndex;

                JLG(PValue, JL, TstIndex);
                if (PValue == (Word_t *)NULL)
                    FAILURE("JudyLGet ret PValue = NULL", 0L);
                if (*PValue != TstIndex)
                    FAILURE("JudyLGet ret wrong Value at", elm);
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

    return (LowIndex);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyCount"

int
TestJudyCount(void *J1, void *JL, Word_t LowIndex, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    elm;
    Word_t    Count1, CountL;
    Word_t    TstIndex = LowIndex;
    int       Rc;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            TstIndex = LowIndex;
            STARTTm(tm1);
            for (elm = 0; elm < Elements; elm++)
            {
                J1C(Count1, J1, LowIndex, TstIndex);

                if (Count1 != (elm + 1))
                    FAILURE("J1C at", elm);

                J1N(Rc, J1, TstIndex);
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    if (JLFlag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            TstIndex = LowIndex;
            STARTTm(tm1);
            for (elm = 0; elm < Elements; elm++)
            {
                Word_t   *PValue;

                JLC(CountL, JL, LowIndex, TstIndex);

                if (CountL != (elm + 1))
                    FAILURE("JLC at", elm);

                JLN(PValue, JL, TstIndex);
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

    return (0);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyNext"

Word_t
TestJudyNext(void *J1, void *JL, Word_t LowIndex, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    elm;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;
    Word_t    Jindex;

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            int       Rc;
            Jindex = LowIndex;

            STARTTm(tm1);
            J1F(Rc, J1, Jindex);

            for (elm = 0; elm < Elements; elm++)
            {
                if (Rc != 1)
                    FAILURE("Judy1Next Rc != 1 =", (Word_t)Rc);

                J1N(Rc, J1, Jindex); // Get next one
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    if (JLFlag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t   *PValue;

//      Get an Index low enough for Elements
            Jindex = LowIndex;

            STARTTm(tm1);
            JLF(PValue, JL, Jindex);

            for (elm = 0; elm < Elements; elm++)
            {
                if (PValue == NULL)
                    FAILURE("JudyLNext ret NULL PValue at", elm);

                JLN(PValue, JL, Jindex); // Get next one
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

//  perhaps a check should be done here -- if I knew what to expect.
    return (Jindex);            // return last one
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyPrev"

int
TestJudyPrev(void *J1, void *JL, Word_t HighIndex, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    elm;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t    J1index = HighIndex;
            int       Rc;

            STARTTm(tm1);
            J1L(Rc, J1, J1index);

            for (elm = 0; elm < Elements; elm++)
            {
                if (Rc != 1)
                    FAILURE("Judy1Prev Rc != 1 =", (Word_t)Rc);

                J1P(Rc, J1, J1index); // Get previous one
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    if (JLFlag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t   *PValue;
            Word_t    JLindex = HighIndex;

            STARTTm(tm1);
            JLL(PValue, JL, JLindex);

            for (elm = 0; elm < Elements; elm++)
            {
                if (PValue == NULL)
                    FAILURE("JudyLPrev ret NULL PValue at", elm);

                JLP(PValue, JL, JLindex); // Get previous one
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

//  perhaps a check should be done here -- if I knew what to expect.
    return (0);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyNextEmpty"

// Returns number of consecutive Indexes
Word_t
TestJudyNextEmpty(void *J1, void *JL, Word_t LowIndex, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    elm;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;
    int       Rc;               // Return code

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t    Seed1 = LowIndex;

            STARTTm(tm1);
            for (elm = 0; elm < Elements; elm++)
            {
                Word_t    J1index;
                J1index = Seed1;

//          Find next Empty Index, J1index is modified by J1NE
                J1NE(Rc, J1, J1index); // Rc = Judy1NextEmpty(J1, &J1index,PJE0)

                if (Rc != 1)
                    FAILURE("Judy1NextEmpty Rcode != 1 =", (Word_t)Rc);

                Seed1 = GetNextIndex(Seed1);
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    if (JLFlag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t    Seed1 = LowIndex;

            STARTTm(tm1);
            for (elm = 0; elm < Elements; elm++)
            {
                Word_t    JLindex;
                JLindex = Seed1;

//          Find next Empty Index, JLindex is modified by JLNE
                JLNE(Rc, JL, JLindex); // Rc = JudyLNextEmpty(JL, &JLindex,PJE0)

                if (Rc != 1)
                    FAILURE("JudyLNextEmpty Rcode != 1 =", (Word_t)Rc);

                Seed1 = GetNextIndex(Seed1);
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

    return (0);
}

// Routine to time and test JudyPrevEmpty routines

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyPrevEmpty"

Word_t
TestJudyPrevEmpty(void *J1, void *JL, Word_t HighIndex, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    elm;

    double    DDel;
    Word_t    icnt;
    Word_t    lp;
    Word_t    Loops;
    int       Rc;

    Loops = (MAXLOOPS / Elements) + MINLOOPS;

    if (J1Flag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t    Seed1 = HighIndex;

            STARTTm(tm1);
            for (elm = 0; elm < Elements; elm++)
            {
                Word_t    J1index;
                J1index = Seed1;

                J1PE(Rc, J1, J1index); // Rc = Judy1PrevEmpty(J1, &J1index,PJE0)

                if (Rc != 1)
                    FAILURE("Judy1PrevEmpty Rc != 1 =", (Word_t)Rc);

                Seed1 = GetNextIndex(Seed1);
            }
            ENDTm(DeltaUSec1, tm1);

            if (DDel > DeltaUSec1)
            {
                icnt = ICNT;
                DDel = DeltaUSec1;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSec1 = DDel / (double)Elements;
    }

    if (JLFlag)
    {
        for (DDel = 1e40, icnt = ICNT, lp = 0; lp < Loops; lp++)
        {
            Word_t    Seed1 = HighIndex;

            STARTTm(tm1);
            for (elm = 0; elm < Elements; elm++)
            {
                Word_t    JLindex;
                JLindex = Seed1;

//          Find next Empty Index, JLindex is modified by JLPE
                JLPE(Rc, JL, JLindex); // Rc = JudyLPrevEmpty(JL, &JLindex,PJE0)

                if (Rc != 1)
                    FAILURE("JudyLPrevEmpty Rcode != 1 =", (Word_t)Rc);

                Seed1 = GetNextIndex(Seed1);
            }
            ENDTm(DeltaUSecL, tm1);

            if (DDel > DeltaUSecL)
            {
                icnt = ICNT;
                DDel = DeltaUSecL;
            }
            else
            {
                if (--icnt == 0)
                    break;
            }
        }
        DeltaUSecL = DDel / (double)Elements;
    }

    return (0);
}

#undef __FUNCTI0N__
#define __FUNCTI0N__ "TestJudyDel"

int
TestJudyDel(void **J1, void **JL, Word_t Seed, Word_t Elements)
{
    TIMER_vars(tm1);            // declare timer variables
    Word_t    TstIndex;
    Word_t    elm;
    Word_t    Seed1;
    int       Rc;

    if (J1Flag)
    {
        STARTTm(tm1);
        for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
        {
            Seed1 = GetNextIndex(Seed1);

            if (DFlag)
                TstIndex = Swizzle(Seed1);
            else
                TstIndex = Seed1;

            J1U(Rc, *J1, TstIndex);
            if (Rc != 1)
                FAILURE("Judy1Unset ret Rcode != 1", (Word_t)Rc);
        }
        ENDTm(DeltaUSec1, tm1);
        DeltaUSec1 /= Elements;
    }

    STARTTm(tm1);
    if (JLFlag)
    {
        for (Seed1 = Seed, elm = 0; elm < Elements; elm++)
        {
            Seed1 = GetNextIndex(Seed1);

            if (DFlag)
                TstIndex = Swizzle(Seed1);
            else
                TstIndex = Seed1;

            JLD(Rc, *JL, TstIndex);
            if (Rc != 1)
                FAILURE("JudyLDel ret Rcode != 1", (Word_t)Rc);
        }
        ENDTm(DeltaUSecL, tm1);
        DeltaUSecL /= Elements;
    }
    return (0);
}

// Routine to get next size of Indexes
int                             // return 1 if last number
NextNumb(Word_t *PNumber,       // pointer to returned next number
         double *PDNumb,        // Temp double of above
         double DMult,          // Multiplier
         Word_t MaxNumb)        // Max number to return
{
//  Save prev number
    double    PrevPDNumb = *PDNumb;
    double    DDiff;

//  Calc next number >= 1.0 beyond previous
    do {



( run in 1.067 second using v1.01-cache-2.11-cpan-0b5f733616e )