83
extern int __Judy1BranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm);
83
extern int j__udy1BranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm);
85
extern int __Judy1LeafB1ToLeaf1(Pjp_t, Pvoid_t);
85
extern int j__udy1LeafB1ToLeaf1(Pjp_t, Pvoid_t);
87
extern Word_t __Judy1Leaf1ToLeaf2(uint16_t *, Pjp_t, Word_t, Pvoid_t);
88
extern Word_t __Judy1Leaf2ToLeaf3(uint8_t *, Pjp_t, Word_t, Pvoid_t);
87
extern Word_t j__udy1Leaf1ToLeaf2(uint16_t *, Pjp_t, Word_t, Pvoid_t);
88
extern Word_t j__udy1Leaf2ToLeaf3(uint8_t *, Pjp_t, Word_t, Pvoid_t);
90
extern Word_t __Judy1Leaf3ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t);
90
extern Word_t j__udy1Leaf3ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t);
92
extern Word_t __Judy1Leaf3ToLeaf4(uint32_t *, Pjp_t, Word_t, Pvoid_t);
93
extern Word_t __Judy1Leaf4ToLeaf5(uint8_t *, Pjp_t, Word_t, Pvoid_t);
94
extern Word_t __Judy1Leaf5ToLeaf6(uint8_t *, Pjp_t, Word_t, Pvoid_t);
95
extern Word_t __Judy1Leaf6ToLeaf7(uint8_t *, Pjp_t, Word_t, Pvoid_t);
96
extern Word_t __Judy1Leaf7ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t);
92
extern Word_t j__udy1Leaf3ToLeaf4(uint32_t *, Pjp_t, Word_t, Pvoid_t);
93
extern Word_t j__udy1Leaf4ToLeaf5(uint8_t *, Pjp_t, Word_t, Pvoid_t);
94
extern Word_t j__udy1Leaf5ToLeaf6(uint8_t *, Pjp_t, Word_t, Pvoid_t);
95
extern Word_t j__udy1Leaf6ToLeaf7(uint8_t *, Pjp_t, Word_t, Pvoid_t);
96
extern Word_t j__udy1Leaf7ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t);
101
extern int __JudyLBranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm);
102
extern int __JudyLLeafB1ToLeaf1(Pjp_t, Pvoid_t);
103
extern Word_t __JudyLLeaf1ToLeaf2(uint16_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
104
extern Word_t __JudyLLeaf2ToLeaf3(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
101
extern int j__udyLBranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm);
102
extern int j__udyLLeafB1ToLeaf1(Pjp_t, Pvoid_t);
103
extern Word_t j__udyLLeaf1ToLeaf2(uint16_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
104
extern Word_t j__udyLLeaf2ToLeaf3(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
106
extern Word_t __JudyLLeaf3ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
106
extern Word_t j__udyLLeaf3ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
108
extern Word_t __JudyLLeaf3ToLeaf4(uint32_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
109
extern Word_t __JudyLLeaf4ToLeaf5(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
110
extern Word_t __JudyLLeaf5ToLeaf6(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
111
extern Word_t __JudyLLeaf6ToLeaf7(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
112
extern Word_t __JudyLLeaf7ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
108
extern Word_t j__udyLLeaf3ToLeaf4(uint32_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
109
extern Word_t j__udyLLeaf4ToLeaf5(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
110
extern Word_t j__udyLLeaf5ToLeaf6(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
111
extern Word_t j__udyLLeaf6ToLeaf7(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
112
extern Word_t j__udyLLeaf7ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
183
183
// Check for population too high to compress a branch to a leaf, meaning just
184
184
// descend through the branch, with a purposeful off-by-one error that
185
185
// constitutes hysteresis = 1. In other words, do not compress until the
186
// branch's CURRENT population fits in the leaf, even BEFORE deleting one
186
// branchs CURRENT population fits in the leaf, even BEFORE deleting one
189
189
// Next is a label for branch-type-specific common code. Variables pop1,
190
190
// level, digit, and Index are in the context.
192
#define JU_BRANCH_KEEP(cLevel,MaxPop1,Next) \
193
if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \
195
assert((cLevel) >= 2); \
197
digit = JU_DIGITATSTATE(Index, cLevel); \
192
#define JU_BRANCH_KEEP(cLevel,MaxPop1,Next) \
193
if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \
195
assert((cLevel) >= 2); \
197
digit = JU_DIGITATSTATE(Index, cLevel); \
201
201
// Support for generic calling of JudyLeaf*ToLeaf*() functions:
203
203
// Note: Cannot use JUDYLCODE() because this contains a comma.
206
#define JU_PVALUEPASS // null.
206
#define JU_PVALUEPASS // null.
208
#define JU_PVALUEPASS Pjv,
208
#define JU_PVALUEPASS Pjv,
211
211
// During compression to a leaf, check if a JP contains nothing but a
212
// cJU_JPIMMED_*_01, in which case shortcut calling __JudyLeaf*ToLeaf*():
212
// cJU_JPIMMED_*_01, in which case shortcut calling j__udyLeaf*ToLeaf*():
214
// Copy the index bytes from the jp_DcdPop0 field (with possible truncation),
214
// Copy the index bytes from the jp_DcdPopO field (with possible truncation),
215
215
// and continue the branch-JP-walk loop. Variables Pjp and Pleaf are in the
218
#define JU_BRANCH_COPY_IMMED_EVEN(cLevel,Pjp,ignore) \
219
if (((Pjp)->jp_Type) == cJU_JPIMMED_1_01 + (cLevel) - 2)\
221
*Pleaf++ = (Pjp)->jp_DcdPop0; \
222
JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \
223
continue; /* for-loop */ \
218
#define JU_BRANCH_COPY_IMMED_EVEN(cLevel,Pjp,ignore) \
219
if (JU_JPTYPE(Pjp) == cJU_JPIMMED_1_01 + (cLevel) - 2) \
221
*Pleaf++ = JU_JPDCDPOP0(Pjp); \
222
JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \
223
continue; /* for-loop */ \
226
#define JU_BRANCH_COPY_IMMED_ODD(cLevel,Pjp,CopyIndex) \
227
if (((Pjp)->jp_Type) == cJU_JPIMMED_1_01 + (cLevel) - 2)\
229
CopyIndex(Pleaf, (Word_t) ((Pjp)->jp_DcdPop0)); \
230
Pleaf += (cLevel); /* index size = level */ \
231
JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \
232
continue; /* for-loop */ \
226
#define JU_BRANCH_COPY_IMMED_ODD(cLevel,Pjp,CopyIndex) \
227
if (JU_JPTYPE(Pjp) == cJU_JPIMMED_1_01 + (cLevel) - 2) \
229
CopyIndex(Pleaf, (Word_t) (JU_JPDCDPOP0(Pjp))); \
230
Pleaf += (cLevel); /* index size = level */ \
231
JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \
232
continue; /* for-loop */ \
235
235
// Compress a BranchL into a leaf one index size larger:
237
237
// Allocate a new leaf, walk the JPs in the old BranchL and pack their contents
238
238
// into the new leaf (of type NewJPType), free the old BranchL, and finally
239
239
// restart the switch to delete Index from the new leaf. (Note that all
240
// BranchL's are the same size.) Variables Pjp, Pjpm, Pleaf, digit, and pop1
240
// BranchLs are the same size.) Variables Pjp, Pjpm, Pleaf, digit, and pop1
241
241
// are in the context.
243
#define JU_BRANCHL_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \
244
LeafToLeaf,Alloc,ValueArea, \
245
CopyImmed,CopyIndex) \
252
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
253
Pjllnew = P_JLL(PjllnewRaw); \
254
Pleaf = (LeafType) Pjllnew; \
255
JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
257
PjblRaw = (Pjbl_t) (Pjp->jp_Addr); \
258
Pjbl = P_JBL(PjblRaw); \
259
numJPs = Pjbl->jbl_NumJPs; \
261
for (offset = 0; offset < numJPs; ++offset) \
263
CopyImmed(cLevel, (Pjbl->jbl_jp) + offset, CopyIndex); \
265
pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \
266
(Pjbl->jbl_jp) + offset, \
267
JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset], \
268
cLevel), (Pvoid_t) Pjpm); \
269
Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
270
JUDYLCODE(Pjv += pop1;) \
272
assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
273
JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
274
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
276
__JudyFreeJBL(PjblRaw, Pjpm); \
278
(Pjp->jp_Type) = (NewJPType); \
279
(Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
280
goto ContinueDelWalk; /* delete from new leaf */ \
243
#define JU_BRANCHL_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \
244
LeafToLeaf,Alloc,ValueArea, \
245
CopyImmed,CopyIndex) \
252
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
253
Pjllnew = P_JLL(PjllnewRaw); \
254
Pleaf = (LeafType) Pjllnew; \
255
JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
257
PjblRaw = (Pjbl_t) (Pjp->jp_Addr); \
258
Pjbl = P_JBL(PjblRaw); \
259
numJPs = Pjbl->jbl_NumJPs; \
261
for (offset = 0; offset < numJPs; ++offset) \
263
CopyImmed(cLevel, (Pjbl->jbl_jp) + offset, CopyIndex); \
265
pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \
266
(Pjbl->jbl_jp) + offset, \
267
JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset], \
268
cLevel), (Pvoid_t) Pjpm); \
269
Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
270
JUDYLCODE(Pjv += pop1;) \
272
assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
273
JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
274
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
276
j__udyFreeJBL(PjblRaw, Pjpm); \
278
Pjp->jp_Type = (NewJPType); \
279
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
280
goto ContinueDelWalk; /* delete from new leaf */ \
283
283
// Overall common code for initial BranchL deletion handling:
286
286
// or else compressed to a leaf. Variables Index, Pjp, and pop1 are in the
289
#define JU_BRANCHL(cLevel,MaxPop1,LeafType,NewJPType, \
290
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
292
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, cLevel)); \
293
assert(ParentLevel > (cLevel)); \
295
pop1 = JU_JPBRANCH_POP0(Pjp->jp_DcdPop0, cLevel) + 1; \
296
JU_BRANCH_KEEP(cLevel, MaxPop1, BranchLKeep); \
297
assert(pop1 == (MaxPop1)); \
299
JU_BRANCHL_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \
300
LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
289
#define JU_BRANCHL(cLevel,MaxPop1,LeafType,NewJPType, \
290
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
292
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \
293
assert(ParentLevel > (cLevel)); \
295
pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \
296
JU_BRANCH_KEEP(cLevel, MaxPop1, BranchLKeep); \
297
assert(pop1 == (MaxPop1)); \
299
JU_BRANCHL_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \
300
LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
303
303
// END OF MACROS, START OF CASES:
305
case cJU_JPBRANCH_L2:
307
JU_BRANCHL(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2,
308
__JudyLeaf1ToLeaf2, __JudyAllocJLL2, JL_LEAF2VALUEAREA,
309
JU_BRANCH_COPY_IMMED_EVEN, ignore);
311
case cJU_JPBRANCH_L3:
313
JU_BRANCHL(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3,
314
__JudyLeaf2ToLeaf3, __JudyAllocJLL3, JL_LEAF3VALUEAREA,
315
JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
305
case cJU_JPBRANCH_L2:
307
JU_BRANCHL(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2,
308
j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
309
JU_BRANCH_COPY_IMMED_EVEN, ignore);
311
case cJU_JPBRANCH_L3:
313
JU_BRANCHL(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3,
314
j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
315
JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
318
case cJU_JPBRANCH_L4:
320
JU_BRANCHL(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4,
321
__JudyLeaf3ToLeaf4, __JudyAllocJLL4, JL_LEAF4VALUEAREA,
322
JU_BRANCH_COPY_IMMED_EVEN, ignore);
324
case cJU_JPBRANCH_L5:
326
JU_BRANCHL(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5,
327
__JudyLeaf4ToLeaf5, __JudyAllocJLL5, JL_LEAF5VALUEAREA,
328
JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
330
case cJU_JPBRANCH_L6:
332
JU_BRANCHL(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6,
333
__JudyLeaf5ToLeaf6, __JudyAllocJLL6, JL_LEAF6VALUEAREA,
334
JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
336
case cJU_JPBRANCH_L7:
338
JU_BRANCHL(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7,
339
__JudyLeaf6ToLeaf7, __JudyAllocJLL7, JL_LEAF7VALUEAREA,
340
JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
318
case cJU_JPBRANCH_L4:
320
JU_BRANCHL(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4,
321
j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
322
JU_BRANCH_COPY_IMMED_EVEN, ignore);
324
case cJU_JPBRANCH_L5:
326
JU_BRANCHL(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5,
327
j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
328
JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
330
case cJU_JPBRANCH_L6:
332
JU_BRANCHL(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6,
333
j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
334
JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
336
case cJU_JPBRANCH_L7:
338
JU_BRANCHL(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7,
339
j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
340
JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
341
341
#endif // JU_64BIT
343
// A top-level BranchL is different and cannot use JU_BRANCHL(): Don't try to
344
// compress to a (JAP) leaf yet, but leave this for a later deletion
343
// A top-level BranchL is different and cannot use JU_BRANCHL(): Dont try to
344
// compress to a (LEAFW) leaf yet, but leave this for a later deletion
345
345
// (hysteresis > 0); and the next JP type depends on the system word size; so
346
// don't use JU_BRANCH_KEEP():
353
level = cJU_ROOTSTATE;
354
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
346
// dont use JU_BRANCH_KEEP():
353
level = cJU_ROOTSTATE;
354
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
359
359
// COMMON CODE FOR KEEPING AND DESCENDING THROUGH A BRANCHL:
415
415
// the new leaf. Variables Pjp, Pjpm, Pleaf, digit, and pop1 are in the
418
// Note: It's no accident that the interface to JU_BRANCHB_COMPRESS() is
418
// Note: Its no accident that the interface to JU_BRANCHB_COMPRESS() is
419
419
// identical to JU_BRANCHL_COMPRESS(). Only the details differ in how to
420
// traverse the branch's JPs.
420
// traverse the branchs JPs.
422
#define JU_BRANCHB_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \
423
LeafToLeaf,Alloc,ValueArea, \
424
CopyImmed,CopyIndex) \
427
Pjbb_t PjbbRaw; /* BranchB to compress */ \
429
Word_t subexp; /* current subexpanse number */ \
430
BITMAPB_t bitmap; /* portion for this subexpanse */ \
431
Pjp_t Pjp2Raw; /* one subexpanse's subarray */ \
434
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
435
Pjllnew = P_JLL(PjllnewRaw); \
436
Pleaf = (LeafType) Pjllnew; \
437
JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
439
PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); \
440
Pjbb = P_JBB(PjbbRaw); \
442
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) \
444
if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0) \
445
continue; /* empty subexpanse */ \
447
digit = subexp * cJU_BITSPERSUBEXPB; \
448
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); \
449
Pjp2 = P_JP(Pjp2Raw); \
450
assert(Pjp2 != (Pjp_t) NULL); \
452
for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit) \
454
if (! (bitmap & 1)) \
455
continue; /* empty sub-subexpanse */ \
457
++offset; /* before any continue */ \
459
CopyImmed(cLevel, Pjp2 + offset - 1, CopyIndex); \
461
pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \
463
JU_DIGITTOSTATE(digit, cLevel), \
465
Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
466
JUDYLCODE(Pjv += pop1;) \
468
__JudyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm); \
470
assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
471
JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
472
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
474
__JudyFreeJBB(PjbbRaw, Pjpm); \
476
(Pjp->jp_Type) = (NewJPType); \
477
(Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
478
goto ContinueDelWalk; /* delete from new leaf */ \
422
#define JU_BRANCHB_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \
423
LeafToLeaf,Alloc,ValueArea, \
424
CopyImmed,CopyIndex) \
427
Pjbb_t PjbbRaw; /* BranchB to compress */ \
429
Word_t subexp; /* current subexpanse number */ \
430
BITMAPB_t bitmap; /* portion for this subexpanse */ \
431
Pjp_t Pjp2Raw; /* one subexpanses subarray */ \
434
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
435
Pjllnew = P_JLL(PjllnewRaw); \
436
Pleaf = (LeafType) Pjllnew; \
437
JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
439
PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); \
440
Pjbb = P_JBB(PjbbRaw); \
442
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) \
444
if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0) \
445
continue; /* empty subexpanse */ \
447
digit = subexp * cJU_BITSPERSUBEXPB; \
448
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); \
449
Pjp2 = P_JP(Pjp2Raw); \
450
assert(Pjp2 != (Pjp_t) NULL); \
452
for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit) \
454
if (! (bitmap & 1)) \
455
continue; /* empty sub-subexpanse */ \
457
++offset; /* before any continue */ \
459
CopyImmed(cLevel, Pjp2 + offset - 1, CopyIndex); \
461
pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \
463
JU_DIGITTOSTATE(digit, cLevel), \
465
Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
466
JUDYLCODE(Pjv += pop1;) \
468
j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm); \
470
assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
471
JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
472
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
474
j__udyFreeJBB(PjbbRaw, Pjpm); \
476
Pjp->jp_Type = (NewJPType); \
477
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
478
goto ContinueDelWalk; /* delete from new leaf */ \
481
481
// Overall common code for initial BranchB deletion handling:
484
484
// or else compressed to a leaf. Variables Index, Pjp, and pop1 are in the
487
#define JU_BRANCHB(cLevel,MaxPop1,LeafType,NewJPType, \
488
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
490
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, cLevel)); \
491
assert(ParentLevel > (cLevel)); \
493
pop1 = JU_JPBRANCH_POP0(Pjp->jp_DcdPop0, cLevel) + 1; \
494
JU_BRANCH_KEEP(cLevel, MaxPop1, BranchBKeep); \
495
assert(pop1 == (MaxPop1)); \
497
JU_BRANCHB_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \
498
LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
487
#define JU_BRANCHB(cLevel,MaxPop1,LeafType,NewJPType, \
488
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
490
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \
491
assert(ParentLevel > (cLevel)); \
493
pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \
494
JU_BRANCH_KEEP(cLevel, MaxPop1, BranchBKeep); \
495
assert(pop1 == (MaxPop1)); \
497
JU_BRANCHB_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \
498
LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
501
501
// END OF MACROS, START OF CASES:
503
// Note: It's no accident that the macro calls for these cases is nearly
504
// identical to the code for BranchL's.
506
case cJU_JPBRANCH_B2:
508
JU_BRANCHB(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2,
509
__JudyLeaf1ToLeaf2, __JudyAllocJLL2, JL_LEAF2VALUEAREA,
510
JU_BRANCH_COPY_IMMED_EVEN, ignore);
512
case cJU_JPBRANCH_B3:
514
JU_BRANCHB(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3,
515
__JudyLeaf2ToLeaf3, __JudyAllocJLL3, JL_LEAF3VALUEAREA,
516
JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
503
// Note: Its no accident that the macro calls for these cases is nearly
504
// identical to the code for BranchLs.
506
case cJU_JPBRANCH_B2:
508
JU_BRANCHB(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2,
509
j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
510
JU_BRANCH_COPY_IMMED_EVEN, ignore);
512
case cJU_JPBRANCH_B3:
514
JU_BRANCHB(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3,
515
j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
516
JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
519
case cJU_JPBRANCH_B4:
521
JU_BRANCHB(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4,
522
__JudyLeaf3ToLeaf4, __JudyAllocJLL4, JL_LEAF4VALUEAREA,
523
JU_BRANCH_COPY_IMMED_EVEN, ignore);
525
case cJU_JPBRANCH_B5:
527
JU_BRANCHB(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5,
528
__JudyLeaf4ToLeaf5, __JudyAllocJLL5, JL_LEAF5VALUEAREA,
529
JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
531
case cJU_JPBRANCH_B6:
533
JU_BRANCHB(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6,
534
__JudyLeaf5ToLeaf6, __JudyAllocJLL6, JL_LEAF6VALUEAREA,
535
JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
537
case cJU_JPBRANCH_B7:
539
JU_BRANCHB(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7,
540
__JudyLeaf6ToLeaf7, __JudyAllocJLL7, JL_LEAF7VALUEAREA,
541
JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
519
case cJU_JPBRANCH_B4:
521
JU_BRANCHB(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4,
522
j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
523
JU_BRANCH_COPY_IMMED_EVEN, ignore);
525
case cJU_JPBRANCH_B5:
527
JU_BRANCHB(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5,
528
j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
529
JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
531
case cJU_JPBRANCH_B6:
533
JU_BRANCHB(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6,
534
j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
535
JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
537
case cJU_JPBRANCH_B7:
539
JU_BRANCHB(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7,
540
j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
541
JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
542
542
#endif // JU_64BIT
544
// A top-level BranchB is different and cannot use JU_BRANCHB(): Don't try to
545
// compress to a (JAP) leaf yet, but leave this for a later deletion
544
// A top-level BranchB is different and cannot use JU_BRANCHB(): Dont try to
545
// compress to a (LEAFW) leaf yet, but leave this for a later deletion
546
546
// (hysteresis > 0); and the next JP type depends on the system word size; so
547
// don't use JU_BRANCH_KEEP():
551
Pjbb_t Pjbb; // BranchB to modify.
552
Word_t subexp; // current subexpanse number.
553
Word_t subexp2; // in second-level loop.
554
BITMAPB_t bitmap; // portion for this subexpanse.
555
BITMAPB_t bitmask; // with digit's bit set.
556
Pjp_t Pjp2Raw; // one subexpanse's subarray.
558
Word_t numJPs; // in one subexpanse.
560
level = cJU_ROOTSTATE;
561
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
547
// dont use JU_BRANCH_KEEP():
551
Pjbb_t Pjbb; // BranchB to modify.
552
Word_t subexp; // current subexpanse number.
553
Word_t subexp2; // in second-level loop.
554
BITMAPB_t bitmap; // portion for this subexpanse.
555
BITMAPB_t bitmask; // with digits bit set.
556
Pjp_t Pjp2Raw; // one subexpanses subarray.
558
Word_t numJPs; // in one subexpanse.
560
level = cJU_ROOTSTATE;
561
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
566
566
// COMMON CODE FOR KEEPING AND DESCENDING THROUGH A BRANCHB:
568
568
// Come here with level and digit set.
571
Pjbb = P_JBB(Pjp->jp_Addr);
572
subexp = digit / cJU_BITSPERSUBEXPB;
573
bitmap = JU_JBB_BITMAP(Pjbb, subexp);
574
bitmask = JU_BITPOSMASKB(digit);
575
assert(bitmap & bitmask); // Index valid => digit's bit is set.
576
DBGCODE(parentJPtype = Pjp->jp_Type;)
571
Pjbb = P_JBB(Pjp->jp_Addr);
572
subexp = digit / cJU_BITSPERSUBEXPB;
573
bitmap = JU_JBB_BITMAP(Pjbb, subexp);
574
bitmask = JU_BITPOSMASKB(digit);
575
assert(bitmap & bitmask); // Index valid => digits bit is set.
576
DBGCODE(parentJPtype = JU_JPTYPE(Pjp);)
578
// Compute digit's offset into the bitmap, with a fast method if all bits are
578
// Compute digits offset into the bitmap, with a fast method if all bits are
581
offset = ((bitmap == (cJU_FULLBITMAPB)) ?
582
digit % cJU_BITSPERSUBEXPB :
583
__JudyCountBitsB(bitmap & JU_MASKLOWEREXC(bitmask)));
581
offset = ((bitmap == (cJU_FULLBITMAPB)) ?
582
digit % cJU_BITSPERSUBEXPB :
583
j__udyCountBitsB(bitmap & JU_MASKLOWEREXC(bitmask)));
585
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
586
Pjp2 = P_JP(Pjp2Raw);
587
assert(Pjp2 != (Pjp_t) NULL); // valid subexpanse pointer.
585
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
586
Pjp2 = P_JP(Pjp2Raw);
587
assert(Pjp2 != (Pjp_t) NULL); // valid subexpanse pointer.
589
589
// If not at a (deletable) JPIMMED_*_01, continue the walk (to descend through
592
if (((Pjp2 + offset)->jp_Type) != cJU_JPIMMED_1_01 + level - 2)
592
if (JU_JPTYPE(Pjp2 + offset) != cJU_JPIMMED_1_01 + level - 2)
598
598
// At JPIMMED_*_01: Ensure the index is in the right expanse, then delete the
599
599
// Immed from the BranchB:
601
assert(((Pjp2 + offset)->jp_DcdPop0)
602
== JU_TRIMTODCDSIZE(Index));
601
assert(JU_JPDCDPOP0(Pjp2 + offset)
602
== JU_TRIMTODCDSIZE(Index));
604
604
// If only one index is left in the subexpanse, free the JP array:
606
if ((numJPs = __JudyCountBitsB(bitmap)) == 1)
608
__JudyFreeJBBJP(Pjp2Raw, /* pop1 = */ 1, Pjpm);
609
JU_JBB_PJP(Pjbb, subexp) = (Pjp_t) NULL;
606
if ((numJPs = j__udyCountBitsB(bitmap)) == 1)
608
j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ 1, Pjpm);
609
JU_JBB_PJP(Pjbb, subexp) = (Pjp_t) NULL;
612
612
// Shrink JP array in-place:
614
else if (JU_BRANCHBJPGROWINPLACE(numJPs - 1))
617
JU_DELETEINPLACE(Pjp2, numJPs, offset, ignore);
614
else if (JU_BRANCHBJPGROWINPLACE(numJPs - 1))
617
JU_DELETEINPLACE(Pjp2, numJPs, offset, ignore);
620
620
// JP array would end up too large; compress it to a smaller one:
627
if ((PjpnewRaw = __JudyAllocJBBJP(numJPs - 1, Pjpm))
628
== (Pjp_t) NULL) return(-1);
629
Pjpnew = P_JP(PjpnewRaw);
631
JU_DELETECOPY(Pjpnew, Pjp2, numJPs, offset, ignore);
632
__JudyFreeJBBJP(Pjp2Raw, numJPs, Pjpm); // old.
634
JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
637
// Clear digit's bit in the bitmap:
639
JU_JBB_BITMAP(Pjbb, subexp) ^= bitmask;
627
if ((PjpnewRaw = j__udyAllocJBBJP(numJPs - 1, Pjpm))
628
== (Pjp_t) NULL) return(-1);
629
Pjpnew = P_JP(PjpnewRaw);
631
JU_DELETECOPY(Pjpnew, Pjp2, numJPs, offset, ignore);
632
j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm); // old.
634
JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
637
// Clear digits bit in the bitmap:
639
JU_JBB_BITMAP(Pjbb, subexp) ^= bitmask;
641
641
// If the current subexpanse alone is still too large for a BranchL (with
642
642
// hysteresis = 1), the delete is all done:
644
if (numJPs > cJU_BRANCHLMAXJPS) return(1);
644
if (numJPs > cJU_BRANCHLMAXJPS) return(1);
646
646
// Consider shrinking the current BranchB to a BranchL:
648
648
// Check the numbers of JPs in other subexpanses in the BranchL. Upon reaching
649
649
// the critical number of numJPs (which could be right at the start; again,
650
// with hysteresis = 1), it's faster to just watch for any non-empty subexpanse
650
// with hysteresis = 1), its faster to just watch for any non-empty subexpanse
651
651
// than to count bits in each subexpanse. Upon finding too many JPs, give up
652
652
// on shrinking the BranchB.
654
for (subexp2 = 0; subexp2 < cJU_NUMSUBEXPB; ++subexp2)
656
if (subexp2 == subexp) continue; // skip current subexpanse.
654
for (subexp2 = 0; subexp2 < cJU_NUMSUBEXPB; ++subexp2)
656
if (subexp2 == subexp) continue; // skip current subexpanse.
658
if ((numJPs == cJU_BRANCHLMAXJPS) ?
659
JU_JBB_BITMAP(Pjbb, subexp2) :
660
((numJPs += __JudyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp2)))
661
> cJU_BRANCHLMAXJPS))
663
return(1); // too many JPs, cannot shrink.
658
if ((numJPs == cJU_BRANCHLMAXJPS) ?
659
JU_JBB_BITMAP(Pjbb, subexp2) :
660
((numJPs += j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp2)))
661
> cJU_BRANCHLMAXJPS))
663
return(1); // too many JPs, cannot shrink.
667
667
// Shrink current BranchB to a BranchL:
692
692
// restart the switch to delete Index from the new leaf. Variables Pjp, Pjpm,
693
693
// digit, and pop1 are in the context.
695
// Note: It's no accident that the interface to JU_BRANCHU_COMPRESS() is
695
// Note: Its no accident that the interface to JU_BRANCHU_COMPRESS() is
696
696
// nearly identical to JU_BRANCHL_COMPRESS(); just NullJPType is added. The
697
// details differ in how to traverse the branch's JPs --
697
// details differ in how to traverse the branchs JPs --
699
699
// -- and also, what to do upon encountering a cJU_JPIMMED_*_01 JP. In
700
// BranchL's and BranchB's the JP must be deleted, but in a BranchU it's merely
700
// BranchLs and BranchBs the JP must be deleted, but in a BranchU its merely
701
701
// converted to a null JP, and this is done by other switch cases, so the "keep
702
702
// branch" situation is simpler here and JU_BRANCH_KEEP() is not used. Also,
703
// there's no code to convert a BranchU to a BranchB since counting the JPs in
703
// theres no code to convert a BranchU to a BranchB since counting the JPs in
704
704
// a BranchU is (at least presently) expensive, and besides, keeping around a
705
705
// BranchU is form of hysteresis.
707
#define JU_BRANCHU_COMPRESS(cLevel,LeafType,MaxPop1,NullJPType,NewJPType, \
708
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
711
Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr); \
712
Pjp_t Pjp2 = JU_JBU_PJP0(Pjp); \
713
Word_t ldigit; /* larger than uint8_t */ \
715
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
716
Pjllnew = P_JLL(PjllnewRaw); \
717
Pleaf = (LeafType) Pjllnew; \
718
JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
720
for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit, ++Pjp2) \
722
/* fast-process common types: */ \
723
if ((Pjp2->jp_Type) == (NullJPType)) continue; \
724
CopyImmed(cLevel, Pjp2, CopyIndex); \
726
pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS Pjp2, \
727
JU_DIGITTOSTATE(ldigit, cLevel), \
729
Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
730
JUDYLCODE(Pjv += pop1;) \
732
assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
733
JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
734
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
736
__JudyFreeJBU(PjbuRaw, Pjpm); \
738
(Pjp->jp_Type) = (NewJPType); \
739
(Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
740
goto ContinueDelWalk; /* delete from new leaf */ \
707
#define JU_BRANCHU_COMPRESS(cLevel,LeafType,MaxPop1,NullJPType,NewJPType, \
708
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
711
Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr); \
712
Pjp_t Pjp2 = JU_JBU_PJP0(Pjp); \
713
Word_t ldigit; /* larger than uint8_t */ \
715
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
716
Pjllnew = P_JLL(PjllnewRaw); \
717
Pleaf = (LeafType) Pjllnew; \
718
JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
720
for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit, ++Pjp2) \
722
/* fast-process common types: */ \
723
if (JU_JPTYPE(Pjp2) == (NullJPType)) continue; \
724
CopyImmed(cLevel, Pjp2, CopyIndex); \
726
pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS Pjp2, \
727
JU_DIGITTOSTATE(ldigit, cLevel), \
729
Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
730
JUDYLCODE(Pjv += pop1;) \
732
assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
733
JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
734
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
736
j__udyFreeJBU(PjbuRaw, Pjpm); \
738
Pjp->jp_Type = (NewJPType); \
739
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
740
goto ContinueDelWalk; /* delete from new leaf */ \
743
743
// Overall common code for initial BranchU deletion handling:
749
749
// Note: BranchU handling differs from BranchL and BranchB as described above.
751
#define JU_BRANCHU(cLevel,MaxPop1,LeafType,NullJPType,NewJPType, \
752
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
754
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, cLevel)); \
755
assert(ParentLevel > (cLevel)); \
756
DBGCODE(parentJPtype = Pjp->jp_Type;) \
758
pop1 = JU_JPBRANCH_POP0(Pjp->jp_DcdPop0, cLevel) + 1; \
760
if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \
763
Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cLevel);\
764
break; /* descend to next level */ \
766
assert(pop1 == (MaxPop1)); \
768
JU_BRANCHU_COMPRESS(cLevel, LeafType, MaxPop1, NullJPType, NewJPType, \
769
LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
751
#define JU_BRANCHU(cLevel,MaxPop1,LeafType,NullJPType,NewJPType, \
752
LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
754
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \
755
assert(ParentLevel > (cLevel)); \
756
DBGCODE(parentJPtype = JU_JPTYPE(Pjp);) \
758
pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \
760
if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \
763
Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cLevel);\
764
break; /* descend to next level */ \
766
assert(pop1 == (MaxPop1)); \
768
JU_BRANCHU_COMPRESS(cLevel, LeafType, MaxPop1, NullJPType, NewJPType, \
769
LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
772
772
// END OF MACROS, START OF CASES:
774
// Note: It's no accident that the macro calls for these cases is nearly
775
// identical to the code for BranchL's, with the addition of cJU_JPNULL*
776
// parameters only needed for BranchU's.
778
case cJU_JPBRANCH_U2:
780
JU_BRANCHU(2, cJU_LEAF2_MAXPOP1, uint16_t *,
781
cJU_JPNULL1, cJU_JPLEAF2,
782
__JudyLeaf1ToLeaf2, __JudyAllocJLL2, JL_LEAF2VALUEAREA,
783
JU_BRANCH_COPY_IMMED_EVEN, ignore);
785
case cJU_JPBRANCH_U3:
787
JU_BRANCHU(3, cJU_LEAF3_MAXPOP1, uint8_t *,
788
cJU_JPNULL2, cJU_JPLEAF3,
789
__JudyLeaf2ToLeaf3, __JudyAllocJLL3, JL_LEAF3VALUEAREA,
790
JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
774
// Note: Its no accident that the macro calls for these cases is nearly
775
// identical to the code for BranchLs, with the addition of cJU_JPNULL*
776
// parameters only needed for BranchUs.
778
case cJU_JPBRANCH_U2:
780
JU_BRANCHU(2, cJU_LEAF2_MAXPOP1, uint16_t *,
781
cJU_JPNULL1, cJU_JPLEAF2,
782
j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
783
JU_BRANCH_COPY_IMMED_EVEN, ignore);
785
case cJU_JPBRANCH_U3:
787
JU_BRANCHU(3, cJU_LEAF3_MAXPOP1, uint8_t *,
788
cJU_JPNULL2, cJU_JPLEAF3,
789
j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
790
JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
793
case cJU_JPBRANCH_U4:
795
JU_BRANCHU(4, cJU_LEAF4_MAXPOP1, uint32_t *,
796
cJU_JPNULL3, cJU_JPLEAF4,
797
__JudyLeaf3ToLeaf4, __JudyAllocJLL4, JL_LEAF4VALUEAREA,
798
JU_BRANCH_COPY_IMMED_EVEN, ignore);
800
case cJU_JPBRANCH_U5:
802
JU_BRANCHU(5, cJU_LEAF5_MAXPOP1, uint8_t *,
803
cJU_JPNULL4, cJU_JPLEAF5,
804
__JudyLeaf4ToLeaf5, __JudyAllocJLL5, JL_LEAF5VALUEAREA,
805
JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
807
case cJU_JPBRANCH_U6:
809
JU_BRANCHU(6, cJU_LEAF6_MAXPOP1, uint8_t *,
810
cJU_JPNULL5, cJU_JPLEAF6,
811
__JudyLeaf5ToLeaf6, __JudyAllocJLL6, JL_LEAF6VALUEAREA,
812
JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
814
case cJU_JPBRANCH_U7:
816
JU_BRANCHU(7, cJU_LEAF7_MAXPOP1, uint8_t *,
817
cJU_JPNULL6, cJU_JPLEAF7,
818
__JudyLeaf6ToLeaf7, __JudyAllocJLL7, JL_LEAF7VALUEAREA,
819
JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
793
case cJU_JPBRANCH_U4:
795
JU_BRANCHU(4, cJU_LEAF4_MAXPOP1, uint32_t *,
796
cJU_JPNULL3, cJU_JPLEAF4,
797
j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
798
JU_BRANCH_COPY_IMMED_EVEN, ignore);
800
case cJU_JPBRANCH_U5:
802
JU_BRANCHU(5, cJU_LEAF5_MAXPOP1, uint8_t *,
803
cJU_JPNULL4, cJU_JPLEAF5,
804
j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
805
JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
807
case cJU_JPBRANCH_U6:
809
JU_BRANCHU(6, cJU_LEAF6_MAXPOP1, uint8_t *,
810
cJU_JPNULL5, cJU_JPLEAF6,
811
j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
812
JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
814
case cJU_JPBRANCH_U7:
816
JU_BRANCHU(7, cJU_LEAF7_MAXPOP1, uint8_t *,
817
cJU_JPNULL6, cJU_JPLEAF7,
818
j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
819
JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
820
820
#endif // JU_64BIT
822
// A top-level BranchU is different and cannot use JU_BRANCHU(): Don't try to
823
// compress to a (JAP) leaf yet, but leave this for a later deletion
822
// A top-level BranchU is different and cannot use JU_BRANCHU(): Dont try to
823
// compress to a (LEAFW) leaf yet, but leave this for a later deletion
824
824
// (hysteresis > 0); just descend through the BranchU:
828
DBGCODE(parentJPtype = Pjp->jp_Type;)
830
level = cJU_ROOTSTATE;
831
Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
828
DBGCODE(parentJPtype = JU_JPTYPE(Pjp);)
830
level = cJU_ROOTSTATE;
831
Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
835
835
// ****************************************************************************
890
890
// JU_JPLEAF_POP0(), such as in JudyInsertBranch.c.
892
892
// TBD: Should JudyInsertBranch.c use JU_JPLEAF_POP0() rather than
893
// cJU_POP0MASK(), for efficiency? Does it know for sure it's a narrow pointer
893
// cJU_POP0MASK(), for efficiency? Does it know for sure its a narrow pointer
894
894
// under the leaf? Not necessarily.
896
#define JU_LEAF_UPLEVEL(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
899
assert(((ParentLevel - 1) == (cIS)) || (pop1 >= (MaxPop1))); \
901
if (((ParentLevel - 1) > (cIS)) /* under narrow pointer */ \
902
&& (pop1 == (MaxPop1))) /* hysteresis = 1 */ \
904
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
905
Pjllnew = P_JLL(PjllnewRaw); \
906
JUDYLCODE(Pjv = ValueArea((LeafType) Pjllnew, MaxPop1);) \
908
(void) LeafToLeaf((LeafType) Pjllnew, JU_PVALUEPASS Pjp, \
909
Index & cJU_DCDMASK(cIS), /* TBD, Doug says */ \
911
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cIS + 1);) \
913
(Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
914
(Pjp->jp_DcdPop0) &= ~cJU_MASKATSTATE((cIS) + 1); /* see above */ \
915
(Pjp->jp_Type) = (NewJPType); \
916
goto ContinueDelWalk; /* delete from new leaf */ \
896
#define JU_LEAF_UPLEVEL(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
899
assert(((ParentLevel - 1) == (cIS)) || (pop1 >= (MaxPop1))); \
901
if (((ParentLevel - 1) > (cIS)) /* under narrow pointer */ \
902
&& (pop1 == (MaxPop1))) /* hysteresis = 1 */ \
905
if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
906
Pjllnew = P_JLL(PjllnewRaw); \
907
JUDYLCODE(Pjv = ValueArea((LeafType) Pjllnew, MaxPop1);) \
909
(void) LeafToLeaf((LeafType) Pjllnew, JU_PVALUEPASS Pjp, \
910
Index & cJU_DCDMASK(cIS), /* TBD, Doug says */ \
912
DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cIS + 1);) \
914
D_cdP0 = (~cJU_MASKATSTATE((cIS) + 1)) & JU_JPDCDPOP0(Pjp); \
915
JU_JPSETADT(Pjp, (Word_t)PjllnewRaw, D_cdP0, NewJPType); \
916
goto ContinueDelWalk; /* delete from new leaf */ \
919
920
// For Leaf3, only support JU_LEAF_UPLEVEL on a 64-bit system, and for Leaf7,
920
921
// there is no JU_LEAF_UPLEVEL:
922
// Note: There's no way here to go from Leaf3 [Leaf7] to JAPLEAF on a 32-bit
923
// [64-bit] system. That's handled in the main code, because it's different in
923
// Note: Theres no way here to go from Leaf3 [Leaf7] to LEAFW on a 32-bit
924
// [64-bit] system. Thats handled in the main code, because its different in
924
925
// that a JPM is involved.
926
927
#ifndef JU_64BIT // 32-bit.
927
#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
928
Alloc,ValueArea) // null.
928
#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
929
Alloc,ValueArea) // null.
930
#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
932
JU_LEAF_UPLEVEL (cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
934
#define JU_LEAF_UPLEVEL_NONE(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
935
Alloc,ValueArea) // null.
931
#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
933
JU_LEAF_UPLEVEL (cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
935
#define JU_LEAF_UPLEVEL_NONE(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
936
Alloc,ValueArea) // null.
938
939
// Compress a Leaf* with pop1 = 2, or a JPIMMED_*_02, into a JPIMMED_*_01:
978
#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\
979
ignore2,ignore3,ignore4, \
980
DeleteCopy,FreeLeaf) \
982
assert(pop1 > (MaxPop1)); \
984
if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
986
Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
987
DeleteCopy((LeafType) (Pjp->jp_1Index), Pleaf, pop1, offset, cIS); \
988
DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index), pop1-1, cIS);) \
989
(Pjp->jp_Type) = (BaseJPType) - 1 + (MaxPop1) - 1; \
990
FreeLeaf(PjllRaw, pop1, Pjpm); \
990
#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\
991
ignore2,ignore3,ignore4, \
992
DeleteCopy,FreeLeaf) \
994
assert(pop1 > (MaxPop1)); \
996
if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
998
Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
999
DeleteCopy((LeafType) (Pjp->jp_1Index), Pleaf, pop1, offset, cIS); \
1000
DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index), pop1-1, cIS);) \
1001
Pjp->jp_Type = (BaseJPType) - 1 + (MaxPop1) - 1; \
1002
FreeLeaf(PjllRaw, pop1, Pjpm); \
996
1008
// Pjv is also in the context.
998
#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\
999
ignore2,ignore3,ignore4, \
1000
DeleteCopy,FreeLeaf) \
1002
assert(pop1 > (MaxPop1)); \
1004
if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
1006
Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
1010
if ((PjvnewRaw = __JudyLAllocJV(pop1 - 1, Pjpm)) \
1011
== (Pjv_t) NULL) return(-1); \
1012
JUDYLCODE(Pjvnew = P_JV(PjvnewRaw);) \
1014
DeleteCopy((LeafType) (Pjp->jp_LIndex), Pleaf, pop1, offset, cIS); \
1015
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \
1016
DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_LIndex), pop1-1, cIS);) \
1017
FreeLeaf(PjllRaw, pop1, Pjpm); \
1018
(Pjp->jp_Addr) = (Word_t) PjvnewRaw; \
1019
(Pjp->jp_Type) = (BaseJPType) - 2 + (MaxPop1); \
1010
#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\
1011
ignore2,ignore3,ignore4, \
1012
DeleteCopy,FreeLeaf) \
1014
assert(pop1 > (MaxPop1)); \
1016
if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
1018
Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
1022
if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) \
1023
== (Pjv_t) NULL) return(-1); \
1024
JUDYLCODE(Pjvnew = P_JV(PjvnewRaw);) \
1026
DeleteCopy((LeafType) (Pjp->jp_LIndex), Pleaf, pop1, offset, cIS); \
1027
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \
1028
DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_LIndex), pop1-1, cIS);) \
1029
FreeLeaf(PjllRaw, pop1, Pjpm); \
1030
Pjp->jp_Addr = (Word_t) PjvnewRaw; \
1031
Pjp->jp_Type = (BaseJPType) - 2 + (MaxPop1); \
1023
1035
// A complicating factor for JudyL & 32-bit is that Leaf2..3, and for JudyL &
1024
1036
// 64-bit Leaf 4..7, go directly to an Immed*_01, where the value is stored in
1030
1042
// This variant compresses a Leaf* with pop1 = 2 into a JPIMMED_*_01:
1032
#define JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1033
ToImmed,SearchLeaf,CopyPIndex, \
1034
DeleteCopy,FreeLeaf) \
1036
assert(pop1 > (MaxPop1)); \
1038
if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
1040
Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
1041
ToImmed(cIS, SearchLeaf, CopyPIndex); \
1042
FreeLeaf(PjllRaw, pop1, Pjpm); \
1043
(Pjp->jp_Type) = (Immed01JPType); \
1044
#define JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1045
ToImmed,SearchLeaf,CopyPIndex, \
1046
DeleteCopy,FreeLeaf) \
1048
assert(pop1 > (MaxPop1)); \
1050
if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
1052
Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
1053
ToImmed(cIS, SearchLeaf, CopyPIndex); \
1054
FreeLeaf(PjllRaw, pop1, Pjpm); \
1055
Pjp->jp_Type = (Immed01JPType); \
1046
1058
#endif // JUDYL
1048
1060
// See comments above about these:
1050
1062
// Note: Here "23" means index size 2 or 3, and "47" means 4..7.
1052
#if (JUDY1 || JU_64BIT)
1053
#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1054
ToImmed,SearchLeaf,CopyPIndex, \
1055
DeleteCopy,FreeLeaf) \
1056
JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \
1057
ignore2,ignore3,ignore4, \
1058
DeleteCopy,FreeLeaf)
1064
#if (defined(JUDY1) || defined(JU_64BIT))
1065
#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1066
ToImmed,SearchLeaf,CopyPIndex, \
1067
DeleteCopy,FreeLeaf) \
1068
JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \
1069
ignore2,ignore3,ignore4, \
1070
DeleteCopy,FreeLeaf)
1059
1071
#else // JUDYL && 32-bit
1060
#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1061
ToImmed,SearchLeaf,CopyPIndex, \
1062
DeleteCopy,FreeLeaf) \
1063
JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1064
ToImmed,SearchLeaf,CopyPIndex, \
1065
DeleteCopy,FreeLeaf)
1072
#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1073
ToImmed,SearchLeaf,CopyPIndex, \
1074
DeleteCopy,FreeLeaf) \
1075
JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1076
ToImmed,SearchLeaf,CopyPIndex, \
1077
DeleteCopy,FreeLeaf)
1068
1080
#ifdef JU_64BIT
1070
#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1071
ToImmed,SearchLeaf,CopyPIndex, \
1072
DeleteCopy,FreeLeaf) \
1073
JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \
1074
ignore2,ignore3,ignore4, \
1075
DeleteCopy,FreeLeaf)
1082
#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1083
ToImmed,SearchLeaf,CopyPIndex, \
1084
DeleteCopy,FreeLeaf) \
1085
JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \
1086
ignore2,ignore3,ignore4, \
1087
DeleteCopy,FreeLeaf)
1076
1088
#else // JUDYL && 64-bit
1077
#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1078
ToImmed,SearchLeaf,CopyPIndex, \
1079
DeleteCopy,FreeLeaf) \
1080
JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1081
ToImmed,SearchLeaf,CopyPIndex, \
1082
DeleteCopy,FreeLeaf)
1089
#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1090
ToImmed,SearchLeaf,CopyPIndex, \
1091
DeleteCopy,FreeLeaf) \
1092
JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1093
ToImmed,SearchLeaf,CopyPIndex, \
1094
DeleteCopy,FreeLeaf)
1083
1095
#endif // JUDYL
1084
1096
#endif // JU_64BIT
1117
#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \
1118
if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \
1119
Pjllnew = P_JLL(PjllnewRaw); \
1120
DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \
1121
DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \
1122
FreeLeaf(PleafRaw, pop1, Pjpm); \
1123
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
1129
#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \
1130
if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \
1131
Pjllnew = P_JLL(PjllnewRaw); \
1132
DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \
1133
DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \
1134
FreeLeaf(PleafRaw, pop1, Pjpm); \
1135
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
1128
#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \
1130
/**/ Pjv_t Pjvnew; \
1132
if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \
1133
Pjllnew = P_JLL(PjllnewRaw); \
1134
/**/ Pjvnew = ValueArea(Pjllnew, pop1 - 1); \
1135
DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \
1136
/**/ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \
1137
DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \
1138
FreeLeaf(PleafRaw, pop1, Pjpm); \
1139
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
1140
#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \
1142
/**/ Pjv_t Pjvnew; \
1144
if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \
1145
Pjllnew = P_JLL(PjllnewRaw); \
1146
/**/ Pjvnew = ValueArea(Pjllnew, pop1 - 1); \
1147
DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \
1148
/**/ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \
1149
DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \
1150
FreeLeaf(PleafRaw, pop1, Pjpm); \
1151
Pjp->jp_Addr = (Word_t) PjllnewRaw; \
1142
1154
#endif // JUDYL
1144
1156
// Overall common code for Leaf* deletion handling:
1152
1164
// Variables Pjp, pop1, Index, and offset are in the context.
1153
1165
// The *Up parameters refer to a leaf one level up, if there is any.
1155
#define JU_LEAF(cIS, \
1157
LeafTypeUp,MaxPop1Up,LeafJPTypeUp,LeafToLeaf, \
1158
AllocUp,ValueAreaUp, \
1159
LeafToImmed,ToImmed,CopyPIndex, \
1160
LeafType,ImmedMaxPop1,ImmedBaseJPType,Immed01JPType, \
1161
SearchLeaf,GrowInPlace,DeleteInPlace,DeleteCopy, \
1162
Alloc,FreeLeaf,ValueArea) \
1167
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, cIS)); \
1168
assert(ParentLevel > (cIS)); \
1170
PleafRaw = (Pjll_t) (Pjp->jp_Addr); \
1171
Pleaf = (LeafType) P_JLL(PleafRaw); \
1172
pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1; \
1174
UpLevel(cIS, LeafTypeUp, MaxPop1Up, LeafJPTypeUp, \
1175
LeafToLeaf, AllocUp, ValueAreaUp); \
1177
offset = SearchLeaf(Pleaf, pop1, Index); \
1178
assert(offset >= 0); /* Index must be valid */ \
1179
JUDYLCODE(Pjv = ValueArea(Pleaf, pop1);) \
1181
LeafToImmed(cIS, LeafType, ImmedMaxPop1, \
1182
ImmedBaseJPType, Immed01JPType, \
1183
ToImmed, SearchLeaf, CopyPIndex, \
1184
DeleteCopy, FreeLeaf); \
1186
JU_LEAF_INPLACE(cIS, GrowInPlace, DeleteInPlace); \
1188
JU_LEAF_SHRINK(cIS, LeafType, DeleteCopy, Alloc, FreeLeaf, \
1167
#define JU_LEAF(cIS, \
1169
LeafTypeUp,MaxPop1Up,LeafJPTypeUp,LeafToLeaf, \
1170
AllocUp,ValueAreaUp, \
1171
LeafToImmed,ToImmed,CopyPIndex, \
1172
LeafType,ImmedMaxPop1,ImmedBaseJPType,Immed01JPType, \
1173
SearchLeaf,GrowInPlace,DeleteInPlace,DeleteCopy, \
1174
Alloc,FreeLeaf,ValueArea) \
1179
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cIS)); \
1180
assert(ParentLevel > (cIS)); \
1182
PleafRaw = (Pjll_t) (Pjp->jp_Addr); \
1183
Pleaf = (LeafType) P_JLL(PleafRaw); \
1184
pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
1186
UpLevel(cIS, LeafTypeUp, MaxPop1Up, LeafJPTypeUp, \
1187
LeafToLeaf, AllocUp, ValueAreaUp); \
1189
offset = SearchLeaf(Pleaf, pop1, Index); \
1190
assert(offset >= 0); /* Index must be valid */ \
1191
JUDYLCODE(Pjv = ValueArea(Pleaf, pop1);) \
1193
LeafToImmed(cIS, LeafType, ImmedMaxPop1, \
1194
ImmedBaseJPType, Immed01JPType, \
1195
ToImmed, SearchLeaf, CopyPIndex, \
1196
DeleteCopy, FreeLeaf); \
1198
JU_LEAF_INPLACE(cIS, GrowInPlace, DeleteInPlace); \
1200
JU_LEAF_SHRINK(cIS, LeafType, DeleteCopy, Alloc, FreeLeaf, \
1192
1204
// END OF MACROS, START OF CASES:
1194
1206
// (*) Leaf1 [[ => 1_15..08 ] => 1_07 => ... => 1_04 ] => 1_03 => 1_02 => 1_01
1196
#if (JUDYL || (! JU_64BIT))
1208
#if (defined(JUDYL) || (! defined(JU_64BIT)))
1200
JU_LEAF_UPLEVEL, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2,
1201
__JudyLeaf1ToLeaf2, __JudyAllocJLL2, JL_LEAF2VALUEAREA,
1202
JU_LEAF_TOIMMED, ignore, ignore,
1203
uint8_t *, cJU_IMMED1_MAXPOP1,
1204
cJU_JPIMMED_1_02, cJU_JPIMMED_1_01, __JudySearchLeaf1,
1205
JU_LEAF1GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1206
__JudyAllocJLL1, __JudyFreeJLL1, JL_LEAF1VALUEAREA);
1212
JU_LEAF_UPLEVEL, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2,
1213
j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
1214
JU_LEAF_TOIMMED, ignore, ignore,
1215
uint8_t *, cJU_IMMED1_MAXPOP1,
1216
cJU_JPIMMED_1_02, cJU_JPIMMED_1_01, j__udySearchLeaf1,
1217
JU_LEAF1GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1218
j__udyAllocJLL1, j__udyFreeJLL1, JL_LEAF1VALUEAREA);
1209
1221
// A complicating factor is that for JudyL & 32-bit, a Leaf2 must go directly
1210
1222
// to an Immed 2_01 and a Leaf3 must go directly to an Immed 3_01:
1212
1224
// Leaf2 [[ => 2_07..04 ] => 2_03 => 2_02 ] => 2_01
1213
// Leaf3 [[ => 3_05..03 ] => 3_02 ] => 3_01
1225
// Leaf3 [[ => 3_05..03 ] => 3_02 ] => 3_01
1215
1227
// Hence use JU_LEAF_TOIMMED_23 instead of JU_LEAF_TOIMMED in the cases below,
1216
1228
// and also the parameters ToImmed and, for odd index sizes, CopyPIndex, are
1222
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF3_MAXPOP1, cJU_JPLEAF3,
1223
__JudyLeaf2ToLeaf3, __JudyAllocJLL3, JL_LEAF3VALUEAREA,
1224
JU_LEAF_TOIMMED_23, JU_TOIMMED_01_EVEN, ignore,
1225
uint16_t *, cJU_IMMED2_MAXPOP1,
1226
cJU_JPIMMED_2_02, cJU_JPIMMED_2_01, __JudySearchLeaf2,
1227
JU_LEAF2GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1228
__JudyAllocJLL2, __JudyFreeJLL2, JL_LEAF2VALUEAREA);
1234
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF3_MAXPOP1, cJU_JPLEAF3,
1235
j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
1236
JU_LEAF_TOIMMED_23, JU_TOIMMED_01_EVEN, ignore,
1237
uint16_t *, cJU_IMMED2_MAXPOP1,
1238
cJU_JPIMMED_2_02, cJU_JPIMMED_2_01, j__udySearchLeaf2,
1239
JU_LEAF2GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1240
j__udyAllocJLL2, j__udyFreeJLL2, JL_LEAF2VALUEAREA);
1230
1242
// On 32-bit there is no transition to "uplevel" for a Leaf3, so use
1231
1243
// JU_LEAF_UPLEVEL64 instead of JU_LEAF_UPLEVEL:
1236
JU_LEAF_UPLEVEL64, uint32_t *, cJU_LEAF4_MAXPOP1,
1238
__JudyLeaf3ToLeaf4, __JudyAllocJLL4, JL_LEAF4VALUEAREA,
1240
JU_TOIMMED_01_ODD, JU_COPY3_PINDEX_TO_LONG,
1241
uint8_t *, cJU_IMMED3_MAXPOP1,
1242
cJU_JPIMMED_3_02, cJU_JPIMMED_3_01, __JudySearchLeaf3,
1243
JU_LEAF3GROWINPLACE, JU_DELETEINPLACE_ODD,
1245
__JudyAllocJLL3, __JudyFreeJLL3, JL_LEAF3VALUEAREA);
1248
JU_LEAF_UPLEVEL64, uint32_t *, cJU_LEAF4_MAXPOP1,
1250
j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
1252
JU_TOIMMED_01_ODD, JU_COPY3_PINDEX_TO_LONG,
1253
uint8_t *, cJU_IMMED3_MAXPOP1,
1254
cJU_JPIMMED_3_02, cJU_JPIMMED_3_01, j__udySearchLeaf3,
1255
JU_LEAF3GROWINPLACE, JU_DELETEINPLACE_ODD,
1257
j__udyAllocJLL3, j__udyFreeJLL3, JL_LEAF3VALUEAREA);
1247
1259
#ifdef JU_64BIT
1257
1269
// Hence use JU_LEAF_TOIMMED_47 instead of JU_LEAF_TOIMMED in the cases below.
1262
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF5_MAXPOP1, cJU_JPLEAF5,
1263
__JudyLeaf4ToLeaf5, __JudyAllocJLL5, JL_LEAF5VALUEAREA,
1264
JU_LEAF_TOIMMED_47, JU_TOIMMED_01_EVEN, ignore,
1265
uint32_t *, cJU_IMMED4_MAXPOP1,
1266
cJ1_JPIMMED_4_02, cJU_JPIMMED_4_01, __JudySearchLeaf4,
1267
JU_LEAF4GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1268
__JudyAllocJLL4, __JudyFreeJLL4, JL_LEAF4VALUEAREA);
1273
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF6_MAXPOP1, cJU_JPLEAF6,
1274
__JudyLeaf5ToLeaf6, __JudyAllocJLL6, JL_LEAF6VALUEAREA,
1276
JU_TOIMMED_01_ODD, JU_COPY5_PINDEX_TO_LONG,
1277
uint8_t *, cJU_IMMED5_MAXPOP1,
1278
cJ1_JPIMMED_5_02, cJU_JPIMMED_5_01, __JudySearchLeaf5,
1279
JU_LEAF5GROWINPLACE, JU_DELETEINPLACE_ODD,
1281
__JudyAllocJLL5, __JudyFreeJLL5, JL_LEAF5VALUEAREA);
1286
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF7_MAXPOP1, cJU_JPLEAF7,
1287
__JudyLeaf6ToLeaf7, __JudyAllocJLL7, JL_LEAF7VALUEAREA,
1289
JU_TOIMMED_01_ODD, JU_COPY6_PINDEX_TO_LONG,
1290
uint8_t *, cJU_IMMED6_MAXPOP1,
1291
cJ1_JPIMMED_6_02, cJU_JPIMMED_6_01, __JudySearchLeaf6,
1292
JU_LEAF6GROWINPLACE, JU_DELETEINPLACE_ODD,
1294
__JudyAllocJLL6, __JudyFreeJLL6, JL_LEAF6VALUEAREA);
1274
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF5_MAXPOP1, cJU_JPLEAF5,
1275
j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
1276
JU_LEAF_TOIMMED_47, JU_TOIMMED_01_EVEN, ignore,
1277
uint32_t *, cJU_IMMED4_MAXPOP1,
1278
cJ1_JPIMMED_4_02, cJU_JPIMMED_4_01, j__udySearchLeaf4,
1279
JU_LEAF4GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1280
j__udyAllocJLL4, j__udyFreeJLL4, JL_LEAF4VALUEAREA);
1285
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF6_MAXPOP1, cJU_JPLEAF6,
1286
j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
1288
JU_TOIMMED_01_ODD, JU_COPY5_PINDEX_TO_LONG,
1289
uint8_t *, cJU_IMMED5_MAXPOP1,
1290
cJ1_JPIMMED_5_02, cJU_JPIMMED_5_01, j__udySearchLeaf5,
1291
JU_LEAF5GROWINPLACE, JU_DELETEINPLACE_ODD,
1293
j__udyAllocJLL5, j__udyFreeJLL5, JL_LEAF5VALUEAREA);
1298
JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF7_MAXPOP1, cJU_JPLEAF7,
1299
j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
1301
JU_TOIMMED_01_ODD, JU_COPY6_PINDEX_TO_LONG,
1302
uint8_t *, cJU_IMMED6_MAXPOP1,
1303
cJ1_JPIMMED_6_02, cJU_JPIMMED_6_01, j__udySearchLeaf6,
1304
JU_LEAF6GROWINPLACE, JU_DELETEINPLACE_ODD,
1306
j__udyAllocJLL6, j__udyFreeJLL6, JL_LEAF6VALUEAREA);
1296
1308
// There is no transition to "uplevel" for a Leaf7, so use JU_LEAF_UPLEVEL_NONE
1297
1309
// instead of JU_LEAF_UPLEVEL, and ignore all of the parameters to that macro:
1302
JU_LEAF_UPLEVEL_NONE, ignore1, ignore2, ignore3, ignore4,
1305
JU_TOIMMED_01_ODD, JU_COPY7_PINDEX_TO_LONG,
1306
uint8_t *, cJU_IMMED7_MAXPOP1,
1307
cJ1_JPIMMED_7_02, cJU_JPIMMED_7_01, __JudySearchLeaf7,
1308
JU_LEAF7GROWINPLACE, JU_DELETEINPLACE_ODD,
1310
__JudyAllocJLL7, __JudyFreeJLL7, JL_LEAF7VALUEAREA);
1314
JU_LEAF_UPLEVEL_NONE, ignore1, ignore2, ignore3, ignore4,
1317
JU_TOIMMED_01_ODD, JU_COPY7_PINDEX_TO_LONG,
1318
uint8_t *, cJU_IMMED7_MAXPOP1,
1319
cJ1_JPIMMED_7_02, cJU_JPIMMED_7_01, j__udySearchLeaf7,
1320
JU_LEAF7GROWINPLACE, JU_DELETEINPLACE_ODD,
1322
j__udyAllocJLL7, j__udyFreeJLL7, JL_LEAF7VALUEAREA);
1311
1323
#endif // JU_64BIT
1314
1326
// ****************************************************************************
1315
1327
// BITMAP LEAF:
1320
Pjv_t PjvnewRaw; // new value area.
1322
Word_t subexp; // 1 of 8 subexpanses in bitmap.
1323
Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
1324
BITMAPL_t bitmap; // for one subexpanse.
1325
BITMAPL_t bitmask; // bit set for Index's digit.
1332
Pjv_t PjvnewRaw; // new value area.
1334
Word_t subexp; // 1 of 8 subexpanses in bitmap.
1335
Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
1336
BITMAPL_t bitmap; // for one subexpanse.
1337
BITMAPL_t bitmask; // bit set for Indexs digit.
1327
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 1));
1328
assert(ParentLevel > 1);
1330
assert(JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index));
1332
pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
1334
// Like a Leaf1, see if it's under a narrow pointer and can become a Leaf2
1339
assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, 1));
1340
assert(ParentLevel > 1);
1342
assert(JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index));
1344
pop1 = JU_JPLEAF_POP0(Pjp) + 1;
1346
// Like a Leaf1, see if its under a narrow pointer and can become a Leaf2
1335
1347
// (hysteresis = 1):
1337
JU_LEAF_UPLEVEL(1, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2,
1338
__JudyLeaf1ToLeaf2, __JudyAllocJLL2,
1349
JU_LEAF_UPLEVEL(1, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2,
1350
j__udyLeaf1ToLeaf2, j__udyAllocJLL2,
1341
#if (JUDY1 && JU_64BIT)
1353
#if (defined(JUDY1) && defined(JU_64BIT))
1343
1355
// Handle the unusual special case, on Judy1 64-bit only, where a LeafB1 goes
1344
1356
// directly to a JPIMMED_1_15; as described in comments in Judy1.h and
1345
1357
// JudyIns.c. Copy 1-byte indexes from old LeafB1 to the Immed:
1347
if ((pop1 - 1) == cJU_IMMED1_MAXPOP1) // hysteresis = 0.
1349
Pjlb_t PjlbRaw; // bitmap in old leaf.
1351
uint8_t * Pleafnew; // JPIMMED as a pointer.
1352
Word_t ldigit; // larger than uint8_t.
1354
PjlbRaw = (Pjlb_t) (Pjp->jp_Addr);
1355
Pjlb = P_JLB(PjlbRaw);
1356
Pleafnew = Pjp->jp_1Index;
1358
JU_BITMAPCLEARL(Pjlb, Index); // unset Index's bit.
1359
if ((pop1 - 1) == cJU_IMMED1_MAXPOP1) // hysteresis = 0.
1361
Pjlb_t PjlbRaw; // bitmap in old leaf.
1363
uint8_t * Pleafnew; // JPIMMED as a pointer.
1364
Word_t ldigit; // larger than uint8_t.
1366
PjlbRaw = (Pjlb_t) (Pjp->jp_Addr);
1367
Pjlb = P_JLB(PjlbRaw);
1368
Pleafnew = Pjp->jp_1Index;
1370
JU_BITMAPCLEARL(Pjlb, Index); // unset Indexs bit.
1360
1372
// TBD: This is very slow, there must be a better way:
1362
for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit)
1364
if (JU_BITMAPTESTL(Pjlb, ldigit))
1366
*Pleafnew++ = ldigit;
1367
assert(Pleafnew - (Pjp->jp_1Index)
1368
<= cJU_IMMED1_MAXPOP1);
1372
DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index),
1373
cJU_IMMED1_MAXPOP1, 1);)
1374
__JudyFreeJLB1(PjlbRaw, Pjpm);
1376
Pjp->jp_Type = cJ1_JPIMMED_1_15;
1374
for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit)
1376
if (JU_BITMAPTESTL(Pjlb, ldigit))
1378
*Pleafnew++ = ldigit;
1379
assert(Pleafnew - (Pjp->jp_1Index)
1380
<= cJU_IMMED1_MAXPOP1);
1384
DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index),
1385
cJU_IMMED1_MAXPOP1, 1);)
1386
j__udyFreeJLB1(PjlbRaw, Pjpm);
1388
Pjp->jp_Type = cJ1_JPIMMED_1_15;
1380
1392
#else // (JUDYL || (! JU_64BIT))
1406
1418
// Get last byte to decode from Index, and pointer to bitmap leaf:
1408
digit = JU_DIGITATSTATE(Index, 1);
1409
Pjlb = P_JLB(Pjp->jp_Addr);
1420
digit = JU_DIGITATSTATE(Index, 1);
1421
Pjlb = P_JLB(Pjp->jp_Addr);
1411
1423
// Prepare additional values:
1413
subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
1414
bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexp's 32-bit map.
1415
PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
1417
bitmask = JU_BITPOSMASKL(digit); // mask for Index.
1419
assert(bitmap & bitmask); // Index must be valid.
1421
if (bitmap == cJU_FULLBITMAPL) // full bitmap, take shortcut:
1423
pop1 = cJU_BITSPERSUBEXPL;
1424
offset = digit % cJU_BITSPERSUBEXPL;
1426
else // compute subexpanse pop1 and value area offset:
1428
pop1 = __JudyCountBitsL(bitmap);
1429
offset = __JudyCountBitsL(bitmap & (bitmask - 1));
1425
subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
1426
bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map.
1427
PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
1429
bitmask = JU_BITPOSMASKL(digit); // mask for Index.
1431
assert(bitmap & bitmask); // Index must be valid.
1433
if (bitmap == cJU_FULLBITMAPL) // full bitmap, take shortcut:
1435
pop1 = cJU_BITSPERSUBEXPL;
1436
offset = digit % cJU_BITSPERSUBEXPL;
1438
else // compute subexpanse pop1 and value area offset:
1440
pop1 = j__udyCountBitsL(bitmap);
1441
offset = j__udyCountBitsL(bitmap & (bitmask - 1));
1432
1444
// Handle solitary Index remaining in subexpanse:
1436
__JudyLFreeJV(PjvRaw, 1, Pjpm);
1438
JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) NULL;
1439
JU_JLB_BITMAP(Pjlb, subexp) = 0;
1448
j__udyLFreeJV(PjvRaw, 1, Pjpm);
1450
JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) NULL;
1451
JU_JLB_BITMAP(Pjlb, subexp) = 0;
1444
1456
// Shrink value area in place or move to a smaller value area:
1446
if (JL_LEAFVGROWINPLACE(pop1 - 1)) // hysteresis = 0.
1448
JU_DELETEINPLACE(Pjv, pop1, offset, ignore);
1452
if ((PjvnewRaw = __JudyLAllocJV(pop1 - 1, Pjpm))
1453
== (Pjv_t) NULL) return(-1);
1454
Pjvnew = P_JV(PjvnewRaw);
1456
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);
1457
__JudyLFreeJV(PjvRaw, pop1, Pjpm);
1458
JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) PjvnewRaw;
1461
JU_JLB_BITMAP(Pjlb, subexp) ^= bitmask; // clear Index's bit.
1458
if (JL_LEAFVGROWINPLACE(pop1 - 1)) // hysteresis = 0.
1460
JU_DELETEINPLACE(Pjv, pop1, offset, ignore);
1464
if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm))
1465
== (Pjv_t) NULL) return(-1);
1466
Pjvnew = P_JV(PjvnewRaw);
1468
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);
1469
j__udyLFreeJV(PjvRaw, pop1, Pjpm);
1470
JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) PjvnewRaw;
1473
JU_JLB_BITMAP(Pjlb, subexp) ^= bitmask; // clear Indexs bit.
1463
1475
#endif // JUDYL
1521
1533
// Variables Pjp and parentJPtype are in the context.
1523
// Note: cJU_JPIMMED_*_01 should only be encountered in BranchU's, not in
1524
// BranchL's or BranchB's (where it's improper to merely modify the JP to be a
1535
// Note: cJU_JPIMMED_*_01 should only be encountered in BranchUs, not in
1536
// BranchLs or BranchBs (where its improper to merely modify the JP to be a
1525
1537
// null JP); that is, BranchL and BranchB code should have already handled
1526
1538
// any cJU_JPIMMED_*_01 by different means.
1528
#define JU_IMMED_01(NewJPType,ParentJPType) \
1530
assert(parentJPtype == (ParentJPType)); \
1531
assert((Pjp->jp_DcdPop0) == JU_TRIMTODCDSIZE(Index)); \
1533
(Pjp->jp_Type) = (NewJPType); \
1534
(Pjp->jp_DcdPop0) = 0; \
1535
(Pjp->jp_Addr) = 0; \
1540
#define JU_IMMED_01(NewJPType,ParentJPType) \
1542
assert(parentJPtype == (ParentJPType)); \
1543
assert(JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(Index)); \
1544
JU_JPSETADT(Pjp, 0, 0, NewJPType); \
1538
1547
// Convert cJ*_JPIMMED_*_02 to cJU_JPIMMED_*_01:
1540
1549
// Move the undeleted Index, whichever does not match the least bytes of Index,
1541
1550
// from undecoded-bytes-only (in jp_1Index or jp_LIndex as appropriate) to
1542
// jp_DcdPop0 (full-field). Pjp, Index, and offset are in the context.
1544
#define JU_IMMED_02(cIS,LeafType,NewJPType) \
1548
assert((ParentLevel - 1) == (cIS)); \
1549
JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \
1550
JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \
1551
JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1552
JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1553
JU_TOIMMED_01_EVEN(cIS, ignore, ignore); \
1554
JUDYLCODE(__JudyLFreeJV(PjvRaw, 2, Pjpm);) \
1555
(Pjp->jp_Type) = (NewJPType); \
1559
#if (JUDY1 || JU_64BIT)
1551
// jp_DcdPopO (full-field). Pjp, Index, and offset are in the context.
1553
#define JU_IMMED_02(cIS,LeafType,NewJPType) \
1557
assert((ParentLevel - 1) == (cIS)); \
1558
JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \
1559
JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \
1560
JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1561
JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1562
JU_TOIMMED_01_EVEN(cIS, ignore, ignore); \
1563
JUDYLCODE(j__udyLFreeJV(PjvRaw, 2, Pjpm);) \
1564
Pjp->jp_Type = (NewJPType); \
1568
#if (defined(JUDY1) || defined(JU_64BIT))
1561
1570
// Variation for "odd" cJ*_JPIMMED_*_02 JP types, which are very different from
1562
1571
// "even" types because they use leaf search code and odd-copy macros:
1564
1573
// Note: JudyL 32-bit has no "odd" JPIMMED_*_02 types.
1566
#define JU_IMMED_02_ODD(cIS,NewJPType,SearchLeaf,CopyPIndex) \
1570
assert((ParentLevel - 1) == (cIS)); \
1571
JUDY1CODE(Pleaf = (uint8_t *) (Pjp->jp_1Index);) \
1572
JUDYLCODE(Pleaf = (uint8_t *) (Pjp->jp_LIndex);) \
1573
JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1574
JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1575
JU_TOIMMED_01_ODD(cIS, SearchLeaf, CopyPIndex); \
1576
JUDYLCODE(__JudyLFreeJV(PjvRaw, 2, Pjpm);) \
1577
(Pjp->jp_Type) = (NewJPType); \
1575
#define JU_IMMED_02_ODD(cIS,NewJPType,SearchLeaf,CopyPIndex) \
1579
assert((ParentLevel - 1) == (cIS)); \
1580
JUDY1CODE(Pleaf = (uint8_t *) (Pjp->jp_1Index);) \
1581
JUDYLCODE(Pleaf = (uint8_t *) (Pjp->jp_LIndex);) \
1582
JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1583
JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1584
JU_TOIMMED_01_ODD(cIS, SearchLeaf, CopyPIndex); \
1585
JUDYLCODE(j__udyLFreeJV(PjvRaw, 2, Pjpm);) \
1586
Pjp->jp_Type = (NewJPType); \
1580
1589
#endif // (JUDY1 || JU_64BIT)
1582
1591
// Core code for deleting one Index (and for JudyL, its value area) from a
1585
1594
// Variables Pleaf, pop1, and offset are in the context.
1588
#define JU_IMMED_DEL(cIS,DeleteInPlace) \
1589
DeleteInPlace(Pleaf, pop1, offset, cIS); \
1590
DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);)
1597
#define JU_IMMED_DEL(cIS,DeleteInPlace) \
1598
DeleteInPlace(Pleaf, pop1, offset, cIS); \
1599
DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);)
1594
1603
// For JudyL the value area might need to be shrunk:
1596
#define JU_IMMED_DEL(cIS,DeleteInPlace) \
1598
if (JL_LEAFVGROWINPLACE(pop1 - 1)) /* hysteresis = 0 */ \
1600
DeleteInPlace( Pleaf, pop1, offset, cIS); \
1601
JU_DELETEINPLACE(Pjv, pop1, offset, ignore); \
1602
DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1609
if ((PjvnewRaw = __JudyLAllocJV(pop1 - 1, Pjpm)) \
1610
== (Pjv_t) NULL) return(-1); \
1611
Pjvnew = P_JV(PjvnewRaw); \
1613
DeleteInPlace(Pleaf, pop1, offset, cIS); \
1614
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore); \
1615
DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1616
__JudyLFreeJV(PjvRaw, pop1, Pjpm); \
1618
(Pjp->jp_Addr) = (Word_t) PjvnewRaw; \
1605
#define JU_IMMED_DEL(cIS,DeleteInPlace) \
1607
if (JL_LEAFVGROWINPLACE(pop1 - 1)) /* hysteresis = 0 */ \
1609
DeleteInPlace( Pleaf, pop1, offset, cIS); \
1610
JU_DELETEINPLACE(Pjv, pop1, offset, ignore); \
1611
DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1618
if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) \
1619
== (Pjv_t) NULL) return(-1); \
1620
Pjvnew = P_JV(PjvnewRaw); \
1622
DeleteInPlace(Pleaf, pop1, offset, cIS); \
1623
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore); \
1624
DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1625
j__udyLFreeJV(PjvRaw, pop1, Pjpm); \
1627
(Pjp->jp_Addr) = (Word_t) PjvnewRaw; \
1620
1629
#endif // JUDYL
1622
1631
// Delete one Index from a larger Immed where no restructuring is required:
1624
1633
// Variables pop1, Pjp, offset, and Index are in the context.
1626
#define JU_IMMED(cIS,LeafType,BaseJPType,SearchLeaf,DeleteInPlace) \
1630
assert((ParentLevel - 1) == (cIS)); \
1631
JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \
1632
JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \
1633
JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1634
JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1635
pop1 = (Pjp->jp_Type) - (BaseJPType) + 2; \
1636
offset = SearchLeaf(Pleaf, pop1, Index); \
1637
assert(offset >= 0); /* Index must be valid */ \
1639
JU_IMMED_DEL(cIS, DeleteInPlace); \
1635
#define JU_IMMED(cIS,LeafType,BaseJPType,SearchLeaf,DeleteInPlace) \
1639
assert((ParentLevel - 1) == (cIS)); \
1640
JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \
1641
JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \
1642
JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1643
JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1644
pop1 = (JU_JPTYPE(Pjp)) - (BaseJPType) + 2; \
1645
offset = SearchLeaf(Pleaf, pop1, Index); \
1646
assert(offset >= 0); /* Index must be valid */ \
1648
JU_IMMED_DEL(cIS, DeleteInPlace); \
1645
1654
// END OF MACROS, START OF CASES:
1647
1656
// Single Index remains in Immed; convert JP to null:
1649
case cJU_JPIMMED_1_01: JU_IMMED_01(cJU_JPNULL1, cJU_JPBRANCH_U2);
1650
case cJU_JPIMMED_2_01: JU_IMMED_01(cJU_JPNULL2, cJU_JPBRANCH_U3);
1658
case cJU_JPIMMED_1_01: JU_IMMED_01(cJU_JPNULL1, cJU_JPBRANCH_U2);
1659
case cJU_JPIMMED_2_01: JU_IMMED_01(cJU_JPNULL2, cJU_JPBRANCH_U3);
1651
1660
#ifndef JU_64BIT
1652
case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U);
1661
case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U);
1654
case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U4);
1655
case cJU_JPIMMED_4_01: JU_IMMED_01(cJU_JPNULL4, cJU_JPBRANCH_U5);
1656
case cJU_JPIMMED_5_01: JU_IMMED_01(cJU_JPNULL5, cJU_JPBRANCH_U6);
1657
case cJU_JPIMMED_6_01: JU_IMMED_01(cJU_JPNULL6, cJU_JPBRANCH_U7);
1658
case cJU_JPIMMED_7_01: JU_IMMED_01(cJU_JPNULL7, cJU_JPBRANCH_U);
1663
case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U4);
1664
case cJU_JPIMMED_4_01: JU_IMMED_01(cJU_JPNULL4, cJU_JPBRANCH_U5);
1665
case cJU_JPIMMED_5_01: JU_IMMED_01(cJU_JPNULL5, cJU_JPBRANCH_U6);
1666
case cJU_JPIMMED_6_01: JU_IMMED_01(cJU_JPNULL6, cJU_JPBRANCH_U7);
1667
case cJU_JPIMMED_7_01: JU_IMMED_01(cJU_JPNULL7, cJU_JPBRANCH_U);
1661
1670
// Multiple Indexes remain in the Immed JP; delete the specified Index:
1663
case cJU_JPIMMED_1_02:
1665
JU_IMMED_02(1, uint8_t *, cJU_JPIMMED_1_01);
1667
case cJU_JPIMMED_1_03:
1668
#if (JUDY1 || JU_64BIT)
1669
case cJU_JPIMMED_1_04:
1670
case cJU_JPIMMED_1_05:
1671
case cJU_JPIMMED_1_06:
1672
case cJU_JPIMMED_1_07:
1674
#if (JUDY1 && JU_64BIT)
1675
case cJ1_JPIMMED_1_08:
1676
case cJ1_JPIMMED_1_09:
1677
case cJ1_JPIMMED_1_10:
1678
case cJ1_JPIMMED_1_11:
1679
case cJ1_JPIMMED_1_12:
1680
case cJ1_JPIMMED_1_13:
1681
case cJ1_JPIMMED_1_14:
1682
case cJ1_JPIMMED_1_15:
1684
JU_IMMED(1, uint8_t *, cJU_JPIMMED_1_02,
1685
__JudySearchLeaf1, JU_DELETEINPLACE);
1687
#if (JUDY1 || JU_64BIT)
1688
case cJU_JPIMMED_2_02:
1690
JU_IMMED_02(2, uint16_t *, cJU_JPIMMED_2_01);
1692
case cJU_JPIMMED_2_03:
1694
#if (JUDY1 && JU_64BIT)
1695
case cJ1_JPIMMED_2_04:
1696
case cJ1_JPIMMED_2_05:
1697
case cJ1_JPIMMED_2_06:
1698
case cJ1_JPIMMED_2_07:
1700
#if (JUDY1 || JU_64BIT)
1701
JU_IMMED(2, uint16_t *, cJU_JPIMMED_2_02,
1702
__JudySearchLeaf2, JU_DELETEINPLACE);
1704
case cJU_JPIMMED_3_02:
1706
JU_IMMED_02_ODD(3, cJU_JPIMMED_3_01,
1707
__JudySearchLeaf3, JU_COPY3_PINDEX_TO_LONG);
1711
#if (JUDY1 && JU_64BIT)
1712
case cJ1_JPIMMED_3_03:
1713
case cJ1_JPIMMED_3_04:
1714
case cJ1_JPIMMED_3_05:
1716
JU_IMMED(3, uint8_t *, cJU_JPIMMED_3_02,
1717
__JudySearchLeaf3, JU_DELETEINPLACE_ODD);
1719
case cJ1_JPIMMED_4_02:
1721
JU_IMMED_02(4, uint32_t *, cJU_JPIMMED_4_01);
1723
case cJ1_JPIMMED_4_03:
1725
JU_IMMED(4, uint32_t *, cJ1_JPIMMED_4_02,
1726
__JudySearchLeaf4, JU_DELETEINPLACE);
1728
case cJ1_JPIMMED_5_02:
1730
JU_IMMED_02_ODD(5, cJU_JPIMMED_5_01,
1731
__JudySearchLeaf5, JU_COPY5_PINDEX_TO_LONG);
1733
case cJ1_JPIMMED_5_03:
1735
JU_IMMED(5, uint8_t *, cJ1_JPIMMED_5_02,
1736
__JudySearchLeaf5, JU_DELETEINPLACE_ODD);
1738
case cJ1_JPIMMED_6_02:
1740
JU_IMMED_02_ODD(6, cJU_JPIMMED_6_01,
1741
__JudySearchLeaf6, JU_COPY6_PINDEX_TO_LONG);
1743
case cJ1_JPIMMED_7_02:
1745
JU_IMMED_02_ODD(7, cJU_JPIMMED_7_01,
1746
__JudySearchLeaf7, JU_COPY7_PINDEX_TO_LONG);
1672
case cJU_JPIMMED_1_02:
1674
JU_IMMED_02(1, uint8_t *, cJU_JPIMMED_1_01);
1676
case cJU_JPIMMED_1_03:
1677
#if (defined(JUDY1) || defined(JU_64BIT))
1678
case cJU_JPIMMED_1_04:
1679
case cJU_JPIMMED_1_05:
1680
case cJU_JPIMMED_1_06:
1681
case cJU_JPIMMED_1_07:
1683
#if (defined(JUDY1) && defined(JU_64BIT))
1684
case cJ1_JPIMMED_1_08:
1685
case cJ1_JPIMMED_1_09:
1686
case cJ1_JPIMMED_1_10:
1687
case cJ1_JPIMMED_1_11:
1688
case cJ1_JPIMMED_1_12:
1689
case cJ1_JPIMMED_1_13:
1690
case cJ1_JPIMMED_1_14:
1691
case cJ1_JPIMMED_1_15:
1693
JU_IMMED(1, uint8_t *, cJU_JPIMMED_1_02,
1694
j__udySearchLeaf1, JU_DELETEINPLACE);
1696
#if (defined(JUDY1) || defined(JU_64BIT))
1697
case cJU_JPIMMED_2_02:
1699
JU_IMMED_02(2, uint16_t *, cJU_JPIMMED_2_01);
1701
case cJU_JPIMMED_2_03:
1703
#if (defined(JUDY1) && defined(JU_64BIT))
1704
case cJ1_JPIMMED_2_04:
1705
case cJ1_JPIMMED_2_05:
1706
case cJ1_JPIMMED_2_06:
1707
case cJ1_JPIMMED_2_07:
1709
#if (defined(JUDY1) || defined(JU_64BIT))
1710
JU_IMMED(2, uint16_t *, cJU_JPIMMED_2_02,
1711
j__udySearchLeaf2, JU_DELETEINPLACE);
1713
case cJU_JPIMMED_3_02:
1715
JU_IMMED_02_ODD(3, cJU_JPIMMED_3_01,
1716
j__udySearchLeaf3, JU_COPY3_PINDEX_TO_LONG);
1720
#if (defined(JUDY1) && defined(JU_64BIT))
1721
case cJ1_JPIMMED_3_03:
1722
case cJ1_JPIMMED_3_04:
1723
case cJ1_JPIMMED_3_05:
1725
JU_IMMED(3, uint8_t *, cJU_JPIMMED_3_02,
1726
j__udySearchLeaf3, JU_DELETEINPLACE_ODD);
1728
case cJ1_JPIMMED_4_02:
1730
JU_IMMED_02(4, uint32_t *, cJU_JPIMMED_4_01);
1732
case cJ1_JPIMMED_4_03:
1734
JU_IMMED(4, uint32_t *, cJ1_JPIMMED_4_02,
1735
j__udySearchLeaf4, JU_DELETEINPLACE);
1737
case cJ1_JPIMMED_5_02:
1739
JU_IMMED_02_ODD(5, cJU_JPIMMED_5_01,
1740
j__udySearchLeaf5, JU_COPY5_PINDEX_TO_LONG);
1742
case cJ1_JPIMMED_5_03:
1744
JU_IMMED(5, uint8_t *, cJ1_JPIMMED_5_02,
1745
j__udySearchLeaf5, JU_DELETEINPLACE_ODD);
1747
case cJ1_JPIMMED_6_02:
1749
JU_IMMED_02_ODD(6, cJU_JPIMMED_6_01,
1750
j__udySearchLeaf6, JU_COPY6_PINDEX_TO_LONG);
1752
case cJ1_JPIMMED_7_02:
1754
JU_IMMED_02_ODD(7, cJU_JPIMMED_7_01,
1755
j__udySearchLeaf7, JU_COPY7_PINDEX_TO_LONG);
1748
1757
#endif // (JUDY1 && JU_64BIT)
1797
1813
// Main entry point. See the manual entry for details.
1800
FUNCTION int Judy1Unset (
1816
FUNCTION int Judy1Unset
1802
FUNCTION int JudyLDel (
1818
FUNCTION int JudyLDel
1804
PPvoid_t PPArray, // in which to delete.
1805
Word_t Index, // to delete.
1806
PJError_t PJError) // optional, for returning error info.
1821
PPvoid_t PPArray, // in which to delete.
1822
Word_t Index, // to delete.
1823
PJError_t PJError // optional, for returning error info.
1808
Word_t pop1; // population of leaf.
1809
int offset; // at which to delete Index.
1810
JUDY1CODE(int retcode;) // return code from Judy1Test().
1826
Word_t pop1; // population of leaf.
1827
int offset; // at which to delete Index.
1828
JUDY1CODE(int retcode;) // return code from Judy1Test().
1811
1829
JUDYLCODE(PPvoid_t PPvalue;) // pointer from JudyLGet().
1814
1832
// CHECK FOR NULL ARRAY POINTER (error by caller):
1816
1834
if (PPArray == (PPvoid_t) NULL)
1818
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1836
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1823
1841
// CHECK IF INDEX IS INVALID:
1825
// If so, there's nothing to do. This saves a lot of time. Pass through
1843
// If so, theres nothing to do. This saves a lot of time. Pass through
1826
1844
// PJError, if any, from the "get" function.
1829
if ((retcode = Judy1Test(*PPArray, Index, PJError)) == JERRI)
1847
if ((retcode = Judy1Test(*PPArray, Index, PJError)) == JERRI)
1832
if (retcode == 0) return(0);
1850
if (retcode == 0) return(0);
1834
if ((PPvalue = JudyLGet(*PPArray, Index, PJError)) == PPJERR)
1852
if ((PPvalue = JudyLGet(*PPArray, Index, PJError)) == PPJERR)
1837
if (PPvalue == (PPvoid_t) NULL) return(0);
1855
if (PPvalue == (PPvoid_t) NULL) return(0);
1841
1859
// ****************************************************************************
1842
// PROCESS TOP LEVEL (JAP) BRANCHES AND LEAVES:
1844
ContinueDel: // for modifying state without recursing.
1846
switch (JAPTYPE(*PPArray))
1849
#if (LOW_POP && JUDYL)
1851
// ****************************************************************************
1854
// Check if Index is in the array (should always be). If so, free the leaf and
1855
// modify the root pointer. Hysteresis = 0; none is possible.
1857
case cJL_JAPLEAF_POPU1:
1859
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1860
assert(Pjlw[0] == Index);
1862
__JudyFreeJLW(Pjlw, /* pop1 = */ 1, (Pjpm_t) NULL);
1864
*PPArray = (Pvoid_t) NULL; // mark Judy array (JAP) as empty.
1865
DBGCODE(JudyCheckPop(*PPArray);)
1870
// ****************************************************************************
1873
// TBD: It is still debatable whether it is faster to have POPU2 types. It
1874
// needs to be measured. This is a lot of fuss for a 2-element array. -- Doug
1876
case cJL_JAPLEAF_POPU2:
1879
// Save the non-deleted Index (whichever it is) and convert the leaf to a
1880
// CJL_JAPLEAF_POPU1 (which is smaller). Hysteresis = 0; none is possible.
1882
// TBD: Once again, this would be much cleaner using a data structure.
1884
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1885
Pjlw_t Pjlwnew = __JudyAllocJLW(2 - 1);
1886
JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
1888
offset = (Index == Pjlw[0]); // 0 or 1 == undeleted Index.
1889
Pjlwnew[0] = Pjlw[0 + offset]; // undeleted Index.
1890
Pjlwnew[1] = Pjlw[2 + offset]; // its value area.
1892
__JudyFreeJLW(Pjlw, /* pop1 = */ 2, (Pjpm_t) NULL);
1894
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJL_JAPLEAF_POPU1);
1895
DBGCODE(JudyCheckPop(*PPArray);)
1898
} // case cJL_JAPLEAF_POPU2.
1900
#endif // (LOW_POP && JUDYL)
1903
// ****************************************************************************
1904
// JAP LEAF, OTHER SIZE:
1860
// PROCESS TOP LEVEL (LEAFW) BRANCHES AND LEAVES:
1862
// ****************************************************************************
1863
// LEAFW LEAF, OTHER SIZE:
1906
1865
// Shrink or convert the leaf as necessary. Hysteresis = 0; none is possible.
1910
JUDYLCODE(Pjv_t Pjv;) // current value area.
1911
JUDYLCODE(Pjv_t Pjvnew;) // value area in new leaf.
1912
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1913
Pjlw_t Pjlwnew; // replacement leaf.
1914
pop1 = Pjlw[0] + 1; // first word of leaf is pop0.
1867
if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
1869
JUDYLCODE(Pjv_t Pjv;) // current value area.
1870
JUDYLCODE(Pjv_t Pjvnew;) // value area in new leaf.
1871
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1872
Pjlw_t Pjlwnew; // replacement leaf.
1873
pop1 = Pjlw[0] + 1; // first word of leaf is pop0.
1916
1875
// Delete single (last) Index from array:
1920
__JudyFreeJLW(Pjlw, /* pop1 = */ 1, (Pjpm_t) NULL);
1921
*PPArray = (Pvoid_t) NULL;
1879
j__udyFreeJLW(Pjlw, /* pop1 = */ 1, (Pjpm_t) NULL);
1880
*PPArray = (Pvoid_t) NULL;
1925
1884
// Locate Index in compressible leaf:
1927
offset = __JudySearchLeafW(Pjlw + 1, pop1, Index);
1928
assert(offset >= 0); // Index must be valid.
1886
offset = j__udySearchLeafW(Pjlw + 1, pop1, Index);
1887
assert(offset >= 0); // Index must be valid.
1930
1889
JUDYLCODE(Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);)
1935
1894
// place from pop1." Also, Pjlw points to the count word, so skip that for
1936
1895
// doing the deletion.
1938
if (JU_LEAFWGROWINPLACE(pop1 - 1))
1940
JU_DELETEINPLACE(Pjlw + 1, pop1, offset, ignore);
1897
if (JU_LEAFWGROWINPLACE(pop1 - 1))
1899
JU_DELETEINPLACE(Pjlw + 1, pop1, offset, ignore);
1941
1900
#ifdef JUDYL // also delete from value area:
1942
JU_DELETEINPLACE(Pjv, pop1, offset, ignore);
1901
JU_DELETEINPLACE(Pjv, pop1, offset, ignore);
1944
DBGCODE(JudyCheckSorted((Pjll_t) (Pjlw + 1), pop1 - 1,
1946
--(Pjlw[0]); // decrement population.
1947
DBGCODE(JudyCheckPop(*PPArray);)
1903
DBGCODE(JudyCheckSorted((Pjll_t) (Pjlw + 1), pop1 - 1,
1905
--(Pjlw[0]); // decrement population.
1906
DBGCODE(JudyCheckPop(*PPArray);)
1951
1910
// Allocate new leaf for use in either case below:
1953
Pjlwnew = __JudyAllocJLW(pop1 - 1);
1954
JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
1956
#if (LOW_POP && JUDYL)
1957
// Shrink leaf to a cJL_JAPLEAF_POPU2:
1959
// Note: The "3" below is equal to pop1, but faster because it's a constant.
1961
if ((pop1 - 1) == 2)
1963
JU_DELETECOPY(Pjlwnew + 0, Pjlw + 1, 3, offset, ignore);
1964
JU_DELETECOPY(Pjlwnew + 2, Pjv, 3, offset, ignore);
1965
DBGCODE(JudyCheckSorted(Pjlwnew, 2, cJU_ROOTSTATE);)
1967
__JudyFreeJLW(Pjlw, pop1, (Pjpm_t) NULL);
1969
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJL_JAPLEAF_POPU2);
1970
DBGCODE(JudyCheckPop(*PPArray);)
1973
#endif // (LOW_POP && JUDYL)
1975
// Shrink to smaller JAPLEAF:
1912
Pjlwnew = j__udyAllocJLW(pop1 - 1);
1913
JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
1915
// Shrink to smaller LEAFW:
1977
1917
// Note: Skip the first word = pop0 in each leaf.
1979
Pjlwnew[0] = (pop1 - 1) - 1;
1980
JU_DELETECOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, ignore);
1919
Pjlwnew[0] = (pop1 - 1) - 1;
1920
JU_DELETECOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, ignore);
1982
1922
#ifdef JUDYL // also delete from value area:
1983
Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 - 1);
1984
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);
1923
Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 - 1);
1924
JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);
1986
DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 - 1, cJU_ROOTSTATE);)
1988
__JudyFreeJLW(Pjlw, pop1, (Pjpm_t) NULL);
1990
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_JAPLEAF);
1991
DBGCODE(JudyCheckPop(*PPArray);)
1994
} // case cJU_JAPLEAF.
1926
DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 - 1, cJU_ROOTSTATE);)
1928
j__udyFreeJLW(Pjlw, pop1, (Pjpm_t) NULL);
1930
//// *PPArray = (Pvoid_t) Pjlwnew | cJU_LEAFW);
1931
*PPArray = (Pvoid_t) Pjlwnew;
1932
DBGCODE(JudyCheckPop(*PPArray);)
1997
1939
// ****************************************************************************
2000
1942
// Traverse through the JPM to do the deletion unless the population is small
2001
// enough to convert immediately to a JAPLEAF.
1943
// enough to convert immediately to a LEAFW.
2006
Pjp_t Pjp; // top-level JP to process.
2007
Word_t digit; // in a branch.
2008
JUDYLCODE(Pjv_t Pjv;) // to value area.
2009
Pjlw_t Pjlwnew; // replacement leaf.
1947
Pjp_t Pjp; // top-level JP to process.
1948
Word_t digit; // in a branch.
1949
JUDYLCODE(Pjv_t Pjv;) // to value area.
1950
Pjlw_t Pjlwnew; // replacement leaf.
2010
1951
DBGCODE(Pjlw_t Pjlwnew_orig;)
2012
Pjpm = P_JPM(*PPArray); // top object in array (tree).
2013
Pjp = &(Pjpm->jpm_JP); // next object (first branch or leaf).
2015
assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
2016
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
2017
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
2020
// CANNOT COMPRESS TO A JAPLEAF => WALK THE TREE (THE NORMAL CASE):
2022
// Hysteresis = 1, that is, do not compress to a leaf the first time it could
2023
// actually be done.
2025
// Note: Recursive code in __JudyDelWalk() knows how to collapse a lower-level
1953
Pjpm = P_JPM(*PPArray); // top object in array (tree).
1954
Pjp = &(Pjpm->jpm_JP); // next object (first branch or leaf).
1956
assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
1957
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
1958
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
1962
// Note: Recursive code in j__udyDelWalk() knows how to collapse a lower-level
2026
1963
// BranchL containing a single JP into the parent JP as a narrow pointer, but
2027
// the code here can't do that for a top-level BranchL. The result can be
2028
// PArray -> JPM -> JAPBranchL containing a single JP. This situation is
1964
// the code here cant do that for a top-level BranchL. The result can be
1965
// PArray -> JPM -> BranchL containing a single JP. This situation is
2029
1966
// unavoidable because a JPM cannot contain a narrow pointer; the BranchL is
2030
1967
// required in order to hold the top digit decoded, and it does not collapse to
2031
// a JAPLEAF until the population is low enough.
1968
// a LEAFW until the population is low enough.
2033
1970
// TBD: Should we add a topdigit field to JPMs so they can hold narrow
2036
if ((Pjpm->jpm_Pop0 + 1) > cJU_JAPLEAF_MAXPOP1) // see above.
2038
if (__JudyDelWalk(Pjp, Index, cJU_ROOTSTATE, Pjpm) == -1)
2040
JU_COPY_ERRNO(PJError, Pjpm);
2044
--(Pjpm->jpm_Pop0); // success; decrement total population.
2045
DBGCODE(JudyCheckPop(*PPArray);)
2050
// COMPRESS A BRANCH[LBU] TO A JAPLEAF:
1973
if (j__udyDelWalk(Pjp, Index, cJU_ROOTSTATE, Pjpm) == -1)
1975
JU_COPY_ERRNO(PJError, Pjpm);
1979
--(Pjpm->jpm_Pop0); // success; decrement total population.
1981
if ((Pjpm->jpm_Pop0 + 1) != cJU_LEAFW_MAXPOP1)
1983
DBGCODE(JudyCheckPop(*PPArray);)
1987
// COMPRESS A BRANCH[LBU] TO A LEAFW:
2052
// Then start over to delete the Index from the new leaf. In other words,
2053
// "compress and then delete."
2055
assert((Pjpm->jpm_Pop0) + 1 == cJU_JAPLEAF_MAXPOP1);
2057
Pjlwnew = __JudyAllocJLW(cJU_JAPLEAF_MAXPOP1);
2058
JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
1989
Pjlwnew = j__udyAllocJLW(cJU_LEAFW_MAXPOP1);
1990
JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
2060
1992
// Plug leaf into root pointer and set population count:
2062
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_JAPLEAF);
1994
//// *PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_LEAFW);
1995
*PPArray = (Pvoid_t) Pjlwnew;
2063
1996
#ifdef JUDYL // prepare value area:
2064
Pjv = JL_LEAFWVALUEAREA(Pjlwnew, cJU_JAPLEAF_MAXPOP1);
1997
Pjv = JL_LEAFWVALUEAREA(Pjlwnew, cJU_LEAFW_MAXPOP1);
2066
*Pjlwnew++ = cJU_JAPLEAF_MAXPOP1 - 1; // set pop0.
2067
DBGCODE(Pjlwnew_orig = Pjlwnew;)
2069
switch (Pjp->jp_Type)
2073
// JPBRANCH_L: Copy each JP's indexes to the new JAPLEAF and free the old
1999
*Pjlwnew++ = cJU_LEAFW_MAXPOP1 - 1; // set pop0.
2000
DBGCODE(Pjlwnew_orig = Pjlwnew;)
2002
switch (JU_JPTYPE(Pjp))
2005
// JPBRANCH_L: Copy each JPs indexes to the new LEAFW and free the old
2076
case cJU_JPBRANCH_L:
2078
Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
2079
Pjbl_t Pjbl = P_JBL(PjblRaw);
2081
for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
2083
pop1 = __JudyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2084
(Pjbl->jbl_jp) + offset,
2085
JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset],
2088
Pjlwnew += pop1; // advance through indexes.
2089
JUDYLCODE(Pjv += pop1;) // advance through values.
2091
__JudyFreeJBL(PjblRaw, Pjpm);
2093
assert(Pjlwnew == Pjlwnew_orig + cJU_JAPLEAF_MAXPOP1);
2094
break; // delete Index from new JAPLEAF.
2098
// JPBRANCH_B: Copy each JP's indexes to the new JAPLEAF and free the old
2008
case cJU_JPBRANCH_L:
2010
Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
2011
Pjbl_t Pjbl = P_JBL(PjblRaw);
2013
for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
2015
pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2016
(Pjbl->jbl_jp) + offset,
2017
JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset],
2020
Pjlwnew += pop1; // advance through indexes.
2021
JUDYLCODE(Pjv += pop1;) // advance through values.
2023
j__udyFreeJBL(PjblRaw, Pjpm);
2025
assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1);
2026
break; // delete Index from new LEAFW.
2029
// JPBRANCH_B: Copy each JPs indexes to the new LEAFW and free the old
2099
2030
// branch, including each JP subarray:
2101
case cJU_JPBRANCH_B:
2103
Pjbb_t PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
2104
Pjbb_t Pjbb = P_JBB(PjbbRaw);
2105
Word_t subexp; // current subexpanse number.
2106
BITMAPB_t bitmap; // portion for this subexpanse.
2107
Pjp_t Pjp2Raw; // one subexpanse's subarray.
2110
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
2112
if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0)
2113
continue; // skip empty subexpanse.
2115
digit = subexp * cJU_BITSPERSUBEXPB;
2116
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
2117
Pjp2 = P_JP(Pjp2Raw);
2118
assert(Pjp2 != (Pjp_t) NULL);
2032
case cJU_JPBRANCH_B:
2034
Pjbb_t PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
2035
Pjbb_t Pjbb = P_JBB(PjbbRaw);
2036
Word_t subexp; // current subexpanse number.
2037
BITMAPB_t bitmap; // portion for this subexpanse.
2038
Pjp_t Pjp2Raw; // one subexpanses subarray.
2041
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
2043
if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0)
2044
continue; // skip empty subexpanse.
2046
digit = subexp * cJU_BITSPERSUBEXPB;
2047
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
2048
Pjp2 = P_JP(Pjp2Raw);
2049
assert(Pjp2 != (Pjp_t) NULL);
2120
2051
// Walk through bits for all possible sub-subexpanses (digits); increment
2121
2052
// offset for each populated subexpanse; until no more set bits:
2123
for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit)
2125
if (! (bitmap & 1)) // skip empty sub-subexpanse.
2128
pop1 = __JudyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2130
JU_DIGITTOSTATE(digit, cJU_BYTESPERWORD),
2132
Pjlwnew += pop1; // advance through indexes.
2133
JUDYLCODE(Pjv += pop1;) // advance through values.
2136
__JudyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm);
2138
__JudyFreeJBB(PjbbRaw, Pjpm);
2140
assert(Pjlwnew == Pjlwnew_orig + cJU_JAPLEAF_MAXPOP1);
2141
break; // delete Index from new JAPLEAF.
2143
} // case cJU_JPBRANCH_B.
2146
// JPBRANCH_U: Copy each JP's indexes to the new JAPLEAF and free the old
2054
for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit)
2056
if (! (bitmap & 1)) // skip empty sub-subexpanse.
2059
pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2061
JU_DIGITTOSTATE(digit, cJU_BYTESPERWORD),
2063
Pjlwnew += pop1; // advance through indexes.
2064
JUDYLCODE(Pjv += pop1;) // advance through values.
2067
j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm);
2069
j__udyFreeJBB(PjbbRaw, Pjpm);
2071
assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1);
2072
break; // delete Index from new LEAFW.
2074
} // case cJU_JPBRANCH_B.
2077
// JPBRANCH_U: Copy each JPs indexes to the new LEAFW and free the old
2149
case cJU_JPBRANCH_U:
2151
Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr);
2152
Pjbu_t Pjbu = P_JBU(PjbuRaw);
2153
Word_t ldigit; // larger than uint8_t.
2080
case cJU_JPBRANCH_U:
2082
Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr);
2083
Pjbu_t Pjbu = P_JBU(PjbuRaw);
2084
Word_t ldigit; // larger than uint8_t.
2155
for (Pjp = Pjbu->jbu_jp, ldigit = 0;
2156
ldigit < cJU_BRANCHUNUMJPS;
2086
for (Pjp = Pjbu->jbu_jp, ldigit = 0;
2087
ldigit < cJU_BRANCHUNUMJPS;
2160
2091
// Shortcuts, to save a little time for possibly big branches:
2162
if ((Pjp->jp_Type) == cJU_JPNULLMAX) // skip null JP.
2093
if ((JU_JPTYPE(Pjp)) == cJU_JPNULLMAX) // skip null JP.
2165
2096
// TBD: Should the following shortcut also be used in BranchL and BranchB
2168
2099
#ifndef JU_64BIT
2169
if ((Pjp->jp_Type) == cJU_JPIMMED_3_01)
2100
if ((JU_JPTYPE(Pjp)) == cJU_JPIMMED_3_01)
2171
if ((Pjp->jp_Type) == cJU_JPIMMED_7_01)
2102
if ((JU_JPTYPE(Pjp)) == cJU_JPIMMED_7_01)
2174
*Pjlwnew++ = JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD)
2175
| (Pjp->jp_DcdPop0); // rebuild Index.
2105
*Pjlwnew++ = JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD)
2106
| JU_JPDCDPOP0(Pjp); // rebuild Index.
2177
*Pjv++ = Pjp->jp_Addr; // copy value area.
2108
*Pjv++ = Pjp->jp_Addr; // copy value area.
2182
pop1 = __JudyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2183
Pjp, JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD),
2185
Pjlwnew += pop1; // advance through indexes.
2186
JUDYLCODE(Pjv += pop1;) // advance through values.
2188
__JudyFreeJBU(PjbuRaw, Pjpm);
2190
assert(Pjlwnew == Pjlwnew_orig + cJU_JAPLEAF_MAXPOP1);
2191
break; // delete Index from new JAPLEAF.
2193
} // case cJU_JPBRANCH_U.
2196
// INVALID JP TYPE UNDER A JAPBRANCH:
2198
default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
2201
} // end switch on sub-JP type.
2203
DBGCODE(JudyCheckSorted((Pjll_t) Pjlwnew_orig, cJU_JAPLEAF_MAXPOP1,
2113
pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2114
Pjp, JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD),
2116
Pjlwnew += pop1; // advance through indexes.
2117
JUDYLCODE(Pjv += pop1;) // advance through values.
2119
j__udyFreeJBU(PjbuRaw, Pjpm);
2121
assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1);
2122
break; // delete Index from new LEAFW.
2124
} // case cJU_JPBRANCH_U.
2127
// INVALID JP TYPE in jpm_t struct
2129
default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
2132
} // end switch on sub-JP type.
2134
DBGCODE(JudyCheckSorted((Pjll_t) Pjlwnew_orig, cJU_LEAFW_MAXPOP1,
2207
2137
// FREE JPM (no longer needed):
2209
__JudyFreeJPM(Pjpm, (Pjpm_t) NULL);
2210
DBGCODE(JudyCheckPop(*PPArray);)
2211
goto ContinueDel; // delete Index from new leaf.
2213
} // end case cJU_JAPBRANCH.
2216
// INVALID ROOT (JAP) POINTER:
2219
JUDY1CODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDY1);)
2220
JUDYLCODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDYL);)
2223
} // switch on JP type.
2139
j__udyFreeJPM(Pjpm, (Pjpm_t) NULL);
2140
DBGCODE(JudyCheckPop(*PPArray);)
2227
2146
} // Judy1Unset() / JudyLDel()