49
49
#ifdef JUDYGETINLINE
50
FUNCTION int __Judy1Test(
50
FUNCTION int j__udy1Test
52
FUNCTION int Judy1Test(
52
FUNCTION int Judy1Test
57
57
#ifdef JUDYGETINLINE
58
FUNCTION PPvoid_t __JudyLGet(
58
FUNCTION PPvoid_t j__udyLGet
60
FUNCTION PPvoid_t JudyLGet(
60
FUNCTION PPvoid_t JudyLGet
65
65
#ifdef JUDYGETINLINE
66
Pvoid_t Pjpmvoid, // Pjpm in array with pop1 > 31.
67
Word_t Index) // to retrieve.
66
Pvoid_t PArray, // from which to retrieve.
67
Word_t Index // to retrieve.
69
Pcvoid_t PArray, // from which to retrieve.
70
Word_t Index, // to retrieve.
71
PJError_t PJError) // optional, for returning error info.
69
Pcvoid_t PArray, // from which to retrieve.
70
Word_t Index, // to retrieve.
71
PJError_t PJError // optional, for returning error info.
74
Pjp_t Pjp; // current JP while walking the tree.
75
Pjpm_t Pjpm; // for global accounting.
75
Pjp_t Pjp; // current JP while walking the tree.
76
Pjpm_t Pjpm; // for global accounting.
77
uint8_t Digit; // byte just decoded from Index.
78
Word_t Pop1; // leaf population (number of indexes).
79
Pjll_t Pjll; // pointer to LeafL.
80
DBGCODE(uint8_t ParentJPType;)
76
82
#ifndef JUDYGETINLINE
77
uint8_t JAPtype; // type of JAP (root pointer).
79
uint8_t Digit; // byte just decoded from Index.
80
Word_t Pop1; // leaf population (number of indexes).
81
Pjll_t Pjll; // pointer to LeafL.
82
DBGCODE(uint8_t ParentJPType;)
86
Pjpm = (Pjpm_t) Pjpmvoid; // cc optimizes this out.
87
Pjp = &(Pjpm->jpm_JP); // JP to first node (always a branch).
89
// Most frequent subcase is a BranchU below the JPM; otherwise it must be a
90
// BranchB or BranchL:
92
if (Pjp->jp_Type == cJU_JPBRANCH_U) goto JudyBranchU;
95
#else // ! JUDYGETINLINE
84
if (PArray == (Pcvoid_t) NULL) // empty array.
87
JUDYLCODE(return((PPvoid_t) NULL);)
98
90
// ****************************************************************************
99
// PROCESS TOP LEVEL "JAP" BRANCHES AND LEAVES:
101
JAPtype = JAPTYPE(PArray);
103
// Use "if" statements instead of a switch to "force" the order of the "switch"
104
// so the frequent cases are faster:
106
// Most common case first:
108
if (JAPtype == cJU_JAPBRANCH)
110
Pjpm = P_JPM(PArray);
111
Pjp = &(Pjpm->jpm_JP); // top branch is below JPM.
113
// Most frequent subcase is a BranchU below the JPM; otherwise it must be a
114
// BranchB or BranchL:
116
if (Pjp->jp_Type == cJU_JPBRANCH_U) goto JudyBranchU;
120
#if (LOW_POP && JUDYL)
121
else if (JAPtype == cJL_JAPLEAF_POPU1)
123
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
125
if (Index == Pjlw[0]) return((PPvoid_t) (Pjlw + 1 + 0));
126
return((PPvoid_t) NULL);
128
else if (JAPtype == cJL_JAPLEAF_POPU2)
130
if (Pjlw[0] == Index) return((PPvoid_t) (Pjlw + 2 + 0));
131
if (Pjlw[1] == Index) return((PPvoid_t) (Pjlw + 2 + 1));
132
return((PPvoid_t) NULL);
134
#endif // (LOW_POP && JUDYL)
136
else if (JAPtype == cJU_JAPLEAF)
138
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
139
int posidx; // signed offset in leaf.
142
posidx = __JudySearchLeafW(Pjlw + 1, Pop1, Index);
91
// PROCESS TOP LEVEL BRANCHES AND LEAF:
93
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
95
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
96
int posidx; // signed offset in leaf.
99
posidx = j__udySearchLeafW(Pjlw + 1, Pop1, Index);
146
103
JUDY1CODE(return(1);)
147
104
JUDYLCODE(return((PPvoid_t) (JL_LEAFWVALUEAREA(Pjlw, Pop1) + posidx));)
150
JUDY1CODE(return(0);)
151
JUDYLCODE(return((PPvoid_t) NULL);)
153
else if (PArray == (Pcvoid_t) NULL) // empty array.
155
JUDY1CODE(return(0);)
156
JUDYLCODE(return((PPvoid_t) NULL);)
159
// Any other case is an invalid root pointer (including cJU_JAPNULL with
160
// non-null address part):
162
// Note: Here, and in other places, do not fold these macros into a generic
163
// JU_ERRNO_NOTJUDY, because the following is more explicit, AND yields a
164
// different je_ErrID (line number) for each case.
166
JUDY1CODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDY1); return(JERRI );)
167
JUDYLCODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDYL); return(PPJERR);)
106
JUDY1CODE(return(0);)
107
JUDYLCODE(return((PPvoid_t) NULL);)
169
110
#endif // ! JUDYGETINLINE
112
Pjpm = P_JPM(PArray);
113
Pjp = &(Pjpm->jpm_JP); // top branch is below JPM.
172
115
// ****************************************************************************
173
116
// WALK THE JUDY TREE USING A STATE MACHINE:
175
ContinueWalk: // for going down one level; come here with Pjp set.
118
ContinueWalk: // for going down one level; come here with Pjp set.
178
JudyPrintJP(Pjp, "g", __LINE__);
121
JudyPrintJP(Pjp, "g", __LINE__);
180
switch (Pjp->jp_Type)
123
switch (JU_JPTYPE(Pjp))
183
126
// Ensure the switch table starts at 0 for speed; otherwise more code is
186
case 0: goto ReturnCorrupt; // save a little code.
129
case 0: goto ReturnCorrupt; // save a little code.
189
132
// ****************************************************************************
214
157
// required,since this can be done at leaf level, but it costs nothing to do it
215
158
// sooner, and it aborts an unnecessary traversal sooner.
217
case cJU_JPBRANCH_L2:
219
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 2)) break;
220
Digit = JU_DIGITATSTATE(Index, 2);
223
case cJU_JPBRANCH_L3:
225
#ifdef JU_64BIT // otherwise it's a no-op:
226
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 3)) break;
160
case cJU_JPBRANCH_L2:
162
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
163
Digit = JU_DIGITATSTATE(Index, 2);
166
case cJU_JPBRANCH_L3:
168
#ifdef JU_64BIT // otherwise its a no-op:
169
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
228
Digit = JU_DIGITATSTATE(Index, 3);
171
Digit = JU_DIGITATSTATE(Index, 3);
232
case cJU_JPBRANCH_L4:
234
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 4)) break;
235
Digit = JU_DIGITATSTATE(Index, 4);
238
case cJU_JPBRANCH_L5:
240
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 5)) break;
241
Digit = JU_DIGITATSTATE(Index, 5);
244
case cJU_JPBRANCH_L6:
246
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 6)) break;
247
Digit = JU_DIGITATSTATE(Index, 6);
250
case cJU_JPBRANCH_L7:
252
// JU_DCDNOTMATCHINDEX() would be a no-op.
253
Digit = JU_DIGITATSTATE(Index, 7);
175
case cJU_JPBRANCH_L4:
177
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
178
Digit = JU_DIGITATSTATE(Index, 4);
181
case cJU_JPBRANCH_L5:
183
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
184
Digit = JU_DIGITATSTATE(Index, 5);
187
case cJU_JPBRANCH_L6:
189
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
190
Digit = JU_DIGITATSTATE(Index, 6);
193
case cJU_JPBRANCH_L7:
195
// JU_DCDNOTMATCHINDEX() would be a no-op.
196
Digit = JU_DIGITATSTATE(Index, 7);
256
199
#endif // JU_64BIT
263
Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
265
// Common code for all BranchL's; come here with Digit set:
206
Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
208
// Common code for all BranchLs; come here with Digit set:
268
Pjbl = P_JBL(Pjp->jp_Addr);
273
if (Pjbl->jbl_Expanse[posidx] == Digit)
274
{ // found Digit; continue traversal:
275
DBGCODE(ParentJPType = Pjp->jp_Type;)
276
Pjp = (Pjbl->jbl_jp) + posidx;
279
} while (++posidx != Pjbl->jbl_NumJPs);
211
Pjbl = P_JBL(Pjp->jp_Addr);
216
if (Pjbl->jbl_Expanse[posidx] == Digit)
217
{ // found Digit; continue traversal:
218
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
219
Pjp = Pjbl->jbl_jp + posidx;
222
} while (++posidx != Pjbl->jbl_NumJPs);
285
228
// ****************************************************************************
288
case cJU_JPBRANCH_B2:
290
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 2)) break;
291
Digit = JU_DIGITATSTATE(Index, 2);
294
case cJU_JPBRANCH_B3:
296
#ifdef JU_64BIT // otherwise it's a no-op:
297
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 3)) break;
231
case cJU_JPBRANCH_B2:
233
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
234
Digit = JU_DIGITATSTATE(Index, 2);
237
case cJU_JPBRANCH_B3:
239
#ifdef JU_64BIT // otherwise its a no-op:
240
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
299
Digit = JU_DIGITATSTATE(Index, 3);
242
Digit = JU_DIGITATSTATE(Index, 3);
304
case cJU_JPBRANCH_B4:
306
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 4)) break;
307
Digit = JU_DIGITATSTATE(Index, 4);
310
case cJU_JPBRANCH_B5:
312
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 5)) break;
313
Digit = JU_DIGITATSTATE(Index, 5);
316
case cJU_JPBRANCH_B6:
318
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 6)) break;
319
Digit = JU_DIGITATSTATE(Index, 6);
322
case cJU_JPBRANCH_B7:
324
// JU_DCDNOTMATCHINDEX() would be a no-op.
325
Digit = JU_DIGITATSTATE(Index, 7);
247
case cJU_JPBRANCH_B4:
249
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
250
Digit = JU_DIGITATSTATE(Index, 4);
253
case cJU_JPBRANCH_B5:
255
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
256
Digit = JU_DIGITATSTATE(Index, 5);
259
case cJU_JPBRANCH_B6:
261
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
262
Digit = JU_DIGITATSTATE(Index, 6);
265
case cJU_JPBRANCH_B7:
267
// JU_DCDNOTMATCHINDEX() would be a no-op.
268
Digit = JU_DIGITATSTATE(Index, 7);
328
271
#endif // JU_64BIT
333
Word_t subexp; // in bitmap, 0..7.
334
BITMAPB_t BitMap; // for one subexpanse.
335
BITMAPB_t BitMask; // bit in BitMap for Index's Digit.
337
Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
339
// Common code for all BranchB's; come here with Digit set:
276
Word_t subexp; // in bitmap, 0..7.
277
BITMAPB_t BitMap; // for one subexpanse.
278
BITMAPB_t BitMask; // bit in BitMap for Indexs Digit.
280
Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
282
// Common code for all BranchBs; come here with Digit set:
342
DBGCODE(ParentJPType = Pjp->jp_Type;)
343
Pjbb = P_JBB(Pjp->jp_Addr);
344
subexp = Digit / cJU_BITSPERSUBEXPB;
346
BitMap = JU_JBB_BITMAP(Pjbb, subexp);
347
Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp));
349
BitMask = JU_BITPOSMASKB(Digit);
285
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
286
Pjbb = P_JBB(Pjp->jp_Addr);
287
subexp = Digit / cJU_BITSPERSUBEXPB;
289
BitMap = JU_JBB_BITMAP(Pjbb, subexp);
290
Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp));
292
BitMask = JU_BITPOSMASKB(Digit);
351
294
// No JP in subexpanse for Index => Index not found:
353
if (! (BitMap & BitMask)) break;
296
if (! (BitMap & BitMask)) break;
355
298
// Count JPs in the subexpanse below the one for Index:
357
Pjp += __JudyCountBitsB(BitMap & (BitMask - 1));
361
} // case cJU_JPBRANCH_B*
300
Pjp += j__udyCountBitsB(BitMap & (BitMask - 1));
304
} // case cJU_JPBRANCH_B*
364
307
// ****************************************************************************
367
310
// Notice the reverse order of the cases, and falling through to the next case,
368
311
// for performance.
370
#ifdef notdef // unused, arrive here via shortcut goto:
374
JudyBranchU: // come here on entry to the state machine, with Pjp set.
376
DBGCODE(ParentJPType = Pjp->jp_Type;)
377
Pjp = JU_JBU_PJP(Pjp, Index, cJU_ROOTSTATE);
315
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
316
Pjp = JU_JBU_PJP(Pjp, Index, cJU_ROOTSTATE);
379
318
// If not a BranchU, traverse; otherwise fall into the next case, which makes
380
// this very fast code for a large Judy array (mainly BranchU's), especially
319
// this very fast code for a large Judy array (mainly BranchUs), especially
381
320
// when branches are already in the cache, such as for prev/next:
384
if (Pjp->jp_Type != cJU_JPBRANCH_U3) goto ContinueWalk;
323
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk;
386
if (Pjp->jp_Type != cJU_JPBRANCH_U7) goto ContinueWalk;
325
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U7) goto ContinueWalk;
390
case cJU_JPBRANCH_U7:
392
// JU_DCDNOTMATCHINDEX() would be a no-op.
393
DBGCODE(ParentJPType = Pjp->jp_Type;)
394
Pjp = JU_JBU_PJP(Pjp, Index, 7);
396
if (Pjp->jp_Type != cJU_JPBRANCH_U6) goto ContinueWalk;
399
case cJU_JPBRANCH_U6:
401
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 6)) break;
402
DBGCODE(ParentJPType = Pjp->jp_Type;)
403
Pjp = JU_JBU_PJP(Pjp, Index, 6);
405
if (Pjp->jp_Type != cJU_JPBRANCH_U5) goto ContinueWalk;
408
case cJU_JPBRANCH_U5:
410
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 5)) break;
411
DBGCODE(ParentJPType = Pjp->jp_Type;)
412
Pjp = JU_JBU_PJP(Pjp, Index, 5);
414
if (Pjp->jp_Type != cJU_JPBRANCH_U4) goto ContinueWalk;
417
case cJU_JPBRANCH_U4:
419
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 4)) break;
420
DBGCODE(ParentJPType = Pjp->jp_Type;)
421
Pjp = JU_JBU_PJP(Pjp, Index, 4);
423
if (Pjp->jp_Type != cJU_JPBRANCH_U3) goto ContinueWalk;
329
case cJU_JPBRANCH_U7:
331
// JU_DCDNOTMATCHINDEX() would be a no-op.
332
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
333
Pjp = JU_JBU_PJP(Pjp, Index, 7);
335
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U6) goto ContinueWalk;
338
case cJU_JPBRANCH_U6:
340
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
341
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
342
Pjp = JU_JBU_PJP(Pjp, Index, 6);
344
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U5) goto ContinueWalk;
347
case cJU_JPBRANCH_U5:
349
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
350
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
351
Pjp = JU_JBU_PJP(Pjp, Index, 5);
353
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U4) goto ContinueWalk;
356
case cJU_JPBRANCH_U4:
358
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
359
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
360
Pjp = JU_JBU_PJP(Pjp, Index, 4);
362
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk;
426
365
#endif // JU_64BIT
428
case cJU_JPBRANCH_U3:
367
case cJU_JPBRANCH_U3:
430
#ifdef JU_64BIT // otherwise it's a no-op:
431
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 3)) break;
369
#ifdef JU_64BIT // otherwise its a no-op:
370
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
433
DBGCODE(ParentJPType = Pjp->jp_Type;)
434
Pjp = JU_JBU_PJP(Pjp, Index, 3);
436
if (Pjp->jp_Type != cJU_JPBRANCH_U2) goto ContinueWalk;
439
case cJU_JPBRANCH_U2:
441
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 2)) break;
442
DBGCODE(ParentJPType = Pjp->jp_Type;)
443
Pjp = JU_JBU_PJP(Pjp, Index, 2);
372
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
373
Pjp = JU_JBU_PJP(Pjp, Index, 3);
375
if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U2) goto ContinueWalk;
378
case cJU_JPBRANCH_U2:
380
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
381
DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
382
Pjp = JU_JBU_PJP(Pjp, Index, 2);
445
384
// Note: BranchU2 is a special case that must continue traversal to a leaf,
446
385
// immed, full, or null type:
451
390
// ****************************************************************************
454
393
// Note: Here the calls of JU_DCDNOTMATCHINDEX() are necessary and check
455
394
// whether Index is out of the expanse of a narrow pointer.
457
#if (JUDYL || (! JU_64BIT))
461
int posidx; // signed offset in leaf.
463
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 1)) break;
465
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
466
Pjll = P_JLL(Pjp->jp_Addr);
468
if ((posidx = __JudySearchLeaf1(Pjll, Pop1, Index)) < 0) break;
396
#if (defined(JUDYL) || (! defined(JU_64BIT)))
400
int posidx; // signed offset in leaf.
402
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
404
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
405
Pjll = P_JLL(Pjp->jp_Addr);
407
if ((posidx = j__udySearchLeaf1(Pjll, Pop1, Index)) < 0) break;
470
409
JUDY1CODE(return(1);)
471
410
JUDYLCODE(return((PPvoid_t) (JL_LEAF1VALUEAREA(Pjll, Pop1) + posidx));)
474
413
#endif // (JUDYL || (! JU_64BIT))
478
int posidx; // signed offset in leaf.
480
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 2)) break;
482
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
483
Pjll = P_JLL(Pjp->jp_Addr);
485
if ((posidx = __JudySearchLeaf2(Pjll, Pop1, Index)) < 0) break;
417
int posidx; // signed offset in leaf.
419
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
421
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
422
Pjll = P_JLL(Pjp->jp_Addr);
424
if ((posidx = j__udySearchLeaf2(Pjll, Pop1, Index)) < 0) break;
487
426
JUDY1CODE(return(1);)
488
427
JUDYLCODE(return((PPvoid_t) (JL_LEAF2VALUEAREA(Pjll, Pop1) + posidx));)
492
int posidx; // signed offset in leaf.
431
int posidx; // signed offset in leaf.
494
#ifdef JU_64BIT // otherwise it's a no-op:
495
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 3)) break;
433
#ifdef JU_64BIT // otherwise its a no-op:
434
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
498
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
499
Pjll = P_JLL(Pjp->jp_Addr);
437
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
438
Pjll = P_JLL(Pjp->jp_Addr);
501
if ((posidx = __JudySearchLeaf3(Pjll, Pop1, Index)) < 0) break;
440
if ((posidx = j__udySearchLeaf3(Pjll, Pop1, Index)) < 0) break;
503
442
JUDY1CODE(return(1);)
504
443
JUDYLCODE(return((PPvoid_t) (JL_LEAF3VALUEAREA(Pjll, Pop1) + posidx));)
509
int posidx; // signed offset in leaf.
511
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 4)) break;
513
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
514
Pjll = P_JLL(Pjp->jp_Addr);
516
if ((posidx = __JudySearchLeaf4(Pjll, Pop1, Index)) < 0) break;
448
int posidx; // signed offset in leaf.
450
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
452
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
453
Pjll = P_JLL(Pjp->jp_Addr);
455
if ((posidx = j__udySearchLeaf4(Pjll, Pop1, Index)) < 0) break;
518
457
JUDY1CODE(return(1);)
519
458
JUDYLCODE(return((PPvoid_t) (JL_LEAF4VALUEAREA(Pjll, Pop1) + posidx));)
523
int posidx; // signed offset in leaf.
525
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 5)) break;
527
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
528
Pjll = P_JLL(Pjp->jp_Addr);
530
if ((posidx = __JudySearchLeaf5(Pjll, Pop1, Index)) < 0) break;
462
int posidx; // signed offset in leaf.
464
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
466
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
467
Pjll = P_JLL(Pjp->jp_Addr);
469
if ((posidx = j__udySearchLeaf5(Pjll, Pop1, Index)) < 0) break;
532
471
JUDY1CODE(return(1);)
533
472
JUDYLCODE(return((PPvoid_t) (JL_LEAF5VALUEAREA(Pjll, Pop1) + posidx));)
538
int posidx; // signed offset in leaf.
540
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 6)) break;
542
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
543
Pjll = P_JLL(Pjp->jp_Addr);
545
if ((posidx = __JudySearchLeaf6(Pjll, Pop1, Index)) < 0) break;
477
int posidx; // signed offset in leaf.
479
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
481
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
482
Pjll = P_JLL(Pjp->jp_Addr);
484
if ((posidx = j__udySearchLeaf6(Pjll, Pop1, Index)) < 0) break;
547
486
JUDY1CODE(return(1);)
548
487
JUDYLCODE(return((PPvoid_t) (JL_LEAF6VALUEAREA(Pjll, Pop1) + posidx));)
552
int posidx; // signed offset in leaf.
554
// JU_DCDNOTMATCHINDEX() would be a no-op.
555
Pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
556
Pjll = P_JLL(Pjp->jp_Addr);
558
if ((posidx = __JudySearchLeaf7(Pjll, Pop1, Index)) < 0) break;
491
int posidx; // signed offset in leaf.
493
// JU_DCDNOTMATCHINDEX() would be a no-op.
494
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
495
Pjll = P_JLL(Pjp->jp_Addr);
497
if ((posidx = j__udySearchLeaf7(Pjll, Pop1, Index)) < 0) break;
560
499
JUDY1CODE(return(1);)
561
500
JUDYLCODE(return((PPvoid_t) (JL_LEAF7VALUEAREA(Pjll, Pop1) + posidx));)
563
502
#endif // JU_64BIT
566
505
// ****************************************************************************
574
Word_t subexp; // in bitmap, 0..7.
575
BITMAPL_t BitMap; // for one subexpanse.
576
BITMAPL_t BitMask; // bit in BitMap for Index's Digit.
513
Word_t subexp; // in bitmap, 0..7.
514
BITMAPL_t BitMap; // for one subexpanse.
515
BITMAPL_t BitMask; // bit in BitMap for Indexs Digit.
579
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 1)) break;
518
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
581
Pjlb = P_JLB(Pjp->jp_Addr);
520
Pjlb = P_JLB(Pjp->jp_Addr);
585
// Simply check if Index's bit is set in the bitmap:
524
// Simply check if Indexs bit is set in the bitmap:
587
if (JU_BITMAPTESTL(Pjlb, Index)) return(1);
526
if (JU_BITMAPTESTL(Pjlb, Index)) return(1);
592
531
// JudyL is much more complicated because of value area subarrays:
594
Digit = JU_DIGITATSTATE(Index, 1);
595
subexp = Digit / cJU_BITSPERSUBEXPL;
596
BitMap = JU_JLB_BITMAP(Pjlb, subexp);
597
BitMask = JU_BITPOSMASKL(Digit);
533
Digit = JU_DIGITATSTATE(Index, 1);
534
subexp = Digit / cJU_BITSPERSUBEXPL;
535
BitMap = JU_JLB_BITMAP(Pjlb, subexp);
536
BitMask = JU_BITPOSMASKL(Digit);
599
538
// No value in subexpanse for Index => Index not found:
601
if (! (BitMap & BitMask)) break;
540
if (! (BitMap & BitMask)) break;
603
542
// Count value areas in the subexpanse below the one for Index:
605
Pjv = P_JV(JL_JLB_PVALUE(Pjlb, subexp));
606
assert(Pjv != (Pjv_t) NULL);
607
posidx = __JudyCountBitsL(BitMap & (BitMask - 1));
544
Pjv = P_JV(JL_JLB_PVALUE(Pjlb, subexp));
545
assert(Pjv != (Pjv_t) NULL);
546
posidx = j__udyCountBitsL(BitMap & (BitMask - 1));
609
return((PPvoid_t) (Pjv + posidx));
548
return((PPvoid_t) (Pjv + posidx));
613
} // case cJU_JPLEAF_B1
552
} // case cJU_JPLEAF_B1
620
559
// If the Index is in the expanse, it is necessarily valid (found).
622
case cJ1_JPFULLPOPU1:
624
if (JU_DCDNOTMATCHINDEX(Index, Pjp->jp_DcdPop0, 1)) break;
561
case cJ1_JPFULLPOPU1:
563
if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
566
#ifdef notdef // for future enhancements
569
// Note: Need ? if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
571
case cJ1_JPFULLPOPU1m15:
572
if (Pjp->jp_1Index[14] == (uint8_t)Index) break;
573
case cJ1_JPFULLPOPU1m14:
574
if (Pjp->jp_1Index[13] == (uint8_t)Index) break;
575
case cJ1_JPFULLPOPU1m13:
576
if (Pjp->jp_1Index[12] == (uint8_t)Index) break;
577
case cJ1_JPFULLPOPU1m12:
578
if (Pjp->jp_1Index[11] == (uint8_t)Index) break;
579
case cJ1_JPFULLPOPU1m11:
580
if (Pjp->jp_1Index[10] == (uint8_t)Index) break;
581
case cJ1_JPFULLPOPU1m10:
582
if (Pjp->jp_1Index[9] == (uint8_t)Index) break;
583
case cJ1_JPFULLPOPU1m9:
584
if (Pjp->jp_1Index[8] == (uint8_t)Index) break;
585
case cJ1_JPFULLPOPU1m8:
586
if (Pjp->jp_1Index[7] == (uint8_t)Index) break;
588
case cJ1_JPFULLPOPU1m7:
589
if (Pjp->jp_1Index[6] == (uint8_t)Index) break;
590
case cJ1_JPFULLPOPU1m6:
591
if (Pjp->jp_1Index[5] == (uint8_t)Index) break;
592
case cJ1_JPFULLPOPU1m5:
593
if (Pjp->jp_1Index[4] == (uint8_t)Index) break;
594
case cJ1_JPFULLPOPU1m4:
595
if (Pjp->jp_1Index[3] == (uint8_t)Index) break;
596
case cJ1_JPFULLPOPU1m3:
597
if (Pjp->jp_1Index[2] == (uint8_t)Index) break;
598
case cJ1_JPFULLPOPU1m2:
599
if (Pjp->jp_1Index[1] == (uint8_t)Index) break;
600
case cJ1_JPFULLPOPU1m1:
601
if (Pjp->jp_1Index[0] == (uint8_t)Index) break;
603
return(1); // found, not in exclusion list
629
// Macro used for even (1, 2, 4) sized IMMED_*_02 and up:
631
#define SEARCHIMMEDEVEN(LeafType,Pjp,Index,JPType) \
633
LeafType _Index = (Index); /* necessary for masking Index */ \
634
JUDY1CODE(LeafType *_PLeaf = (LeafType *)((Pjp)->jp_1Index);) \
635
JUDYLCODE(LeafType *_PLeaf = (LeafType *)((Pjp)->jp_LIndex);) \
636
/* if beyond end of leaf */ \
637
if ((_Index) > _PLeaf[(Pjp)->jp_Type - (JPType) + 1]) break; \
639
for(;;) { if (_Index <= *_PLeaf) break; _PLeaf++; } \
640
if ((_Index) == *_PLeaf) /* found ? */ \
642
JUDY1CODE(return(1);) \
643
JUDYLCODE(return((PPvoid_t)(P_JV((Pjp)->jp_Addr) + \
644
(_PLeaf - (LeafType *)((Pjp)->jp_LIndex))));) \
646
break; /* exit not found */ \
650
608
// ****************************************************************************
653
// Note that the contents of jp_DcdPop0 are different for cJU_JPIMMED_*_01:
611
// Note that the contents of jp_DcdPopO are different for cJU_JPIMMED_*_01:
655
case cJU_JPIMMED_1_01:
656
case cJU_JPIMMED_2_01:
657
case cJU_JPIMMED_3_01:
613
case cJU_JPIMMED_1_01:
614
case cJU_JPIMMED_2_01:
615
case cJU_JPIMMED_3_01:
659
case cJU_JPIMMED_4_01:
660
case cJU_JPIMMED_5_01:
661
case cJU_JPIMMED_6_01:
662
case cJU_JPIMMED_7_01:
617
case cJU_JPIMMED_4_01:
618
case cJU_JPIMMED_5_01:
619
case cJU_JPIMMED_6_01:
620
case cJU_JPIMMED_7_01:
664
if (Pjp->jp_DcdPop0 != JU_TRIMTODCDSIZE(Index)) break;
622
if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) break;
666
624
JUDY1CODE(return(1);)
667
625
JUDYLCODE(return((PPvoid_t) &(Pjp->jp_Addr));) // immediate value area.
669
case cJU_JPIMMED_1_02:
670
case cJU_JPIMMED_1_03:
671
#if (JUDY1 || JU_64BIT)
672
case cJU_JPIMMED_1_04:
673
case cJU_JPIMMED_1_05:
674
case cJU_JPIMMED_1_06:
675
case cJU_JPIMMED_1_07:
677
#if (JUDY1 && JU_64BIT)
678
case cJ1_JPIMMED_1_08:
679
case cJ1_JPIMMED_1_09:
680
case cJ1_JPIMMED_1_10:
681
case cJ1_JPIMMED_1_11:
682
case cJ1_JPIMMED_1_12:
683
case cJ1_JPIMMED_1_13:
684
case cJ1_JPIMMED_1_14:
685
case cJ1_JPIMMED_1_15:
687
SEARCHIMMEDEVEN(uint8_t, Pjp, Index, cJU_JPIMMED_1_02);
689
#if (JUDY1 || JU_64BIT)
690
case cJU_JPIMMED_2_02:
691
case cJU_JPIMMED_2_03:
693
#if (JUDY1 && JU_64BIT)
694
case cJ1_JPIMMED_2_04:
695
case cJ1_JPIMMED_2_05:
696
case cJ1_JPIMMED_2_06:
697
case cJ1_JPIMMED_2_07:
700
#if (JUDY1 || JU_64BIT)
701
SEARCHIMMEDEVEN(uint16_t, Pjp, Index, cJU_JPIMMED_2_02);
704
#if (JUDY1 || JU_64BIT)
705
case cJU_JPIMMED_3_02:
707
#if (JUDY1 && JU_64BIT)
708
case cJ1_JPIMMED_3_03:
709
case cJ1_JPIMMED_3_04:
710
case cJ1_JPIMMED_3_05:
712
#if (JUDY1 || JU_64BIT)
628
// Macros to make code more readable and avoid dup errors
716
Pjll = (Pjll_t)(Pjp->jp_1Index);
719
Pjll = (Pjll_t) (Pjp->jp_LIndex);
720
Pjv = P_JV(Pjp->jp_Addr);
722
Pop1 = Pjp->jp_Type - cJU_JPIMMED_3_02 + 2;
724
if ((posidx = __JudySearchLeaf3(Pjll, Pop1, Index)) < 0) break;
726
JUDY1CODE(return(1);)
727
JUDYLCODE(return((PPvoid_t) (Pjv + posidx));)
731
#if (JUDY1 && JU_64BIT)
733
case cJ1_JPIMMED_4_02:
734
case cJ1_JPIMMED_4_03:
735
SEARCHIMMEDEVEN(uint32_t, Pjp, Index, cJ1_JPIMMED_4_02);
737
case cJ1_JPIMMED_5_02:
738
case cJ1_JPIMMED_5_03:
740
Pop1 = Pjp->jp_Type - cJ1_JPIMMED_5_02 + 2;
741
Pjll = (Pjll_t) (Pjp->jp_1Index);
743
if (__JudySearchLeaf5(Pjll, Pop1, Index) < 0) break;
746
case cJ1_JPIMMED_6_02:
748
Pjll = (Pjll_t) (Pjp->jp_1Index);
750
if (__JudySearchLeaf6(Pjll, 2, Index) < 0) break;
753
case cJ1_JPIMMED_7_02:
755
Pjll = (Pjll_t) (Pjp->jp_1Index);
757
if (__JudySearchLeaf7(Pjll, 2, Index) < 0) break;
632
#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \
633
if (((LEAF_T *)((PJP)->jp_1Index))[(IDX) - 1] == (LEAF_T)(INDEX)) \
636
#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \
640
a_ddr = (PJP)->jp_1Index + (((IDX) - 1) * (LFBTS)); \
641
COPY(i_ndex, a_ddr); \
642
if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \
649
#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \
650
if (((LEAF_T *)((PJP)->jp_LIndex))[(IDX) - 1] == (LEAF_T)(INDEX)) \
651
return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1))
653
#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \
657
a_ddr = (PJP)->jp_LIndex + (((IDX) - 1) * (LFBTS)); \
658
COPY(i_ndex, a_ddr); \
659
if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \
660
return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1)); \
664
#if (defined(JUDY1) && defined(JU_64BIT))
665
case cJ1_JPIMMED_1_15: CHECKINDEXNATIVE(uint8_t, Pjp, 15, Index);
666
case cJ1_JPIMMED_1_14: CHECKINDEXNATIVE(uint8_t, Pjp, 14, Index);
667
case cJ1_JPIMMED_1_13: CHECKINDEXNATIVE(uint8_t, Pjp, 13, Index);
668
case cJ1_JPIMMED_1_12: CHECKINDEXNATIVE(uint8_t, Pjp, 12, Index);
669
case cJ1_JPIMMED_1_11: CHECKINDEXNATIVE(uint8_t, Pjp, 11, Index);
670
case cJ1_JPIMMED_1_10: CHECKINDEXNATIVE(uint8_t, Pjp, 10, Index);
671
case cJ1_JPIMMED_1_09: CHECKINDEXNATIVE(uint8_t, Pjp, 9, Index);
672
case cJ1_JPIMMED_1_08: CHECKINDEXNATIVE(uint8_t, Pjp, 8, Index);
674
#if (defined(JUDY1) || defined(JU_64BIT))
675
case cJU_JPIMMED_1_07: CHECKINDEXNATIVE(uint8_t, Pjp, 7, Index);
676
case cJU_JPIMMED_1_06: CHECKINDEXNATIVE(uint8_t, Pjp, 6, Index);
677
case cJU_JPIMMED_1_05: CHECKINDEXNATIVE(uint8_t, Pjp, 5, Index);
678
case cJU_JPIMMED_1_04: CHECKINDEXNATIVE(uint8_t, Pjp, 4, Index);
680
case cJU_JPIMMED_1_03: CHECKINDEXNATIVE(uint8_t, Pjp, 3, Index);
681
case cJU_JPIMMED_1_02: CHECKINDEXNATIVE(uint8_t, Pjp, 2, Index);
682
CHECKINDEXNATIVE(uint8_t, Pjp, 1, Index);
685
#if (defined(JUDY1) && defined(JU_64BIT))
686
case cJ1_JPIMMED_2_07: CHECKINDEXNATIVE(uint16_t, Pjp, 7, Index);
687
case cJ1_JPIMMED_2_06: CHECKINDEXNATIVE(uint16_t, Pjp, 6, Index);
688
case cJ1_JPIMMED_2_05: CHECKINDEXNATIVE(uint16_t, Pjp, 5, Index);
689
case cJ1_JPIMMED_2_04: CHECKINDEXNATIVE(uint16_t, Pjp, 4, Index);
691
#if (defined(JUDY1) || defined(JU_64BIT))
692
case cJU_JPIMMED_2_03: CHECKINDEXNATIVE(uint16_t, Pjp, 3, Index);
693
case cJU_JPIMMED_2_02: CHECKINDEXNATIVE(uint16_t, Pjp, 2, Index);
694
CHECKINDEXNATIVE(uint16_t, Pjp, 1, Index);
698
#if (defined(JUDY1) && defined(JU_64BIT))
699
case cJ1_JPIMMED_3_05:
700
CHECKLEAFNONNAT(3, Pjp, Index, 5, JU_COPY3_PINDEX_TO_LONG);
701
case cJ1_JPIMMED_3_04:
702
CHECKLEAFNONNAT(3, Pjp, Index, 4, JU_COPY3_PINDEX_TO_LONG);
703
case cJ1_JPIMMED_3_03:
704
CHECKLEAFNONNAT(3, Pjp, Index, 3, JU_COPY3_PINDEX_TO_LONG);
706
#if (defined(JUDY1) || defined(JU_64BIT))
707
case cJU_JPIMMED_3_02:
708
CHECKLEAFNONNAT(3, Pjp, Index, 2, JU_COPY3_PINDEX_TO_LONG);
709
CHECKLEAFNONNAT(3, Pjp, Index, 1, JU_COPY3_PINDEX_TO_LONG);
713
#if (defined(JUDY1) && defined(JU_64BIT))
715
case cJ1_JPIMMED_4_03: CHECKINDEXNATIVE(uint32_t, Pjp, 3, Index);
716
case cJ1_JPIMMED_4_02: CHECKINDEXNATIVE(uint32_t, Pjp, 2, Index);
717
CHECKINDEXNATIVE(uint32_t, Pjp, 1, Index);
720
case cJ1_JPIMMED_5_03:
721
CHECKLEAFNONNAT(5, Pjp, Index, 3, JU_COPY5_PINDEX_TO_LONG);
722
case cJ1_JPIMMED_5_02:
723
CHECKLEAFNONNAT(5, Pjp, Index, 2, JU_COPY5_PINDEX_TO_LONG);
724
CHECKLEAFNONNAT(5, Pjp, Index, 1, JU_COPY5_PINDEX_TO_LONG);
727
case cJ1_JPIMMED_6_02:
728
CHECKLEAFNONNAT(6, Pjp, Index, 2, JU_COPY6_PINDEX_TO_LONG);
729
CHECKLEAFNONNAT(6, Pjp, Index, 1, JU_COPY6_PINDEX_TO_LONG);
732
case cJ1_JPIMMED_7_02:
733
CHECKLEAFNONNAT(7, Pjp, Index, 2, JU_COPY7_PINDEX_TO_LONG);
734
CHECKLEAFNONNAT(7, Pjp, Index, 1, JU_COPY7_PINDEX_TO_LONG);
760
737
#endif // (JUDY1 && JU_64BIT)
820
797
// - Consistent JP types (always descending down the tree).
822
// - Sorted linear lists in BranchL's and leaves (using JudyCheckSorted(), but
799
// - Sorted linear lists in BranchLs and leaves (using JudyCheckSorted(), but
823
800
// ideally that function is already called wherever appropriate after any
824
801
// linear list is modified).
826
803
// - Any others possible?
828
#include <stdlib.h> // for getenv() and atol().
805
#include <stdlib.h> // for getenv() and atol().
830
807
static Word_t JudyCheckPopSM(Pjp_t Pjp, Word_t RootPop1);
832
809
FUNCTION void JudyCheckPop(
835
static bool_t checked = FALSE; // already checked env parameter.
836
static bool_t enabled = FALSE; // env parameter set.
837
static bool_t active = FALSE; // calls >= callsmin.
838
static Word_t callsmin; // start point from $CHECKPOP.
839
static Word_t calls = 0; // times called so far.
841
Word_t JAPtype; // JAP type part of PArray.
812
static bool_t checked = FALSE; // already checked env parameter.
813
static bool_t enabled = FALSE; // env parameter set.
814
static bool_t active = FALSE; // calls >= callsmin.
815
static Word_t callsmin; // start point from $CHECKPOP.
816
static Word_t calls = 0; // times called so far.
844
819
// CHECK FOR EXTERNAL ENABLING:
846
if (! checked) // only check once.
848
char * value; // for getenv().
852
if ((value = getenv("CHECKPOP")) == (char *) NULL)
821
if (! checked) // only check once.
823
char * value; // for getenv().
827
if ((value = getenv("CHECKPOP")) == (char *) NULL)
855
// Take this out because nightly tests want to be flavor-independent; it's not
830
// Take this out because nightly tests want to be flavor-independent; its not
856
831
// OK to emit special non-error output from the debug flavor:
858
(void) puts("JudyCheckPop() present but not enabled by "
859
"$CHECKPOP env parameter; set it to the number of "
860
"calls at which to begin checking");
833
(void) puts("JudyCheckPop() present but not enabled by "
834
"$CHECKPOP env parameter; set it to the number of "
835
"calls at which to begin checking");
865
callsmin = atol(value); // note: non-number evaluates to 0.
868
(void) printf("JudyCheckPop() present and enabled; callsmin = "
871
else if (! enabled) return;
840
callsmin = atol(value); // note: non-number evaluates to 0.
843
(void) printf("JudyCheckPop() present and enabled; callsmin = "
846
else if (! enabled) return;
873
848
// Previously or just now enabled; check if non-active or newly active:
877
if (++calls < callsmin) return;
879
(void) printf("JudyCheckPop() activated at call %lu\n", calls);
884
// START AT TOP OF TREE:
886
JAPtype = JAPTYPE(PArray);
892
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
893
assert(Pjlw == (Pjlw_t) NULL); // rest of word must be null.
894
return; // valid null JAP.
897
#if (LOW_POP && JUDYL)
899
// Little or no pop checking is possible for these types, but see function
902
case cJL_JAPLEAF_POPU1: return;
903
case cJL_JAPLEAF_POPU2: return;
908
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
909
assert(*Pjlw + 1 <= cJU_JAPLEAF_MAXPOP1);
852
if (++calls < callsmin) return;
854
(void) printf("JudyCheckPop() activated at call %lu\n", calls);
858
// IGNORE LEAFW AT TOP OF TREE:
860
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
913
863
// Check JPM pop0 against tree, recursively:
915
865
// Note: The traversal code in JudyCheckPopSM() is simplest when the case
916
866
// statement for each JP type compares the pop1 for that JP to its subtree (if
917
// any) after traversing the subtree (that's the hard part) and adding up
918
// actual pop1's. A top branch's JP in the JPM does not have room for a
867
// any) after traversing the subtree (thats the hard part) and adding up
868
// actual pop1s. A top branchs JP in the JPM does not have room for a
919
869
// full-word pop1, so pass it in as a special case.
923
Pjpm_t Pjpm = P_JPM(PArray);
924
(void) JudyCheckPopSM(&(Pjpm->jpm_JP), Pjpm->jpm_Pop0 + 1);
929
assert(FALSE); // unrecognized JAP type => corruption.
872
Pjpm_t Pjpm = P_JPM(PArray);
873
(void) JudyCheckPopSM(&(Pjpm->jpm_JP), Pjpm->jpm_Pop0 + 1);
931
877
} // JudyCheckPop()
937
883
// Recursive state machine (subroutine) for JudyCheckPop(): Given a Pjp (other
938
884
// than JPNULL*; caller should shortcut) and the root population for top-level
939
// branches, check the subtree's actual pop1 against its nominal value, and
885
// branches, check the subtrees actual pop1 against its nominal value, and
940
886
// return the total pop1 for the subtree.
942
888
// Note: Expect RootPop1 to be ignored at lower levels, so pass down 0, which
943
889
// should pop an assertion if this expectation is violated.
945
891
FUNCTION static Word_t JudyCheckPopSM(
946
Pjp_t Pjp, // top of subtree.
947
Word_t RootPop1) // whole array, for top-level branches only.
892
Pjp_t Pjp, // top of subtree.
893
Word_t RootPop1) // whole array, for top-level branches only.
949
Word_t pop1_jp; // nominal population from the JP.
950
Word_t pop1 = 0; // actual population at this level.
951
Word_t offset; // in a branch.
895
Word_t pop1_jp; // nominal population from the JP.
896
Word_t pop1 = 0; // actual population at this level.
897
Word_t offset; // in a branch.
953
#define PREPBRANCH(cPopBytes,Next) \
954
pop1_jp = JU_JPBRANCH_POP0(Pjp->jp_DcdPop0, cPopBytes) + 1; goto Next
899
#define PREPBRANCH(cPopBytes,Next) \
900
pop1_jp = JU_JPBRANCH_POP0(Pjp, cPopBytes) + 1; goto Next
956
902
assert((((Word_t) (Pjp->jp_Addr)) & 7) == 3);
957
switch (Pjp->jp_Type)
903
switch (JU_JPTYPE(Pjp))
960
case cJU_JPBRANCH_L2: PREPBRANCH(2, BranchL);
961
case cJU_JPBRANCH_L3: PREPBRANCH(3, BranchL);
906
case cJU_JPBRANCH_L2: PREPBRANCH(2, BranchL);
907
case cJU_JPBRANCH_L3: PREPBRANCH(3, BranchL);
963
case cJU_JPBRANCH_L4: PREPBRANCH(4, BranchL);
964
case cJU_JPBRANCH_L5: PREPBRANCH(5, BranchL);
965
case cJU_JPBRANCH_L6: PREPBRANCH(6, BranchL);
966
case cJU_JPBRANCH_L7: PREPBRANCH(7, BranchL);
909
case cJU_JPBRANCH_L4: PREPBRANCH(4, BranchL);
910
case cJU_JPBRANCH_L5: PREPBRANCH(5, BranchL);
911
case cJU_JPBRANCH_L6: PREPBRANCH(6, BranchL);
912
case cJU_JPBRANCH_L7: PREPBRANCH(7, BranchL);
968
case cJU_JPBRANCH_L: pop1_jp = RootPop1;
914
case cJU_JPBRANCH_L: pop1_jp = RootPop1;
972
Pjbl = P_JBL(Pjp->jp_Addr);
974
for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
975
pop1 += JudyCheckPopSM((Pjbl->jbl_jp) + offset, 0);
977
assert(pop1_jp == pop1);
981
case cJU_JPBRANCH_B2: PREPBRANCH(2, BranchB);
982
case cJU_JPBRANCH_B3: PREPBRANCH(3, BranchB);
918
Pjbl = P_JBL(Pjp->jp_Addr);
920
for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
921
pop1 += JudyCheckPopSM((Pjbl->jbl_jp) + offset, 0);
923
assert(pop1_jp == pop1);
927
case cJU_JPBRANCH_B2: PREPBRANCH(2, BranchB);
928
case cJU_JPBRANCH_B3: PREPBRANCH(3, BranchB);
984
case cJU_JPBRANCH_B4: PREPBRANCH(4, BranchB);
985
case cJU_JPBRANCH_B5: PREPBRANCH(5, BranchB);
986
case cJU_JPBRANCH_B6: PREPBRANCH(6, BranchB);
987
case cJU_JPBRANCH_B7: PREPBRANCH(7, BranchB);
930
case cJU_JPBRANCH_B4: PREPBRANCH(4, BranchB);
931
case cJU_JPBRANCH_B5: PREPBRANCH(5, BranchB);
932
case cJU_JPBRANCH_B6: PREPBRANCH(6, BranchB);
933
case cJU_JPBRANCH_B7: PREPBRANCH(7, BranchB);
989
case cJU_JPBRANCH_B: pop1_jp = RootPop1;
935
case cJU_JPBRANCH_B: pop1_jp = RootPop1;
995
Pjbb = P_JBB(Pjp->jp_Addr);
997
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
999
jpcount = __JudyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
1001
for (offset = 0; offset < jpcount; ++offset)
1003
pop1 += JudyCheckPopSM(P_JP(JU_JBB_PJP(Pjbb, subexp))
1008
assert(pop1_jp == pop1);
1012
case cJU_JPBRANCH_U2: PREPBRANCH(2, BranchU);
1013
case cJU_JPBRANCH_U3: PREPBRANCH(3, BranchU);
941
Pjbb = P_JBB(Pjp->jp_Addr);
943
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
945
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
947
for (offset = 0; offset < jpcount; ++offset)
949
pop1 += JudyCheckPopSM(P_JP(JU_JBB_PJP(Pjbb, subexp))
954
assert(pop1_jp == pop1);
958
case cJU_JPBRANCH_U2: PREPBRANCH(2, BranchU);
959
case cJU_JPBRANCH_U3: PREPBRANCH(3, BranchU);
1015
case cJU_JPBRANCH_U4: PREPBRANCH(4, BranchU);
1016
case cJU_JPBRANCH_U5: PREPBRANCH(5, BranchU);
1017
case cJU_JPBRANCH_U6: PREPBRANCH(6, BranchU);
1018
case cJU_JPBRANCH_U7: PREPBRANCH(7, BranchU);
961
case cJU_JPBRANCH_U4: PREPBRANCH(4, BranchU);
962
case cJU_JPBRANCH_U5: PREPBRANCH(5, BranchU);
963
case cJU_JPBRANCH_U6: PREPBRANCH(6, BranchU);
964
case cJU_JPBRANCH_U7: PREPBRANCH(7, BranchU);
1020
case cJU_JPBRANCH_U: pop1_jp = RootPop1;
966
case cJU_JPBRANCH_U: pop1_jp = RootPop1;
1024
Pjbu = P_JBU(Pjp->jp_Addr);
1026
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
1028
if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
1029
&& ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
1031
continue; // skip null JP to save time.
1034
pop1 += JudyCheckPopSM((Pjbu->jbu_jp) + offset, 0);
1037
assert(pop1_jp == pop1);
970
Pjbu = P_JBU(Pjp->jp_Addr);
972
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
974
if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
975
&& ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
977
continue; // skip null JP to save time.
980
pop1 += JudyCheckPopSM((Pjbu->jbu_jp) + offset, 0);
983
assert(pop1_jp == pop1);
1042
988
// -- Cases below here terminate and do not recurse. --
1044
// For all of these cases except JPLEAF_B1, there is no way to check the JP's
990
// For all of these cases except JPLEAF_B1, there is no way to check the JPs
1045
991
// pop1 against the object itself; just return the pop1; but for linear leaves,
1046
992
// a bounds check is possible.
1048
#define CHECKLEAF(MaxPop1) \
1049
pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1; \
1050
assert(pop1 >= 1); \
1051
assert(pop1 <= (MaxPop1)); \
1054
#if (JUDYL || (! JU_64BIT ))
1055
case cJU_JPLEAF1: CHECKLEAF(cJU_LEAF1_MAXPOP1);
1057
case cJU_JPLEAF2: CHECKLEAF(cJU_LEAF2_MAXPOP1);
1058
case cJU_JPLEAF3: CHECKLEAF(cJU_LEAF3_MAXPOP1);
1060
case cJU_JPLEAF4: CHECKLEAF(cJU_LEAF4_MAXPOP1);
1061
case cJU_JPLEAF5: CHECKLEAF(cJU_LEAF5_MAXPOP1);
1062
case cJU_JPLEAF6: CHECKLEAF(cJU_LEAF6_MAXPOP1);
1063
case cJU_JPLEAF7: CHECKLEAF(cJU_LEAF7_MAXPOP1);
1071
pop1_jp = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
1073
Pjlb = P_JLB(Pjp->jp_Addr);
1075
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
1076
pop1 += __JudyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
1078
assert(pop1_jp == pop1);
1082
JUDY1CODE(case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0);)
1084
case cJU_JPIMMED_1_01: return(1);
1085
case cJU_JPIMMED_2_01: return(1);
1086
case cJU_JPIMMED_3_01: return(1);
1088
case cJU_JPIMMED_4_01: return(1);
1089
case cJU_JPIMMED_5_01: return(1);
1090
case cJU_JPIMMED_6_01: return(1);
1091
case cJU_JPIMMED_7_01: return(1);
1094
case cJU_JPIMMED_1_02: return(2);
1095
case cJU_JPIMMED_1_03: return(3);
1096
#if (JUDY1 || JU_64BIT)
1097
case cJU_JPIMMED_1_04: return(4);
1098
case cJU_JPIMMED_1_05: return(5);
1099
case cJU_JPIMMED_1_06: return(6);
1100
case cJU_JPIMMED_1_07: return(7);
1102
#if (JUDY1 && JU_64BIT)
1103
case cJ1_JPIMMED_1_08: return(8);
1104
case cJ1_JPIMMED_1_09: return(9);
1105
case cJ1_JPIMMED_1_10: return(10);
1106
case cJ1_JPIMMED_1_11: return(11);
1107
case cJ1_JPIMMED_1_12: return(12);
1108
case cJ1_JPIMMED_1_13: return(13);
1109
case cJ1_JPIMMED_1_14: return(14);
1110
case cJ1_JPIMMED_1_15: return(15);
1113
#if (JUDY1 || JU_64BIT)
1114
case cJU_JPIMMED_2_02: return(2);
1115
case cJU_JPIMMED_2_03: return(3);
1117
#if (JUDY1 && JU_64BIT)
1118
case cJ1_JPIMMED_2_04: return(4);
1119
case cJ1_JPIMMED_2_05: return(5);
1120
case cJ1_JPIMMED_2_06: return(6);
1121
case cJ1_JPIMMED_2_07: return(7);
1124
#if (JUDY1 || JU_64BIT)
1125
case cJU_JPIMMED_3_02: return(2);
1127
#if (JUDY1 && JU_64BIT)
1128
case cJ1_JPIMMED_3_03: return(3);
1129
case cJ1_JPIMMED_3_04: return(4);
1130
case cJ1_JPIMMED_3_05: return(5);
1132
case cJ1_JPIMMED_4_02: return(2);
1133
case cJ1_JPIMMED_4_03: return(3);
1134
case cJ1_JPIMMED_5_02: return(2);
1135
case cJ1_JPIMMED_5_03: return(3);
1136
case cJ1_JPIMMED_6_02: return(2);
1137
case cJ1_JPIMMED_7_02: return(2);
1140
} // switch (Pjp->jp_Type)
1142
assert(FALSE); // unrecognized JP type => corruption.
1143
return(0); // to make some compilers happy.
994
#define CHECKLEAF(MaxPop1) \
995
pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
997
assert(pop1 <= (MaxPop1)); \
1000
#if (defined(JUDYL) || (! defined(JU_64BIT)))
1001
case cJU_JPLEAF1: CHECKLEAF(cJU_LEAF1_MAXPOP1);
1003
case cJU_JPLEAF2: CHECKLEAF(cJU_LEAF2_MAXPOP1);
1004
case cJU_JPLEAF3: CHECKLEAF(cJU_LEAF3_MAXPOP1);
1006
case cJU_JPLEAF4: CHECKLEAF(cJU_LEAF4_MAXPOP1);
1007
case cJU_JPLEAF5: CHECKLEAF(cJU_LEAF5_MAXPOP1);
1008
case cJU_JPLEAF6: CHECKLEAF(cJU_LEAF6_MAXPOP1);
1009
case cJU_JPLEAF7: CHECKLEAF(cJU_LEAF7_MAXPOP1);
1017
pop1_jp = JU_JPLEAF_POP0(Pjp) + 1;
1019
Pjlb = P_JLB(Pjp->jp_Addr);
1021
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
1022
pop1 += j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
1024
assert(pop1_jp == pop1);
1028
JUDY1CODE(case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0);)
1030
case cJU_JPIMMED_1_01: return(1);
1031
case cJU_JPIMMED_2_01: return(1);
1032
case cJU_JPIMMED_3_01: return(1);
1034
case cJU_JPIMMED_4_01: return(1);
1035
case cJU_JPIMMED_5_01: return(1);
1036
case cJU_JPIMMED_6_01: return(1);
1037
case cJU_JPIMMED_7_01: return(1);
1040
case cJU_JPIMMED_1_02: return(2);
1041
case cJU_JPIMMED_1_03: return(3);
1042
#if (defined(JUDY1) || defined(JU_64BIT))
1043
case cJU_JPIMMED_1_04: return(4);
1044
case cJU_JPIMMED_1_05: return(5);
1045
case cJU_JPIMMED_1_06: return(6);
1046
case cJU_JPIMMED_1_07: return(7);
1048
#if (defined(JUDY1) && defined(JU_64BIT))
1049
case cJ1_JPIMMED_1_08: return(8);
1050
case cJ1_JPIMMED_1_09: return(9);
1051
case cJ1_JPIMMED_1_10: return(10);
1052
case cJ1_JPIMMED_1_11: return(11);
1053
case cJ1_JPIMMED_1_12: return(12);
1054
case cJ1_JPIMMED_1_13: return(13);
1055
case cJ1_JPIMMED_1_14: return(14);
1056
case cJ1_JPIMMED_1_15: return(15);
1059
#if (defined(JUDY1) || defined(JU_64BIT))
1060
case cJU_JPIMMED_2_02: return(2);
1061
case cJU_JPIMMED_2_03: return(3);
1063
#if (defined(JUDY1) && defined(JU_64BIT))
1064
case cJ1_JPIMMED_2_04: return(4);
1065
case cJ1_JPIMMED_2_05: return(5);
1066
case cJ1_JPIMMED_2_06: return(6);
1067
case cJ1_JPIMMED_2_07: return(7);
1070
#if (defined(JUDY1) || defined(JU_64BIT))
1071
case cJU_JPIMMED_3_02: return(2);
1073
#if (defined(JUDY1) && defined(JU_64BIT))
1074
case cJ1_JPIMMED_3_03: return(3);
1075
case cJ1_JPIMMED_3_04: return(4);
1076
case cJ1_JPIMMED_3_05: return(5);
1078
case cJ1_JPIMMED_4_02: return(2);
1079
case cJ1_JPIMMED_4_03: return(3);
1080
case cJ1_JPIMMED_5_02: return(2);
1081
case cJ1_JPIMMED_5_03: return(3);
1082
case cJ1_JPIMMED_6_02: return(2);
1083
case cJ1_JPIMMED_7_02: return(2);
1086
} // switch (JU_JPTYPE(Pjp))
1088
assert(FALSE); // unrecognized JP type => corruption.
1089
return(0); // to make some compilers happy.
1145
1091
} // JudyCheckPopSM()