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 )