Alien-Judy
view release on metacpan or search on metacpan
src/judy-1.0.5/src/JudyCommon/JudyInsArray.c view on Meta::CPAN
// Error (rare), or end of indexes while traversing new BranchU (performance
// path); either way, mark the remaining JPs, if any, in the BranchU as nulls
// and exit the loop:
//
// Arrive here with digit and Pjp set to the first JP to set to null.
ClearBranch:
for (/* null */; digit < cJU_BRANCHUNUMJPS; ++digit, ++Pjp)
SETJPNULL(Pjp);
break; // saves one more compare.
} // for each digit
// FINISH JPBRANCH_U*:
//
// Arrive here with a BranchU built under Pjbu, numJPs set, and either: retval
// == TRUE and *PPop1 unmodified, or else retval == FALSE, *PPop1 set to the
// actual number of indexes saved (possibly 0 for complete failure at a lower
// level upon the first call of j__udyInsArray()), and the Judy error set in
// Pjpm. Either way, PIndex points to an index within the expanse just
// handled.
Pjbany = (Word_t) PjbuRaw; // default = use this BranchU.
JPtype = branchU_JPtype[levelsub];
// Check for complete failure above:
assert((! retval) || *PPop1); // sanity check.
if ((! retval) && (*PPop1 == 0)) // nothing stored, full failure.
{
j__udyFreeJBU(PjbuRaw, Pjpm);
SETJPNULL_PARENT;
return(FALSE);
}
// Complete or partial success so far; watch for sorting error after the
// maximum digit (255) in the BranchU, which is indicated by having more
// indexes to store in the BranchUs expanse:
//
// For example, if an index to store has a digit of 255 at levelsub, followed
// by an index with a digit of 254, the for-loop above runs out of digits
// without reducing pop1 to 0.
if (pop1 != 0)
{
JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED);
*PPop1 -= pop1; // deduct unsaved indexes.
retval = FALSE;
}
assert(*PPop1 != 0); // branch (still) cannot be empty.
// OPTIONALLY COMPRESS JPBRANCH_U*:
//
// See if the BranchU should be compressed to a BranchL or BranchB; if so, do
// that and free the BranchU; otherwise just use the existing BranchU. Follow
// the same rules as in JudyIns.c (version 4.95): Only check local population
// (cJU_OPP_UNCOMP_POP0) for BranchL, and only check global memory efficiency
// (JU_OPP_UNCOMPRESS) for BranchB. TBD: Have the rules changed?
//
// Note: Because of differing order of operations, the latter compression
// might not result in the same set of branch nodes as a series of sequential
// insertions.
//
// Note: Allocating a BranchU only to sometimes convert it to a BranchL or
// BranchB is unfortunate, but attempting to work with a temporary BranchU on
// the stack and then allocate and keep it as a BranchU in many cases is worse
// in terms of error handling.
// COMPRESS JPBRANCH_U* TO JPBRANCH_L*:
if (numJPs <= cJU_BRANCHLMAXJPS) // JPs fit in a BranchL.
{
Pjbl_t PjblRaw = (Pjbl_t) NULL; // new BranchL; init for cc.
Pjbl_t Pjbl;
if ((*PPop1 > JU_BRANCHL_MAX_POP) // pop too high.
|| ((PjblRaw = j__udyAllocJBL(Pjpm)) == (Pjbl_t) NULL))
{ // cant alloc BranchL.
goto SetParent; // just keep BranchU.
}
Pjbl = P_JBL(PjblRaw);
// Copy BranchU JPs to BranchL:
(Pjbl->jbl_NumJPs) = numJPs;
offset = 0;
for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit)
{
if ((((Pjbu->jbu_jp) + digit)->jp_Type) == JPtype_null)
continue;
(Pjbl->jbl_Expanse[offset ]) = digit;
(Pjbl->jbl_jp [offset++]) = Pjbu->jbu_jp[digit];
}
assert(offset == numJPs); // found same number.
// Free the BranchU and prepare to use the new BranchL instead:
j__udyFreeJBU(PjbuRaw, Pjpm);
Pjbany = (Word_t) PjblRaw;
JPtype = branchL_JPtype[levelsub];
} // compress to BranchL
// COMPRESS JPBRANCH_U* TO JPBRANCH_B*:
//
// If unable to allocate the BranchB or any JP subarray, free all related
// memory and just keep the BranchU.
//
// Note: This use of JU_OPP_UNCOMPRESS is a bit conservative because the
// BranchU is already allocated while the (presumably smaller) BranchB is not,
// the opposite of how its used in single-insert code.
( run in 0.772 second using v1.01-cache-2.11-cpan-e1769b4cff6 )