Alien-Judy

 view release on metacpan or  search on metacpan

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


// Shrink JP array in-place:

            else if (JU_BRANCHBJPGROWINPLACE(numJPs - 1))
            {
                assert(numJPs > 0);
                JU_DELETEINPLACE(Pjp2, numJPs, offset, ignore);
            }

// JP array would end up too large; compress it to a smaller one:

            else
            {
                Pjp_t PjpnewRaw;
                Pjp_t Pjpnew;

                if ((PjpnewRaw = j__udyAllocJBBJP(numJPs - 1, Pjpm))
                 == (Pjp_t) NULL) return(-1);
                Pjpnew = P_JP(PjpnewRaw);

                JU_DELETECOPY(Pjpnew, Pjp2, numJPs, offset, ignore);
                j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm);         // old.

                JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
            }

// Clear digits bit in the bitmap:

            JU_JBB_BITMAP(Pjbb, subexp) ^= bitmask;

// If the current subexpanse alone is still too large for a BranchL (with
// hysteresis = 1), the delete is all done:

            if (numJPs > cJU_BRANCHLMAXJPS) return(1);

// Consider shrinking the current BranchB to a BranchL:
//
// Check the numbers of JPs in other subexpanses in the BranchL.  Upon reaching
// the critical number of numJPs (which could be right at the start; again,
// with hysteresis = 1), its faster to just watch for any non-empty subexpanse
// than to count bits in each subexpanse.  Upon finding too many JPs, give up
// on shrinking the BranchB.

            for (subexp2 = 0; subexp2 < cJU_NUMSUBEXPB; ++subexp2)
            {
                if (subexp2 == subexp) continue;  // skip current subexpanse.

                if ((numJPs == cJU_BRANCHLMAXJPS) ?
                    JU_JBB_BITMAP(Pjbb, subexp2) :
                    ((numJPs += j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp2)))
                     > cJU_BRANCHLMAXJPS))
                {
                    return(1);          // too many JPs, cannot shrink.
                }
            }

// Shrink current BranchB to a BranchL:
//
// Note:  In this rare case, ignore the return value, do not pass it to the
// caller, because the deletion is already successfully completed and the
// caller(s) must decrement population counts.  The only errors expected from
// this call are JU_ERRNO_NOMEM and JU_ERRNO_OVERRUN, neither of which is worth
// forwarding from this point.  See also 4.1, 4.8, and 4.15 of this file.

            (void) j__udyBranchBToBranchL(Pjp, Pjpm);
            return(1);

        } // case.


// ****************************************************************************
// UNCOMPRESSED BRANCH:
//
// MACROS FOR COMMON CODE:
//
// Note the reuse of common macros here, defined earlier:  JU_PVALUE*.
//
// Compress a BranchU into a leaf one index size larger:
//
// Allocate a new leaf, walk the JPs in the old BranchU and pack their contents
// into the new leaf (of type NewJPType), free the old BranchU, and finally
// restart the switch to delete Index from the new leaf.  Variables Pjp, Pjpm,
// digit, and pop1 are in the context.
//
// Note:  Its no accident that the interface to JU_BRANCHU_COMPRESS() is
// nearly identical to JU_BRANCHL_COMPRESS(); just NullJPType is added.  The
// details differ in how to traverse the branchs JPs --
//
// -- and also, what to do upon encountering a cJU_JPIMMED_*_01 JP.  In
// BranchLs and BranchBs the JP must be deleted, but in a BranchU its merely
// converted to a null JP, and this is done by other switch cases, so the "keep
// branch" situation is simpler here and JU_BRANCH_KEEP() is not used.  Also,
// theres no code to convert a BranchU to a BranchB since counting the JPs in
// a BranchU is (at least presently) expensive, and besides, keeping around a
// BranchU is form of hysteresis.

#define JU_BRANCHU_COMPRESS(cLevel,LeafType,MaxPop1,NullJPType,NewJPType,   \
                            LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
        {                                                               \
            LeafType Pleaf;                                             \
            Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr);                   \
            Pjp_t  Pjp2    = JU_JBU_PJP0(Pjp);                          \
            Word_t ldigit;      /* larger than uint8_t */               \
                                                                        \
            if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1);   \
            Pjllnew = P_JLL(PjllnewRaw);                                \
            Pleaf   = (LeafType) Pjllnew;                               \
  JUDYLCODE(Pjv     = ValueArea(Pleaf, MaxPop1);)                       \
                                                                        \
            for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit, ++Pjp2) \
            {                                                           \
                /* fast-process common types: */                        \
                if (JU_JPTYPE(Pjp2) == (NullJPType)) continue;          \
                CopyImmed(cLevel, Pjp2, CopyIndex);                     \
                                                                        \
                pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS Pjp2,            \
                                  JU_DIGITTOSTATE(ldigit, cLevel),      \
                                  (Pvoid_t) Pjpm);                      \
                Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
      JUDYLCODE(Pjv  += pop1;)                                          \
            }                                                           \



( run in 1.304 second using v1.01-cache-2.11-cpan-39bf76dae61 )