master
c 1,873 lines 70.8 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.116 $ $Source: /judy/src/JudyCommon/JudyIns.c $
19 //
20 // Judy1Set() and JudyLIns() functions for Judy1 and JudyL.
21 // Compile with one of -DJUDY1 or -DJUDYL.
22 //
23 // TBD: Should some of the assertions here be converted to product code that
24 // returns JU_ERRNO_CORRUPT?
25
26 #if (! (defined(JUDY1) || defined(JUDYL)))
27 #error: One of -DJUDY1 or -DJUDYL must be specified.
28 #endif
29
30 #ifdef JUDY1
31 #include "Judy1.h"
32 #else
33 #include "JudyL.h"
34 #endif
35
36 #include "JudyPrivate1L.h"
37
38 // Note: Call JudyCheckPop() even before "already inserted" returns, to catch
39 // population errors; see fix in 4.84:
40
41 DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
42 DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);)
43
44 #ifdef TRACEJP
45 #include "JudyPrintJP.c"
46 #endif
47
48
49 // These are defined to generic values in JudyCommon/JudyPrivateTypes.h:
50 //
51 // TBD: These should be exported from a header file, but perhaps not, as they
52 // are only used here, and exported from Judy*Decascade, which is a separate
53 // file for profiling reasons (to prevent inlining), but which potentially
54 // could be merged with this file, either in SoftCM or at compile-time.
55
56 #ifdef JUDY1
57 extern int j__udy1CreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
58 extern int j__udy1CreateBranchU(Pjp_t, Pvoid_t);
59
60 #ifndef JU_64BIT
61 extern int j__udy1Cascade1(Pjp_t, Pvoid_t);
62 #endif
63 extern int j__udy1Cascade2(Pjp_t, Pvoid_t);
64 extern int j__udy1Cascade3(Pjp_t, Pvoid_t);
65 #ifdef JU_64BIT
66 extern int j__udy1Cascade4(Pjp_t, Pvoid_t);
67 extern int j__udy1Cascade5(Pjp_t, Pvoid_t);
68 extern int j__udy1Cascade6(Pjp_t, Pvoid_t);
69 extern int j__udy1Cascade7(Pjp_t, Pvoid_t);
70 #endif
71 extern int j__udy1CascadeL(Pjp_t, Pvoid_t);
72
73 extern int j__udy1InsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
74
75 #else // JUDYL
76
77 extern int j__udyLCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
78 extern int j__udyLCreateBranchU(Pjp_t, Pvoid_t);
79
80 extern int j__udyLCascade1(Pjp_t, Pvoid_t);
81 extern int j__udyLCascade2(Pjp_t, Pvoid_t);
82 extern int j__udyLCascade3(Pjp_t, Pvoid_t);
83 #ifdef JU_64BIT
84 extern int j__udyLCascade4(Pjp_t, Pvoid_t);
85 extern int j__udyLCascade5(Pjp_t, Pvoid_t);
86 extern int j__udyLCascade6(Pjp_t, Pvoid_t);
87 extern int j__udyLCascade7(Pjp_t, Pvoid_t);
88 #endif
89 extern int j__udyLCascadeL(Pjp_t, Pvoid_t);
90
91 extern int j__udyLInsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
92 #endif
93
94
95 // ****************************************************************************
96 // MACROS FOR COMMON CODE:
97 //
98 // Check if Index is an outlier to (that is, not a member of) this expanse:
99 //
100 // An outlier is an Index in-the-expanse of the slot containing the pointer,
101 // but not-in-the-expanse of the "narrow" pointer in that slot. (This means
102 // the Dcd part of the Index differs from the equivalent part of jp_DcdPopO.)
103 // Therefore, the remedy is to put a cJU_JPBRANCH_L* between the narrow pointer
104 // and the object to which it points, and add the outlier Index as an Immediate
105 // in the cJU_JPBRANCH_L*. The "trick" is placing the cJU_JPBRANCH_L* at a
106 // Level that is as low as possible. This is determined by counting the digits
107 // in the existing narrow pointer that are the same as the digits in the new
108 // Index (see j__udyInsertBranch()).
109 //
110 // Note: At some high Levels, cJU_DCDMASK() is all zeros => dead code; assume
111 // the compiler optimizes this out.
112
113 #define JU_CHECK_IF_OUTLIER(Pjp, Index, cLevel, Pjpm) \
114 if (JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)) \
115 return(j__udyInsertBranch(Pjp, Index, cLevel, Pjpm))
116
117 // Check if an Index is already in a leaf or immediate, after calling
118 // j__udySearchLeaf*() to set Offset:
119 //
120 // A non-negative Offset means the Index already exists, so return 0; otherwise
121 // complement Offset to proceed.
122
123 #ifdef JUDY1
124 #define Pjv ignore // placeholder.
125 #define JU_CHECK_IF_EXISTS(Offset,ignore,Pjpm) \
126 { \
127 if ((Offset) >= 0) return(0); \
128 (Offset) = ~(Offset); \
129 }
130 #else
131 // For JudyL, also set the value area pointer in the Pjpm:
132
133 #define JU_CHECK_IF_EXISTS(Offset,Pjv,Pjpm) \
134 { \
135 if ((Offset) >= 0) \
136 { \
137 (Pjpm)->jpm_PValue = (Pjv) + (Offset); \
138 return(0); \
139 } \
140 (Offset) = ~(Offset); \
141 }
142 #endif
143
144
145 // ****************************************************************************
146 // __ J U D Y I N S W A L K
147 //
148 // Walk the Judy tree to do a set/insert. This is only called internally, and
149 // recursively. Unlike Judy1Test() and JudyLGet(), the extra time required for
150 // recursion should be negligible compared with the total.
151 //
152 // Return -1 for error (details in JPM), 0 for Index already inserted, 1 for
153 // new Index inserted.
154
155 FUNCTION static int j__udyInsWalk(
156 Pjp_t Pjp, // current JP to descend.
157 Word_t Index, // to insert.
158 Pjpm_t Pjpm) // for returning info to top Level.
159 {
160 uint8_t digit; // from Index, current offset into a branch.
161 jp_t newJP; // for creating a new Immed JP.
162 Word_t exppop1; // expanse (leaf) population.
163 int retcode; // return codes: -1, 0, 1.
164
165 #ifdef SUBEXPCOUNTS
166 // Pointer to BranchB/U subexpanse counter:
167 //
168 // Note: Very important for performance reasons (avoids cache fills).
169
170 PWord_t PSubExp = (PWord_t) NULL;
171 #endif
172
173 ContinueInsWalk: // for modifying state without recursing.
174
175 #ifdef TRACEJP
176 JudyPrintJP(Pjp, "i", __LINE__);
177 #endif
178
179 switch (JU_JPTYPE(Pjp)) // entry: Pjp, Index.
180 {
181
182
183 // ****************************************************************************
184 // JPNULL*:
185 //
186 // Convert JP in place from current null type to cJU_JPIMMED_*_01 by
187 // calculating new JP type.
188
189 case cJU_JPNULL1:
190 case cJU_JPNULL2:
191 case cJU_JPNULL3:
192 #ifdef JU_64BIT
193 case cJU_JPNULL4:
194 case cJU_JPNULL5:
195 case cJU_JPNULL6:
196 case cJU_JPNULL7:
197 #endif
198 assert((Pjp->jp_Addr) == 0);
199 JU_JPSETADT(Pjp, 0, Index, JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01 - cJU_JPNULL1);
200 #ifdef JUDYL
201 // value area is first word of new Immed_01 JP:
202 Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
203 #endif
204 return(1);
205
206
207 // ****************************************************************************
208 // JPBRANCH_L*:
209 //
210 // If the new Index is not an outlier to the branchs expanse, and the branch
211 // should not be converted to uncompressed, extract the digit and record the
212 // Immediate type to create for a new Immed JP, before going to common code.
213 //
214 // Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit.
215
216 #define JU_BRANCH_OUTLIER(DIGIT,POP1,cLEVEL,PJP,INDEX,PJPM) \
217 JU_CHECK_IF_OUTLIER(PJP, INDEX, cLEVEL, PJPM); \
218 (DIGIT) = JU_DIGITATSTATE(INDEX, cLEVEL); \
219 (POP1) = JU_JPBRANCH_POP0(PJP, cLEVEL)
220
221 case cJU_JPBRANCH_L2:
222 JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
223 goto JudyBranchL;
224
225 case cJU_JPBRANCH_L3:
226 JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
227 goto JudyBranchL;
228
229 #ifdef JU_64BIT
230 case cJU_JPBRANCH_L4:
231 JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
232 goto JudyBranchL;
233
234 case cJU_JPBRANCH_L5:
235 JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
236 goto JudyBranchL;
237
238 case cJU_JPBRANCH_L6:
239 JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
240 goto JudyBranchL;
241
242 case cJU_JPBRANCH_L7:
243 JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
244 goto JudyBranchL;
245 #endif
246
247 // Similar to common code above, but no outlier check is needed, and the Immed
248 // type depends on the word size:
249
250 case cJU_JPBRANCH_L:
251 {
252 Pjbl_t PjblRaw; // pointer to old linear branch.
253 Pjbl_t Pjbl;
254 Pjbu_t PjbuRaw; // pointer to new uncompressed branch.
255 Pjbu_t Pjbu;
256 Word_t numJPs; // number of JPs = populated expanses.
257 int offset; // in branch.
258
259 digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
260 exppop1 = Pjpm->jpm_Pop0;
261
262 // fall through:
263
264 // COMMON CODE FOR LINEAR BRANCHES:
265 //
266 // Come here with digit and exppop1 already set.
267
268 JudyBranchL:
269 PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
270 Pjbl = P_JBL(PjblRaw);
271
272 // If population under this branch greater than:
273
274 if (exppop1 > JU_BRANCHL_MAX_POP)
275 goto ConvertBranchLtoU;
276
277 numJPs = Pjbl->jbl_NumJPs;
278
279 if ((numJPs == 0) || (numJPs > cJU_BRANCHLMAXJPS))
280 {
281 JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
282 return(-1);
283 }
284
285 // Search for a match to the digit:
286
287 offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse), numJPs,
288 digit);
289
290 // If Index is found, offset is into an array of 1..cJU_BRANCHLMAXJPS JPs:
291
292 if (offset >= 0)
293 {
294 Pjp = (Pjbl->jbl_jp) + offset; // address of next JP.
295 break; // continue walk.
296 }
297
298 // Expanse is missing (not populated) for the passed Index, so insert an Immed
299 // -- if theres room:
300
301 if (numJPs < cJU_BRANCHLMAXJPS)
302 {
303 offset = ~offset; // insertion offset.
304
305 JU_JPSETADT(&newJP, 0, Index,
306 JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_L2);
307
308 JU_INSERTINPLACE(Pjbl->jbl_Expanse, numJPs, offset, digit);
309 JU_INSERTINPLACE(Pjbl->jbl_jp, numJPs, offset, newJP);
310
311 DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse),
312 numJPs + 1, /* IndexSize = */ 1);)
313 ++(Pjbl->jbl_NumJPs);
314 #ifdef JUDYL
315 // value area is first word of new Immed 01 JP:
316 Pjpm->jpm_PValue = (Pjv_t) ((Pjbl->jbl_jp) + offset);
317 #endif
318 return(1);
319 }
320
321
322 // MAXED OUT LINEAR BRANCH, CONVERT TO A BITMAP BRANCH, THEN INSERT:
323 //
324 // Copy the linear branch to a bitmap branch.
325 //
326 // TBD: Consider renaming j__udyCreateBranchB() to j__udyConvertBranchLtoB().
327
328 assert((numJPs) <= cJU_BRANCHLMAXJPS);
329
330 if (j__udyCreateBranchB(Pjp, Pjbl->jbl_jp, Pjbl->jbl_Expanse,
331 numJPs, Pjpm) == -1)
332 {
333 return(-1);
334 }
335
336 // Convert jp_Type from linear branch to equivalent bitmap branch:
337
338 Pjp->jp_Type += cJU_JPBRANCH_B - cJU_JPBRANCH_L;
339
340 j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
341
342 // Having changed branch types, now do the insert in the new branch type:
343
344 goto ContinueInsWalk;
345
346
347 // OPPORTUNISTICALLY CONVERT FROM BRANCHL TO BRANCHU:
348 //
349 // Memory efficiency is no object because the branchs pop1 is large enough, so
350 // speed up array access. Come here with PjblRaw set. Note: This is goto
351 // code because the previous block used to fall through into it as well, but no
352 // longer.
353
354 ConvertBranchLtoU:
355
356 // Allocate memory for an uncompressed branch:
357
358 if ((PjbuRaw = j__udyAllocJBU(Pjpm)) == (Pjbu_t) NULL)
359 return(-1);
360 Pjbu = P_JBU(PjbuRaw);
361
362 // Set the proper NULL type for most of the uncompressed branchs JPs:
363
364 JU_JPSETADT(&newJP, 0, 0,
365 JU_JPTYPE(Pjp) - cJU_JPBRANCH_L2 + cJU_JPNULL1);
366
367 // Initialize: Pre-set uncompressed branch to mostly JPNULL*s:
368
369 for (numJPs = 0; numJPs < cJU_BRANCHUNUMJPS; ++numJPs)
370 Pjbu->jbu_jp[numJPs] = newJP;
371
372 // Copy JPs from linear branch to uncompressed branch:
373
374 {
375 #ifdef SUBEXPCOUNTS
376 Word_t popmask = cJU_POP0MASK(JU_JPTYPE(Pjp))
377 - cJU_JPBRANCH_L2 - 2;
378
379 for (numJPs = 0; numJPs < cJU_NUMSUBEXPU; ++numJPs)
380 Pjbu->jbu_subPop1[numJPs] = 0;
381 #endif
382 for (numJPs = 0; numJPs < Pjbl->jbl_NumJPs; ++numJPs)
383 {
384 Pjp_t Pjp1 = &(Pjbl->jbl_jp[numJPs]);
385 offset = Pjbl->jbl_Expanse[numJPs];
386 Pjbu->jbu_jp[offset] = *Pjp1;
387 #ifdef SUBEXPCOUNTS
388 Pjbu->jbu_subPop1[offset/cJU_NUMSUBEXPU] +=
389 JU_JPDCDPOP0(Pjp1) & popmask + 1;
390 #endif
391 }
392 }
393 j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
394
395 // Plug new values into parent JP:
396
397 Pjp->jp_Addr = (Word_t) PjbuRaw;
398 Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_L; // to BranchU.
399
400 // Save global population of last BranchU conversion:
401
402 Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0;
403 goto ContinueInsWalk;
404
405 } // case cJU_JPBRANCH_L.
406
407
408 // ****************************************************************************
409 // JPBRANCH_B*:
410 //
411 // If the new Index is not an outlier to the branchs expanse, extract the
412 // digit and record the Immediate type to create for a new Immed JP, before
413 // going to common code.
414 //
415 // Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit.
416
417 case cJU_JPBRANCH_B2:
418 JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
419 goto JudyBranchB;
420
421 case cJU_JPBRANCH_B3:
422 JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
423 goto JudyBranchB;
424
425 #ifdef JU_64BIT
426 case cJU_JPBRANCH_B4:
427 JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
428 goto JudyBranchB;
429
430 case cJU_JPBRANCH_B5:
431 JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
432 goto JudyBranchB;
433
434 case cJU_JPBRANCH_B6:
435 JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
436 goto JudyBranchB;
437
438 case cJU_JPBRANCH_B7:
439 JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
440 goto JudyBranchB;
441 #endif
442
443 case cJU_JPBRANCH_B:
444 {
445 Pjbb_t Pjbb; // pointer to bitmap branch.
446 Pjbb_t PjbbRaw; // pointer to bitmap branch.
447 Pjp_t Pjp2Raw; // 1 of N arrays of JPs.
448 Pjp_t Pjp2; // 1 of N arrays of JPs.
449 Word_t subexp; // 1 of N subexpanses in bitmap.
450 BITMAPB_t bitmap; // for one subexpanse.
451 BITMAPB_t bitmask; // bit set for Indexs digit.
452 Word_t numJPs; // number of JPs = populated expanses.
453 int offset; // in bitmap branch.
454
455 // Similar to common code above, but no outlier check is needed, and the Immed
456 // type depends on the word size:
457
458 digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
459 exppop1 = Pjpm->jpm_Pop0;
460
461 // fall through:
462
463
464 // COMMON CODE FOR BITMAP BRANCHES:
465 //
466 // Come here with digit and exppop1 already set.
467
468 JudyBranchB:
469
470 // If population increment is greater than.. (300):
471
472 if ((Pjpm->jpm_Pop0 - Pjpm->jpm_LastUPop0) > JU_BTOU_POP_INCREMENT)
473 {
474
475 // If total population of array is greater than.. (750):
476
477 if (Pjpm->jpm_Pop0 > JU_BRANCHB_MAX_POP)
478 {
479
480 // If population under the branch is greater than.. (135):
481
482 if (exppop1 > JU_BRANCHB_MIN_POP)
483 {
484 if (j__udyCreateBranchU(Pjp, Pjpm) == -1) return(-1);
485
486 // Save global population of last BranchU conversion:
487
488 Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0;
489
490 goto ContinueInsWalk;
491 }
492 }
493 }
494
495 // CONTINUE TO USE BRANCHB:
496 //
497 // Get pointer to bitmap branch (JBB):
498
499 PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
500 Pjbb = P_JBB(PjbbRaw);
501
502 // Form the Int32 offset, and Bit offset values:
503 //
504 // 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
505 // |SubExpanse | Bit offset |
506 //
507 // Get the 1 of 8 expanses from digit, Bits 5..7 = 1 of 8, and get the 32-bit
508 // word that may have a bit set:
509
510 subexp = digit / cJU_BITSPERSUBEXPB;
511 bitmap = JU_JBB_BITMAP(Pjbb, subexp);
512
513 Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
514 Pjp2 = P_JP(Pjp2Raw);
515
516 // Get the bit position that represents the desired expanse, and get the offset
517 // into the array of JPs for the JP that matches the bit.
518
519 bitmask = JU_BITPOSMASKB(digit);
520 offset = j__udyCountBitsB(bitmap & (bitmask - 1));
521
522 // If JP is already in this expanse, get Pjp and continue the walk:
523
524 if (bitmap & bitmask)
525 {
526 #ifdef SUBEXPCOUNTS
527 PSubExp = &(Pjbb->jbb_Counts[subexp]); // ptr to subexp counts.
528 #endif
529 Pjp = Pjp2 + offset;
530 break; // continue walk.
531 }
532
533
534 // ADD NEW EXPANSE FOR NEW INDEX:
535 //
536 // The new expanse always an cJU_JPIMMED_*_01 containing just the new Index, so
537 // finish setting up an Immed JP.
538
539 JU_JPSETADT(&newJP, 0, Index,
540 JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_B2);
541
542 // Get 1 of the 8 JP arrays and calculate number of JPs in subexpanse array:
543
544 Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
545 Pjp2 = P_JP(Pjp2Raw);
546 numJPs = j__udyCountBitsB(bitmap);
547
548 // Expand branch JP subarray in-place:
549
550 if (JU_BRANCHBJPGROWINPLACE(numJPs))
551 {
552 assert(numJPs > 0);
553 JU_INSERTINPLACE(Pjp2, numJPs, offset, newJP);
554 #ifdef JUDYL
555 // value area is first word of new Immed 01 JP:
556 Pjpm->jpm_PValue = (Pjv_t) (Pjp2 + offset);
557 #endif
558 }
559
560 // No room, allocate a bigger bitmap branch JP subarray:
561
562 else
563 {
564 Pjp_t PjpnewRaw;
565 Pjp_t Pjpnew;
566
567 if ((PjpnewRaw = j__udyAllocJBBJP(numJPs + 1, Pjpm)) == 0)
568 return(-1);
569 Pjpnew = P_JP(PjpnewRaw);
570
571 // If there was an old JP array, then copy it, insert the new Immed JP, and
572 // free the old array:
573
574 if (numJPs)
575 {
576 JU_INSERTCOPY(Pjpnew, Pjp2, numJPs, offset, newJP);
577 j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm);
578 #ifdef JUDYL
579 // value area is first word of new Immed 01 JP:
580 Pjpm->jpm_PValue = (Pjv_t) (Pjpnew + offset);
581 #endif
582 }
583
584 // New JP subarray; point to cJU_JPIMMED_*_01 and place it:
585
586 else
587 {
588 assert(JU_JBB_PJP(Pjbb, subexp) == (Pjp_t) NULL);
589 Pjp = Pjpnew;
590 *Pjp = newJP; // copy to new memory.
591 #ifdef JUDYL
592 // value area is first word of new Immed 01 JP:
593 Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
594 #endif
595 }
596
597 // Place new JP subarray in BranchB:
598
599 JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
600
601 } // else
602
603 // Set the new Indexs bit:
604
605 JU_JBB_BITMAP(Pjbb, subexp) |= bitmask;
606
607 return(1);
608
609 } // case
610
611
612 // ****************************************************************************
613 // JPBRANCH_U*:
614 //
615 // Just drop through the JP for the correct digit. If the JP turns out to be a
616 // JPNULL*, thats OK, the memory is already allocated, and the next walk
617 // simply places an Immed in it.
618 //
619 #ifdef SUBEXPCOUNTS
620 #define JU_GETSUBEXP(PSubExp,Pjbu,Digit) \
621 (PSubExp) = &((Pjbu)->jbu_subPop1[(Digit) / cJU_NUMSUBEXPU])
622 #else
623 #define JU_GETSUBEXP(PSubExp,Pjbu,Digit) // null.
624 #endif
625
626 #define JU_JBU_PJP_SUBEXP(Pjp,PSubExp,Index,Level) \
627 { \
628 uint8_t digit = JU_DIGITATSTATE(Index, Level); \
629 Pjbu_t P_jbu = P_JBU((Pjp)->jp_Addr); \
630 (Pjp) = &(P_jbu->jbu_jp[digit]); \
631 JU_GETSUBEXP(PSubExp, P_jbu, digit); \
632 }
633
634 case cJU_JPBRANCH_U2:
635 JU_CHECK_IF_OUTLIER(Pjp, Index, 2, Pjpm);
636 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 2);
637 break;
638
639 #ifdef JU_64BIT
640 case cJU_JPBRANCH_U3:
641 JU_CHECK_IF_OUTLIER(Pjp, Index, 3, Pjpm);
642 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
643 break;
644
645 case cJU_JPBRANCH_U4:
646 JU_CHECK_IF_OUTLIER(Pjp, Index, 4, Pjpm);
647 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 4);
648 break;
649
650 case cJU_JPBRANCH_U5:
651 JU_CHECK_IF_OUTLIER(Pjp, Index, 5, Pjpm);
652 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 5);
653 break;
654
655 case cJU_JPBRANCH_U6:
656 JU_CHECK_IF_OUTLIER(Pjp, Index, 6, Pjpm);
657 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 6);
658 break;
659
660 case cJU_JPBRANCH_U7:
661 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 7);
662 #else
663 case cJU_JPBRANCH_U3:
664 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
665 #endif
666 break;
667
668 case cJU_JPBRANCH_U:
669 JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, cJU_ROOTSTATE);
670 break;
671
672
673 // ****************************************************************************
674 // JPLEAF*:
675 //
676 // COMMON CODE FRAGMENTS TO MINIMIZE REDUNDANCY BELOW:
677 //
678 // These are necessary to support performance by function and loop unrolling
679 // while avoiding huge amounts of nearly identical code.
680 //
681 // Prepare to handle a linear leaf: Check for an outlier; set pop1 and pointer
682 // to leaf:
683
684 #ifdef JUDY1
685 #define JU_LEAFVALUE(Pjv) // null.
686 #define JU_LEAFPREPVALUE(Pjv, ValueArea) // null.
687 #else
688 #define JU_LEAFVALUE(Pjv) Pjv_t Pjv
689 #define JU_LEAFPREPVALUE(Pjv, ValueArea) (Pjv) = ValueArea(Pleaf, exppop1)
690 #endif
691
692 #define JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea) \
693 Pjll_t PjllRaw; \
694 Type Pleaf; /* specific type */ \
695 int offset; \
696 JU_LEAFVALUE(Pjv); \
697 \
698 JU_CHECK_IF_OUTLIER(Pjp, Index, cIS, Pjpm); \
699 \
700 exppop1 = JU_JPLEAF_POP0(Pjp) + 1; \
701 assert(exppop1 <= (MaxPop1)); \
702 PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
703 Pleaf = (Type) P_JLL(PjllRaw); \
704 JU_LEAFPREPVALUE(Pjv, ValueArea)
705
706 // Add to, or grow, a linear leaf: Find Index position; if the Index is
707 // absent, if theres room in the leaf, insert the Index [and value of 0] in
708 // place, otherwise grow the leaf:
709 //
710 // Note: These insertions always take place with whole words, using
711 // JU_INSERTINPLACE() or JU_INSERTCOPY().
712
713 #ifdef JUDY1
714 #define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) // null.
715 #else
716 #define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) \
717 JU_INSERTINPLACE(Pjv, ExpPop1, Offset, 0); \
718 Pjpm->jpm_PValue = (Pjv) + (Offset)
719 #endif
720
721 #ifdef JUDY1
722 #define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) // null.
723 #else
724 #define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) \
725 { \
726 Pjv_t Pjvnew = ValueArea(Pleafnew, (ExpPop1) + 1); \
727 JU_INSERTCOPY(Pjvnew, Pjv, ExpPop1, Offset, 0); \
728 Pjpm->jpm_PValue = (Pjvnew) + (Offset); \
729 }
730 #endif
731
732 #define JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
733 InsertInPlace,InsertCopy,Alloc,Free) \
734 \
735 offset = Search(Pleaf, exppop1, Index); \
736 JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
737 \
738 if (GrowInPlace(exppop1)) /* add to current leaf */ \
739 { \
740 InsertInPlace(Pleaf, exppop1, offset, Index); \
741 JU_LEAFGROWVALUEADD(Pjv, exppop1, offset); \
742 DBGCODE(JudyCheckSorted((Pjll_t) Pleaf, exppop1 + 1, cIS);) \
743 return(1); \
744 } \
745 \
746 if (exppop1 < (MaxPop1)) /* grow to new leaf */ \
747 { \
748 Pjll_t PjllnewRaw; \
749 Type Pleafnew; \
750 if ((PjllnewRaw = Alloc(exppop1 + 1, Pjpm)) == 0) return(-1); \
751 Pleafnew = (Type) P_JLL(PjllnewRaw); \
752 InsertCopy(Pleafnew, Pleaf, exppop1, offset, Index); \
753 JU_LEAFGROWVALUENEW(ValueArea, Pjv, exppop1, offset); \
754 DBGCODE(JudyCheckSorted((Pjll_t) Pleafnew, exppop1 + 1, cIS);) \
755 Free(PjllRaw, exppop1, Pjpm); \
756 (Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
757 return(1); \
758 } \
759 assert(exppop1 == (MaxPop1))
760
761 // Handle linear leaf overflow (cascade): Splay or compress into smaller
762 // leaves:
763
764 #define JU_LEAFCASCADE(MaxPop1,Cascade,Free) \
765 if (Cascade(Pjp, Pjpm) == -1) return(-1); \
766 Free(PjllRaw, MaxPop1, Pjpm); \
767 goto ContinueInsWalk
768
769 // Wrapper around all of the above:
770
771 #define JU_LEAFSET(cIS,Type,MaxPop1,Search,GrowInPlace,InsertInPlace, \
772 InsertCopy,Cascade,Alloc,Free,ValueArea) \
773 { \
774 JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea); \
775 JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
776 InsertInPlace,InsertCopy,Alloc,Free); \
777 JU_LEAFCASCADE(MaxPop1,Cascade,Free); \
778 }
779
780 // END OF MACROS; LEAFL CASES START HERE:
781 //
782 // 64-bit Judy1 does not have 1-byte leaves:
783
784 #if (defined(JUDYL) || (! defined(JU_64BIT)))
785
786 case cJU_JPLEAF1:
787
788 JU_LEAFSET(1, uint8_t *, cJU_LEAF1_MAXPOP1, j__udySearchLeaf1,
789 JU_LEAF1GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
790 j__udyCascade1, j__udyAllocJLL1, j__udyFreeJLL1,
791 JL_LEAF1VALUEAREA);
792
793 #endif // (JUDYL || ! JU_64BIT)
794
795 case cJU_JPLEAF2:
796
797 JU_LEAFSET(2, uint16_t *, cJU_LEAF2_MAXPOP1, j__udySearchLeaf2,
798 JU_LEAF2GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
799 j__udyCascade2, j__udyAllocJLL2, j__udyFreeJLL2,
800 JL_LEAF2VALUEAREA);
801
802 case cJU_JPLEAF3:
803
804 JU_LEAFSET(3, uint8_t *, cJU_LEAF3_MAXPOP1, j__udySearchLeaf3,
805 JU_LEAF3GROWINPLACE, JU_INSERTINPLACE3, JU_INSERTCOPY3,
806 j__udyCascade3, j__udyAllocJLL3, j__udyFreeJLL3,
807 JL_LEAF3VALUEAREA);
808
809 #ifdef JU_64BIT
810 case cJU_JPLEAF4:
811
812 JU_LEAFSET(4, uint32_t *, cJU_LEAF4_MAXPOP1, j__udySearchLeaf4,
813 JU_LEAF4GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
814 j__udyCascade4, j__udyAllocJLL4, j__udyFreeJLL4,
815 JL_LEAF4VALUEAREA);
816
817 case cJU_JPLEAF5:
818
819 JU_LEAFSET(5, uint8_t *, cJU_LEAF5_MAXPOP1, j__udySearchLeaf5,
820 JU_LEAF5GROWINPLACE, JU_INSERTINPLACE5, JU_INSERTCOPY5,
821 j__udyCascade5, j__udyAllocJLL5, j__udyFreeJLL5,
822 JL_LEAF5VALUEAREA);
823
824 case cJU_JPLEAF6:
825
826 JU_LEAFSET(6, uint8_t *, cJU_LEAF6_MAXPOP1, j__udySearchLeaf6,
827 JU_LEAF6GROWINPLACE, JU_INSERTINPLACE6, JU_INSERTCOPY6,
828 j__udyCascade6, j__udyAllocJLL6, j__udyFreeJLL6,
829 JL_LEAF6VALUEAREA);
830
831 case cJU_JPLEAF7:
832
833 JU_LEAFSET(7, uint8_t *, cJU_LEAF7_MAXPOP1, j__udySearchLeaf7,
834 JU_LEAF7GROWINPLACE, JU_INSERTINPLACE7, JU_INSERTCOPY7,
835 j__udyCascade7, j__udyAllocJLL7, j__udyFreeJLL7,
836 JL_LEAF7VALUEAREA);
837 #endif // JU_64BIT
838
839
840 // ****************************************************************************
841 // JPLEAF_B1:
842 //
843 // 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
844 // |SubExpanse | Bit offset |
845 //
846 // Note: For JudyL, values are stored in 8 subexpanses, each a linear word
847 // array of up to 32 values each.
848
849 case cJU_JPLEAF_B1:
850 {
851 #ifdef JUDYL
852 Pjv_t PjvRaw; // pointer to value part of the leaf.
853 Pjv_t Pjv; // pointer to value part of the leaf.
854 Pjv_t PjvnewRaw; // new value area.
855 Pjv_t Pjvnew; // new value area.
856 Word_t subexp; // 1 of 8 subexpanses in bitmap.
857 Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
858 BITMAPL_t bitmap; // for one subexpanse.
859 BITMAPL_t bitmask; // bit set for Indexs digit.
860 int offset; // of index in value area.
861 #endif
862
863 JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
864
865 #ifdef JUDY1
866
867 // If Index (bit) is already set, return now:
868
869 if (JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index)) return(0);
870
871 // If bitmap is not full, set the new Indexs bit; otherwise convert to a Full:
872
873 if ((exppop1 = JU_JPLEAF_POP0(Pjp) + 1)
874 < cJU_JPFULLPOPU1_POP0)
875 {
876 JU_BITMAPSETL(P_JLB(Pjp->jp_Addr), Index);
877 }
878 else
879 {
880 j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // free LeafB1.
881 Pjp->jp_Type = cJ1_JPFULLPOPU1;
882 Pjp->jp_Addr = 0;
883 }
884
885 #else // JUDYL
886
887 // This is very different from Judy1 because of the need to return a value area
888 // even for an existing Index, or manage the value area for a new Index, and
889 // because JudyL has no Full type:
890
891 // Get last byte to decode from Index, and pointer to bitmap leaf:
892
893 digit = JU_DIGITATSTATE(Index, 1);
894 Pjlb = P_JLB(Pjp->jp_Addr);
895
896 // Prepare additional values:
897
898 subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
899 bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map.
900 PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
901 Pjv = P_JV(PjvRaw); // corresponding values.
902 bitmask = JU_BITPOSMASKL(digit); // mask for Index.
903 offset = j__udyCountBitsL(bitmap & (bitmask - 1)); // of Index.
904
905 // If Index already exists, get value pointer and exit:
906
907 if (bitmap & bitmask)
908 {
909 assert(Pjv);
910 Pjpm->jpm_PValue = Pjv + offset; // existing value.
911 return(0);
912 }
913
914 // Get the total bits set = expanse population of Value area:
915
916 exppop1 = j__udyCountBitsL(bitmap);
917
918 // If the value area can grow in place, do it:
919
920 if (JL_LEAFVGROWINPLACE(exppop1))
921 {
922 JU_INSERTINPLACE(Pjv, exppop1, offset, 0);
923 JU_JLB_BITMAP(Pjlb, subexp) |= bitmask; // set Indexs bit.
924 Pjpm->jpm_PValue = Pjv + offset; // new value area.
925 return(1);
926 }
927
928 // Increase size of value area:
929
930 if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm))
931 == (Pjv_t) NULL) return(-1);
932 Pjvnew = P_JV(PjvnewRaw);
933
934 if (exppop1) // have existing value area.
935 {
936 assert(Pjv);
937 JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0);
938 Pjpm->jpm_PValue = Pjvnew + offset;
939 j__udyLFreeJV(PjvRaw, exppop1, Pjpm); // free old values.
940 }
941 else // first index, new value area:
942 {
943 Pjpm->jpm_PValue = Pjvnew;
944 *(Pjpm->jpm_PValue) = 0;
945 }
946
947 // Set bit for new Index and place new leaf value area in bitmap:
948
949 JU_JLB_BITMAP(Pjlb, subexp) |= bitmask;
950 JL_JLB_PVALUE(Pjlb, subexp) = PjvnewRaw;
951
952 #endif // JUDYL
953
954 return(1);
955
956 } // case
957
958
959 #ifdef JUDY1
960 // ****************************************************************************
961 // JPFULLPOPU1:
962 //
963 // If Index is not an outlier, then by definition its already set.
964
965 case cJ1_JPFULLPOPU1:
966
967 JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
968 return(0);
969 #endif
970
971
972 // ****************************************************************************
973 // JPIMMED*:
974 //
975 // This is some of the most complex code in Judy considering Judy1 versus JudyL
976 // and 32-bit versus 64-bit variations. The following comments attempt to make
977 // this clearer.
978 //
979 // Of the 2 words in a JP, for immediate indexes Judy1 can use 2 words - 1 byte
980 // = 7 [15] bytes, but JudyL can only use 1 word - 1 byte = 3 [7] bytes because
981 // the other word is needed for a value area or a pointer to a value area.
982 //
983 // For both Judy1 and JudyL, cJU_JPIMMED_*_01 indexes are in word 2; otherwise
984 // for Judy1 only, a list of 2 or more indexes starts in word 1. JudyL keeps
985 // the list in word 2 because word 1 is a pointer (to a LeafV, that is, a leaf
986 // containing only values). Furthermore, cJU_JPIMMED_*_01 indexes are stored
987 // all-but-first-byte in jp_DcdPopO, not just the Index Sizes bytes.
988 //
989 // TBD: This can be confusing because Doug didnt use data structures for it.
990 // Instead he often directly accesses Pjp for the first word and jp_DcdPopO for
991 // the second word. It would be nice to use data structs, starting with
992 // jp_1Index and jp_LIndex where possible.
993 //
994 // Maximum Immed JP types for Judy1/JudyL, depending on Index Size (cIS):
995 //
996 // 32-bit 64-bit
997 //
998 // bytes: 7/ 3 15/ 7 (Judy1/JudyL)
999 //
1000 // cIS
1001 // 1_ 07/03 15/07 (as in: cJ1_JPIMMED_1_07)
1002 // 2_ 03/01 07/03
1003 // 3_ 02/01 05/02
1004 // 4_ 03/01
1005 // 5_ 03/01
1006 // 6_ 02/01
1007 // 7_ 02/01
1008 //
1009 // State transitions while inserting an Index, matching the above table:
1010 // (Yes, this is very terse... Study it and it will make sense.)
1011 // (Note, parts of this diagram are repeated below for quick reference.)
1012 //
1013 // +-- reformat JP here for Judy1 only, from word-2 to word-1
1014 // |
1015 // | JUDY1 || JU_64BIT JUDY1 && JU_64BIT
1016 // V
1017 // 1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] Leaf1 (*)
1018 // 2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] Leaf2
1019 // 3_01 => [ 3_02 => [ 3_03..05 => ]] Leaf3
1020 // JU_64BIT only:
1021 // 4_01 => [[ 4_02..03 => ]] Leaf4
1022 // 5_01 => [[ 5_02..03 => ]] Leaf5
1023 // 6_01 => [[ 6_02 => ]] Leaf6
1024 // 7_01 => [[ 7_02 => ]] Leaf7
1025 //
1026 // (*) For Judy1 & 64-bit, go directly from cJU_JPIMMED_1_15 to a LeafB1; skip
1027 // Leaf1, as described in Judy1.h regarding cJ1_JPLEAF1.
1028
1029
1030 // COMMON CODE FRAGMENTS TO MINIMIZE REDUNDANCY BELOW:
1031 //
1032 // These are necessary to support performance by function and loop unrolling
1033 // while avoiding huge amounts of nearly identical code.
1034 //
1035 // The differences between Judy1 and JudyL with respect to value area handling
1036 // are just too large for completely common code between them... Oh well, some
1037 // big ifdefs follow. However, even in the following ifdefd code, use cJU_*,
1038 // JU_*, and Judy*() instead of cJ1_* / cJL_*, J1_* / JL_*, and
1039 // Judy1*()/JudyL*(), for minimum diffs.
1040 //
1041 // Handle growth of cJU_JPIMMED_*_01 to cJU_JPIMMED_*_02, for an even or odd
1042 // Index Size (cIS), given oldIndex, Index, and Pjll in the context:
1043 //
1044 // Put oldIndex and Index in their proper order. For odd indexes, must copy
1045 // bytes.
1046
1047 #ifdef JUDY1
1048
1049 #define JU_IMMSET_01_COPY_EVEN(ignore1,ignore2) \
1050 if (oldIndex < Index) { Pjll[0] = oldIndex; Pjll[1] = Index; } \
1051 else { Pjll[0] = Index; Pjll[1] = oldIndex; }
1052
1053 #define JU_IMMSET_01_COPY_ODD(cIS,CopyWord) \
1054 if (oldIndex < Index) \
1055 { \
1056 CopyWord(Pjll + 0, oldIndex); \
1057 CopyWord(Pjll + (cIS), Index); \
1058 } \
1059 else \
1060 { \
1061 CopyWord(Pjll + 0, Index); \
1062 CopyWord(Pjll + (cIS), oldIndex); \
1063 }
1064
1065 // The "real" *_01 Copy macro:
1066 //
1067 // Trim the high byte off Index, look for a match with the old Index, and if
1068 // none, insert the new Index in the leaf in the correct place, given Pjp and
1069 // Index in the context.
1070 //
1071 // Note: A single immediate index lives in the jp_DcdPopO field, but two or
1072 // more reside starting at Pjp->jp_1Index.
1073
1074 #define JU_IMMSET_01_COPY(cIS,LeafType,NewJPType,Copy,CopyWord) \
1075 { \
1076 LeafType Pjll; \
1077 Word_t oldIndex = JU_JPDCDPOP0(Pjp); \
1078 \
1079 Index = JU_TRIMTODCDSIZE(Index); \
1080 if (oldIndex == Index) return(0); \
1081 \
1082 Pjll = (LeafType) (Pjp->jp_1Index); \
1083 Copy(cIS,CopyWord); \
1084 DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \
1085 \
1086 Pjp->jp_Type = (NewJPType); \
1087 return(1); \
1088 }
1089
1090 #else // JUDYL
1091
1092 // Variations to also handle value areas; see comments above:
1093 //
1094 // For JudyL, Pjv (start of value area) and oldValue are also in the context;
1095 // leave Pjv set to the value area for Index.
1096
1097 #define JU_IMMSET_01_COPY_EVEN(cIS,CopyWord) \
1098 if (oldIndex < Index) \
1099 { \
1100 Pjll[0] = oldIndex; \
1101 Pjv [0] = oldValue; \
1102 Pjll[1] = Index; \
1103 ++Pjv; \
1104 } \
1105 else \
1106 { \
1107 Pjll[0] = Index; \
1108 Pjll[1] = oldIndex; \
1109 Pjv [1] = oldValue; \
1110 }
1111
1112 #define JU_IMMSET_01_COPY_ODD(cIS,CopyWord) \
1113 if (oldIndex < Index) \
1114 { \
1115 CopyWord(Pjll + 0, oldIndex); \
1116 CopyWord(Pjll + (cIS), Index); \
1117 Pjv[0] = oldValue; \
1118 ++Pjv; \
1119 } \
1120 else \
1121 { \
1122 CopyWord(Pjll + 0, Index); \
1123 CopyWord(Pjll + (cIS), oldIndex); \
1124 Pjv[1] = oldValue; \
1125 }
1126
1127 // The old value area is in the first word (*Pjp), and Pjv and Pjpm are also in
1128 // the context. Also, unlike Judy1, indexes remain in word 2 (jp_LIndex),
1129 // meaning insert-in-place rather than copy.
1130 //
1131 // Return jpm_PValue pointing to Indexs value area. If Index is new, allocate
1132 // a 2-value-leaf and attach it to the JP.
1133
1134 #define JU_IMMSET_01_COPY(cIS,LeafType,NewJPType,Copy,CopyWord) \
1135 { \
1136 LeafType Pjll; \
1137 Word_t oldIndex = JU_JPDCDPOP0(Pjp); \
1138 Word_t oldValue; \
1139 Pjv_t PjvRaw; \
1140 Pjv_t Pjv; \
1141 \
1142 Index = JU_TRIMTODCDSIZE(Index); \
1143 \
1144 if (oldIndex == Index) \
1145 { \
1146 Pjpm->jpm_PValue = (Pjv_t) Pjp; \
1147 return(0); \
1148 } \
1149 \
1150 if ((PjvRaw = j__udyLAllocJV(2, Pjpm)) == (Pjv_t) NULL) \
1151 return(-1); \
1152 Pjv = P_JV(PjvRaw); \
1153 \
1154 oldValue = Pjp->jp_Addr; \
1155 (Pjp->jp_Addr) = (Word_t) PjvRaw; \
1156 Pjll = (LeafType) (Pjp->jp_LIndex); \
1157 \
1158 Copy(cIS,CopyWord); \
1159 DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \
1160 \
1161 Pjp->jp_Type = (NewJPType); \
1162 *Pjv = 0; \
1163 Pjpm->jpm_PValue = Pjv; \
1164 return(1); \
1165 }
1166
1167 // The following is a unique mix of JU_IMMSET_01() and JU_IMMSETCASCADE() for
1168 // going from cJU_JPIMMED_*_01 directly to a cJU_JPLEAF* for JudyL:
1169 //
1170 // If Index is not already set, allocate a leaf, copy the old and new indexes
1171 // into it, clear and return the new value area, and modify the current JP.
1172 // Note that jp_DcdPop is set to a pop0 of 0 for now, and incremented later.
1173
1174
1175 #define JU_IMMSET_01_CASCADE(cIS,LeafType,NewJPType,ValueArea, \
1176 Copy,CopyWord,Alloc) \
1177 { \
1178 Word_t D_P0; \
1179 LeafType PjllRaw; \
1180 LeafType Pjll; \
1181 Word_t oldIndex = JU_JPDCDPOP0(Pjp); \
1182 Word_t oldValue; \
1183 Pjv_t Pjv; \
1184 \
1185 Index = JU_TRIMTODCDSIZE(Index); \
1186 \
1187 if (oldIndex == Index) \
1188 { \
1189 Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr)); \
1190 return(0); \
1191 } \
1192 \
1193 if ((PjllRaw = (LeafType) Alloc(2, Pjpm)) == (LeafType) NULL) \
1194 return(-1); \
1195 Pjll = (LeafType) P_JLL(PjllRaw); \
1196 Pjv = ValueArea(Pjll, 2); \
1197 \
1198 oldValue = Pjp->jp_Addr; \
1199 \
1200 Copy(cIS,CopyWord); \
1201 DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \
1202 \
1203 *Pjv = 0; \
1204 Pjpm->jpm_PValue = Pjv; \
1205 D_P0 = Index & cJU_DCDMASK(cIS); /* pop0 = 0 */ \
1206 JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1207 \
1208 return(1); \
1209 }
1210
1211 #endif // JUDYL
1212
1213 // Handle growth of cJU_JPIMMED_*_[02..15]:
1214
1215 #ifdef JUDY1
1216
1217 // Insert an Index into an immediate JP that has room for more, if the Index is
1218 // not already present; given Pjp, Index, exppop1, Pjv, and Pjpm in the
1219 // context:
1220 //
1221 // Note: Use this only when the JP format doesnt change, that is, going from
1222 // cJU_JPIMMED_X_0Y to cJU_JPIMMED_X_0Z, where X >= 2 and Y+1 = Z.
1223 //
1224 // Note: Incrementing jp_Type is how to increase the Index population.
1225
1226 #define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1227 { \
1228 LeafType Pjll; \
1229 int offset; \
1230 \
1231 exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \
1232 offset = Search((Pjll_t) (Pjp->jp_1Index), exppop1, Index); \
1233 \
1234 JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1235 \
1236 Pjll = (LeafType) (Pjp->jp_1Index); \
1237 InsertInPlace(Pjll, exppop1, offset, Index); \
1238 DBGCODE(JudyCheckSorted(Pjll, exppop1 + 1, cIS);) \
1239 ++(Pjp->jp_Type); \
1240 return(1); \
1241 }
1242
1243 // Insert an Index into an immediate JP that has no room for more:
1244 //
1245 // If the Index is not already present, do a cascade (to a leaf); given Pjp,
1246 // Index, Pjv, and Pjpm in the context.
1247
1248
1249 #define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1250 ignore,Search,InsertCopy,Alloc) \
1251 { \
1252 Word_t D_P0; \
1253 Pjll_t PjllRaw; \
1254 Pjll_t Pjll; \
1255 int offset; \
1256 \
1257 offset = Search((Pjll_t) (Pjp->jp_1Index), (OldPop1), Index); \
1258 JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1259 \
1260 if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) return(-1); \
1261 Pjll = P_JLL(PjllRaw); \
1262 \
1263 InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_1Index), \
1264 OldPop1, offset, Index); \
1265 DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1266 \
1267 D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1268 JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1269 return(1); \
1270 }
1271
1272 #else // JUDYL
1273
1274 // Variations to also handle value areas; see comments above:
1275 //
1276 // For JudyL, Pjv (start of value area) is also in the context.
1277 //
1278 // TBD: This code makes a true but weak assumption that a JudyL 32-bit 2-index
1279 // value area must be copied to a new 3-index value area. AND it doesnt know
1280 // anything about JudyL 64-bit cases (cJU_JPIMMED_1_0[3-7] only) where the
1281 // value area can grow in place! However, this should not break it, just slow
1282 // it down.
1283
1284 #define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1285 { \
1286 LeafType Pleaf; \
1287 int offset; \
1288 Pjv_t PjvRaw; \
1289 Pjv_t Pjv; \
1290 Pjv_t PjvnewRaw; \
1291 Pjv_t Pjvnew; \
1292 \
1293 exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \
1294 offset = Search((Pjll_t) (Pjp->jp_LIndex), exppop1, Index); \
1295 PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1296 Pjv = P_JV(PjvRaw); \
1297 \
1298 JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1299 \
1300 if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm)) \
1301 == (Pjv_t) NULL) return(-1); \
1302 Pjvnew = P_JV(PjvnewRaw); \
1303 \
1304 Pleaf = (LeafType) (Pjp->jp_LIndex); \
1305 \
1306 InsertInPlace(Pleaf, exppop1, offset, Index); \
1307 /* see TBD above about this: */ \
1308 JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0); \
1309 DBGCODE(JudyCheckSorted(Pleaf, exppop1 + 1, cIS);) \
1310 j__udyLFreeJV(PjvRaw, exppop1, Pjpm); \
1311 Pjp->jp_Addr = (Word_t) PjvnewRaw; \
1312 Pjpm->jpm_PValue = Pjvnew + offset; \
1313 \
1314 ++(Pjp->jp_Type); \
1315 return(1); \
1316 }
1317
1318 #define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1319 ValueArea,Search,InsertCopy,Alloc) \
1320 { \
1321 Word_t D_P0; \
1322 Pjll_t PjllRaw; \
1323 Pjll_t Pjll; \
1324 int offset; \
1325 Pjv_t PjvRaw; \
1326 Pjv_t Pjv; \
1327 Pjv_t Pjvnew; \
1328 \
1329 PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1330 Pjv = P_JV(PjvRaw); \
1331 offset = Search((Pjll_t) (Pjp->jp_LIndex), (OldPop1), Index); \
1332 JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1333 \
1334 if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) \
1335 return(-1); \
1336 Pjll = P_JLL(PjllRaw); \
1337 InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_LIndex), \
1338 OldPop1, offset, Index); \
1339 DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1340 \
1341 Pjvnew = ValueArea(Pjll, (OldPop1) + 1); \
1342 JU_INSERTCOPY(Pjvnew, Pjv, OldPop1, offset, 0); \
1343 j__udyLFreeJV(PjvRaw, (OldPop1), Pjpm); \
1344 Pjpm->jpm_PValue = Pjvnew + offset; \
1345 \
1346 D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1347 JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1348 return(1); \
1349 }
1350
1351 #endif // JUDYL
1352
1353 // Common convenience/shorthand wrappers around JU_IMMSET_01_COPY() for
1354 // even/odd index sizes:
1355
1356 #define JU_IMMSET_01( cIS, LeafType, NewJPType) \
1357 JU_IMMSET_01_COPY(cIS, LeafType, NewJPType, JU_IMMSET_01_COPY_EVEN, \
1358 ignore)
1359
1360 #define JU_IMMSET_01_ODD( cIS, NewJPType, CopyWord) \
1361 JU_IMMSET_01_COPY(cIS, uint8_t *, NewJPType, JU_IMMSET_01_COPY_ODD, \
1362 CopyWord)
1363
1364
1365 // END OF MACROS; IMMED CASES START HERE:
1366
1367 // cJU_JPIMMED_*_01 cases:
1368 //
1369 // 1_01 always leads to 1_02:
1370 //
1371 // (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1372
1373 case cJU_JPIMMED_1_01: JU_IMMSET_01(1, uint8_t *, cJU_JPIMMED_1_02);
1374
1375 // 2_01 leads to 2_02, and 3_01 leads to 3_02, except for JudyL 32-bit, where
1376 // they lead to a leaf:
1377 //
1378 // (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL)
1379 // (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL)
1380
1381 #if (defined(JUDY1) || defined(JU_64BIT))
1382 case cJU_JPIMMED_2_01: JU_IMMSET_01(2, uint16_t *, cJU_JPIMMED_2_02);
1383 case cJU_JPIMMED_3_01: JU_IMMSET_01_ODD (3, cJU_JPIMMED_3_02,
1384 JU_COPY3_LONG_TO_PINDEX);
1385 #else
1386 case cJU_JPIMMED_2_01:
1387 JU_IMMSET_01_CASCADE(2, uint16_t *, cJU_JPLEAF2, JL_LEAF2VALUEAREA,
1388 JU_IMMSET_01_COPY_EVEN, ignore,
1389 j__udyAllocJLL2);
1390 case cJU_JPIMMED_3_01:
1391 JU_IMMSET_01_CASCADE(3, uint8_t *, cJU_JPLEAF3, JL_LEAF3VALUEAREA,
1392 JU_IMMSET_01_COPY_ODD,
1393 JU_COPY3_LONG_TO_PINDEX, j__udyAllocJLL3);
1394 #endif
1395
1396 #ifdef JU_64BIT
1397
1398 // [4-7]_01 lead to [4-7]_02 for Judy1, and to leaves for JudyL:
1399 //
1400 // (4_01 => [[ 4_02..03 => ]] LeafL)
1401 // (5_01 => [[ 5_02..03 => ]] LeafL)
1402 // (6_01 => [[ 6_02 => ]] LeafL)
1403 // (7_01 => [[ 7_02 => ]] LeafL)
1404
1405 #ifdef JUDY1
1406 case cJU_JPIMMED_4_01: JU_IMMSET_01(4, uint32_t *, cJ1_JPIMMED_4_02);
1407 case cJU_JPIMMED_5_01: JU_IMMSET_01_ODD(5, cJ1_JPIMMED_5_02,
1408 JU_COPY5_LONG_TO_PINDEX);
1409 case cJU_JPIMMED_6_01: JU_IMMSET_01_ODD(6, cJ1_JPIMMED_6_02,
1410 JU_COPY6_LONG_TO_PINDEX);
1411 case cJU_JPIMMED_7_01: JU_IMMSET_01_ODD(7, cJ1_JPIMMED_7_02,
1412 JU_COPY7_LONG_TO_PINDEX);
1413 #else // JUDYL
1414 case cJU_JPIMMED_4_01:
1415 JU_IMMSET_01_CASCADE(4, uint32_t *, cJU_JPLEAF4, JL_LEAF4VALUEAREA,
1416 JU_IMMSET_01_COPY_EVEN, ignore,
1417 j__udyAllocJLL4);
1418 case cJU_JPIMMED_5_01:
1419 JU_IMMSET_01_CASCADE(5, uint8_t *, cJU_JPLEAF5, JL_LEAF5VALUEAREA,
1420 JU_IMMSET_01_COPY_ODD,
1421 JU_COPY5_LONG_TO_PINDEX, j__udyAllocJLL5);
1422 case cJU_JPIMMED_6_01:
1423 JU_IMMSET_01_CASCADE(6, uint8_t *, cJU_JPLEAF6, JL_LEAF6VALUEAREA,
1424 JU_IMMSET_01_COPY_ODD,
1425 JU_COPY6_LONG_TO_PINDEX, j__udyAllocJLL6);
1426 case cJU_JPIMMED_7_01:
1427 JU_IMMSET_01_CASCADE(7, uint8_t *, cJU_JPLEAF7, JL_LEAF7VALUEAREA,
1428 JU_IMMSET_01_COPY_ODD,
1429 JU_COPY7_LONG_TO_PINDEX, j__udyAllocJLL7);
1430 #endif // JUDYL
1431 #endif // JU_64BIT
1432
1433 // cJU_JPIMMED_1_* cases that can grow in place:
1434 //
1435 // (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1436
1437 case cJU_JPIMMED_1_02:
1438 #if (defined(JUDY1) || defined(JU_64BIT))
1439 case cJU_JPIMMED_1_03:
1440 case cJU_JPIMMED_1_04:
1441 case cJU_JPIMMED_1_05:
1442 case cJU_JPIMMED_1_06:
1443 #endif
1444 #if (defined(JUDY1) && defined(JU_64BIT))
1445 case cJU_JPIMMED_1_07:
1446 case cJ1_JPIMMED_1_08:
1447 case cJ1_JPIMMED_1_09:
1448 case cJ1_JPIMMED_1_10:
1449 case cJ1_JPIMMED_1_11:
1450 case cJ1_JPIMMED_1_12:
1451 case cJ1_JPIMMED_1_13:
1452 case cJ1_JPIMMED_1_14:
1453 #endif
1454 JU_IMMSETINPLACE(1, uint8_t *, cJU_JPIMMED_1_02, j__udySearchLeaf1,
1455 JU_INSERTINPLACE);
1456
1457 // cJU_JPIMMED_1_* cases that must cascade:
1458 //
1459 // (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1460
1461 #if (defined(JUDYL) && (! defined(JU_64BIT)))
1462 case cJU_JPIMMED_1_03:
1463 JU_IMMSETCASCADE(1, 3, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1464 j__udySearchLeaf1, JU_INSERTCOPY,
1465 j__udyAllocJLL1);
1466 #endif
1467 #if (defined(JUDY1) && (! defined(JU_64BIT)))
1468 case cJU_JPIMMED_1_07:
1469 JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, ignore,
1470 j__udySearchLeaf1, JU_INSERTCOPY,
1471 j__udyAllocJLL1);
1472
1473 #endif
1474 #if (defined(JUDYL) && defined(JU_64BIT))
1475 case cJU_JPIMMED_1_07:
1476 JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1477 j__udySearchLeaf1, JU_INSERTCOPY,
1478 j__udyAllocJLL1);
1479
1480 #endif
1481 #if (defined(JUDY1) && defined(JU_64BIT))
1482 // Special case, as described above, go directly from Immed to LeafB1:
1483
1484 case cJ1_JPIMMED_1_15:
1485 {
1486 Word_t DcdP0;
1487 int offset;
1488 Pjlb_t PjlbRaw;
1489 Pjlb_t Pjlb;
1490
1491 offset = j__udySearchLeaf1((Pjll_t) Pjp->jp_1Index, 15, Index);
1492
1493 JU_CHECK_IF_EXISTS(offset, ignore, Pjpm);
1494
1495 // Create a bitmap leaf (special case for Judy1 64-bit only, see usage): Set
1496 // new Index in bitmap, copy an Immed1_15 to the bitmap, and set the parent JP
1497 // EXCEPT jp_DcdPopO, leaving any followup to the caller:
1498
1499 if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
1500 return(-1);
1501 Pjlb = P_JLB(PjlbRaw);
1502
1503 JU_BITMAPSETL(Pjlb, Index);
1504
1505 for (offset = 0; offset < 15; ++offset)
1506 JU_BITMAPSETL(Pjlb, Pjp->jp_1Index[offset]);
1507
1508 // Set jp_DcdPopO including the current pop0; incremented later:
1509 DcdP0 = (Index & cJU_DCDMASK(1)) + 15 - 1;
1510 JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1);
1511
1512 return(1);
1513 }
1514 #endif
1515
1516 // cJU_JPIMMED_[2..7]_[02..15] cases that grow in place or cascade:
1517 //
1518 // (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL)
1519
1520 #if (defined(JUDY1) || defined(JU_64BIT))
1521 case cJU_JPIMMED_2_02:
1522 #endif
1523 #if (defined(JUDY1) && defined(JU_64BIT))
1524 case cJU_JPIMMED_2_03:
1525 case cJ1_JPIMMED_2_04:
1526 case cJ1_JPIMMED_2_05:
1527 case cJ1_JPIMMED_2_06:
1528 #endif
1529 #if (defined(JUDY1) || defined(JU_64BIT))
1530 JU_IMMSETINPLACE(2, uint16_t *, cJU_JPIMMED_2_02, j__udySearchLeaf2,
1531 JU_INSERTINPLACE);
1532 #endif
1533
1534 #undef OLDPOP1
1535 #if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT)))
1536 case cJU_JPIMMED_2_03:
1537 #define OLDPOP1 3
1538 #endif
1539 #if (defined(JUDY1) && defined(JU_64BIT))
1540 case cJ1_JPIMMED_2_07:
1541 #define OLDPOP1 7
1542 #endif
1543 #if (defined(JUDY1) || defined(JU_64BIT))
1544 JU_IMMSETCASCADE(2, OLDPOP1, uint16_t *, cJU_JPLEAF2,
1545 JL_LEAF2VALUEAREA, j__udySearchLeaf2,
1546 JU_INSERTCOPY, j__udyAllocJLL2);
1547 #endif
1548
1549 // (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL)
1550
1551 #if (defined(JUDY1) && defined(JU_64BIT))
1552 case cJU_JPIMMED_3_02:
1553 case cJ1_JPIMMED_3_03:
1554 case cJ1_JPIMMED_3_04:
1555
1556 JU_IMMSETINPLACE(3, uint8_t *, cJU_JPIMMED_3_02, j__udySearchLeaf3,
1557 JU_INSERTINPLACE3);
1558 #endif
1559
1560 #undef OLDPOP1
1561 #if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT)))
1562 case cJU_JPIMMED_3_02:
1563 #define OLDPOP1 2
1564 #endif
1565 #if (defined(JUDY1) && defined(JU_64BIT))
1566 case cJ1_JPIMMED_3_05:
1567 #define OLDPOP1 5
1568 #endif
1569 #if (defined(JUDY1) || defined(JU_64BIT))
1570 JU_IMMSETCASCADE(3, OLDPOP1, uint8_t *, cJU_JPLEAF3,
1571 JL_LEAF3VALUEAREA, j__udySearchLeaf3,
1572 JU_INSERTCOPY3, j__udyAllocJLL3);
1573 #endif
1574
1575 #if (defined(JUDY1) && defined(JU_64BIT))
1576
1577 // (4_01 => [[ 4_02..03 => ]] LeafL)
1578
1579 case cJ1_JPIMMED_4_02:
1580
1581 JU_IMMSETINPLACE(4, uint32_t *, cJ1_JPIMMED_4_02, j__udySearchLeaf4,
1582 JU_INSERTINPLACE);
1583
1584 case cJ1_JPIMMED_4_03:
1585
1586 JU_IMMSETCASCADE(4, 3, uint32_t *, cJU_JPLEAF4, ignore,
1587 j__udySearchLeaf4, JU_INSERTCOPY,
1588 j__udyAllocJLL4);
1589
1590 // (5_01 => [[ 5_02..03 => ]] LeafL)
1591
1592 case cJ1_JPIMMED_5_02:
1593
1594 JU_IMMSETINPLACE(5, uint8_t *, cJ1_JPIMMED_5_02, j__udySearchLeaf5,
1595 JU_INSERTINPLACE5);
1596
1597 case cJ1_JPIMMED_5_03:
1598
1599 JU_IMMSETCASCADE(5, 3, uint8_t *, cJU_JPLEAF5, ignore,
1600 j__udySearchLeaf5, JU_INSERTCOPY5,
1601 j__udyAllocJLL5);
1602
1603 // (6_01 => [[ 6_02 => ]] LeafL)
1604
1605 case cJ1_JPIMMED_6_02:
1606
1607 JU_IMMSETCASCADE(6, 2, uint8_t *, cJU_JPLEAF6, ignore,
1608 j__udySearchLeaf6, JU_INSERTCOPY6,
1609 j__udyAllocJLL6);
1610
1611 // (7_01 => [[ 7_02 => ]] LeafL)
1612
1613 case cJ1_JPIMMED_7_02:
1614
1615 JU_IMMSETCASCADE(7, 2, uint8_t *, cJU_JPLEAF7, ignore,
1616 j__udySearchLeaf7, JU_INSERTCOPY7,
1617 j__udyAllocJLL7);
1618
1619 #endif // (JUDY1 && JU_64BIT)
1620
1621
1622 // ****************************************************************************
1623 // INVALID JP TYPE:
1624
1625 default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(-1);
1626
1627 } // switch on JP type
1628
1629 {
1630
1631 #ifdef SUBEXPCOUNTS
1632
1633 // This code might seem strange here. However it saves some memory read time
1634 // during insert (~70nS) because a pipelined processor does not need to "stall"
1635 // waiting for the memory read to complete. Hope the compiler is not too smart
1636 // or dumb and moves the code down to where it looks like it belongs (below a
1637 // few lines).
1638
1639 Word_t SubExpCount = 0; // current subexpanse counter.
1640
1641 if (PSubExp != (PWord_t) NULL) // only if BranchB/U.
1642 SubExpCount = PSubExp[0];
1643 #endif
1644
1645 // PROCESS JP -- RECURSIVELY:
1646 //
1647 // For non-Immed JP types, if successful, post-increment the population count
1648 // at this Level.
1649
1650 retcode = j__udyInsWalk(Pjp, Index, Pjpm);
1651
1652 // Successful insert, increment JP and subexpanse count:
1653
1654 if ((JU_JPTYPE(Pjp) < cJU_JPIMMED_1_01) && (retcode == 1))
1655 {
1656 jp_t JP;
1657 Word_t DcdP0;
1658 #ifdef SUBEXPCOUNTS
1659
1660 // Note: Pjp must be a pointer to a BranchB/U:
1661
1662 if (PSubExp != (PWord_t) NULL) PSubExp[0] = SubExpCount + 1;
1663 #endif
1664
1665 JP = *Pjp;
1666 DcdP0 = JU_JPDCDPOP0(Pjp) + 1;
1667 JU_JPSETADT(Pjp, JP.jp_Addr, DcdP0, JU_JPTYPE(&JP));
1668 }
1669 }
1670 return(retcode);
1671
1672 } // j__udyInsWalk()
1673
1674
1675 // ****************************************************************************
1676 // J U D Y 1 S E T
1677 // J U D Y L I N S
1678 //
1679 // Main entry point. See the manual entry for details.
1680
1681 #ifdef JUDY1
1682 FUNCTION int Judy1Set
1683 #else
1684 FUNCTION PPvoid_t JudyLIns
1685 #endif
1686 (
1687 PPvoid_t PPArray, // in which to insert.
1688 Word_t Index, // to insert.
1689 PJError_t PJError // optional, for returning error info.
1690 )
1691 {
1692 #ifdef JUDY1
1693 #define Pjv ignore // placeholders for macros.
1694 #define Pjvnew ignore
1695 #else
1696 Pjv_t Pjv; // value area in old leaf.
1697 Pjv_t Pjvnew; // value area in new leaf.
1698 #endif
1699 Pjpm_t Pjpm; // array-global info.
1700 int offset; // position in which to store new Index.
1701 Pjlw_t Pjlw;
1702
1703
1704 // CHECK FOR NULL POINTER (error by caller):
1705
1706 if (PPArray == (PPvoid_t) NULL)
1707 {
1708 JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1709 JUDY1CODE(return(JERRI );)
1710 JUDYLCODE(return(PPJERR);)
1711 }
1712
1713 Pjlw = P_JLW(*PPArray); // first word of leaf.
1714
1715 // ****************************************************************************
1716 // PROCESS TOP LEVEL "JRP" BRANCHES AND LEAVES:
1717
1718 // ****************************************************************************
1719 // JRPNULL (EMPTY ARRAY): BUILD A LEAFW WITH ONE INDEX:
1720
1721 // if a valid empty array (null pointer), so create an array of population == 1:
1722
1723 if (Pjlw == (Pjlw_t)NULL)
1724 {
1725 Pjlw_t Pjlwnew;
1726
1727 Pjlwnew = j__udyAllocJLW(1);
1728 JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1729 JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1730
1731 Pjlwnew[0] = 1 - 1; // pop0 = 0.
1732 Pjlwnew[1] = Index;
1733
1734 *PPArray = (Pvoid_t) Pjlwnew;
1735 DBGCODE(JudyCheckPop(*PPArray);)
1736
1737 JUDY1CODE(return(1); )
1738 JUDYLCODE(Pjlwnew[2] = 0; ) // value area.
1739 JUDYLCODE(return((PPvoid_t) (Pjlwnew + 2)); )
1740
1741 } // NULL JRP
1742
1743 // ****************************************************************************
1744 // LEAFW, OTHER SIZE:
1745
1746 if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
1747 {
1748 Pjlw_t Pjlwnew;
1749 Word_t pop1;
1750
1751 Pjlw = P_JLW(*PPArray); // first word of leaf.
1752 pop1 = Pjlw[0] + 1;
1753
1754 #ifdef JUDYL
1755 Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);
1756 #endif
1757 offset = j__udySearchLeafW(Pjlw + 1, pop1, Index);
1758
1759 if (offset >= 0) // index is already valid:
1760 {
1761 DBGCODE(JudyCheckPop(*PPArray);)
1762 JUDY1CODE(return(0); )
1763 JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1764 }
1765
1766 offset = ~offset;
1767
1768 // Insert index in cases where no new memory is needed:
1769
1770 if (JU_LEAFWGROWINPLACE(pop1))
1771 {
1772 ++Pjlw[0]; // increase population.
1773
1774 JU_INSERTINPLACE(Pjlw + 1, pop1, offset, Index);
1775 #ifdef JUDYL
1776 JU_INSERTINPLACE(Pjv, pop1, offset, 0);
1777 #endif
1778 DBGCODE(JudyCheckPop(*PPArray);)
1779 DBGCODE(JudyCheckSorted(Pjlw + 1, pop1 + 1, cJU_ROOTSTATE);)
1780
1781 JUDY1CODE(return(1); )
1782 JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1783 }
1784
1785 // Insert index into a new, larger leaf:
1786
1787 if (pop1 < cJU_LEAFW_MAXPOP1) // can grow to a larger leaf.
1788 {
1789 Pjlwnew = j__udyAllocJLW(pop1 + 1);
1790 JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1791 JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1792
1793 Pjlwnew[0] = pop1; // set pop0 in new leaf.
1794
1795 JU_INSERTCOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, Index);
1796 #ifdef JUDYL
1797 Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 + 1);
1798 JU_INSERTCOPY(Pjvnew, Pjv, pop1, offset, 0);
1799 #endif
1800 DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 + 1, cJU_ROOTSTATE);)
1801
1802 j__udyFreeJLW(Pjlw, pop1, NULL);
1803
1804 *PPArray = (Pvoid_t) Pjlwnew;
1805 DBGCODE(JudyCheckPop(*PPArray);)
1806
1807 JUDY1CODE(return(1); )
1808 JUDYLCODE(return((PPvoid_t) (Pjvnew + offset)); )
1809 }
1810
1811 assert(pop1 == cJU_LEAFW_MAXPOP1);
1812
1813 // Leaf at max size => cannot insert new index, so cascade instead:
1814 //
1815 // Upon cascading from a LEAFW leaf to the first branch, must allocate and
1816 // initialize a JPM.
1817
1818 Pjpm = j__udyAllocJPM();
1819 JUDY1CODE(JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI );)
1820 JUDYLCODE(JU_CHECKALLOC(Pjpm_t, Pjpm, PPJERR);)
1821
1822 (Pjpm->jpm_Pop0) = cJU_LEAFW_MAXPOP1 - 1;
1823 (Pjpm->jpm_JP.jp_Addr) = (Word_t) Pjlw;
1824
1825 if (j__udyCascadeL(&(Pjpm->jpm_JP), Pjpm) == -1)
1826 {
1827 JU_COPY_ERRNO(PJError, Pjpm);
1828 JUDY1CODE(return(JERRI );)
1829 JUDYLCODE(return(PPJERR);)
1830 }
1831
1832 // Note: No need to pass Pjpm for memory decrement; LEAFW memory is never
1833 // counted in a JPM at all:
1834
1835 j__udyFreeJLW(Pjlw, cJU_LEAFW_MAXPOP1, NULL);
1836 *PPArray = (Pvoid_t) Pjpm;
1837
1838 } // JU_LEAFW
1839
1840 // ****************************************************************************
1841 // BRANCH:
1842
1843 {
1844 int retcode; // really only needed for Judy1, but free for JudyL.
1845
1846 Pjpm = P_JPM(*PPArray);
1847 retcode = j__udyInsWalk(&(Pjpm->jpm_JP), Index, Pjpm);
1848
1849 if (retcode == -1)
1850 {
1851 JU_COPY_ERRNO(PJError, Pjpm);
1852 JUDY1CODE(return(JERRI );)
1853 JUDYLCODE(return(PPJERR);)
1854 }
1855
1856 if (retcode == 1) ++(Pjpm->jpm_Pop0); // incr total array popu.
1857
1858 assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
1859 || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
1860 || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
1861 DBGCODE(JudyCheckPop(*PPArray);)
1862
1863 #ifdef JUDY1
1864 assert((retcode == 0) || (retcode == 1));
1865 return(retcode); // == JU_RET_*_JPM().
1866 #else
1867 assert(Pjpm->jpm_PValue != (Pjv_t) NULL);
1868 return((PPvoid_t) Pjpm->jpm_PValue);
1869 #endif
1870 }
1871 /*NOTREACHED*/
1872
1873 } // Judy1Set() / JudyLIns()