54
54
// could be merged with this file, either in SoftCM or at compile-time.
57
extern int __Judy1CreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
58
extern int __Judy1CreateBranchU(Pjp_t, Pvoid_t);
57
extern int j__udy1CreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
58
extern int j__udy1CreateBranchU(Pjp_t, Pvoid_t);
61
extern int __Judy1Cascade1(Pjp_t, Pvoid_t);
61
extern int j__udy1Cascade1(Pjp_t, Pvoid_t);
63
extern int __Judy1Cascade2(Pjp_t, Pvoid_t);
64
extern int __Judy1Cascade3(Pjp_t, Pvoid_t);
63
extern int j__udy1Cascade2(Pjp_t, Pvoid_t);
64
extern int j__udy1Cascade3(Pjp_t, Pvoid_t);
66
extern int __Judy1Cascade4(Pjp_t, Pvoid_t);
67
extern int __Judy1Cascade5(Pjp_t, Pvoid_t);
68
extern int __Judy1Cascade6(Pjp_t, Pvoid_t);
69
extern int __Judy1Cascade7(Pjp_t, Pvoid_t);
66
extern int j__udy1Cascade4(Pjp_t, Pvoid_t);
67
extern int j__udy1Cascade5(Pjp_t, Pvoid_t);
68
extern int j__udy1Cascade6(Pjp_t, Pvoid_t);
69
extern int j__udy1Cascade7(Pjp_t, Pvoid_t);
71
extern int __Judy1CascadeL(Pjp_t, Pvoid_t);
71
extern int j__udy1CascadeL(Pjp_t, Pvoid_t);
73
extern int __Judy1InsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
73
extern int j__udy1InsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
77
extern int __JudyLCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
78
extern int __JudyLCreateBranchU(Pjp_t, Pvoid_t);
77
extern int j__udyLCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
78
extern int j__udyLCreateBranchU(Pjp_t, Pvoid_t);
80
extern int __JudyLCascade1(Pjp_t, Pvoid_t);
81
extern int __JudyLCascade2(Pjp_t, Pvoid_t);
82
extern int __JudyLCascade3(Pjp_t, Pvoid_t);
80
extern int j__udyLCascade1(Pjp_t, Pvoid_t);
81
extern int j__udyLCascade2(Pjp_t, Pvoid_t);
82
extern int j__udyLCascade3(Pjp_t, Pvoid_t);
84
extern int __JudyLCascade4(Pjp_t, Pvoid_t);
85
extern int __JudyLCascade5(Pjp_t, Pvoid_t);
86
extern int __JudyLCascade6(Pjp_t, Pvoid_t);
87
extern int __JudyLCascade7(Pjp_t, Pvoid_t);
84
extern int j__udyLCascade4(Pjp_t, Pvoid_t);
85
extern int j__udyLCascade5(Pjp_t, Pvoid_t);
86
extern int j__udyLCascade6(Pjp_t, Pvoid_t);
87
extern int j__udyLCascade7(Pjp_t, Pvoid_t);
89
extern int __JudyLCascadeL(Pjp_t, Pvoid_t);
89
extern int j__udyLCascadeL(Pjp_t, Pvoid_t);
91
extern int __JudyLInsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
91
extern int j__udyLInsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
186
186
// Convert JP in place from current null type to cJU_JPIMMED_*_01 by
187
187
// calculating new JP type.
198
assert((Pjp->jp_Addr) == 0);
200
(Pjp->jp_DcdPop0) = Index; // truncates.
201
// TBD: Make this a macro:
202
(Pjp->jp_Type) = (Pjp->jp_Type) + cJU_JPIMMED_1_01 - cJU_JPNULL1;
198
assert((Pjp->jp_Addr) == 0);
199
JU_JPSETADT(Pjp, 0, Index, JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01 - cJU_JPNULL1);
204
// value area is first word of new Immed_01 JP:
205
Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
201
// value area is first word of new Immed_01 JP:
202
Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
210
207
// ****************************************************************************
213
// If the new Index is not an outlier to the branch's expanse, and the branch
210
// If the new Index is not an outlier to the branchs expanse, and the branch
214
211
// should not be converted to uncompressed, extract the digit and record the
215
212
// Immediate type to create for a new Immed JP, before going to common code.
217
214
// Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit.
219
#define JU_BRANCH_OUTLIER(DIGIT,POP1,cLEVEL,PJP,INDEX,PJPM) \
220
JU_CHECK_IF_OUTLIER(PJP, INDEX, cLEVEL, PJPM); \
221
(DIGIT) = JU_DIGITATSTATE(INDEX, cLEVEL); \
222
(POP1) = JU_JPBRANCH_POP0((PJP)->jp_DcdPop0, cLEVEL)
224
case cJU_JPBRANCH_L2:
225
JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
228
case cJU_JPBRANCH_L3:
229
JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
216
#define JU_BRANCH_OUTLIER(DIGIT,POP1,cLEVEL,PJP,INDEX,PJPM) \
217
JU_CHECK_IF_OUTLIER(PJP, INDEX, cLEVEL, PJPM); \
218
(DIGIT) = JU_DIGITATSTATE(INDEX, cLEVEL); \
219
(POP1) = JU_JPBRANCH_POP0(PJP, cLEVEL)
221
case cJU_JPBRANCH_L2:
222
JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
225
case cJU_JPBRANCH_L3:
226
JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
233
case cJU_JPBRANCH_L4:
234
JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
237
case cJU_JPBRANCH_L5:
238
JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
241
case cJU_JPBRANCH_L6:
242
JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
245
case cJU_JPBRANCH_L7:
246
JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
230
case cJU_JPBRANCH_L4:
231
JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
234
case cJU_JPBRANCH_L5:
235
JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
238
case cJU_JPBRANCH_L6:
239
JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
242
case cJU_JPBRANCH_L7:
243
JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
250
247
// Similar to common code above, but no outlier check is needed, and the Immed
251
248
// type depends on the word size:
255
Pjbl_t PjblRaw; // pointer to old linear branch.
257
Pjbu_t PjbuRaw; // pointer to new uncompressed branch.
259
Word_t numJPs; // number of JPs = populated expanses.
260
int offset; // in branch.
262
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
263
exppop1 = Pjpm->jpm_Pop0;
252
Pjbl_t PjblRaw; // pointer to old linear branch.
254
Pjbu_t PjbuRaw; // pointer to new uncompressed branch.
256
Word_t numJPs; // number of JPs = populated expanses.
257
int offset; // in branch.
259
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
260
exppop1 = Pjpm->jpm_Pop0;
267
264
// COMMON CODE FOR LINEAR BRANCHES:
269
266
// Come here with digit and exppop1 already set.
272
PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
273
Pjbl = P_JBL(PjblRaw);
269
PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
270
Pjbl = P_JBL(PjblRaw);
275
272
// If population under this branch greater than:
277
if (exppop1 > JU_BRANCHL_MAX_POP)
278
goto ConvertBranchLtoU;
274
if (exppop1 > JU_BRANCHL_MAX_POP)
275
goto ConvertBranchLtoU;
280
numJPs = Pjbl->jbl_NumJPs;
277
numJPs = Pjbl->jbl_NumJPs;
282
279
if ((numJPs == 0) || (numJPs > cJU_BRANCHLMAXJPS))
288
285
// Search for a match to the digit:
290
offset = __JudySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse), numJPs,
287
offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse), numJPs,
293
290
// If Index is found, offset is into an array of 1..cJU_BRANCHLMAXJPS JPs:
297
Pjp = (Pjbl->jbl_jp) + offset; // address of next JP.
298
break; // continue walk.
294
Pjp = (Pjbl->jbl_jp) + offset; // address of next JP.
295
break; // continue walk.
301
298
// Expanse is missing (not populated) for the passed Index, so insert an Immed
302
// -- if there's room:
304
if (numJPs < cJU_BRANCHLMAXJPS)
306
offset = ~offset; // insertion offset.
308
newJP.jp_Addr = 0; // initial value (mainly for JudyL).
309
newJP.jp_DcdPop0 = Index; // truncates.
310
newJP.jp_Type = Pjp->jp_Type +
311
cJU_JPIMMED_1_01-cJU_JPBRANCH_L2;
313
JU_INSERTINPLACE(Pjbl->jbl_Expanse, numJPs, offset, digit);
314
JU_INSERTINPLACE(Pjbl->jbl_jp, numJPs, offset, newJP);
316
DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse),
317
numJPs + 1, /* IndexSize = */ 1);)
318
++(Pjbl->jbl_NumJPs);
299
// -- if theres room:
301
if (numJPs < cJU_BRANCHLMAXJPS)
303
offset = ~offset; // insertion offset.
305
JU_JPSETADT(&newJP, 0, Index,
306
JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_L2);
308
JU_INSERTINPLACE(Pjbl->jbl_Expanse, numJPs, offset, digit);
309
JU_INSERTINPLACE(Pjbl->jbl_jp, numJPs, offset, newJP);
311
DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse),
312
numJPs + 1, /* IndexSize = */ 1);)
313
++(Pjbl->jbl_NumJPs);
320
// value area is first word of new Immed 01 JP:
321
Pjpm->jpm_PValue = (Pjv_t) ((Pjbl->jbl_jp) + offset);
315
// value area is first word of new Immed 01 JP:
316
Pjpm->jpm_PValue = (Pjv_t) ((Pjbl->jbl_jp) + offset);
327
322
// MAXED OUT LINEAR BRANCH, CONVERT TO A BITMAP BRANCH, THEN INSERT:
329
324
// Copy the linear branch to a bitmap branch.
331
// TBD: Consider renaming __JudyCreateBranchB() to __JudyConvertBranchLtoB().
333
assert((numJPs) <= cJU_BRANCHLMAXJPS);
335
if (__JudyCreateBranchB(Pjp, Pjbl->jbl_jp, Pjbl->jbl_Expanse,
326
// TBD: Consider renaming j__udyCreateBranchB() to j__udyConvertBranchLtoB().
328
assert((numJPs) <= cJU_BRANCHLMAXJPS);
330
if (j__udyCreateBranchB(Pjp, Pjbl->jbl_jp, Pjbl->jbl_Expanse,
341
336
// Convert jp_Type from linear branch to equivalent bitmap branch:
343
(Pjp->jp_Type) += cJU_JPBRANCH_B - cJU_JPBRANCH_L;
338
Pjp->jp_Type += cJU_JPBRANCH_B - cJU_JPBRANCH_L;
345
__JudyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
340
j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
347
342
// Having changed branch types, now do the insert in the new branch type:
349
goto ContinueInsWalk;
344
goto ContinueInsWalk;
352
347
// OPPORTUNISTICALLY CONVERT FROM BRANCHL TO BRANCHU:
354
// Memory efficiency is no object because the branch's pop1 is large enough, so
349
// Memory efficiency is no object because the branchs pop1 is large enough, so
355
350
// speed up array access. Come here with PjblRaw set. Note: This is goto
356
351
// code because the previous block used to fall through into it as well, but no
361
356
// Allocate memory for an uncompressed branch:
363
if ((PjbuRaw = __JudyAllocJBU(Pjpm)) == (Pjbu_t) NULL)
365
Pjbu = P_JBU(PjbuRaw);
367
// Set the proper NULL type for most of the uncompressed branch's JPs:
370
newJP.jp_DcdPop0 = 0;
371
newJP.jp_Type = Pjp->jp_Type - cJU_JPBRANCH_L2 + cJU_JPNULL1;
358
if ((PjbuRaw = j__udyAllocJBU(Pjpm)) == (Pjbu_t) NULL)
360
Pjbu = P_JBU(PjbuRaw);
362
// Set the proper NULL type for most of the uncompressed branchs JPs:
364
JU_JPSETADT(&newJP, 0, 0,
365
JU_JPTYPE(Pjp) - cJU_JPBRANCH_L2 + cJU_JPNULL1);
373
367
// Initialize: Pre-set uncompressed branch to mostly JPNULL*s:
375
for (numJPs = 0; numJPs < cJU_BRANCHUNUMJPS; ++numJPs)
376
Pjbu->jbu_jp[numJPs] = newJP;
369
for (numJPs = 0; numJPs < cJU_BRANCHUNUMJPS; ++numJPs)
370
Pjbu->jbu_jp[numJPs] = newJP;
378
372
// Copy JPs from linear branch to uncompressed branch:
381
375
#ifdef SUBEXPCOUNTS
382
Word_t popmask = cJU_POP0MASK((Pjp->jp_Type)
383
- cJU_JPBRANCH_L2 - 2);
376
Word_t popmask = cJU_POP0MASK(JU_JPTYPE(Pjp))
377
- cJU_JPBRANCH_L2 - 2;
385
for (numJPs = 0; numJPs < cJU_NUMSUBEXPU; ++numJPs)
386
Pjbu->jbu_subPop1[numJPs] = 0;
379
for (numJPs = 0; numJPs < cJU_NUMSUBEXPU; ++numJPs)
380
Pjbu->jbu_subPop1[numJPs] = 0;
388
for (numJPs = 0; numJPs < Pjbl->jbl_NumJPs; ++numJPs)
390
Pjp_t Pjp1 = &(Pjbl->jbl_jp[numJPs]);
391
offset = Pjbl->jbl_Expanse[numJPs];
392
Pjbu->jbu_jp[offset] = *Pjp1;
382
for (numJPs = 0; numJPs < Pjbl->jbl_NumJPs; ++numJPs)
384
Pjp_t Pjp1 = &(Pjbl->jbl_jp[numJPs]);
385
offset = Pjbl->jbl_Expanse[numJPs];
386
Pjbu->jbu_jp[offset] = *Pjp1;
393
387
#ifdef SUBEXPCOUNTS
394
Pjbu->jbu_subPop1[offset/cJU_NUMSUBEXPU] +=
395
(Pjp1->jp_DcdPop0) & popmask + 1;
388
Pjbu->jbu_subPop1[offset/cJU_NUMSUBEXPU] +=
389
JU_JPDCDPOP0(Pjp1) & popmask + 1;
399
__JudyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
393
j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
401
395
// Plug new values into parent JP:
403
Pjp->jp_Addr = (Word_t) PjbuRaw;
404
Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_L; // to BranchU.
397
Pjp->jp_Addr = (Word_t) PjbuRaw;
398
Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_L; // to BranchU.
406
400
// Save global population of last BranchU conversion:
408
Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0;
409
goto ContinueInsWalk;
402
Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0;
403
goto ContinueInsWalk;
411
} // case cJU_JPBRANCH_L.
405
} // case cJU_JPBRANCH_L.
414
408
// ****************************************************************************
417
// If the new Index is not an outlier to the branch's expanse, extract the
411
// If the new Index is not an outlier to the branchs expanse, extract the
418
412
// digit and record the Immediate type to create for a new Immed JP, before
419
413
// going to common code.
421
415
// Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit.
423
case cJU_JPBRANCH_B2:
424
JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
417
case cJU_JPBRANCH_B2:
418
JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
427
case cJU_JPBRANCH_B3:
428
JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
421
case cJU_JPBRANCH_B3:
422
JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
432
case cJU_JPBRANCH_B4:
433
JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
436
case cJU_JPBRANCH_B5:
437
JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
440
case cJU_JPBRANCH_B6:
441
JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
444
case cJU_JPBRANCH_B7:
445
JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
426
case cJU_JPBRANCH_B4:
427
JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
430
case cJU_JPBRANCH_B5:
431
JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
434
case cJU_JPBRANCH_B6:
435
JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
438
case cJU_JPBRANCH_B7:
439
JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
451
Pjbb_t Pjbb; // pointer to bitmap branch.
452
Pjbb_t PjbbRaw; // pointer to bitmap branch.
453
Pjp_t Pjp2Raw; // 1 of N arrays of JPs.
454
Pjp_t Pjp2; // 1 of N arrays of JPs.
455
Word_t subexp; // 1 of N subexpanses in bitmap.
456
BITMAPB_t bitmap; // for one subexpanse.
457
BITMAPB_t bitmask; // bit set for Index's digit.
458
Word_t numJPs; // number of JPs = populated expanses.
459
int offset; // in bitmap branch.
445
Pjbb_t Pjbb; // pointer to bitmap branch.
446
Pjbb_t PjbbRaw; // pointer to bitmap branch.
447
Pjp_t Pjp2Raw; // 1 of N arrays of JPs.
448
Pjp_t Pjp2; // 1 of N arrays of JPs.
449
Word_t subexp; // 1 of N subexpanses in bitmap.
450
BITMAPB_t bitmap; // for one subexpanse.
451
BITMAPB_t bitmask; // bit set for Indexs digit.
452
Word_t numJPs; // number of JPs = populated expanses.
453
int offset; // in bitmap branch.
461
455
// Similar to common code above, but no outlier check is needed, and the Immed
462
456
// type depends on the word size:
464
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
465
exppop1 = Pjpm->jpm_Pop0;
458
digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
459
exppop1 = Pjpm->jpm_Pop0;
470
464
// COMMON CODE FOR BITMAP BRANCHES:
542
536
// The new expanse always an cJU_JPIMMED_*_01 containing just the new Index, so
543
537
// finish setting up an Immed JP.
545
newJP.jp_Addr = 0; // initial value (for JudyL).
546
newJP.jp_DcdPop0 = Index; // truncates.
547
newJP.jp_Type = Pjp->jp_Type + cJU_JPIMMED_1_01-cJU_JPBRANCH_B2;
539
JU_JPSETADT(&newJP, 0, Index,
540
JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_B2);
549
542
// Get 1 of the 8 JP arrays and calculate number of JPs in subexpanse array:
551
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
552
Pjp2 = P_JP(Pjp2Raw);
553
numJPs = __JudyCountBitsB(bitmap);
544
Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
545
Pjp2 = P_JP(Pjp2Raw);
546
numJPs = j__udyCountBitsB(bitmap);
555
548
// Expand branch JP subarray in-place:
557
if (JU_BRANCHBJPGROWINPLACE(numJPs))
560
JU_INSERTINPLACE(Pjp2, numJPs, offset, newJP);
550
if (JU_BRANCHBJPGROWINPLACE(numJPs))
553
JU_INSERTINPLACE(Pjp2, numJPs, offset, newJP);
562
// value area is first word of new Immed 01 JP:
563
Pjpm->jpm_PValue = (Pjv_t) (Pjp2 + offset);
555
// value area is first word of new Immed 01 JP:
556
Pjpm->jpm_PValue = (Pjv_t) (Pjp2 + offset);
567
560
// No room, allocate a bigger bitmap branch JP subarray:
574
if ((PjpnewRaw = __JudyAllocJBBJP(numJPs + 1, Pjpm)) == 0)
576
Pjpnew = P_JP(PjpnewRaw);
567
if ((PjpnewRaw = j__udyAllocJBBJP(numJPs + 1, Pjpm)) == 0)
569
Pjpnew = P_JP(PjpnewRaw);
578
571
// If there was an old JP array, then copy it, insert the new Immed JP, and
579
572
// free the old array:
583
JU_INSERTCOPY(Pjpnew, Pjp2, numJPs, offset, newJP);
584
__JudyFreeJBBJP(Pjp2Raw, numJPs, Pjpm);
576
JU_INSERTCOPY(Pjpnew, Pjp2, numJPs, offset, newJP);
577
j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm);
586
// value area is first word of new Immed 01 JP:
587
Pjpm->jpm_PValue = (Pjv_t) (Pjpnew + offset);
579
// value area is first word of new Immed 01 JP:
580
Pjpm->jpm_PValue = (Pjv_t) (Pjpnew + offset);
591
584
// New JP subarray; point to cJU_JPIMMED_*_01 and place it:
595
assert(JU_JBB_PJP(Pjbb, subexp) == (Pjp_t) NULL);
597
*Pjp = newJP; // copy to new memory.
588
assert(JU_JBB_PJP(Pjbb, subexp) == (Pjp_t) NULL);
590
*Pjp = newJP; // copy to new memory.
599
// value area is first word of new Immed 01 JP:
600
Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
592
// value area is first word of new Immed 01 JP:
593
Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
604
597
// Place new JP subarray in BranchB:
606
JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
610
// Set the new Index's bit:
612
JU_JBB_BITMAP(Pjbb, subexp) |= bitmask;
599
JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
603
// Set the new Indexs bit:
605
JU_JBB_BITMAP(Pjbb, subexp) |= bitmask;
619
612
// ****************************************************************************
622
615
// Just drop through the JP for the correct digit. If the JP turns out to be a
623
// JPNULL*, that's OK, the memory is already allocated, and the next walk
616
// JPNULL*, thats OK, the memory is already allocated, and the next walk
624
617
// simply places an Immed in it.
626
619
#ifdef SUBEXPCOUNTS
627
#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) \
628
(PSubExp) = &((Pjbu)->jbu_subPop1[(Digit) / cJU_NUMSUBEXPU])
620
#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) \
621
(PSubExp) = &((Pjbu)->jbu_subPop1[(Digit) / cJU_NUMSUBEXPU])
630
623
#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) // null.
633
#define JU_JBU_PJP_SUBEXP(Pjp,PSubExp,Index,Level) \
635
uint8_t _digit = JU_DIGITATSTATE(Index, Level); \
636
Pjbu_t _Pjbu = P_JBU((Pjp)->jp_Addr); \
637
(Pjp) = &(_Pjbu->jbu_jp[_digit]); \
638
JU_GETSUBEXP(PSubExp, _Pjbu, _digit); \
626
#define JU_JBU_PJP_SUBEXP(Pjp,PSubExp,Index,Level) \
628
uint8_t digit = JU_DIGITATSTATE(Index, Level); \
629
Pjbu_t P_jbu = P_JBU((Pjp)->jp_Addr); \
630
(Pjp) = &(P_jbu->jbu_jp[digit]); \
631
JU_GETSUBEXP(PSubExp, P_jbu, digit); \
641
case cJU_JPBRANCH_U2:
642
JU_CHECK_IF_OUTLIER(Pjp, Index, 2, Pjpm);
643
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 2);
634
case cJU_JPBRANCH_U2:
635
JU_CHECK_IF_OUTLIER(Pjp, Index, 2, Pjpm);
636
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 2);
647
case cJU_JPBRANCH_U3:
648
JU_CHECK_IF_OUTLIER(Pjp, Index, 3, Pjpm);
649
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
652
case cJU_JPBRANCH_U4:
653
JU_CHECK_IF_OUTLIER(Pjp, Index, 4, Pjpm);
654
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 4);
657
case cJU_JPBRANCH_U5:
658
JU_CHECK_IF_OUTLIER(Pjp, Index, 5, Pjpm);
659
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 5);
662
case cJU_JPBRANCH_U6:
663
JU_CHECK_IF_OUTLIER(Pjp, Index, 6, Pjpm);
664
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 6);
667
case cJU_JPBRANCH_U7:
668
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 7);
640
case cJU_JPBRANCH_U3:
641
JU_CHECK_IF_OUTLIER(Pjp, Index, 3, Pjpm);
642
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
645
case cJU_JPBRANCH_U4:
646
JU_CHECK_IF_OUTLIER(Pjp, Index, 4, Pjpm);
647
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 4);
650
case cJU_JPBRANCH_U5:
651
JU_CHECK_IF_OUTLIER(Pjp, Index, 5, Pjpm);
652
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 5);
655
case cJU_JPBRANCH_U6:
656
JU_CHECK_IF_OUTLIER(Pjp, Index, 6, Pjpm);
657
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 6);
660
case cJU_JPBRANCH_U7:
661
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 7);
670
case cJU_JPBRANCH_U3:
671
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
663
case cJU_JPBRANCH_U3:
664
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
676
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, cJU_ROOTSTATE);
669
JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, cJU_ROOTSTATE);
680
673
// ****************************************************************************
692
#define JU_LEAFVALUE(Pjv) // null.
693
#define JU_LEAFPREPVALUE(Pjv, ValueArea) // null.
685
#define JU_LEAFVALUE(Pjv) // null.
686
#define JU_LEAFPREPVALUE(Pjv, ValueArea) // null.
695
#define JU_LEAFVALUE(Pjv) Pjv_t Pjv
696
#define JU_LEAFPREPVALUE(Pjv, ValueArea) (Pjv) = ValueArea(Pleaf, exppop1)
688
#define JU_LEAFVALUE(Pjv) Pjv_t Pjv
689
#define JU_LEAFPREPVALUE(Pjv, ValueArea) (Pjv) = ValueArea(Pleaf, exppop1)
699
#define JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea) \
701
Type Pleaf; /* specific type */ \
705
JU_CHECK_IF_OUTLIER(Pjp, Index, cIS, Pjpm); \
707
exppop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1; \
708
assert(exppop1 <= (MaxPop1)); \
709
PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
710
Pleaf = (Type) P_JLL(PjllRaw); \
711
JU_LEAFPREPVALUE(Pjv, ValueArea)
692
#define JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea) \
694
Type Pleaf; /* specific type */ \
698
JU_CHECK_IF_OUTLIER(Pjp, Index, cIS, Pjpm); \
700
exppop1 = JU_JPLEAF_POP0(Pjp) + 1; \
701
assert(exppop1 <= (MaxPop1)); \
702
PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
703
Pleaf = (Type) P_JLL(PjllRaw); \
704
JU_LEAFPREPVALUE(Pjv, ValueArea)
713
706
// Add to, or grow, a linear leaf: Find Index position; if the Index is
714
// absent, if there's room in the leaf, insert the Index [and value of 0] in
707
// absent, if theres room in the leaf, insert the Index [and value of 0] in
715
708
// place, otherwise grow the leaf:
717
710
// Note: These insertions always take place with whole words, using
718
711
// JU_INSERTINPLACE() or JU_INSERTCOPY().
721
#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) // null.
714
#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) // null.
723
#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) \
724
JU_INSERTINPLACE(Pjv, ExpPop1, Offset, 0); \
725
Pjpm->jpm_PValue = (Pjv) + (Offset)
716
#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) \
717
JU_INSERTINPLACE(Pjv, ExpPop1, Offset, 0); \
718
Pjpm->jpm_PValue = (Pjv) + (Offset)
729
#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) // null.
722
#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) // null.
731
#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) \
733
Pjv_t Pjvnew = ValueArea(Pleafnew, (ExpPop1) + 1); \
734
JU_INSERTCOPY(Pjvnew, Pjv, ExpPop1, Offset, 0); \
735
Pjpm->jpm_PValue = (Pjvnew) + (Offset); \
724
#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) \
726
Pjv_t Pjvnew = ValueArea(Pleafnew, (ExpPop1) + 1); \
727
JU_INSERTCOPY(Pjvnew, Pjv, ExpPop1, Offset, 0); \
728
Pjpm->jpm_PValue = (Pjvnew) + (Offset); \
739
#define JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
740
InsertInPlace,InsertCopy,Alloc,Free) \
742
offset = Search(Pleaf, exppop1, Index); \
743
JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
745
if (GrowInPlace(exppop1)) /* add to current leaf */ \
747
InsertInPlace(Pleaf, exppop1, offset, Index); \
748
JU_LEAFGROWVALUEADD(Pjv, exppop1, offset); \
749
DBGCODE(JudyCheckSorted((Pjll_t) Pleaf, exppop1 + 1, cIS);) \
753
if (exppop1 < (MaxPop1)) /* grow to new leaf */ \
757
if ((PjllnewRaw = Alloc(exppop1 + 1, Pjpm)) == 0) return(-1); \
758
Pleafnew = (Type) P_JLL(PjllnewRaw); \
759
InsertCopy(Pleafnew, Pleaf, exppop1, offset, Index); \
760
JU_LEAFGROWVALUENEW(ValueArea, Pjv, exppop1, offset); \
761
DBGCODE(JudyCheckSorted((Pjll_t) Pleafnew, exppop1 + 1, cIS);) \
762
Free(PjllRaw, exppop1, Pjpm); \
763
(Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
766
assert(exppop1 == (MaxPop1))
732
#define JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
733
InsertInPlace,InsertCopy,Alloc,Free) \
735
offset = Search(Pleaf, exppop1, Index); \
736
JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
738
if (GrowInPlace(exppop1)) /* add to current leaf */ \
740
InsertInPlace(Pleaf, exppop1, offset, Index); \
741
JU_LEAFGROWVALUEADD(Pjv, exppop1, offset); \
742
DBGCODE(JudyCheckSorted((Pjll_t) Pleaf, exppop1 + 1, cIS);) \
746
if (exppop1 < (MaxPop1)) /* grow to new leaf */ \
750
if ((PjllnewRaw = Alloc(exppop1 + 1, Pjpm)) == 0) return(-1); \
751
Pleafnew = (Type) P_JLL(PjllnewRaw); \
752
InsertCopy(Pleafnew, Pleaf, exppop1, offset, Index); \
753
JU_LEAFGROWVALUENEW(ValueArea, Pjv, exppop1, offset); \
754
DBGCODE(JudyCheckSorted((Pjll_t) Pleafnew, exppop1 + 1, cIS);) \
755
Free(PjllRaw, exppop1, Pjpm); \
756
(Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
759
assert(exppop1 == (MaxPop1))
768
761
// Handle linear leaf overflow (cascade): Splay or compress into smaller
771
#define JU_LEAFCASCADE(MaxPop1,Cascade,Free) \
772
if (Cascade(Pjp, Pjpm) == -1) return(-1); \
773
Free(PjllRaw, MaxPop1, Pjpm); \
764
#define JU_LEAFCASCADE(MaxPop1,Cascade,Free) \
765
if (Cascade(Pjp, Pjpm) == -1) return(-1); \
766
Free(PjllRaw, MaxPop1, Pjpm); \
776
769
// Wrapper around all of the above:
778
#define JU_LEAFSET(cIS,Type,MaxPop1,Search,GrowInPlace,InsertInPlace, \
779
InsertCopy,Cascade,Alloc,Free,ValueArea) \
781
JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea); \
782
JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
783
InsertInPlace,InsertCopy,Alloc,Free); \
784
JU_LEAFCASCADE(MaxPop1,Cascade,Free); \
771
#define JU_LEAFSET(cIS,Type,MaxPop1,Search,GrowInPlace,InsertInPlace, \
772
InsertCopy,Cascade,Alloc,Free,ValueArea) \
774
JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea); \
775
JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
776
InsertInPlace,InsertCopy,Alloc,Free); \
777
JU_LEAFCASCADE(MaxPop1,Cascade,Free); \
787
780
// END OF MACROS; LEAFL CASES START HERE:
789
782
// 64-bit Judy1 does not have 1-byte leaves:
791
#if (JUDYL || (! JU_64BIT))
795
JU_LEAFSET(1, uint8_t *, cJU_LEAF1_MAXPOP1, __JudySearchLeaf1,
796
JU_LEAF1GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
797
__JudyCascade1, __JudyAllocJLL1, __JudyFreeJLL1,
784
#if (defined(JUDYL) || (! defined(JU_64BIT)))
788
JU_LEAFSET(1, uint8_t *, cJU_LEAF1_MAXPOP1, j__udySearchLeaf1,
789
JU_LEAF1GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
790
j__udyCascade1, j__udyAllocJLL1, j__udyFreeJLL1,
800
793
#endif // (JUDYL || ! JU_64BIT)
804
JU_LEAFSET(2, uint16_t *, cJU_LEAF2_MAXPOP1, __JudySearchLeaf2,
805
JU_LEAF2GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
806
__JudyCascade2, __JudyAllocJLL2, __JudyFreeJLL2,
811
JU_LEAFSET(3, uint8_t *, cJU_LEAF3_MAXPOP1, __JudySearchLeaf3,
812
JU_LEAF3GROWINPLACE, JU_INSERTINPLACE3, JU_INSERTCOPY3,
813
__JudyCascade3, __JudyAllocJLL3, __JudyFreeJLL3,
797
JU_LEAFSET(2, uint16_t *, cJU_LEAF2_MAXPOP1, j__udySearchLeaf2,
798
JU_LEAF2GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
799
j__udyCascade2, j__udyAllocJLL2, j__udyFreeJLL2,
804
JU_LEAFSET(3, uint8_t *, cJU_LEAF3_MAXPOP1, j__udySearchLeaf3,
805
JU_LEAF3GROWINPLACE, JU_INSERTINPLACE3, JU_INSERTCOPY3,
806
j__udyCascade3, j__udyAllocJLL3, j__udyFreeJLL3,
819
JU_LEAFSET(4, uint32_t *, cJU_LEAF4_MAXPOP1, __JudySearchLeaf4,
820
JU_LEAF4GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
821
__JudyCascade4, __JudyAllocJLL4, __JudyFreeJLL4,
826
JU_LEAFSET(5, uint8_t *, cJU_LEAF5_MAXPOP1, __JudySearchLeaf5,
827
JU_LEAF5GROWINPLACE, JU_INSERTINPLACE5, JU_INSERTCOPY5,
828
__JudyCascade5, __JudyAllocJLL5, __JudyFreeJLL5,
833
JU_LEAFSET(6, uint8_t *, cJU_LEAF6_MAXPOP1, __JudySearchLeaf6,
834
JU_LEAF6GROWINPLACE, JU_INSERTINPLACE6, JU_INSERTCOPY6,
835
__JudyCascade6, __JudyAllocJLL6, __JudyFreeJLL6,
840
JU_LEAFSET(7, uint8_t *, cJU_LEAF7_MAXPOP1, __JudySearchLeaf7,
841
JU_LEAF7GROWINPLACE, JU_INSERTINPLACE7, JU_INSERTCOPY7,
842
__JudyCascade7, __JudyAllocJLL7, __JudyFreeJLL7,
812
JU_LEAFSET(4, uint32_t *, cJU_LEAF4_MAXPOP1, j__udySearchLeaf4,
813
JU_LEAF4GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
814
j__udyCascade4, j__udyAllocJLL4, j__udyFreeJLL4,
819
JU_LEAFSET(5, uint8_t *, cJU_LEAF5_MAXPOP1, j__udySearchLeaf5,
820
JU_LEAF5GROWINPLACE, JU_INSERTINPLACE5, JU_INSERTCOPY5,
821
j__udyCascade5, j__udyAllocJLL5, j__udyFreeJLL5,
826
JU_LEAFSET(6, uint8_t *, cJU_LEAF6_MAXPOP1, j__udySearchLeaf6,
827
JU_LEAF6GROWINPLACE, JU_INSERTINPLACE6, JU_INSERTCOPY6,
828
j__udyCascade6, j__udyAllocJLL6, j__udyFreeJLL6,
833
JU_LEAFSET(7, uint8_t *, cJU_LEAF7_MAXPOP1, j__udySearchLeaf7,
834
JU_LEAF7GROWINPLACE, JU_INSERTINPLACE7, JU_INSERTCOPY7,
835
j__udyCascade7, j__udyAllocJLL7, j__udyFreeJLL7,
844
837
#endif // JU_64BIT
847
840
// ****************************************************************************
850
// 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
851
// |SubExpanse | Bit offset |
843
// 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
844
// |SubExpanse | Bit offset |
853
846
// Note: For JudyL, values are stored in 8 subexpanses, each a linear word
854
847
// array of up to 32 values each.
859
Pjv_t PjvRaw; // pointer to value part of the leaf.
860
Pjv_t Pjv; // pointer to value part of the leaf.
861
Pjv_t PjvnewRaw; // new value area.
862
Pjv_t Pjvnew; // new value area.
863
Word_t subexp; // 1 of 8 subexpanses in bitmap.
864
Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
865
BITMAPL_t bitmap; // for one subexpanse.
866
BITMAPL_t bitmask; // bit set for Index's digit.
867
int offset; // of index in value area.
852
Pjv_t PjvRaw; // pointer to value part of the leaf.
853
Pjv_t Pjv; // pointer to value part of the leaf.
854
Pjv_t PjvnewRaw; // new value area.
855
Pjv_t Pjvnew; // new value area.
856
Word_t subexp; // 1 of 8 subexpanses in bitmap.
857
Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
858
BITMAPL_t bitmap; // for one subexpanse.
859
BITMAPL_t bitmask; // bit set for Indexs digit.
860
int offset; // of index in value area.
870
JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
863
JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
874
867
// If Index (bit) is already set, return now:
876
if (JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index)) return(0);
878
// If bitmap is not full, set the new Index's bit; otherwise convert to a Full:
880
if ((exppop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1)
881
< cJU_JPFULLPOPU1_POP0)
883
JU_BITMAPSETL(P_JLB(Pjp->jp_Addr), Index);
887
__JudyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // free LeafB1.
888
Pjp->jp_Type = cJ1_JPFULLPOPU1;
869
if (JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index)) return(0);
871
// If bitmap is not full, set the new Indexs bit; otherwise convert to a Full:
873
if ((exppop1 = JU_JPLEAF_POP0(Pjp) + 1)
874
< cJU_JPFULLPOPU1_POP0)
876
JU_BITMAPSETL(P_JLB(Pjp->jp_Addr), Index);
880
j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // free LeafB1.
881
Pjp->jp_Type = cJ1_JPFULLPOPU1;
898
891
// Get last byte to decode from Index, and pointer to bitmap leaf:
900
digit = JU_DIGITATSTATE(Index, 1);
901
Pjlb = P_JLB(Pjp->jp_Addr);
893
digit = JU_DIGITATSTATE(Index, 1);
894
Pjlb = P_JLB(Pjp->jp_Addr);
903
896
// Prepare additional values:
905
subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
906
bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexp's 32-bit map.
907
PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
908
Pjv = P_JV(PjvRaw); // corresponding values.
909
bitmask = JU_BITPOSMASKL(digit); // mask for Index.
910
offset = __JudyCountBitsL(bitmap & (bitmask - 1)); // of Index.
898
subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
899
bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map.
900
PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
901
Pjv = P_JV(PjvRaw); // corresponding values.
902
bitmask = JU_BITPOSMASKL(digit); // mask for Index.
903
offset = j__udyCountBitsL(bitmap & (bitmask - 1)); // of Index.
912
905
// If Index already exists, get value pointer and exit:
914
if (bitmap & bitmask)
917
Pjpm->jpm_PValue = Pjv + offset; // existing value.
907
if (bitmap & bitmask)
910
Pjpm->jpm_PValue = Pjv + offset; // existing value.
921
914
// Get the total bits set = expanse population of Value area:
923
exppop1 = __JudyCountBitsL(bitmap);
916
exppop1 = j__udyCountBitsL(bitmap);
925
918
// If the value area can grow in place, do it:
927
if (JL_LEAFVGROWINPLACE(exppop1))
929
JU_INSERTINPLACE(Pjv, exppop1, offset, 0);
930
JU_JLB_BITMAP(Pjlb, subexp) |= bitmask; // set Index's bit.
931
Pjpm->jpm_PValue = Pjv + offset; // new value area.
920
if (JL_LEAFVGROWINPLACE(exppop1))
922
JU_INSERTINPLACE(Pjv, exppop1, offset, 0);
923
JU_JLB_BITMAP(Pjlb, subexp) |= bitmask; // set Indexs bit.
924
Pjpm->jpm_PValue = Pjv + offset; // new value area.
935
928
// Increase size of value area:
937
if ((PjvnewRaw = __JudyLAllocJV(exppop1 + 1, Pjpm))
938
== (Pjv_t) NULL) return(-1);
939
Pjvnew = P_JV(PjvnewRaw);
930
if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm))
931
== (Pjv_t) NULL) return(-1);
932
Pjvnew = P_JV(PjvnewRaw);
941
if (exppop1) // have existing value area.
944
JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0);
945
Pjpm->jpm_PValue = Pjvnew + offset;
946
__JudyLFreeJV(PjvRaw, exppop1, Pjpm); // free old values.
948
else // first index, new value area:
950
Pjpm->jpm_PValue = Pjvnew;
951
*(Pjpm->jpm_PValue) = 0;
934
if (exppop1) // have existing value area.
937
JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0);
938
Pjpm->jpm_PValue = Pjvnew + offset;
939
j__udyLFreeJV(PjvRaw, exppop1, Pjpm); // free old values.
941
else // first index, new value area:
943
Pjpm->jpm_PValue = Pjvnew;
944
*(Pjpm->jpm_PValue) = 0;
954
947
// Set bit for new Index and place new leaf value area in bitmap:
956
JU_JLB_BITMAP(Pjlb, subexp) |= bitmask;
957
JL_JLB_PVALUE(Pjlb, subexp) = PjvnewRaw;
949
JU_JLB_BITMAP(Pjlb, subexp) |= bitmask;
950
JL_JLB_PVALUE(Pjlb, subexp) = PjvnewRaw;
967
960
// ****************************************************************************
970
// If Index is not an outlier, then by definition it's already set.
972
case cJ1_JPFULLPOPU1:
974
JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
963
// If Index is not an outlier, then by definition its already set.
965
case cJ1_JPFULLPOPU1:
967
JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
1224
1218
// not already present; given Pjp, Index, exppop1, Pjv, and Pjpm in the
1227
// Note: Use this only when the JP format doesn't change, that is, going from
1221
// Note: Use this only when the JP format doesnt change, that is, going from
1228
1222
// cJU_JPIMMED_X_0Y to cJU_JPIMMED_X_0Z, where X >= 2 and Y+1 = Z.
1230
1224
// Note: Incrementing jp_Type is how to increase the Index population.
1232
#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1237
exppop1 = (Pjp->jp_Type) - (BaseJPType_02) + 2; \
1238
offset = Search((Pjll_t) (Pjp->jp_1Index), exppop1, Index); \
1240
JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1242
Pjll = (LeafType) (Pjp->jp_1Index); \
1243
InsertInPlace(Pjll, exppop1, offset, Index); \
1244
DBGCODE(JudyCheckSorted(Pjll, exppop1 + 1, cIS);) \
1226
#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1231
exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \
1232
offset = Search((Pjll_t) (Pjp->jp_1Index), exppop1, Index); \
1234
JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1236
Pjll = (LeafType) (Pjp->jp_1Index); \
1237
InsertInPlace(Pjll, exppop1, offset, Index); \
1238
DBGCODE(JudyCheckSorted(Pjll, exppop1 + 1, cIS);) \
1249
1243
// Insert an Index into an immediate JP that has no room for more:
1251
1245
// If the Index is not already present, do a cascade (to a leaf); given Pjp,
1252
1246
// Index, Pjv, and Pjpm in the context.
1254
#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1255
ignore,Search,InsertCopy,Alloc) \
1261
offset = Search((Pjll_t) (Pjp->jp_1Index), (OldPop1), Index); \
1262
JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1264
if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) return(-1); \
1265
Pjll = P_JLL(PjllRaw); \
1267
InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_1Index), \
1268
OldPop1, offset, Index); \
1269
DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1271
(Pjp->jp_Type) = (NewJPType); \
1272
(Pjp->jp_Addr) = (Word_t) PjllRaw; \
1273
(Pjp->jp_DcdPop0) = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1249
#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1250
ignore,Search,InsertCopy,Alloc) \
1257
offset = Search((Pjll_t) (Pjp->jp_1Index), (OldPop1), Index); \
1258
JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1260
if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) return(-1); \
1261
Pjll = P_JLL(PjllRaw); \
1263
InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_1Index), \
1264
OldPop1, offset, Index); \
1265
DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1267
D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1268
JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1281
1276
// For JudyL, Pjv (start of value area) is also in the context.
1283
1278
// TBD: This code makes a true but weak assumption that a JudyL 32-bit 2-index
1284
// value area must be copied to a new 3-index value area. AND it doesn't know
1279
// value area must be copied to a new 3-index value area. AND it doesnt know
1285
1280
// anything about JudyL 64-bit cases (cJU_JPIMMED_1_0[3-7] only) where the
1286
1281
// value area can grow in place! However, this should not break it, just slow
1289
#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1298
exppop1 = (Pjp->jp_Type) - (BaseJPType_02) + 2; \
1299
offset = Search((Pjll_t) (Pjp->jp_LIndex), exppop1, Index); \
1300
PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1301
Pjv = P_JV(PjvRaw); \
1303
JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1305
if ((PjvnewRaw = __JudyLAllocJV(exppop1 + 1, Pjpm)) \
1306
== (Pjv_t) NULL) return(-1); \
1307
Pjvnew = P_JV(PjvnewRaw); \
1309
Pleaf = (LeafType) (Pjp->jp_LIndex); \
1311
InsertInPlace(Pleaf, exppop1, offset, Index); \
1312
/* see TBD above about this: */ \
1313
JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0); \
1314
DBGCODE(JudyCheckSorted(Pleaf, exppop1 + 1, cIS);) \
1315
__JudyLFreeJV(PjvRaw, exppop1, Pjpm); \
1316
Pjp->jp_Addr = (Word_t) PjvnewRaw; \
1317
Pjpm->jpm_PValue = Pjvnew + offset; \
1323
#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1324
ValueArea,Search,InsertCopy,Alloc) \
1333
PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1334
Pjv = P_JV(PjvRaw); \
1335
offset = Search((Pjll_t) (Pjp->jp_LIndex), (OldPop1), Index); \
1336
JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1338
if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) \
1340
Pjll = P_JLL(PjllRaw); \
1341
InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_LIndex), \
1342
OldPop1, offset, Index); \
1343
DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1345
Pjvnew = ValueArea(Pjll, (OldPop1) + 1); \
1346
JU_INSERTCOPY(Pjvnew, Pjv, OldPop1, offset, 0); \
1347
__JudyLFreeJV(PjvRaw, (OldPop1), Pjpm); \
1348
Pjpm->jpm_PValue = Pjvnew + offset; \
1350
(Pjp->jp_Type) = (NewJPType); \
1351
(Pjp->jp_Addr) = (Word_t) PjllRaw; \
1352
(Pjp->jp_DcdPop0) = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1284
#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1293
exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \
1294
offset = Search((Pjll_t) (Pjp->jp_LIndex), exppop1, Index); \
1295
PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1296
Pjv = P_JV(PjvRaw); \
1298
JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1300
if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm)) \
1301
== (Pjv_t) NULL) return(-1); \
1302
Pjvnew = P_JV(PjvnewRaw); \
1304
Pleaf = (LeafType) (Pjp->jp_LIndex); \
1306
InsertInPlace(Pleaf, exppop1, offset, Index); \
1307
/* see TBD above about this: */ \
1308
JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0); \
1309
DBGCODE(JudyCheckSorted(Pleaf, exppop1 + 1, cIS);) \
1310
j__udyLFreeJV(PjvRaw, exppop1, Pjpm); \
1311
Pjp->jp_Addr = (Word_t) PjvnewRaw; \
1312
Pjpm->jpm_PValue = Pjvnew + offset; \
1318
#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1319
ValueArea,Search,InsertCopy,Alloc) \
1329
PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1330
Pjv = P_JV(PjvRaw); \
1331
offset = Search((Pjll_t) (Pjp->jp_LIndex), (OldPop1), Index); \
1332
JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1334
if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) \
1336
Pjll = P_JLL(PjllRaw); \
1337
InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_LIndex), \
1338
OldPop1, offset, Index); \
1339
DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1341
Pjvnew = ValueArea(Pjll, (OldPop1) + 1); \
1342
JU_INSERTCOPY(Pjvnew, Pjv, OldPop1, offset, 0); \
1343
j__udyLFreeJV(PjvRaw, (OldPop1), Pjpm); \
1344
Pjpm->jpm_PValue = Pjvnew + offset; \
1346
D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1347
JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1355
1351
#endif // JUDYL
1357
1353
// Common convenience/shorthand wrappers around JU_IMMSET_01_COPY() for
1358
1354
// even/odd index sizes:
1360
#define JU_IMMSET_01( cIS, LeafType, NewJPType) \
1361
JU_IMMSET_01_COPY(cIS, LeafType, NewJPType, JU_IMMSET_01_COPY_EVEN, \
1356
#define JU_IMMSET_01( cIS, LeafType, NewJPType) \
1357
JU_IMMSET_01_COPY(cIS, LeafType, NewJPType, JU_IMMSET_01_COPY_EVEN, \
1364
#define JU_IMMSET_01_ODD( cIS, NewJPType, CopyWord) \
1365
JU_IMMSET_01_COPY(cIS, uint8_t *, NewJPType, JU_IMMSET_01_COPY_ODD, \
1360
#define JU_IMMSET_01_ODD( cIS, NewJPType, CopyWord) \
1361
JU_IMMSET_01_COPY(cIS, uint8_t *, NewJPType, JU_IMMSET_01_COPY_ODD, \
1369
1365
// END OF MACROS; IMMED CASES START HERE:
1439
1435
// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1441
case cJU_JPIMMED_1_02:
1442
#if (JUDY1 || JU_64BIT)
1443
case cJU_JPIMMED_1_03:
1444
case cJU_JPIMMED_1_04:
1445
case cJU_JPIMMED_1_05:
1446
case cJU_JPIMMED_1_06:
1448
#if (JUDY1 && JU_64BIT)
1449
case cJU_JPIMMED_1_07:
1450
case cJ1_JPIMMED_1_08:
1451
case cJ1_JPIMMED_1_09:
1452
case cJ1_JPIMMED_1_10:
1453
case cJ1_JPIMMED_1_11:
1454
case cJ1_JPIMMED_1_12:
1455
case cJ1_JPIMMED_1_13:
1456
case cJ1_JPIMMED_1_14:
1458
JU_IMMSETINPLACE(1, uint8_t *, cJU_JPIMMED_1_02, __JudySearchLeaf1,
1437
case cJU_JPIMMED_1_02:
1438
#if (defined(JUDY1) || defined(JU_64BIT))
1439
case cJU_JPIMMED_1_03:
1440
case cJU_JPIMMED_1_04:
1441
case cJU_JPIMMED_1_05:
1442
case cJU_JPIMMED_1_06:
1444
#if (defined(JUDY1) && defined(JU_64BIT))
1445
case cJU_JPIMMED_1_07:
1446
case cJ1_JPIMMED_1_08:
1447
case cJ1_JPIMMED_1_09:
1448
case cJ1_JPIMMED_1_10:
1449
case cJ1_JPIMMED_1_11:
1450
case cJ1_JPIMMED_1_12:
1451
case cJ1_JPIMMED_1_13:
1452
case cJ1_JPIMMED_1_14:
1454
JU_IMMSETINPLACE(1, uint8_t *, cJU_JPIMMED_1_02, j__udySearchLeaf1,
1461
1457
// cJU_JPIMMED_1_* cases that must cascade:
1463
1459
// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1465
#if (JUDYL && (! JU_64BIT))
1466
case cJU_JPIMMED_1_03:
1467
JU_IMMSETCASCADE(1, 3, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1468
__JudySearchLeaf1, JU_INSERTCOPY,
1471
#if (JUDY1 && (! JU_64BIT))
1472
case cJU_JPIMMED_1_07:
1473
JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, ignore,
1474
__JudySearchLeaf1, JU_INSERTCOPY,
1478
#if (JUDYL && JU_64BIT)
1479
case cJU_JPIMMED_1_07:
1480
JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1481
__JudySearchLeaf1, JU_INSERTCOPY,
1485
#if (JUDY1 && JU_64BIT)
1461
#if (defined(JUDYL) && (! defined(JU_64BIT)))
1462
case cJU_JPIMMED_1_03:
1463
JU_IMMSETCASCADE(1, 3, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1464
j__udySearchLeaf1, JU_INSERTCOPY,
1467
#if (defined(JUDY1) && (! defined(JU_64BIT)))
1468
case cJU_JPIMMED_1_07:
1469
JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, ignore,
1470
j__udySearchLeaf1, JU_INSERTCOPY,
1474
#if (defined(JUDYL) && defined(JU_64BIT))
1475
case cJU_JPIMMED_1_07:
1476
JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1477
j__udySearchLeaf1, JU_INSERTCOPY,
1481
#if (defined(JUDY1) && defined(JU_64BIT))
1486
1482
// Special case, as described above, go directly from Immed to LeafB1:
1488
case cJ1_JPIMMED_1_15:
1494
offset = __JudySearchLeaf1((Pjll_t) Pjp->jp_1Index, 15, Index);
1496
JU_CHECK_IF_EXISTS(offset, ignore, Pjpm);
1484
case cJ1_JPIMMED_1_15:
1491
offset = j__udySearchLeaf1((Pjll_t) Pjp->jp_1Index, 15, Index);
1493
JU_CHECK_IF_EXISTS(offset, ignore, Pjpm);
1498
1495
// Create a bitmap leaf (special case for Judy1 64-bit only, see usage): Set
1499
1496
// new Index in bitmap, copy an Immed1_15 to the bitmap, and set the parent JP
1500
// EXCEPT jp_DcdPop0, leaving any followup to the caller:
1502
if ((PjlbRaw = __JudyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
1504
Pjlb = P_JLB(PjlbRaw);
1506
JU_BITMAPSETL(Pjlb, Index);
1508
for (offset = 0; offset < 15; ++offset)
1509
JU_BITMAPSETL(Pjlb, Pjp->jp_1Index[offset]);
1511
Pjp->jp_Addr = (Word_t) PjlbRaw;
1512
Pjp->jp_Type = cJU_JPLEAF_B1;
1514
// Set jp_DcdPop0 including the current pop0; incremented later:
1515
Pjp->jp_DcdPop0 = (Index & cJU_DCDMASK(1)) + 15 - 1;
1497
// EXCEPT jp_DcdPopO, leaving any followup to the caller:
1499
if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
1501
Pjlb = P_JLB(PjlbRaw);
1503
JU_BITMAPSETL(Pjlb, Index);
1505
for (offset = 0; offset < 15; ++offset)
1506
JU_BITMAPSETL(Pjlb, Pjp->jp_1Index[offset]);
1508
// Set jp_DcdPopO including the current pop0; incremented later:
1509
DcdP0 = (Index & cJU_DCDMASK(1)) + 15 - 1;
1510
JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1);
1520
1516
// cJU_JPIMMED_[2..7]_[02..15] cases that grow in place or cascade:
1522
1518
// (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL)
1524
#if (JUDY1 || JU_64BIT)
1525
case cJU_JPIMMED_2_02:
1527
#if (JUDY1 && JU_64BIT)
1528
case cJU_JPIMMED_2_03:
1529
case cJ1_JPIMMED_2_04:
1530
case cJ1_JPIMMED_2_05:
1531
case cJ1_JPIMMED_2_06:
1533
#if (JUDY1 || JU_64BIT)
1534
JU_IMMSETINPLACE(2, uint16_t *, cJU_JPIMMED_2_02, __JudySearchLeaf2,
1520
#if (defined(JUDY1) || defined(JU_64BIT))
1521
case cJU_JPIMMED_2_02:
1523
#if (defined(JUDY1) && defined(JU_64BIT))
1524
case cJU_JPIMMED_2_03:
1525
case cJ1_JPIMMED_2_04:
1526
case cJ1_JPIMMED_2_05:
1527
case cJ1_JPIMMED_2_06:
1529
#if (defined(JUDY1) || defined(JU_64BIT))
1530
JU_IMMSETINPLACE(2, uint16_t *, cJU_JPIMMED_2_02, j__udySearchLeaf2,
1539
#if ((JUDY1 && (! JU_64BIT)) || (JUDYL && JU_64BIT))
1540
case cJU_JPIMMED_2_03:
1543
#if (JUDY1 && JU_64BIT)
1544
case cJ1_JPIMMED_2_07:
1547
#if (JUDY1 || JU_64BIT)
1548
JU_IMMSETCASCADE(2, OLDPOP1, uint16_t *, cJU_JPLEAF2,
1549
JL_LEAF2VALUEAREA, __JudySearchLeaf2,
1550
JU_INSERTCOPY, __JudyAllocJLL2);
1535
#if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT)))
1536
case cJU_JPIMMED_2_03:
1539
#if (defined(JUDY1) && defined(JU_64BIT))
1540
case cJ1_JPIMMED_2_07:
1543
#if (defined(JUDY1) || defined(JU_64BIT))
1544
JU_IMMSETCASCADE(2, OLDPOP1, uint16_t *, cJU_JPLEAF2,
1545
JL_LEAF2VALUEAREA, j__udySearchLeaf2,
1546
JU_INSERTCOPY, j__udyAllocJLL2);
1553
1549
// (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL)
1555
#if (JUDY1 && JU_64BIT)
1556
case cJU_JPIMMED_3_02:
1557
case cJ1_JPIMMED_3_03:
1558
case cJ1_JPIMMED_3_04:
1551
#if (defined(JUDY1) && defined(JU_64BIT))
1552
case cJU_JPIMMED_3_02:
1553
case cJ1_JPIMMED_3_03:
1554
case cJ1_JPIMMED_3_04:
1560
JU_IMMSETINPLACE(3, uint8_t *, cJU_JPIMMED_3_02, __JudySearchLeaf3,
1556
JU_IMMSETINPLACE(3, uint8_t *, cJU_JPIMMED_3_02, j__udySearchLeaf3,
1565
#if ((JUDY1 && (! JU_64BIT)) || (JUDYL && JU_64BIT))
1566
case cJU_JPIMMED_3_02:
1569
#if (JUDY1 && JU_64BIT)
1570
case cJ1_JPIMMED_3_05:
1573
#if (JUDY1 || JU_64BIT)
1574
JU_IMMSETCASCADE(3, OLDPOP1, uint8_t *, cJU_JPLEAF3,
1575
JL_LEAF3VALUEAREA, __JudySearchLeaf3,
1576
JU_INSERTCOPY3, __JudyAllocJLL3);
1561
#if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT)))
1562
case cJU_JPIMMED_3_02:
1565
#if (defined(JUDY1) && defined(JU_64BIT))
1566
case cJ1_JPIMMED_3_05:
1569
#if (defined(JUDY1) || defined(JU_64BIT))
1570
JU_IMMSETCASCADE(3, OLDPOP1, uint8_t *, cJU_JPLEAF3,
1571
JL_LEAF3VALUEAREA, j__udySearchLeaf3,
1572
JU_INSERTCOPY3, j__udyAllocJLL3);
1579
#if (JUDY1 && JU_64BIT)
1575
#if (defined(JUDY1) && defined(JU_64BIT))
1581
1577
// (4_01 => [[ 4_02..03 => ]] LeafL)
1583
case cJ1_JPIMMED_4_02:
1585
JU_IMMSETINPLACE(4, uint32_t *, cJ1_JPIMMED_4_02, __JudySearchLeaf4,
1588
case cJ1_JPIMMED_4_03:
1590
JU_IMMSETCASCADE(4, 3, uint32_t *, cJU_JPLEAF4, ignore,
1591
__JudySearchLeaf4, JU_INSERTCOPY,
1579
case cJ1_JPIMMED_4_02:
1581
JU_IMMSETINPLACE(4, uint32_t *, cJ1_JPIMMED_4_02, j__udySearchLeaf4,
1584
case cJ1_JPIMMED_4_03:
1586
JU_IMMSETCASCADE(4, 3, uint32_t *, cJU_JPLEAF4, ignore,
1587
j__udySearchLeaf4, JU_INSERTCOPY,
1594
1590
// (5_01 => [[ 5_02..03 => ]] LeafL)
1596
case cJ1_JPIMMED_5_02:
1598
JU_IMMSETINPLACE(5, uint8_t *, cJ1_JPIMMED_5_02, __JudySearchLeaf5,
1601
case cJ1_JPIMMED_5_03:
1603
JU_IMMSETCASCADE(5, 3, uint8_t *, cJU_JPLEAF5, ignore,
1604
__JudySearchLeaf5, JU_INSERTCOPY5,
1592
case cJ1_JPIMMED_5_02:
1594
JU_IMMSETINPLACE(5, uint8_t *, cJ1_JPIMMED_5_02, j__udySearchLeaf5,
1597
case cJ1_JPIMMED_5_03:
1599
JU_IMMSETCASCADE(5, 3, uint8_t *, cJU_JPLEAF5, ignore,
1600
j__udySearchLeaf5, JU_INSERTCOPY5,
1607
1603
// (6_01 => [[ 6_02 => ]] LeafL)
1609
case cJ1_JPIMMED_6_02:
1605
case cJ1_JPIMMED_6_02:
1611
JU_IMMSETCASCADE(6, 2, uint8_t *, cJU_JPLEAF6, ignore,
1612
__JudySearchLeaf6, JU_INSERTCOPY6,
1607
JU_IMMSETCASCADE(6, 2, uint8_t *, cJU_JPLEAF6, ignore,
1608
j__udySearchLeaf6, JU_INSERTCOPY6,
1615
1611
// (7_01 => [[ 7_02 => ]] LeafL)
1617
case cJ1_JPIMMED_7_02:
1613
case cJ1_JPIMMED_7_02:
1619
JU_IMMSETCASCADE(7, 2, uint8_t *, cJU_JPLEAF7, ignore,
1620
__JudySearchLeaf7, JU_INSERTCOPY7,
1615
JU_IMMSETCASCADE(7, 2, uint8_t *, cJU_JPLEAF7, ignore,
1616
j__udySearchLeaf7, JU_INSERTCOPY7,
1623
1619
#endif // (JUDY1 && JU_64BIT)
1678
1679
// Main entry point. See the manual entry for details.
1681
FUNCTION int Judy1Set(
1682
FUNCTION int Judy1Set
1683
FUNCTION PPvoid_t JudyLIns(
1684
FUNCTION PPvoid_t JudyLIns
1685
PPvoid_t PPArray, // in which to insert.
1686
Word_t Index, // to insert.
1687
PJError_t PJError) // optional, for returning error info.
1687
PPvoid_t PPArray, // in which to insert.
1688
Word_t Index, // to insert.
1689
PJError_t PJError // optional, for returning error info.
1690
#define Pjv ignore // placeholders for macros.
1691
#define Pjvnew ignore
1693
#define Pjv ignore // placeholders for macros.
1694
#define Pjvnew ignore
1693
Pjv_t Pjv; // value area in old leaf.
1694
Pjv_t Pjvnew; // value area in new leaf.
1696
Pjv_t Pjv; // value area in old leaf.
1697
Pjv_t Pjvnew; // value area in new leaf.
1696
Pjpm_t Pjpm; // array-global info.
1697
int offset; // position in which to store new Index.
1699
Pjpm_t Pjpm; // array-global info.
1700
int offset; // position in which to store new Index.
1700
1704
// CHECK FOR NULL POINTER (error by caller):
1702
if (PPArray == (PPvoid_t) NULL)
1704
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1705
JUDY1CODE(return(JERRI );)
1706
JUDYLCODE(return(PPJERR);)
1710
// ****************************************************************************
1711
// PROCESS TOP LEVEL "JAP" BRANCHES AND LEAVES:
1713
switch (JAPTYPE(*PPArray))
1717
// ****************************************************************************
1718
// JAPNULL (EMPTY ARRAY): BUILD A JAP LEAF WITH ONE INDEX:
1722
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1725
if (Pjlw != (Pjlw_t) NULL) goto NotJudyArray;
1727
// A valid empty array (null pointer), so create an array of population == 1:
1729
Pjlwnew = __JudyAllocJLW(1);
1730
JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1731
JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1733
#if (LOW_POP && JUDYL)
1736
Pjlwnew[1] = 0; // value area.
1738
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJL_JAPLEAF_POPU1);
1739
return((PPvoid_t) (Pjlwnew + 1));
1741
#else // Both JUDY1 and JUDYL without LOW_POP
1743
Pjlwnew[0] = 1 - 1; // pop0 = 0.
1746
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_JAPLEAF);
1747
DBGCODE(JudyCheckPop(*PPArray);)
1706
if (PPArray == (PPvoid_t) NULL)
1708
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1709
JUDY1CODE(return(JERRI );)
1710
JUDYLCODE(return(PPJERR);)
1713
Pjlw = P_JLW(*PPArray); // first word of leaf.
1715
// ****************************************************************************
1716
// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAVES:
1718
// ****************************************************************************
1719
// JRPNULL (EMPTY ARRAY): BUILD A LEAFW WITH ONE INDEX:
1721
// if a valid empty array (null pointer), so create an array of population == 1:
1723
if (Pjlw == (Pjlw_t)NULL)
1727
Pjlwnew = j__udyAllocJLW(1);
1728
JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1729
JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1731
Pjlwnew[0] = 1 - 1; // pop0 = 0.
1734
*PPArray = (Pvoid_t) Pjlwnew;
1735
DBGCODE(JudyCheckPop(*PPArray);)
1749
1737
JUDY1CODE(return(1); )
1750
JUDYLCODE(Pjlwnew[2] = 0; ) // value area.
1738
JUDYLCODE(Pjlwnew[2] = 0; ) // value area.
1751
1739
JUDYLCODE(return((PPvoid_t) (Pjlwnew + 2)); )
1755
#endif // Both JUDY1 and JUDYL without LOW_POP
1758
#if (LOW_POP && JUDYL)
1760
// ****************************************************************************
1763
// TBD: It is still debatable whether it is faster to have POPU1 and POPU2
1764
// types. It needs to be measured. This is a lot of fuss for a 1 and 2
1765
// element arrays. -- Doug
1767
// First check if Index is already inserted
1769
case cJL_JAPLEAF_POPU1:
1771
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1774
if (Pjlw[0] == Index)
1776
DBGCODE(JudyCheckPop(*PPArray);)
1777
return((PPvoid_t) (Pjlw + 1));
1780
// Obtain memory for new, larger JAP leaf, and populate it:
1782
Pjlwnew = __JudyAllocJLW(2);
1783
JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);
1785
// Do a fast copy/insert in sorted order:
1787
// Note: CI2() is shorthand.
1789
#define CI2(Offset,i0,i1,v0,v1) \
1791
offset = (Offset); \
1792
Pjlwnew[0] = (i0); \
1793
Pjlwnew[1] = (i1); \
1794
Pjvnew [0] = (v0); \
1795
Pjvnew [1] = (v1); \
1798
Pjv = JL_LEAFWVALUEAREA(Pjlw, 1);
1799
Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, 2);
1801
if (Index < Pjlw[0]) CI2(0, Index, Pjlw[0], 0, Pjv[0])
1802
else CI2(1, Pjlw[0], Index, Pjv[0], 0)
1804
// Free old leaf and set new leaf type in root pointer:
1806
__JudyFreeJLW(Pjlw, 1, NULL);
1807
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJL_JAPLEAF_POPU2);
1809
DBGCODE(JudyCheckPop(*PPArray);)
1810
return((PPvoid_t) (Pjvnew + offset));
1812
} //cJL_JAPLEAF_POPU1
1815
// ****************************************************************************
1818
// First check if Index is already inserted:
1820
case cJL_JAPLEAF_POPU2:
1822
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1825
if (Pjlw[0] == Index)
1827
DBGCODE(JudyCheckPop(*PPArray);)
1828
return((PPvoid_t) (Pjlw + 0 + 2));
1830
if (Pjlw[1] == Index)
1832
DBGCODE(JudyCheckPop(*PPArray);)
1833
return((PPvoid_t) (Pjlw + 1 + 2));
1836
// Obtain memory for new, larger JAP leaf, and populate it:
1838
Pjlwnew = __JudyAllocJLW(3);
1839
JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);
1841
Pjlwnew[0] = 3 - 1; // pop0 = 2.
1843
// Do a fast copy/insert in sorted order:
1845
// Note: CI3() is shorthand.
1848
#define CI3(Offset,i0,i1,i2,v0,v1,v2) \
1850
offset = (Offset); \
1851
Pjlwnew[1] = (i0); \
1852
Pjlwnew[2] = (i1); \
1853
Pjlwnew[3] = (i2); \
1854
Pjvnew [0] = (v0); \
1855
Pjvnew [1] = (v1); \
1856
Pjvnew [2] = (v2); \
1859
Pjv = JL_LEAFWVALUEAREA(Pjlw, 2);
1860
Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, 3);
1862
if (Index < Pjlw[0])
1863
CI3(0, Index, Pjlw[0], Pjlw[1], 0, Pjv[0], Pjv[1])
1864
else if (Index < Pjlw[1])
1865
CI3(1, Pjlw[0], Index, Pjlw[1], Pjv[0], 0, Pjv[1])
1867
CI3(2, Pjlw[0], Pjlw[1], Index, Pjv[0], Pjv[1], 0)
1869
// Free old leaf and set new leaf type in root pointer:
1871
__JudyFreeJLW(Pjlw, 2, NULL);
1872
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_JAPLEAF);
1874
DBGCODE(JudyCheckPop(*PPArray);)
1875
return((PPvoid_t) (Pjvnew + offset));
1877
} // cJL_JAPLEAF_POPU2
1879
#endif // JUDYL && LOW_POP
1882
// ****************************************************************************
1883
// JAPLEAF, OTHER SIZE:
1887
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1889
Word_t pop1 = Pjlw[0] + 1;
1890
assert(pop1 <= cJU_JAPLEAF_MAXPOP1);
1743
// ****************************************************************************
1744
// LEAFW, OTHER SIZE:
1746
if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
1751
Pjlw = P_JLW(*PPArray); // first word of leaf.
1893
Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);
1755
Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);
1895
offset = __JudySearchLeafW(Pjlw + 1, pop1, Index);
1897
if (offset >= 0) // index is already valid:
1899
DBGCODE(JudyCheckPop(*PPArray);)
1900
JUDY1CODE(return(0); )
1901
JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1757
offset = j__udySearchLeafW(Pjlw + 1, pop1, Index);
1759
if (offset >= 0) // index is already valid:
1761
DBGCODE(JudyCheckPop(*PPArray);)
1762
JUDY1CODE(return(0); )
1763
JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1906
1768
// Insert index in cases where no new memory is needed:
1908
if (JU_LEAFWGROWINPLACE(pop1))
1910
++Pjlw[0]; // increase population.
1770
if (JU_LEAFWGROWINPLACE(pop1))
1772
++Pjlw[0]; // increase population.
1912
JU_INSERTINPLACE(Pjlw + 1, pop1, offset, Index);
1774
JU_INSERTINPLACE(Pjlw + 1, pop1, offset, Index);
1914
JU_INSERTINPLACE(Pjv, pop1, offset, 0);
1776
JU_INSERTINPLACE(Pjv, pop1, offset, 0);
1916
DBGCODE(JudyCheckPop(*PPArray);)
1917
DBGCODE(JudyCheckSorted(Pjlw + 1, pop1 + 1, cJU_ROOTSTATE);)
1778
DBGCODE(JudyCheckPop(*PPArray);)
1779
DBGCODE(JudyCheckSorted(Pjlw + 1, pop1 + 1, cJU_ROOTSTATE);)
1919
1781
JUDY1CODE(return(1); )
1920
1782
JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1923
1785
// Insert index into a new, larger leaf:
1925
if (pop1 < cJU_JAPLEAF_MAXPOP1) // can grow to a larger leaf.
1927
Pjlwnew = __JudyAllocJLW(pop1 + 1);
1928
JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1929
JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1931
Pjlwnew[0] = pop1; // set pop0 in new leaf.
1933
JU_INSERTCOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, Index);
1787
if (pop1 < cJU_LEAFW_MAXPOP1) // can grow to a larger leaf.
1789
Pjlwnew = j__udyAllocJLW(pop1 + 1);
1790
JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1791
JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1793
Pjlwnew[0] = pop1; // set pop0 in new leaf.
1795
JU_INSERTCOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, Index);
1935
Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 + 1);
1936
JU_INSERTCOPY(Pjvnew, Pjv, pop1, offset, 0);
1797
Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 + 1);
1798
JU_INSERTCOPY(Pjvnew, Pjv, pop1, offset, 0);
1938
DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 + 1, cJU_ROOTSTATE);)
1940
__JudyFreeJLW(Pjlw, pop1, NULL);
1942
*PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_JAPLEAF);
1943
DBGCODE(JudyCheckPop(*PPArray);)
1800
DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 + 1, cJU_ROOTSTATE);)
1802
j__udyFreeJLW(Pjlw, pop1, NULL);
1804
*PPArray = (Pvoid_t) Pjlwnew;
1805
DBGCODE(JudyCheckPop(*PPArray);)
1945
1807
JUDY1CODE(return(1); )
1946
1808
JUDYLCODE(return((PPvoid_t) (Pjvnew + offset)); )
1949
assert(pop1 == cJU_JAPLEAF_MAXPOP1);
1811
assert(pop1 == cJU_LEAFW_MAXPOP1);
1951
1813
// Leaf at max size => cannot insert new index, so cascade instead:
1953
// Upon cascading from a JAP leaf to the first branch, must allocate and
1815
// Upon cascading from a LEAFW leaf to the first branch, must allocate and
1954
1816
// initialize a JPM.
1956
Pjpm = __JudyAllocJPM();
1957
JUDY1CODE(JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI );)
1958
JUDYLCODE(JU_CHECKALLOC(Pjpm_t, Pjpm, PPJERR);)
1960
(Pjpm->jpm_Pop0) = cJU_JAPLEAF_MAXPOP1 - 1;
1961
(Pjpm->jpm_JP.jp_Addr) = (Word_t) Pjlw;
1962
(Pjpm->jpm_JP.jp_Type) = cJU_JAPLEAF;
1964
if (__JudyCascadeL(&(Pjpm->jpm_JP), Pjpm) == -1)
1966
JU_COPY_ERRNO(PJError, Pjpm);
1967
JUDY1CODE(return(JERRI );)
1968
JUDYLCODE(return(PPJERR);)
1971
// Note: No need to pass Pjpm for memory decrement; JAPLEAF memory is never
1818
Pjpm = j__udyAllocJPM();
1819
JUDY1CODE(JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI );)
1820
JUDYLCODE(JU_CHECKALLOC(Pjpm_t, Pjpm, PPJERR);)
1822
(Pjpm->jpm_Pop0) = cJU_LEAFW_MAXPOP1 - 1;
1823
(Pjpm->jpm_JP.jp_Addr) = (Word_t) Pjlw;
1825
if (j__udyCascadeL(&(Pjpm->jpm_JP), Pjpm) == -1)
1827
JU_COPY_ERRNO(PJError, Pjpm);
1828
JUDY1CODE(return(JERRI );)
1829
JUDYLCODE(return(PPJERR);)
1832
// Note: No need to pass Pjpm for memory decrement; LEAFW memory is never
1972
1833
// counted in a JPM at all:
1974
__JudyFreeJLW(Pjlw, cJU_JAPLEAF_MAXPOP1, NULL);
1975
*PPArray = (Pvoid_t) ((Word_t) Pjpm | cJU_JAPBRANCH);
1835
j__udyFreeJLW(Pjlw, cJU_LEAFW_MAXPOP1, NULL);
1836
*PPArray = (Pvoid_t) Pjpm;
1982
1840
// ****************************************************************************
1987
int retcode; // really only needed for Judy1, but free for JudyL.
1989
Pjpm = P_JPM(*PPArray);
1991
retcode = __JudyInsWalk(&(Pjpm->jpm_JP), Index, Pjpm);
1995
JU_COPY_ERRNO(PJError, Pjpm);
1996
JUDY1CODE(return(JERRI );)
1997
JUDYLCODE(return(PPJERR);)
2000
if (retcode == 1) ++(Pjpm->jpm_Pop0); // incr total array popu.
2002
assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
2003
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
2004
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
2005
DBGCODE(JudyCheckPop(*PPArray);)
1844
int retcode; // really only needed for Judy1, but free for JudyL.
1846
Pjpm = P_JPM(*PPArray);
1847
retcode = j__udyInsWalk(&(Pjpm->jpm_JP), Index, Pjpm);
1851
JU_COPY_ERRNO(PJError, Pjpm);
1852
JUDY1CODE(return(JERRI );)
1853
JUDYLCODE(return(PPJERR);)
1856
if (retcode == 1) ++(Pjpm->jpm_Pop0); // incr total array popu.
1858
assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
1859
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
1860
|| ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
1861
DBGCODE(JudyCheckPop(*PPArray);)
2008
assert((retcode == 0) || (retcode == 1));
2009
return(retcode); // == JU_RET_*_JPM().
1864
assert((retcode == 0) || (retcode == 1));
1865
return(retcode); // == JU_RET_*_JPM().
2011
assert(Pjpm->jpm_PValue != (Pjv_t) NULL);
2012
return((PPvoid_t) Pjpm->jpm_PValue);
1867
assert(Pjpm->jpm_PValue != (Pjv_t) NULL);
1868
return((PPvoid_t) Pjpm->jpm_PValue);
2017
// ****************************************************************************
2018
// INVALID JAP TYPE:
2023
JUDY1CODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDY1); return(JERRI );)
2024
JUDYLCODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDYL); return(PPJERR);)
2030
1873
} // Judy1Set() / JudyLIns()