Alien-Judy

 view release on metacpan or  search on metacpan

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

JudySLIns(PPvoid_t PPArray, const uint8_t * Index, PJError_t PJError)
{
    PPvoid_t  PPArrayOrig = PPArray;    // for error reporting.
    const uint8_t *pos = Index;         // place in Index.
    const uint8_t *pos2 = (uint8_t *) NULL;     // old Index (SCL being moved).
    Word_t    len;                      // bytes remaining.

// Note:  len2 is set when needed and only used when valid, but this is not
// clear to gcc -Wall, so initialize it here to avoid a warning:

    Word_t    len2 = 0;                 // for old Index (SCL being moved).
    Word_t    scl2 = 0;                 // size in words of SCL
    Word_t    indexword;                // buffer for aligned copy.
    Word_t    indexword2;               // for old Index (SCL being moved).
    PPvoid_t  PPValue;                  // from JudyL array.
    PPvoid_t  PPValue2;                 // for old Index (SCL being moved).
    Pscl_t    Pscl = (Pscl_t) NULL;     // shortcut leaf.
    Pscl_t    Pscl2;                    // for old Index (SCL being moved).

// CHECK FOR CALLER ERROR (NULL POINTERS):

    if (PPArray == (PPvoid_t) NULL)
    {
        JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
        return (PPJERR);
    }
    if (Index == (uint8_t *) NULL)
    {
        JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
        return (PPJERR);
    }

    len = STRLEN(Index);        // bytes remaining.

// APPEND SHORTCUT LEAF:
//
// If PPArray, which is the root pointer to the first or next JudyL array in
// the tree, points to null (no next JudyL array), AND there is no shortcut
// leaf being carried down, append a shortcut leaf here for the new Index, no
// matter how much of the Index string remains (one or more bytes, including
// the trailing \0).

    while (1)                           // until return.
    {
        if (*PPArray == (Pvoid_t)NULL)  // no next JudyL array.
        {
            if (Pscl == (Pscl_t) NULL)  // no SCL being carried down.
            {
                APPEND_SCL(Pscl, PPArray, pos, len, PJError);   // returns if error.
                return (&(Pscl->scl_Pvalue));
            }
            // else do nothing here; see below.
        }

// CARRY DOWN PRE-EXISTING SHORTCUT LEAF:
//
// When PPArray points to a pre-existing shortcut leaf, if its Index is equal
// to the Index to be inserted, meaning no insertion is required, return its
// value area; otherwise, "move it aside" and "carry it down" -- replace it
// (see below) with one or more levels of JudyL arrays.  Moving it aside
// initially just means setting Pscl non-null, both as a flag and for later
// use, and clearing the pointer to the SCL in the JudyL array.

        else if (IS_PSCL(*PPArray))
        {
            assert(Pscl == (Pscl_t) NULL);      // no nested SCLs.

            Pscl = CLEAR_PSCL(*PPArray);

            pos2 = Pscl->scl_Index;     // note: pos2 is always word-aligned.
            len2 = STRLEN(pos2);        // bytes remaining.

//          first check if string is already inserted

            if ((len == len2) && (STRCMP(pos, pos2) == 0))
                return (&(Pscl->scl_Pvalue));

            *PPArray = (Pvoid_t)NULL;   // disconnect SCL.

            scl2 = SCLSIZE(len2);       // save for JudyFree

            // continue with *PPArray now clear, and Pscl, pos2, len2 set.
        }

// CHECK IF OLD AND NEW INDEXES DIVERGE IN THE CURRENT INDEX WORD:
//
// If a shortcut leaf is being carried down and its remaining Index chars now
// diverge from the remaining chars of the Index being inserted, that is, if
// the next words of each Index differ, "plug in" the old Index here, in a new
// JudyL array, before proceeding.
//
// Note:  Call JudyLIns() for the SCL Index word before calling it for the new
// Index word, so PPValue remains correct for the latter.  (JudyLIns() return
// values are not stable across multiple calls.)
//
// Note:  Although pos2 is word-aligned, and a Pscl_t is a whole number of
// words in size, pos2 is not certain to be null-padded through a whole word,
// so copy it first to an index word for later use.
//
// See header comments about premature return().

        COPYSTRINGtoWORD(indexword, pos);       // copy next 4[8] bytes.

        if (Pscl != (Pscl_t) NULL)
        {
            COPYSTRINGtoWORD(indexword2, pos2); // copy next 4[8] bytes.

            if (indexword != indexword2)        // SCL and new Indexes diverge.
            {
                assert(*PPArray == (Pvoid_t)NULL);      // should be new JudyL array.

// Note:  If JudyLIns() returns JU_ERRNO_NOTJUDYL here, *PPArray should not be
// modified, so JudySLModifyErrno() can do the right thing.

                if ((PPValue2 = JudyLIns(PPArray, indexword2, PJError))
                    == PPJERR)
                {
                    JudySLModifyErrno(PJError, *PPArray, *PPArrayOrig);
                    return (PPJERR);
                }



( run in 0.517 second using v1.01-cache-2.11-cpan-140bd7fdf52 )