1
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
3
// This program is free software; you can redistribute it and/or modify it
4
// under the term of the GNU Lesser General Public License as published by the
5
// Free Software Foundation; either version 2 of the License, or (at your
6
// option) any later version.
8
// This program is distributed in the hope that it will be useful, but WITHOUT
9
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13
// You should have received a copy of the GNU Lesser General Public License
14
// along with this program; if not, write to the Free Software Foundation,
15
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// @(#) $Revision: 4.28 $ $Source: /judy/src/JudyCommon/JudyByCount.c $
20
// Judy*ByCount() function for Judy1 and JudyL.
21
// Compile with one of -DJUDY1 or -DJUDYL.
23
// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
24
// version with cache line optimizations deleted, for testing.
26
// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count().
27
// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a
28
// given Index (that is, its position in the list of valid indexes from the
29
// beginning) as a degenerate case, because in general the count between two
30
// Indexes, inclusive, is not always just the difference in their ordinals.
31
// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index
34
// Note: Like Judy*Count(), this code must "count sideways" in branches, which
35
// can result in a lot of cache line fills. However, unlike Judy*Count(), this
36
// code does not receive a specific Index, hence digit, where to start in each
37
// branch, so it can't accurately calculate cache line fills required in each
38
// direction. The best it can do is an approximation based on the total
39
// population of the expanse (pop1 from Pjp) and the ordinal of the target
40
// Index (see SETOFFSET()) within the expanse.
42
// Compile with -DSMARTMETRICS to obtain global variables containing smart
43
// cache line metrics. Note: Don't turn this on simultaneously for this file
44
// and JudyCount.c because they export the same globals.
45
// ****************************************************************************
47
#if (! (JUDY1 || JUDYL))
48
Error: One of -DJUDY1 or -DJUDYL must be specified.
57
#include "JudyPrivate1L.h"
59
// These are imported from JudyCount.c:
61
// TBD: Should this be in common code? Exported from a header file?
64
extern Word_t __Judy1JPPop1(const Pjp_t Pjp);
65
#define __JudyJPPop1 __Judy1JPPop1
67
extern Word_t __JudyLJPPop1(const Pjp_t Pjp);
68
#define __JudyJPPop1 __JudyLJPPop1
71
// Avoid duplicate symbols since this file is multi-compiled:
75
Word_t jbb_upward = 0; // counts of directions taken:
76
Word_t jbb_downward = 0;
77
Word_t jbu_upward = 0;
78
Word_t jbu_downward = 0;
79
Word_t jlb_upward = 0;
80
Word_t jlb_downward = 0;
82
extern Word_t jbb_upward;
83
extern Word_t jbb_downward;
84
extern Word_t jbu_upward;
85
extern Word_t jbu_downward;
86
extern Word_t jlb_upward;
87
extern Word_t jlb_downward;
92
// ****************************************************************************
93
// J U D Y 1 B Y C O U N T
94
// J U D Y L B Y C O U N T
96
// See the manual entry.
99
FUNCTION int Judy1ByCount(
101
FUNCTION PPvoid_t JudyLByCount(
103
Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
104
const Word_t Count, // ordinal of Index to find, 1..MAX.
105
Word_t * PIndex, // to return found Index.
106
PJError_t PJError) // optional, for returning error info.
108
Word_t Count0; // Count, base-0, to match pop0.
109
Word_t JAPtype; // type part of PArray.
110
Word_t state; // current state in SM.
111
Word_t pop1; // of current branch or leaf, or of expanse.
112
Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
113
Word_t digit; // current word in branch.
114
Word_t jpcount; // JPs in a BranchB subexpanse.
115
long jpnum; // JP number in a branch (base 0).
116
long subexp; // for stepping through layer 1 (subexpanses).
117
int offset; // index ordinal within a leaf, base 0.
119
Pjp_t Pjp; // current JP in branch.
120
Pjll_t Pjll; // current Judy linear leaf.
123
// CHECK FOR EMPTY ARRAY OR NULL PINDEX:
125
if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
127
if (PIndex == (PWord_t) NULL)
129
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
130
JUDY1CODE(return(JERRI );)
131
JUDYLCODE(return(PPJERR);)
134
// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
135
// desired, to represent the last index in a full array:
137
// Note: Think of Count0 as a reliable "number of Indexes below the target."
140
assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
146
// Use an if/then for speed rather than a switch, and put the most common cases
149
JAPtype = JAPTYPE(PArray);
151
if (JAPtype == cJU_JAPBRANCH)
153
Pjpm_t Pjpm = P_JPM(PArray);
155
if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
157
Pjp = &(Pjpm->jpm_JP);
158
pop1 = (Pjpm->jpm_Pop0) + 1;
163
if (JAPtype == cJU_JAPLEAF)
165
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
167
if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
169
*PIndex = Pjlw[Count]; // Index, base 1.
171
JU_RET_FOUND_JAPLEAF(Pjlw, Pjlw[0] + 1, Count0);
174
#if (LOW_POP && JUDYL)
175
if (JAPtype == cJL_JAPLEAF_POPU1)
177
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
179
if (Count0) JU_RET_NOTFOUND; // wrong value.
183
return((PPvoid_t) ((Pjlw) + 1));
186
if (JAPtype == cJL_JAPLEAF_POPU2)
188
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
190
if (Count0 > 1) JU_RET_NOTFOUND; // too high.
192
*PIndex = Pjlw[Count0]; // Index, base 0.
194
return((PPvoid_t) ((Pjlw) + 2 + Count0));
196
#endif // (LOW_POP && JUDYL)
198
JUDY1CODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDY1); return(JERRI );)
199
JUDYLCODE(JU_SET_ERRNO(PJError, JU_ERRNO_NOTJUDYL); return(PPJERR);)
204
// Prepare to handle a root-level or lower-level branch: Save the current
205
// state, obtain the total population for the branch in a state-dependent way,
206
// and then branch to common code for multiple cases.
208
// For root-level branches, the state is always cJU_ROOTSTATE, and the array
209
// population must already be set in pop1; it is not available in jp_DcdPop0.
211
// Note: The total population is only needed in cases where the common code
212
// "counts down" instead of up to minimize cache line fills. However, it's
213
// available cheaply, and it's better to do it with a constant shift (constant
214
// state value) instead of a variable shift later "when needed".
216
#define PREPB_ROOT(Next) \
217
state = cJU_ROOTSTATE; \
220
// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
221
// (only if state < cJU_ROOTSTATE - 1):
223
#define PREPB_DCD(Pjp,cState,Next) \
224
JU_SETDCD(*PIndex, (Pjp)->jp_DcdPop0, cState); \
225
PREPB((Pjp), cState, Next)
227
#define PREPB(Pjp,cState,Next) \
229
pop1 = JU_JPBRANCH_POP0((Pjp)->jp_DcdPop0, (cState)) + 1; \
232
// Calculate whether the ordinal of an Index within a given expanse falls in
233
// the lower or upper half of the expanse's population, taking care with
234
// unsigned math and boundary conditions:
236
// Note: Assume the ordinal falls within the expanse's population, that is,
237
// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
239
// Note: If the ordinal is the middle element, it doesn't matter whether
240
// LOWERHALF() is TRUE or FALSE.
242
#define LOWERHALF(Count0,Pop1lower,Pop1exp) \
243
(((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
245
// Calculate the (signed) offset within a leaf to the desired ordinal (Count -
246
// Pop1lower; offset is one less), and optionally ensure it's in range:
248
#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
249
(Offset) = (Count0) - (Pop1lower); \
250
assert((Offset) >= 0); \
251
assert((Offset) <= JU_JPLEAF_POP0((Pjp)->jp_DcdPop0))
253
// Variations for immediate indexes, with and without pop1-specific assertions:
255
#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
256
(Offset) = (Count0) - (Pop1lower); \
257
assert((Offset) >= 0); \
258
assert((Offset) < (cPop1))
260
#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
261
(Offset) = (Count0) - (Pop1lower)
264
// STATE MACHINE -- TRAVERSE TREE:
266
// In branches, look for the expanse (digit), if any, where the total pop1
267
// below or at that expanse would meet or exceed Count, meaning the Index must
268
// be in this expanse.
270
SMByCount: // return here for next branch/leaf.
272
switch (Pjp->jp_Type)
276
// ----------------------------------------------------------------------------
277
// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
278
// expanse (digit) containing Count, and "recurse".
280
// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
282
// Note: A JBL should always fit in one cache line => no need to count up
283
// versus down to save cache line fills.
285
// TBD: The previous is no longer true. Consider enhancing this code to count
286
// up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
287
// sets pop1 for the whole array, but that value is not used here. 001215:
288
// Maybe it's true again?
290
case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
292
case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
294
case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
295
case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
296
case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
297
case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
298
case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
300
case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
304
// Common code (state-independent) for all cases of linear branches:
307
Pjbl = P_JBL(Pjp->jp_Addr);
309
for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
311
if ((pop1 = __JudyJPPop1((Pjbl->jbl_jp) + jpnum))
314
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
315
JUDY1CODE(return(JERRI );)
316
JUDYLCODE(return(PPJERR);)
320
// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
321
// >=, but instead use the following expression:
323
if (pop1lower + pop1 > Count0) // Index is in this expanse.
325
JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
326
Pjp = (Pjbl->jbl_jp) + jpnum;
327
goto SMByCount; // look under this expanse.
330
pop1lower += pop1; // add this JP's pop1.
333
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
334
JUDY1CODE(return(JERRI );)
335
JUDYLCODE(return(PPJERR);)
337
} // case cJU_JPBRANCH_L
340
// ----------------------------------------------------------------------------
341
// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
342
// until finding the expanse (digit) containing Count, and "recurse".
344
// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
346
case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
348
case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
350
case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
351
case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
352
case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
353
case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
354
case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
356
case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
360
// Common code (state-independent) for all cases of bitmap branches:
363
Pjbb = P_JBB(Pjp->jp_Addr);
365
// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
367
// Note: BMPJP0 exists separately to support assertions.
369
#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
370
#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
373
// Common code for descending through a JP:
375
// Determine the digit for the expanse and save it in *PIndex; then "recurse".
377
#define JBB_FOUNDEXPANSE \
379
JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
380
JU_SETDIGIT(*PIndex, digit, state); \
381
Pjp = BMPJP(subexp, jpnum); \
386
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
388
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1's
389
// in JPs upwards, or subtracting the pop1's in JPs downwards:
391
// See header comments about limitations of this for Judy*ByCount().
395
// COUNT UPWARD, adding each "below" JP's pop1:
397
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
399
if (LOWERHALF(Count0, pop1lower, pop1))
405
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
407
if ((jpcount = __JudyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
408
&& (BMPJP0(subexp) == (Pjp_t) NULL))
410
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
411
JUDY1CODE(return(JERRI );)
412
JUDYLCODE(return(PPJERR);)
415
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
417
for (jpnum = 0; jpnum < jpcount; ++jpnum)
419
if ((pop1 = __JudyJPPop1(BMPJP(subexp, jpnum)))
422
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
423
JUDY1CODE(return(JERRI );)
424
JUDYLCODE(return(PPJERR);)
428
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
430
if (pop1lower + pop1 > Count0)
431
JBB_FOUNDEXPANSE; // Index is in this expanse.
433
pop1lower += pop1; // add this JP's pop1.
436
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
440
// COUNT DOWNWARD, subtracting each "above" JP's pop1 from the whole expanse's
448
pop1lower += pop1; // add whole branch to start.
450
for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
452
if ((jpcount = __JudyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
453
&& (BMPJP0(subexp) == (Pjp_t) NULL))
455
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
456
JUDY1CODE(return(JERRI );)
457
JUDYLCODE(return(PPJERR);)
460
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
462
for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
464
if ((pop1 = __JudyJPPop1(BMPJP(subexp, jpnum)))
467
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
468
JUDY1CODE(return(JERRI );)
469
JUDYLCODE(return(PPJERR);)
473
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
477
// Beware unsigned math problems:
479
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
480
JBB_FOUNDEXPANSE; // Index is in this expanse.
486
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
487
JUDY1CODE(return(JERRI );)
488
JUDYLCODE(return(PPJERR);)
490
} // case cJU_JPBRANCH_B
493
// ----------------------------------------------------------------------------
494
// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
495
// downwards until finding the expanse (digit) containing Count, and "recurse".
497
case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
499
case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
501
case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
502
case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
503
case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
504
case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
505
case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
507
case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
511
// Common code (state-independent) for all cases of uncompressed branches:
514
Pjbu = P_JBU(Pjp->jp_Addr);
516
// Common code for descending through a JP:
518
// Save the digit for the expanse in *PIndex, then "recurse".
520
#define JBU_FOUNDEXPANSE \
522
JU_SETDIGIT(*PIndex, jpnum, state); \
523
Pjp = (Pjbu->jbu_jp) + jpnum; \
528
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
530
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1's
531
// in JPs upwards, or subtracting the pop1's in JPs downwards:
533
// See header comments about limitations of this for Judy*ByCount().
537
// COUNT UPWARD, simply adding the pop1 of each JP:
539
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
541
if (LOWERHALF(Count0, pop1lower, pop1))
548
for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
550
// shortcut, save a function call:
552
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
555
if ((pop1 = __JudyJPPop1((Pjbu->jbu_jp) + jpnum))
558
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
559
JUDY1CODE(return(JERRI );)
560
JUDYLCODE(return(PPJERR);)
564
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
566
if (pop1lower + pop1 > Count0)
567
JBU_FOUNDEXPANSE; // Index is in this expanse.
569
pop1lower += pop1; // add this JP's pop1.
571
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
575
// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
583
pop1lower += pop1; // add whole branch to start.
585
for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
587
// shortcut, save a function call:
589
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
592
if ((pop1 = __JudyJPPop1(Pjbu->jbu_jp + jpnum))
595
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
596
JUDY1CODE(return(JERRI );)
597
JUDYLCODE(return(PPJERR);)
601
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
605
// Beware unsigned math problems:
607
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
608
JBU_FOUNDEXPANSE; // Index is in this expanse.
613
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
614
JUDY1CODE(return(JERRI );)
615
JUDYLCODE(return(PPJERR);)
617
} // case cJU_JPBRANCH_U
619
// ----------------------------------------------------------------------------
622
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
623
// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
626
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
627
// (linear leaf) as a side-effect, but don't depend on that (for JUDYL, which
628
// is the only cases that need it anyway).
630
#define PREPL_DCD(cState) \
631
JU_SETDCD(*PIndex, Pjp->jp_DcdPop0, cState); \
635
#define PREPL_SETPOP1 // not needed in any cases.
637
#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1
641
Pjll = P_JLL(Pjp->jp_Addr); \
643
SETOFFSET(offset, Count0, pop1lower, Pjp)
645
#if (JUDYL || ! JU_64BIT)
649
JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
650
JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
656
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
657
| ((uint16_t *) Pjll)[offset];
658
JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
665
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
666
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
667
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
675
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
676
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
677
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
683
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
684
| ((uint32_t *) Pjll)[offset];
685
JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
691
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
692
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
693
JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
700
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
701
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
702
JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
709
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
710
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
711
JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
716
// ----------------------------------------------------------------------------
719
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
720
// counting bits. First copy Dcd bytes (always present since state 1 <
721
// cJU_ROOTSTATE) to *PIndex.
723
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
724
// (bitmap leaf) as a side-effect, but don't depend on that.
730
JU_SETDCD(*PIndex, Pjp->jp_DcdPop0, 1);
731
Pjlb = P_JLB(Pjp->jp_Addr);
732
pop1 = JU_JPLEAF_POP0(Pjp->jp_DcdPop0) + 1;
734
// COUNT UPWARD, adding the pop1 of each subexpanse:
736
// The entire bitmap should fit in one cache line, but still try to save some
737
// CPU time by counting the fewest possible number of subexpanses from the
740
// See header comments about limitations of this for Judy*ByCount().
742
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
744
if (LOWERHALF(Count0, pop1lower, pop1))
750
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
752
pop1 = __JudyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
754
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
756
if (pop1lower + pop1 > Count0)
757
goto LeafB1; // Index is in this subexpanse.
759
pop1lower += pop1; // add this subexpanse's pop1.
761
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
765
// COUNT DOWNWARD, subtracting each "above" subexpanse's pop1 from the whole
773
pop1lower += pop1; // add whole leaf to start.
775
for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
777
pop1lower -= __JudyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
779
// Beware unsigned math problems:
781
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
782
goto LeafB1; // Index is in this subexpanse.
787
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
788
JUDY1CODE(return(JERRI );)
789
JUDYLCODE(return(PPJERR);)
792
// RETURN INDEX FOUND:
794
// Come here with subexp set to the correct subexpanse, and pop1lower set to
795
// the sum for all lower expanses and subexpanses in the Judy tree. Calculate
796
// and save in *PIndex the digit corresponding to the ordinal in this
800
SETOFFSET(offset, Count0, pop1lower, Pjp);
801
JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
802
JU_SETDIGIT1(*PIndex, digit);
803
JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
804
// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
806
} // case cJU_JPLEAF_B1
810
// ----------------------------------------------------------------------------
813
// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
814
// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
815
// as the LSB in *PIndex.
817
case cJ1_JPFULLPOPU1:
819
JU_SETDCD(*PIndex, Pjp->jp_DcdPop0, 1);
820
SETOFFSET(offset, Count0, pop1lower, Pjp);
822
assert(offset <= cJU_JPFULLPOPU1_POP0);
823
JU_SETDIGIT1(*PIndex, offset);
824
JU_RET_FOUND_FULLPOPU1;
828
// ----------------------------------------------------------------------------
831
// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
832
// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
833
// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
834
// of the immediate Index.
836
#define SET_01(cState) JU_SETDIGITS(*PIndex, Pjp->jp_DcdPop0, cState)
838
case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
839
case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
840
case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
842
case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
843
case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
844
case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
845
case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
850
DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
851
JU_RET_FOUND_IMM_01(Pjp);
853
// Shorthand for where to find start of Index bytes array:
856
#define PJI (Pjp->jp_1Index)
858
#define PJI (Pjp->jp_LIndex)
861
// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
862
// the Index Size of the Immediate:
864
#ifndef DEBUG // simple placeholder:
865
#define IMM(cPop1,Next) \
867
#else // extra pop1-specific checking:
868
#define IMM(cPop1,Next) \
869
SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
873
case cJU_JPIMMED_1_02: IMM( 2, Imm1);
874
case cJU_JPIMMED_1_03: IMM( 3, Imm1);
875
#if (JUDY1 || JU_64BIT)
876
case cJU_JPIMMED_1_04: IMM( 4, Imm1);
877
case cJU_JPIMMED_1_05: IMM( 5, Imm1);
878
case cJU_JPIMMED_1_06: IMM( 6, Imm1);
879
case cJU_JPIMMED_1_07: IMM( 7, Imm1);
881
#if (JUDY1 && JU_64BIT)
882
case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
883
case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
884
case cJ1_JPIMMED_1_10: IMM(10, Imm1);
885
case cJ1_JPIMMED_1_11: IMM(11, Imm1);
886
case cJ1_JPIMMED_1_12: IMM(12, Imm1);
887
case cJ1_JPIMMED_1_13: IMM(13, Imm1);
888
case cJ1_JPIMMED_1_14: IMM(14, Imm1);
889
case cJ1_JPIMMED_1_15: IMM(15, Imm1);
892
Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
893
JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
894
JU_RET_FOUND_IMM(Pjp, offset);
896
#if (JUDY1 || JU_64BIT)
897
case cJU_JPIMMED_2_02: IMM(2, Imm2);
898
case cJU_JPIMMED_2_03: IMM(3, Imm2);
900
#if (JUDY1 && JU_64BIT)
901
case cJ1_JPIMMED_2_04: IMM(4, Imm2);
902
case cJ1_JPIMMED_2_05: IMM(5, Imm2);
903
case cJ1_JPIMMED_2_06: IMM(6, Imm2);
904
case cJ1_JPIMMED_2_07: IMM(7, Imm2);
907
#if (JUDY1 || JU_64BIT)
908
Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
909
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
910
| ((uint16_t *) PJI)[offset];
911
JU_RET_FOUND_IMM(Pjp, offset);
914
#if (JUDY1 || JU_64BIT)
915
case cJU_JPIMMED_3_02: IMM(2, Imm3);
917
#if (JUDY1 && JU_64BIT)
918
case cJ1_JPIMMED_3_03: IMM(3, Imm3);
919
case cJ1_JPIMMED_3_04: IMM(4, Imm3);
920
case cJ1_JPIMMED_3_05: IMM(5, Imm3);
923
#if (JUDY1 || JU_64BIT)
927
SETOFFSET_IMM(offset, Count0, pop1lower);
928
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
929
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
930
JU_RET_FOUND_IMM(Pjp, offset);
934
#if (JUDY1 && JU_64BIT)
935
case cJ1_JPIMMED_4_02: IMM(2, Imm4);
936
case cJ1_JPIMMED_4_03: IMM(3, Imm4);
938
Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
939
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
940
| ((uint32_t *) PJI)[offset];
941
JU_RET_FOUND_IMM(Pjp, offset);
943
case cJ1_JPIMMED_5_02: IMM(2, Imm5);
944
case cJ1_JPIMMED_5_03: IMM(3, Imm5);
949
SETOFFSET_IMM(offset, Count0, pop1lower);
950
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
951
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
952
JU_RET_FOUND_IMM(Pjp, offset);
955
case cJ1_JPIMMED_6_02: IMM(2, Imm6);
960
SETOFFSET_IMM(offset, Count0, pop1lower);
961
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
962
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
963
JU_RET_FOUND_IMM(Pjp, offset);
966
case cJ1_JPIMMED_7_02: IMM(2, Imm7);
971
SETOFFSET_IMM(offset, Count0, pop1lower);
972
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
973
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
974
JU_RET_FOUND_IMM(Pjp, offset);
976
#endif // (JUDY1 && JU_64BIT)
979
// ----------------------------------------------------------------------------
980
// UNEXPECTED JP TYPES:
982
default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
983
JUDY1CODE(return(JERRI );)
984
JUDYLCODE(return(PPJERR);)
986
} // SMByCount switch.
990
} // Judy1ByCount() / JudyLByCount()