3
<!-- @(#) $Revision: 4.53 $ $Source: /judy/doc/ext/JudyL_3x.htm $ --->
4
<TITLE>JudyL(3X)</TITLE>
8
<TABLE border=0 width="100%"><TR>
9
<TD width="40%" align="left">JudyL(3X)</TD>
10
<TD width="10%" align="center"> </TD>
11
<TD width="40%" align="right">JudyL(3X)</TD>
21
C library for creating and accessing a dynamic array of words, using
22
any value of a word as an index
26
<DT><B>SYNOPSIS</B></DT>
29
cc [flags] <I>sourcefiles</I> -lJudy
31
#include <Judy.h>
33
int Rc_int; // return code - integer
34
Word_t Rc_word; // return code - unsigned word
35
Word_t Index, Index1, Index2, Nth;
36
Word_t * PValue; // pointer to return value
38
Pvoid_t PJLArray = (Pvoid_t) NULL; // initialize JudyL array
41
<A href="#JLI" >JLI</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLIns">JudyLIns()</A>
42
<A href="#JLD" >JLD</A>( Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLDel">JudyLDel()</A>
43
<A href="#JLG" >JLG</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLGet">JudyLGet()</A>
44
<A href="#JLC" >JLC</A>( Rc_word, PJLArray, Index1, Index2); // <A href="JudyL_funcs_3x.htm#JudyLCount">JudyLCount()</A>
45
<A href="#JLBC" >JLBC</A>(PValue, PJLArray, Nth, Index); // <A href="JudyL_funcs_3x.htm#JudyLByCount">JudyLByCount()</A>
46
<A href="#JLFA" >JLFA</A>(Rc_word, PJLArray); // <A href="JudyL_funcs_3x.htm#JudyLFreeArray">JudyLFreeArray()</A>
47
<A href="#JLMU" >JLMU</A>(Rc_word, PJLArray); // <A href="JudyL_funcs_3x.htm#JudyLMemUsed">JudyLMemUsed()</A>
48
<A href="#JLF" >JLF</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLFirst">JudyLFirst()</A>
49
<A href="#JLN" >JLN</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLNext">JudyLNext()</A>
50
<A href="#JLL" >JLL</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLLast">JudyLLast()</A>
51
<A href="#JLP" >JLP</A>( PValue, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLPrev">JudyLPrev()</A>
52
<A href="#JLFE">JLFE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLFirstEmpty">JudyLFirstEmpty()</A>
53
<A href="#JLNE" >JLNE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLNextEmpty">JudyLNextEmpty()</A>
54
<A href="#JLLE" >JLLE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLLastEmpty">JudyLLastEmpty()</A>
55
<A href="#JLPE" >JLPE</A>(Rc_int, PJLArray, Index); // <A href="JudyL_funcs_3x.htm#JudyLPrevEmpty">JudyLPrevEmpty()</A>
60
<DT><B>DESCRIPTION</B></DT>
62
A JudyL array is the equivalent of an array of word-sized values.
63
A value is addressed by an <B>Index</B> (key).
64
The array may be sparse, and the <B>Index</B> may be any word-sized number.
65
Memory to support the array is allocated as index/value pairs are inserted,
66
and released as index/value pairs are deleted.
68
As with an ordinary array, there are no duplicate indexes in a JudyL array.
70
The value may be used as a scalar, or a pointer to a structure or block of data
71
(or even another Judy array).
73
A JudyL array is allocated with a <B>NULL</B> pointer
75
Pvoid_t PJLArray = (Pvoid_t) NULL;
79
Using the macros described here, rather than the
80
<A href="JudyL_funcs_3x.htm">JudyL function calls</A>,
81
the default error handling sends a
82
message to the standard error and terminates the program with <B>exit(1)</B>.
83
For other error handling methods, see the
84
<A href="#JLERR">ERRORS</A> section.
87
Because the macro forms are faster and have a simpler error
88
handling interface than the equivalent
89
<A href="JudyL_funcs_3x.htm">JudyL functions</A>,
90
they are the preferred way of calling the JudyL functions.
94
<DT><A name="JLI"><B>JLI(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLIns">JudyLIns()</A></DT>
96
Insert an <B>Index</B> and value in the JudyL array <B>PJLArray</B>.
97
If the <B>Index</B> is successfully inserted,
98
the value is initialized to 0. If the <B>Index</B> was already present,
99
the value is not modified.
101
Return <B>PValue</B> pointing to <B>Index</B>'s value.
102
Your program must use this pointer to modify the value,
109
<B>JLI()</B> and <B>JLD()</B> reorganize the JudyL array.
111
pointers returned from previous <B>JudyL</B> calls become
112
invalid and must be reacquired.
115
<DT><A name="JLD"><B>JLD(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLDel">JudyLDel()</A></DT>
117
Delete the <B>Index</B>/value pair from the JudyL array.
119
Return <B>Rc_int</B> set to 1 if successful.
120
Return <B>Rc_int</B> set to 0 if <B>Index</B> was not present.
123
<DT><A name="JLG"><B>JLG(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLGet">JudyLGet()</A></DT>
125
Get the pointer to <B>Index</B>'s value.
127
Return <B>PValue</B> pointing to <B>Index</B>'s value.
128
Return <B>PValue</B> set to <B>NULL</B> if the <B>Index</B> was not present.
131
<DT><A name="JLC"><B>JLC(Rc_word, PJLArray, Index1, Index2)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLCount">JudyLCount()</A></DT>
133
Count the number of indexes present in the JudyL array <B>PJLArray</B> between
134
<B>Index1</B> and <B>Index2</B> (inclusive).
136
Return <B>Rc_word</B> set to the count.
137
A return value of 0 can be valid as a count.
139
To count all indexes present in a JudyL array, use:
141
JLC(Rc_word, PJLArray, 0, -1);
145
<DT><A name="JLBC"><B>JLBC(PValue, PJLArray, Nth, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLByCount">JudyLByCount()</A></DT>
147
Locate the <B>Nth</B> index that is present in the JudyL array
148
<B>PJLArray</B> (<B>Nth</B> = 1 returns the first index present).
150
Return <B>PValue</B> pointing to its value and <B>Index</B>
151
set to the <B>Nth</B> index if found, otherwise return
152
<B>PValue</B> set to <B>NULL</B> (the value of <B>Index</B>
153
contains no useful information).
156
<DT><A name="JLFA"><B>JLFA(Rc_word, PJLArray)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLFreeArray">JudyLFreeArray()</A></DT>
158
Given a pointer to a JudyL array, free the entire array (much faster
160
<B>JLN()</B>, <B>JLD()</B> loop).
162
Return <B>Rc_word</B> set to the number of bytes freed and <B>PJLArray</B>
165
<DT><A name="JLMU"><B>JLMU(Rc_word, PJLArray)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLMemUsed">JudyLMemUsed()</A></DT>
167
Return <B>Rc_word</B> set to the number of bytes of memory currently in use
169
This is a very fast routine, and may be used after
170
a <B>JLI()</B> or <B>JLD()</B> call with little performance impact.
172
<DT><B>JudyL Search Functions</B></DT>
174
<B>JLF()</B>, <B>JLN()</B>, <B>JLL()</B>, <B>JLP()</B>
175
allow you to search for indexes
177
You may search inclusively or exclusively,
178
in either forward or reverse directions.
180
<B>Index</B> is returned set to the found index, and
181
<B>PValue</B> is returned set to a pointer to <B>Index</B>'s value.
183
<B>PValue</B> is returned set to <B>NULL</B>,
184
and <B>Index</B> contains no useful information.
185
<B>PValue</B> must be tested for non-<B>NULL</B> prior
186
to using <B>Index</B>,
187
since a search failure is possible.
189
<B>JLFE()</B>, <B>JLNE()</B>, <B>JLLE()</B>, <B>JLPE()</B> allow you to search for
190
indexes that are not present ("empty") in the array.
191
You may search inclusively or exclusively,
192
in either forward or reverse directions.
194
<B>Index</B> is returned set to a not present ("empty") index, and
195
<B>Rc_int</B> is returned set to 1.
197
<B>Rc_int</B> is returned set to 0, and
198
and <B>Index</B> contains no useful information.
199
<B>Rc_int</B> must be checked prior to using <B>Index</B>,
200
since a search failure is possible.
203
<DT><A name="JLF"><B>JLF(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLFirst">JudyLFirst()</A></DT>
205
Search (inclusive) for the first index present that is equal to or greater than the
207
(Start with <B>Index</B> = 0 to find the first index in the array.)
208
<B>JLF()</B> is typically used to <I>begin</I> a sorted-order scan of
209
the indexes present in a JudyL array.
212
<DT><A name="JLN"><B>JLN(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLNext">JudyLNext()</A></DT>
214
Search (exclusive) for the next index present that is greater than the passed
216
<B>JLN()</B> is typically used to <I>continue</I> a sorted-order scan of
217
the indexes present in a JudyL array, or to locate a "neighbor" of a given
221
<DT><A name="JLL"><B>JLL(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLLast">JudyLLast()</A></DT>
223
Search (inclusive) for the last index present that is equal
224
to or less than the passed <B>Index</B>.
225
(Start with <B>Index</B> = -1, that is, all ones, to find
226
the last index in the array.)
227
<B>JLL()</B> is typically used to <I>begin</I> a reverse-sorted-order
228
scan of the indexes present in a JudyL array.
231
<DT><A name="JLP"><B>JLP(PValue, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLPrev">JudyLPrev()</A></DT>
233
Search (exclusive) for the previous index present that is less than the
235
<B>JLP()</B> is typically used to <I>continue</I> a reverse-sorted-order
236
scan of the indexes present in a JudyL array, or to locate a "neighbor" of
240
<DT><A name="JLFE"><B>JLFE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLFirstEmpty">JudyLFirstEmpty()</A></DT>
242
Search (inclusive) for the first index absent that is equal to or greater than the passed
244
(Start with <B>Index</B> = 0 to find the first index absent in the array.)
247
<DT><A name="JLNE"><B>JLNE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLNextEmpty">JudyLNextEmpty()</A></DT>
249
Search (exclusive) for the next index absent that is greater than the passed <B>Index</B>.
252
<DT><A name="JLLE"><B>JLLE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLLastEmpty">JudyLLastEmpty()</A></DT>
254
Search (inclusive) for the last index absent that is equal to or less than
255
the passed <B>Index</B>.
256
(Start with <B>Index</B> = -1, that is, all ones, to find the last index absent
260
<DT><A name="JLPE"><B>JLPE(Rc_int, PJLArray, Index)</B></A> // <A href="JudyL_funcs_3x.htm#JudyLPrevEmpty">JudyLPrevEmpty()</A></DT>
262
Search (exclusive) for the previous index absent that is less than the passed
266
<DT><B>Multi-dimensional JudyL Arrays</B></DT>
268
Storing in a JudyL (or JudySL) array a value that is actually a pointer
269
to another JudyL (or JudySL) array supports dynamic multi-dimensional
270
arrays, or similarly, arrays where one or more of the keys/indexes is
271
longer than one word and treated as a series of words.
272
Multi-dimensional arrays (trees) built using JudyL (or JudySL) arrays
273
(as the branch nodes) are usually very fast and efficient.
274
When the dimensionality (and/or length of each key/index) of the array
275
is fixed, the implementation is straightforward and can be thought of as:
277
Array[dim1, dim2, dim3, dim4];
280
However, for applications where the tree is dynamic, such as when a
281
JudyL (or JudySL) value (subsidiary pointer) points to a user-defined
282
node (that is, it "escapes" from the hierarchy of JudyL/JudySL arrays)
283
because the number of dimensions (and/or the length of one or more
284
keys/indexes) is dynamic, the pointer must be recognizable as pointing
285
to such a node rather than another Judy array.
286
A value of 4 in the least significant 3 bits of a JudyL (or JudySL)
287
array pointer indicates that the pointer is not in fact to a subsidiary
288
Judy array, but rather it points (with the least three bits masked off)
289
to a user-defined location.
290
The <B>Judy.h</B> header file defines two values: <B>JLAP_MASK</B> to
291
mask the last 3 bits of the pointer, and <B>JLAP_INVALID</B> that has
292
the value 0x4 for checking the value of the pointer (<B>JLAP_INVALID ==
295
The following example code segment can be used to determine whether or
296
not a pointer points to another JudyL or JudySL array:
299
// Obtain a pointer to a value:
301
JLG (PValue, PJLArray, Index1);
303
// Check if it is a JudyL/JudySL array pointer:
305
if ((*PValue & JLAP_MASK) == JLAP_INVALID) // not a Judy array pointer.
307
UPointer = (UPointer_t) (*PValue & ~JLAP_MASK); // mask and cast.
308
printf("User object pointer is 0x%lx\n", (Word_t) UPointer);
311
else // a JudyL array pointer, traverse through it:
313
Pvoid_t PJLArray1 = (Pvoid_t) *PValue;
314
JLG(PValue1, PJLArray1, Index2);
319
Note: This works because <I>malloc</I>() guarantees to return a pointer
320
with the least 3 bits == 0x0.
321
You must add <B>JLAP_INVALID</B> to the pointer, and remove it before
322
using the pointer, to note that it is not a pointer to a JudyL array.
327
<DT><A name="JLERR"><B>ERRORS</B></A></DT>
329
There are two categories of Judy error returns:
331
1) User programming errors (bugs) such as memory corruption or
334
2) Out-of-memory (<I>malloc</I>() failure) when modifying a JudyL array with <B>JLI()</B>
336
<P>There are three methods of handling errors when using the macros:
338
1) Default error handling.
340
2) User-specified <B>JUDYERROR()</B> macro.
342
3) Disable macro error handling.
345
<DT><B>Default Error Handling Method</B></DT>
347
The default is to print error messages to <B>stderr</B>, for example:
349
File 'YourCfile.c', line 1234: JudyLIns(), JU_ERRNO_* == 2, ID == 321
351
This indicates that an error occurred in a <B>JLI()</B> call at line 1234 in 'YourCfile.c'.
352
JU_ERRNO_* == 2 is JU_ERRNO_NOMEM (as defined in the Judy.h file).
353
The ID number indicates the Judy source line number where the error was detected.
355
Your program then terminates with an <B>exit(1)</B>.
358
<DT><B>User-Specified JUDYERROR() Macro Method</B> </DT>
361
The <B>JUDYERROR()</B> macro provides flexibility for handling error returns
362
as needed to suit your program while still accessing JudyL arrays using macros
363
instead of function calls. You can modify <B>JUDYERROR()</B> to distinguish between
364
the two types of errors (described above), and explicitly test for the remaining
365
JU_ERRNO_NOMEM errors possible in your program.
368
// This is an example of JudyL macro API to continue when out of memory.
370
#ifndef JUDYERROR_NOTEST
371
#include <stdio.h> // needed for fprintf()
373
// This is the macro that the Judy macro APIs use for return codes of -1:
375
#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \
377
if ((JudyErrno) != JU_ERRNO_NOMEM) /* ! a malloc() failure */ \
379
(void) fprintf(stderr, "File '%s', line %d: %s(), " \
380
"JU_ERRNO_* == %d, ID == %d\n", \
381
CallerFile, CallerLine, \
382
JudyFunc, JudyErrno, JudyErrID); \
386
#endif // JUDYERROR_NOTEST not defined
388
This error handling macro must be included before the <B>#include <Judy.h></B>
389
statement in your program.
392
<DT><B>Disable Macro Error Handling</B> </DT>
395
When your program is "bug free",
396
the only errors occurring should be <I>malloc</I>(3) errors.
397
You can turn off error handling included in
398
the JudyL macros by using
400
#define JUDYERROR_NOTEST 1
402
(in your program code), or
404
cc -DJUDYERROR_NOTEST <I>sourcefile</I> -lJudy
406
(on your command line).
411
<DT><B>EXAMPLE</B></DT>
413
Read a series of index/value pairs from the standard input, store each
414
in a JudyL array, and then print out in sorted order.
418
#include <stdio.h>
419
#include <Judy.h>
421
Word_t Index; // array index
422
Word_t Value; // array element value
423
Word_t * PValue; // pointer to array element value
424
int Rc_int; // return code
426
Pvoid_t PJLArray = (Pvoid_t) NULL; // initialize JudyL array
428
while (scanf("%lu %lu", &Index, &Value))
430
JLI(PValue, PJLArray, Index);
431
If (PValue == PJERR) goto process_malloc_failure;
432
*PValue = Value; // store new value
434
// Next, visit all the stored indexes in sorted order, first ascending,
435
// then descending, and delete each index during the second pass.
438
JLF(PValue, PJLArray, Index);
439
while (PValue != NULL)
441
printf("%lu %lu\n", Index, *PValue));
442
JLN(PValue, PJLArray, Index);
446
JLL(PValue, PJLArray, Index);
447
while (PValue != NULL)
449
printf("%lu %lu\n", Index, *PValue));
451
JLD(Rc_int, PJLArray, Index);
452
if (Rc_int == JERR) goto process_malloc_failure;
454
JLP(PValue, PJLArray, Index);
461
<DT><B>AUTHOR</B></DT>
463
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
467
<DT><B>SEE ALSO</B></DT>
469
<A href="Judy_3x.htm">Judy(3X)</A>,
470
<A href="Judy1_3x.htm">Judy1(3X)</A>,
471
<A href="Judy1_funcs_3x.htm">Judy1_funcs(3X)</A>,
472
<A href="JudyL_funcs_3x.htm">JudyL_funcs(3X)</A>,
473
<A href="JudySL_3x.htm">JudySL(3X)</A>,
474
<A href="JudySL_funcs_3x.htm">JudySL_funcs(3X)</A>,
479
<A href="http://www.sourcejudy.com/">
480
http://www.sourcejudy.com/</A>,
481
for more information and Application Notes.