master
c 954 lines 27.7 KB
Raw
1 // Copyright (C) 2000 - 2002 Hewlett-Packard Company
2 //
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.
7 //
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
11 // for more details.
12 //
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
16 // _________________
17
18 // @(#) $Revision: 4.28 $ $Source: /judy/src/JudyCommon/JudyByCount.c $
19 //
20 // Judy*ByCount() function for Judy1 and JudyL.
21 // Compile with one of -DJUDY1 or -DJUDYL.
22 //
23 // Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
24 // version with cache line optimizations deleted, for testing.
25 //
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
32 // mapper.
33 //
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 cant 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.
41 //
42 // Compile with -DSMARTMETRICS to obtain global variables containing smart
43 // cache line metrics. Note: Dont turn this on simultaneously for this file
44 // and JudyCount.c because they export the same globals.
45 // ****************************************************************************
46
47 #if (! (defined(JUDY1) || defined(JUDYL)))
48 #error: One of -DJUDY1 or -DJUDYL must be specified.
49 #endif
50
51 #ifdef JUDY1
52 #include "Judy1.h"
53 #else
54 #include "JudyL.h"
55 #endif
56
57 #include "JudyPrivate1L.h"
58
59 // These are imported from JudyCount.c:
60 //
61 // TBD: Should this be in common code? Exported from a header file?
62
63 #ifdef JUDY1
64 extern Word_t j__udy1JPPop1(const Pjp_t Pjp);
65 #define j__udyJPPop1 j__udy1JPPop1
66 #else
67 extern Word_t j__udyLJPPop1(const Pjp_t Pjp);
68 #define j__udyJPPop1 j__udyLJPPop1
69 #endif
70
71 // Avoid duplicate symbols since this file is multi-compiled:
72
73 #ifdef SMARTMETRICS
74 #ifdef JUDY1
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;
81 #else
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;
88 #endif
89 #endif
90
91
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
95 //
96 // See the manual entry.
97
98 #ifdef JUDY1
99 FUNCTION int Judy1ByCount
100 #else
101 FUNCTION PPvoid_t JudyLByCount
102 #endif
103 (
104 Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
105 Word_t Count, // ordinal of Index to find, 1..MAX.
106 Word_t * PIndex, // to return found Index.
107 PJError_t PJError // optional, for returning error info.
108 )
109 {
110 Word_t Count0; // Count, base-0, to match pop0.
111 Word_t state; // current state in SM.
112 Word_t pop1; // of current branch or leaf, or of expanse.
113 Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
114 Word_t digit; // current word in branch.
115 Word_t jpcount; // JPs in a BranchB subexpanse.
116 long jpnum; // JP number in a branch (base 0).
117 long subexp; // for stepping through layer 1 (subexpanses).
118 int offset; // index ordinal within a leaf, base 0.
119
120 Pjp_t Pjp; // current JP in branch.
121 Pjll_t Pjll; // current Judy linear leaf.
122
123
124 // CHECK FOR EMPTY ARRAY OR NULL PINDEX:
125
126 if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
127
128 if (PIndex == (PWord_t) NULL)
129 {
130 JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
131 JUDY1CODE(return(JERRI );)
132 JUDYLCODE(return(PPJERR);)
133 }
134
135 // Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
136 // desired, to represent the last index in a full array:
137 //
138 // Note: Think of Count0 as a reliable "number of Indexes below the target."
139
140 Count0 = Count - 1;
141 assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
142 pop1lower = 0;
143
144 if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
145 {
146 Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
147
148 if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
149
150 *PIndex = Pjlw[Count]; // Index, base 1.
151
152 JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0);
153 }
154 else
155 {
156 Pjpm_t Pjpm = P_JPM(PArray);
157
158 if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
159
160 Pjp = &(Pjpm->jpm_JP);
161 pop1 = (Pjpm->jpm_Pop0) + 1;
162
163 // goto SMByCount;
164 }
165
166 // COMMON CODE:
167 //
168 // Prepare to handle a root-level or lower-level branch: Save the current
169 // state, obtain the total population for the branch in a state-dependent way,
170 // and then branch to common code for multiple cases.
171 //
172 // For root-level branches, the state is always cJU_ROOTSTATE, and the array
173 // population must already be set in pop1; it is not available in jp_DcdPopO.
174 //
175 // Note: The total population is only needed in cases where the common code
176 // "counts down" instead of up to minimize cache line fills. However, its
177 // available cheaply, and its better to do it with a constant shift (constant
178 // state value) instead of a variable shift later "when needed".
179
180 #define PREPB_ROOT(Next) \
181 state = cJU_ROOTSTATE; \
182 goto Next
183
184 // Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
185 // (only if state < cJU_ROOTSTATE - 1):
186
187 #define PREPB_DCD(Pjp,cState,Next) \
188 JU_SETDCD(*PIndex, Pjp, cState); \
189 PREPB((Pjp), cState, Next)
190
191 #define PREPB(Pjp,cState,Next) \
192 state = (cState); \
193 pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
194 goto Next
195
196 // Calculate whether the ordinal of an Index within a given expanse falls in
197 // the lower or upper half of the expanses population, taking care with
198 // unsigned math and boundary conditions:
199 //
200 // Note: Assume the ordinal falls within the expanses population, that is,
201 // 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
202 //
203 // Note: If the ordinal is the middle element, it doesnt matter whether
204 // LOWERHALF() is TRUE or FALSE.
205
206 #define LOWERHALF(Count0,Pop1lower,Pop1exp) \
207 (((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
208
209 // Calculate the (signed) offset within a leaf to the desired ordinal (Count -
210 // Pop1lower; offset is one less), and optionally ensure its in range:
211
212 #define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
213 (Offset) = (Count0) - (Pop1lower); \
214 assert((Offset) >= 0); \
215 assert((Offset) <= JU_JPLEAF_POP0(Pjp))
216
217 // Variations for immediate indexes, with and without pop1-specific assertions:
218
219 #define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
220 (Offset) = (Count0) - (Pop1lower); \
221 assert((Offset) >= 0); \
222 assert((Offset) < (cPop1))
223
224 #define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
225 (Offset) = (Count0) - (Pop1lower)
226
227
228 // STATE MACHINE -- TRAVERSE TREE:
229 //
230 // In branches, look for the expanse (digit), if any, where the total pop1
231 // below or at that expanse would meet or exceed Count, meaning the Index must
232 // be in this expanse.
233
234 SMByCount: // return here for next branch/leaf.
235
236 switch (JU_JPTYPE(Pjp))
237 {
238
239
240 // ----------------------------------------------------------------------------
241 // LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
242 // expanse (digit) containing Count, and "recurse".
243 //
244 // Note: There are no null JPs in a JBL; watch out for pop1 == 0.
245 //
246 // Note: A JBL should always fit in one cache line => no need to count up
247 // versus down to save cache line fills.
248 //
249 // TBD: The previous is no longer true. Consider enhancing this code to count
250 // up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
251 // sets pop1 for the whole array, but that value is not used here. 001215:
252 // Maybe its true again?
253
254 case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
255 #ifndef JU_64BIT
256 case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
257 #else
258 case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
259 case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
260 case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
261 case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
262 case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
263 #endif
264 case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
265 {
266 Pjbl_t Pjbl;
267
268 // Common code (state-independent) for all cases of linear branches:
269
270 BranchL:
271 Pjbl = P_JBL(Pjp->jp_Addr);
272
273 for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
274 {
275 if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum))
276 == cJU_ALLONES)
277 {
278 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
279 JUDY1CODE(return(JERRI );)
280 JUDYLCODE(return(PPJERR);)
281 }
282 assert(pop1 != 0);
283
284 // Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
285 // >=, but instead use the following expression:
286
287 if (pop1lower + pop1 > Count0) // Index is in this expanse.
288 {
289 JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
290 Pjp = (Pjbl->jbl_jp) + jpnum;
291 goto SMByCount; // look under this expanse.
292 }
293
294 pop1lower += pop1; // add this JPs pop1.
295 }
296
297 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
298 JUDY1CODE(return(JERRI );)
299 JUDYLCODE(return(PPJERR);)
300
301 } // case cJU_JPBRANCH_L
302
303
304 // ----------------------------------------------------------------------------
305 // BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
306 // until finding the expanse (digit) containing Count, and "recurse".
307 //
308 // Note: There are no null JPs in a JBB; watch out for pop1 == 0.
309
310 case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
311 #ifndef JU_64BIT
312 case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
313 #else
314 case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
315 case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
316 case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
317 case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
318 case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
319 #endif
320 case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
321 {
322 Pjbb_t Pjbb;
323
324 // Common code (state-independent) for all cases of bitmap branches:
325
326 BranchB:
327 Pjbb = P_JBB(Pjp->jp_Addr);
328
329 // Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
330 //
331 // Note: BMPJP0 exists separately to support assertions.
332
333 #define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
334 #define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
335
336
337 // Common code for descending through a JP:
338 //
339 // Determine the digit for the expanse and save it in *PIndex; then "recurse".
340
341 #define JBB_FOUNDEXPANSE \
342 { \
343 JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
344 JU_SETDIGIT(*PIndex, digit, state); \
345 Pjp = BMPJP(subexp, jpnum); \
346 goto SMByCount; \
347 }
348
349
350 #ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
351
352 // FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
353 // in JPs upwards, or subtracting the pop1s in JPs downwards:
354 //
355 // See header comments about limitations of this for Judy*ByCount().
356
357 #endif
358
359 // COUNT UPWARD, adding each "below" JPs pop1:
360
361 #ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
362
363 if (LOWERHALF(Count0, pop1lower, pop1))
364 {
365 #endif
366 #ifdef SMARTMETRICS
367 ++jbb_upward;
368 #endif
369 for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
370 {
371 if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
372 && (BMPJP0(subexp) == (Pjp_t) NULL))
373 {
374 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
375 JUDY1CODE(return(JERRI );)
376 JUDYLCODE(return(PPJERR);)
377 }
378
379 // Note: An empty subexpanse (jpcount == 0) is handled "for free":
380
381 for (jpnum = 0; jpnum < jpcount; ++jpnum)
382 {
383 if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
384 == cJU_ALLONES)
385 {
386 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
387 JUDY1CODE(return(JERRI );)
388 JUDYLCODE(return(PPJERR);)
389 }
390 assert(pop1 != 0);
391
392 // Warning: pop1lower and pop1 are unsigned, see earlier comment:
393
394 if (pop1lower + pop1 > Count0)
395 JBB_FOUNDEXPANSE; // Index is in this expanse.
396
397 pop1lower += pop1; // add this JPs pop1.
398 }
399 }
400 #ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
401 }
402
403
404 // COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses
405 // pop1:
406
407 else
408 {
409 #ifdef SMARTMETRICS
410 ++jbb_downward;
411 #endif
412 pop1lower += pop1; // add whole branch to start.
413
414 for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
415 {
416 if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
417 && (BMPJP0(subexp) == (Pjp_t) NULL))
418 {
419 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
420 JUDY1CODE(return(JERRI );)
421 JUDYLCODE(return(PPJERR);)
422 }
423
424 // Note: An empty subexpanse (jpcount == 0) is handled "for free":
425
426 for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
427 {
428 if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
429 == cJU_ALLONES)
430 {
431 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
432 JUDY1CODE(return(JERRI );)
433 JUDYLCODE(return(PPJERR);)
434 }
435 assert(pop1 != 0);
436
437 // Warning: pop1lower and pop1 are unsigned, see earlier comment:
438
439 pop1lower -= pop1;
440
441 // Beware unsigned math problems:
442
443 if ((pop1lower == 0) || (pop1lower - 1 < Count0))
444 JBB_FOUNDEXPANSE; // Index is in this expanse.
445 }
446 }
447 }
448 #endif // NOSMARTJBB
449
450 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
451 JUDY1CODE(return(JERRI );)
452 JUDYLCODE(return(PPJERR);)
453
454 } // case cJU_JPBRANCH_B
455
456
457 // ----------------------------------------------------------------------------
458 // UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
459 // downwards until finding the expanse (digit) containing Count, and "recurse".
460
461 case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
462 #ifndef JU_64BIT
463 case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
464 #else
465 case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
466 case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
467 case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
468 case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
469 case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
470 #endif
471 case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
472 {
473 Pjbu_t Pjbu;
474
475 // Common code (state-independent) for all cases of uncompressed branches:
476
477 BranchU:
478 Pjbu = P_JBU(Pjp->jp_Addr);
479
480 // Common code for descending through a JP:
481 //
482 // Save the digit for the expanse in *PIndex, then "recurse".
483
484 #define JBU_FOUNDEXPANSE \
485 { \
486 JU_SETDIGIT(*PIndex, jpnum, state); \
487 Pjp = (Pjbu->jbu_jp) + jpnum; \
488 goto SMByCount; \
489 }
490
491
492 #ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
493
494 // FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
495 // in JPs upwards, or subtracting the pop1s in JPs downwards:
496 //
497 // See header comments about limitations of this for Judy*ByCount().
498
499 #endif
500
501 // COUNT UPWARD, simply adding the pop1 of each JP:
502
503 #ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
504
505 if (LOWERHALF(Count0, pop1lower, pop1))
506 {
507 #endif
508 #ifdef SMARTMETRICS
509 ++jbu_upward;
510 #endif
511
512 for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
513 {
514 // shortcut, save a function call:
515
516 if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
517 continue;
518
519 if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum))
520 == cJU_ALLONES)
521 {
522 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
523 JUDY1CODE(return(JERRI );)
524 JUDYLCODE(return(PPJERR);)
525 }
526 assert(pop1 != 0);
527
528 // Warning: pop1lower and pop1 are unsigned, see earlier comment:
529
530 if (pop1lower + pop1 > Count0)
531 JBU_FOUNDEXPANSE; // Index is in this expanse.
532
533 pop1lower += pop1; // add this JPs pop1.
534 }
535 #ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
536 }
537
538
539 // COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
540 // expanses pop1:
541
542 else
543 {
544 #ifdef SMARTMETRICS
545 ++jbu_downward;
546 #endif
547 pop1lower += pop1; // add whole branch to start.
548
549 for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
550 {
551 // shortcut, save a function call:
552
553 if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
554 continue;
555
556 if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
557 == cJU_ALLONES)
558 {
559 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
560 JUDY1CODE(return(JERRI );)
561 JUDYLCODE(return(PPJERR);)
562 }
563 assert(pop1 != 0);
564
565 // Warning: pop1lower and pop1 are unsigned, see earlier comment:
566
567 pop1lower -= pop1;
568
569 // Beware unsigned math problems:
570
571 if ((pop1lower == 0) || (pop1lower - 1 < Count0))
572 JBU_FOUNDEXPANSE; // Index is in this expanse.
573 }
574 }
575 #endif // NOSMARTJBU
576
577 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
578 JUDY1CODE(return(JERRI );)
579 JUDYLCODE(return(PPJERR);)
580
581 } // case cJU_JPBRANCH_U
582
583 // ----------------------------------------------------------------------------
584 // LINEAR LEAF:
585 //
586 // Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
587 // copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
588 // *PIndex.
589 //
590 // Note: The preceding branch traversal code MIGHT set pop1 for this expanse
591 // (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which
592 // is the only cases that need it anyway).
593
594 #define PREPL_DCD(cState) \
595 JU_SETDCD(*PIndex, Pjp, cState); \
596 PREPL
597
598 #ifdef JUDY1
599 #define PREPL_SETPOP1 // not needed in any cases.
600 #else
601 #define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
602 #endif
603
604 #define PREPL \
605 Pjll = P_JLL(Pjp->jp_Addr); \
606 PREPL_SETPOP1; \
607 SETOFFSET(offset, Count0, pop1lower, Pjp)
608
609 #if (defined(JUDYL) || (! defined(JU_64BIT)))
610 case cJU_JPLEAF1:
611
612 PREPL_DCD(1);
613 JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
614 JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
615 #endif
616
617 case cJU_JPLEAF2:
618
619 PREPL_DCD(2);
620 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
621 | ((uint16_t *) Pjll)[offset];
622 JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
623
624 #ifndef JU_64BIT
625 case cJU_JPLEAF3:
626 {
627 Word_t lsb;
628 PREPL;
629 JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
630 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
631 JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
632 }
633
634 #else
635 case cJU_JPLEAF3:
636 {
637 Word_t lsb;
638 PREPL_DCD(3);
639 JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
640 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
641 JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
642 }
643
644 case cJU_JPLEAF4:
645
646 PREPL_DCD(4);
647 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
648 | ((uint32_t *) Pjll)[offset];
649 JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
650
651 case cJU_JPLEAF5:
652 {
653 Word_t lsb;
654 PREPL_DCD(5);
655 JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
656 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
657 JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
658 }
659
660 case cJU_JPLEAF6:
661 {
662 Word_t lsb;
663 PREPL_DCD(6);
664 JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
665 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
666 JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
667 }
668
669 case cJU_JPLEAF7:
670 {
671 Word_t lsb;
672 PREPL;
673 JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
674 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
675 JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
676 }
677 #endif
678
679
680 // ----------------------------------------------------------------------------
681 // BITMAP LEAF:
682 //
683 // Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
684 // counting bits. First copy Dcd bytes (always present since state 1 <
685 // cJU_ROOTSTATE) to *PIndex.
686 //
687 // Note: The preceding branch traversal code MIGHT set pop1 for this expanse
688 // (bitmap leaf) as a side-effect, but dont depend on that.
689
690 case cJU_JPLEAF_B1:
691 {
692 Pjlb_t Pjlb;
693
694 JU_SETDCD(*PIndex, Pjp, 1);
695 Pjlb = P_JLB(Pjp->jp_Addr);
696 pop1 = JU_JPLEAF_POP0(Pjp) + 1;
697
698 // COUNT UPWARD, adding the pop1 of each subexpanse:
699 //
700 // The entire bitmap should fit in one cache line, but still try to save some
701 // CPU time by counting the fewest possible number of subexpanses from the
702 // bitmap.
703 //
704 // See header comments about limitations of this for Judy*ByCount().
705
706 #ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
707
708 if (LOWERHALF(Count0, pop1lower, pop1))
709 {
710 #endif
711 #ifdef SMARTMETRICS
712 ++jlb_upward;
713 #endif
714 for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
715 {
716 pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
717
718 // Warning: pop1lower and pop1 are unsigned, see earlier comment:
719
720 if (pop1lower + pop1 > Count0)
721 goto LeafB1; // Index is in this subexpanse.
722
723 pop1lower += pop1; // add this subexpanses pop1.
724 }
725 #ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
726 }
727
728
729 // COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole
730 // expanses pop1:
731
732 else
733 {
734 #ifdef SMARTMETRICS
735 ++jlb_downward;
736 #endif
737 pop1lower += pop1; // add whole leaf to start.
738
739 for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
740 {
741 pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
742
743 // Beware unsigned math problems:
744
745 if ((pop1lower == 0) || (pop1lower - 1 < Count0))
746 goto LeafB1; // Index is in this subexpanse.
747 }
748 }
749 #endif // NOSMARTJLB
750
751 JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
752 JUDY1CODE(return(JERRI );)
753 JUDYLCODE(return(PPJERR);)
754
755
756 // RETURN INDEX FOUND:
757 //
758 // Come here with subexp set to the correct subexpanse, and pop1lower set to
759 // the sum for all lower expanses and subexpanses in the Judy tree. Calculate
760 // and save in *PIndex the digit corresponding to the ordinal in this
761 // subexpanse.
762
763 LeafB1:
764 SETOFFSET(offset, Count0, pop1lower, Pjp);
765 JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
766 JU_SETDIGIT1(*PIndex, digit);
767 JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
768 // == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
769
770 } // case cJU_JPLEAF_B1
771
772
773 #ifdef JUDY1
774 // ----------------------------------------------------------------------------
775 // FULL POPULATION:
776 //
777 // Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
778 // then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
779 // as the LSB in *PIndex.
780
781 case cJ1_JPFULLPOPU1:
782
783 JU_SETDCD(*PIndex, Pjp, 1);
784 SETOFFSET(offset, Count0, pop1lower, Pjp);
785 assert(offset >= 0);
786 assert(offset <= cJU_JPFULLPOPU1_POP0);
787 JU_SETDIGIT1(*PIndex, offset);
788 JU_RET_FOUND_FULLPOPU1;
789 #endif
790
791
792 // ----------------------------------------------------------------------------
793 // IMMEDIATE:
794 //
795 // Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
796 // depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
797 // Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
798 // of the immediate Index.
799
800 #define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
801
802 case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
803 case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
804 case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
805 #ifdef JU_64BIT
806 case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
807 case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
808 case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
809 case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
810 #endif
811
812 Imm_01:
813
814 DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
815 JU_RET_FOUND_IMM_01(Pjp);
816
817 // Shorthand for where to find start of Index bytes array:
818
819 #ifdef JUDY1
820 #define PJI (Pjp->jp_1Index)
821 #else
822 #define PJI (Pjp->jp_LIndex)
823 #endif
824
825 // Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
826 // the Index Size of the Immediate:
827
828 #ifndef DEBUG // simple placeholder:
829 #define IMM(cPop1,Next) \
830 goto Next
831 #else // extra pop1-specific checking:
832 #define IMM(cPop1,Next) \
833 SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
834 goto Next
835 #endif
836
837 case cJU_JPIMMED_1_02: IMM( 2, Imm1);
838 case cJU_JPIMMED_1_03: IMM( 3, Imm1);
839 #if (defined(JUDY1) || defined(JU_64BIT))
840 case cJU_JPIMMED_1_04: IMM( 4, Imm1);
841 case cJU_JPIMMED_1_05: IMM( 5, Imm1);
842 case cJU_JPIMMED_1_06: IMM( 6, Imm1);
843 case cJU_JPIMMED_1_07: IMM( 7, Imm1);
844 #endif
845 #if (defined(JUDY1) && defined(JU_64BIT))
846 case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
847 case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
848 case cJ1_JPIMMED_1_10: IMM(10, Imm1);
849 case cJ1_JPIMMED_1_11: IMM(11, Imm1);
850 case cJ1_JPIMMED_1_12: IMM(12, Imm1);
851 case cJ1_JPIMMED_1_13: IMM(13, Imm1);
852 case cJ1_JPIMMED_1_14: IMM(14, Imm1);
853 case cJ1_JPIMMED_1_15: IMM(15, Imm1);
854 #endif
855
856 Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
857 JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
858 JU_RET_FOUND_IMM(Pjp, offset);
859
860 #if (defined(JUDY1) || defined(JU_64BIT))
861 case cJU_JPIMMED_2_02: IMM(2, Imm2);
862 case cJU_JPIMMED_2_03: IMM(3, Imm2);
863 #endif
864 #if (defined(JUDY1) && defined(JU_64BIT))
865 case cJ1_JPIMMED_2_04: IMM(4, Imm2);
866 case cJ1_JPIMMED_2_05: IMM(5, Imm2);
867 case cJ1_JPIMMED_2_06: IMM(6, Imm2);
868 case cJ1_JPIMMED_2_07: IMM(7, Imm2);
869 #endif
870
871 #if (defined(JUDY1) || defined(JU_64BIT))
872 Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
873 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
874 | ((uint16_t *) PJI)[offset];
875 JU_RET_FOUND_IMM(Pjp, offset);
876 #endif
877
878 #if (defined(JUDY1) || defined(JU_64BIT))
879 case cJU_JPIMMED_3_02: IMM(2, Imm3);
880 #endif
881 #if (defined(JUDY1) && defined(JU_64BIT))
882 case cJ1_JPIMMED_3_03: IMM(3, Imm3);
883 case cJ1_JPIMMED_3_04: IMM(4, Imm3);
884 case cJ1_JPIMMED_3_05: IMM(5, Imm3);
885 #endif
886
887 #if (defined(JUDY1) || defined(JU_64BIT))
888 Imm3:
889 {
890 Word_t lsb;
891 SETOFFSET_IMM(offset, Count0, pop1lower);
892 JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
893 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
894 JU_RET_FOUND_IMM(Pjp, offset);
895 }
896 #endif
897
898 #if (defined(JUDY1) && defined(JU_64BIT))
899 case cJ1_JPIMMED_4_02: IMM(2, Imm4);
900 case cJ1_JPIMMED_4_03: IMM(3, Imm4);
901
902 Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
903 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
904 | ((uint32_t *) PJI)[offset];
905 JU_RET_FOUND_IMM(Pjp, offset);
906
907 case cJ1_JPIMMED_5_02: IMM(2, Imm5);
908 case cJ1_JPIMMED_5_03: IMM(3, Imm5);
909
910 Imm5:
911 {
912 Word_t lsb;
913 SETOFFSET_IMM(offset, Count0, pop1lower);
914 JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
915 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
916 JU_RET_FOUND_IMM(Pjp, offset);
917 }
918
919 case cJ1_JPIMMED_6_02: IMM(2, Imm6);
920
921 Imm6:
922 {
923 Word_t lsb;
924 SETOFFSET_IMM(offset, Count0, pop1lower);
925 JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
926 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
927 JU_RET_FOUND_IMM(Pjp, offset);
928 }
929
930 case cJ1_JPIMMED_7_02: IMM(2, Imm7);
931
932 Imm7:
933 {
934 Word_t lsb;
935 SETOFFSET_IMM(offset, Count0, pop1lower);
936 JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
937 *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
938 JU_RET_FOUND_IMM(Pjp, offset);
939 }
940 #endif // (JUDY1 && JU_64BIT)
941
942
943 // ----------------------------------------------------------------------------
944 // UNEXPECTED JP TYPES:
945
946 default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
947 JUDY1CODE(return(JERRI );)
948 JUDYLCODE(return(PPJERR);)
949
950 } // SMByCount switch.
951
952 /*NOTREACHED*/
953
954 } // Judy1ByCount() / JudyLByCount()