.TH JudyL 3 .SH NAME JudyL \- C library for creating and accessing a dynamic array of words, using a word as an index. .PP .SH SYNOPSIS .PP .nf .ps +1 .ft B cc [flags] \fIsourcefiles\fP -lJudy .PP .ft B #include .PP .ft B int Rc_int; // return code - integer Word_t Rc_word; // return code - unsigned word Word_t Index, Index1, Index2, Nth; PWord_t PValue; // pointer to return value Pvoid_t PJLArray = (Pvoid_t) NULL; // initialize JudyL array .PP .ft B JLI( PValue, PJLArray, Index); // JudyLIns() JLD( Rc_int, PJLArray, Index); // JudyLDel() JLG( PValue, PJLArray, Index); // JudyLGet() JLC( Rc_word, PJLArray, Index1, Index2); // JudyLCount() JLBC(PValue, PJLArray, Nth, Index); // JudyLByCount() JLFA(Rc_word, PJLArray); // JudyLFreeArray() JLMU(Rc_word, PJLArray); // JudyLMemUsed() JLF( PValue, PJLArray, Index); // JudyLFirst() JLN( PValue, PJLArray, Index); // JudyLNext() JLL( PValue, PJLArray, Index); // JudyLLast() JLP( PValue, PJLArray, Index); // JudyLPrev() JLFE(Rc_int, PJLArray, Index); // JudyLFirstEmpty() JLNE(Rc_int, PJLArray, Index); // JudyLNextEmpty() JLLE(Rc_int, PJLArray, Index); // JudyLLastEmpty() JLPE(Rc_int, PJLArray, Index); // JudyLPrevEmpty() .ft P .ps .fi .PP .SH DESCRIPTION A JudyL array is the equivalent of an array of word-sized values. A \fBValue\fP is addressed by an \fBIndex\fP (key). The array may be sparse, and the \fBIndex\fP may be any word-sized number. Memory to support the array is allocated as index/value pairs are inserted, and released as index/value pairs are deleted. A JudyL array can also be thought of as a mapper, that is "map" a word to another word/pointer. .PP As with an ordinary array, there are no duplicate indexes in a JudyL array. .PP The value may be used as a scalar, or a pointer to a structure or block of data (or even another Judy array). .PP A JudyL array is allocated with a \fBNULL\fP pointer .PP .nf .ps +1 Pvoid_t PJLArray = (Pvoid_t) NULL; .ps .fi .PP Using the macros described here, rather than the \fBJudyL function calls\fP, the default error handling sends a message to the standard error and terminates the program with \fIexit(1);\fP. For other error handling methods, see the \fIERRORS\fP section. \fIJLI\fP( PValue, PJLArray, Index); // \fBJudyLIns()\fP .PP Because the macro forms are sometimes faster and have a simpler error handling interface than the equivalent \fBJudyL functions\fP, they are the preferred way of calling the JudyL functions. .PP .TP 15 \fBJLI(PValue, PJLArray, Index)\fP // \fBJudyLIns()\fP Insert an \fBIndex\fP and \fBValue\fP into the JudyL array \fBPJLArray\fP. If the \fBIndex\fP is successfully inserted, the \fBValue\fP is initialized to 0. If the \fBIndex\fP was already present, the \fBValue\fP is not modified. .IP Return \fBPValue\fP pointing to \fBValue\fP. Your program can use this pointer to read or modify \fBValue\fP until the next \fBJLI()\fP (insert), \fBJLD()\fP (delete) or \fBJLFA()\fP (freearray) is executed on \fBPJLArray\fP. Examples: .IP .nf .ps +1 *PValue = 1234; Value = *PValue; .ps .fi .IP Return \fBPValue\fP set to \fBPJERR\fP if a \fImalloc()\fP fail occured. \fBNote\fP: \fBJLI()\fP and \fBJLD()\fP reorganize the JudyL array. Therefore, \fBPValue\fP returned from previous \fBJudyL\fP calls become invalid and must be re-acquired. .IP .TP 15 \fBJLD(Rc_int, PJLArray, Index)\fP // \fBJudyLDel()\fP Delete the \fBIndex\fP/\fBValue\fP pair from the JudyL array. .IP Return \fBRc_int\fP set to 1 if successful. Return \fBRc_int\fP set to 0 if \fBIndex\fP was not present. Return \fBRc_int\fP set to \fBJERR\fP if a \fImalloc()\fP fail occured. .IP .TP 15 \fBJLG(PValue, PJLArray, Index)\fP // \fBJudyLGet()\fP Get the pointer \fBPValue\fP associated with \fBIndex\fP in the \fBPJLArray\fP Judy array. .IP Return \fBPValue\fP pointing to \fBValue\fP. Return \fBPValue\fP set to \fBNULL\fP if the \fBIndex\fP was not present. Return \fBPValue\fP set to \fBPJERR\fP if a \fImalloc()\fP fail occured. .IP .TP 15 \fBJLC(Rc_word, PJLArray, Index1, Index2)\fP // \fBJudyLCount()\fP Count the number of indexes present in the JudyL array \fBPJLArray\fP between \fBIndex1\fP and \fBIndex2\fP (inclusive). .IP Return \fBRc_word\fP set to the count. A return value of 0 can be valid as a count. .IP To count all indexes present in a JudyL array, use: .IP .nf .ps +1 JLC(Rc_word, PJLArray, 0, -1); .ps .fi .IP .TP 15 \fBJLBC(PValue, PJLArray, Nth, Index)\fP // \fBJudyLByCount()\fP Locate the \fBNth\fP index that is present in the JudyL array \fBPJLArray\fP (\fBNth\fP = 1 returns the first index present). .IP Return \fBPValue\fP pointing to its \fBValue\fP and \fBIndex\fP set to the \fBNth\fP index if found, otherwise return \fBPValue\fP set to \fBNULL\fP (the value of \fBIndex\fP is undefined). .IP .TP 15 \fBJLFA(Rc_word, PJLArray)\fP // \fBJudyLFreeArray()\fP Given a pointer to a JudyL array, free the entire array (much faster than using a \fBJLN()\fP, \fBJLD()\fP loop). .IP Return \fBRc_word\fP set to the number of bytes freed and \fBPJLArray\fP set to \fBNULL\fP. .IP .TP 15 \fBJLMU(Rc_word, PJLArray)\fP // \fBJudyLMemUsed()\fP Return \fBRc_word\fP set to the number of bytes of memory \fImalloc()\fP'ed by \fBPJLArray\fP. This is a very fast routine, and may be used before and after a \fBJLI()\fP or \fBJLD()\fP call with little performance impact. .IP .TP 15 \fBJudyL Search Functions\fP \fBJLF()\fP, \fBJLN()\fP, \fBJLL()\fP, \fBJLP()\fP allow you to search for indexes in the array. You may search inclusively or exclusively, in either forward or reverse directions. If successful, \fBIndex\fP is returned set to the found index, and \fBPValue\fP is returned set to a pointer to \fBIndex\fP's \fBValue\fP. If unsuccessful, \fBPValue\fP is returned set to \fBNULL\fP, and \fBIndex\fP contains no useful information. \fBPValue\fP must be tested for non-\fBNULL\fP prior to using \fBIndex\fP, since a search failure is possible. .IP \fBJLFE()\fP, \fBJLNE()\fP, \fBJLLE()\fP, \fBJLPE()\fP allow you to search for indexes that are not present ("empty") in the array. You may search inclusively or exclusively, in either forward or reverse directions. If successful, \fBIndex\fP is returned set to a not present ("empty") index, and \fBRc_int\fP is returned set to 1. If unsuccessful, \fBRc_int\fP is returned set to 0, and and \fBIndex\fP contains no useful information. \fBRc_int\fP must be checked prior to using \fBIndex\fP, since a search failure is possible. .IP .TP 15 \fBJLF(PValue, PJLArray, Index)\fP // \fBJudyLFirst()\fP Search (inclusive) for the first index present that is equal to or greater than the passed \fBIndex\fP. (Start with \fBIndex\fP = 0 to find the first index in the array.) \fBJLF()\fP is typically used to \fIbegin\fP a sorted-order scan of the indexes present in a JudyL array. .IP .TP 15 \fBJLN(PValue, PJLArray, Index)\fP // \fBJudyLNext()\fP Search (exclusive) for the next index present that is greater than the passed \fBIndex\fP. \fBJLN()\fP is typically used to \fIcontinue\fP a sorted-order scan of the indexes present in a JudyL array, or to locate a "neighbor" of a given index. .IP .TP 15 \fBJLL(PValue, PJLArray, Index)\fP // \fBJudyLLast()\fP Search (inclusive) for the last index present that is equal to or less than the passed \fBIndex\fP. (Start with \fBIndex\fP = -1, that is, all ones, to find the last index in the array.) \fBJLL()\fP is typically used to \fIbegin\fP a reverse-sorted-order scan of the indexes present in a JudyL array. .IP .TP 15 \fBJLP(PValue, PJLArray, Index)\fP // \fBJudyLPrev()\fP Search (exclusive) for the previous index present that is less than the passed \fBIndex\fP. \fBJLP()\fP is typically used to \fIcontinue\fP a reverse-sorted-order scan of the indexes present in a JudyL array, or to locate a "neighbor" of a given index. .IP .TP 15 \fBJLFE(Rc_int, PJLArray, Index)\fP // \fBJudyLFirstEmpty()\fP Search (inclusive) for the first index absent that is equal to or greater than the passed \fBIndex\fP. (Start with \fBIndex\fP = 0 to find the first index absent in the array.) .IP .TP 15 \fBJLNE(Rc_int, PJLArray, Index)\fP // \fBJudyLNextEmpty()\fP Search (exclusive) for the next index absent that is greater than the passed \fBIndex\fP. .IP .TP 15 \fBJLLE(Rc_int, PJLArray, Index)\fP // \fBJudyLLastEmpty()\fP Search (inclusive) for the last index absent that is equal to or less than the passed \fBIndex\fP. (Start with \fBIndex\fP = -1, that is, all ones, to find the last index absent in the array.) .IP .TP 15 \fBJLPE(Rc_int, PJLArray, Index)\fP // \fBJudyLPrevEmpty()\fP Search (exclusive) for the previous index absent that is less than the passed \fBIndex\fP. .PP .SH Multi-dimensional JudyL Arrays Storing a pointer to another JudyL array in a JudyL array's \fBValue\fP is a simple way to support dynamic multi-dimensional arrays. These arrays (or trees) built using JudyL arrays are very fast and memory efficient. (In fact, that is how JudySL and JudyHS are implemented). An arbitrary number of dimensions can be realized this way. To terminate the number of dimensions (or tree), the \fBValue\fP pointer is marked to \fBNOT\fP point to another Judy array. A \fBJLAP_INVALID\fP flag is used in the least significant bit(s) of the pointer. After the flag \fBJLAP_INVALID\fP is removed, it is used as a pointer to the users data. The \fBJudy.h\fP header file defines \fBJLAP_INVALID\fP. See code fragment below. .PP Note: The current version of \fBJudy.h\fP changed this flag from 0x4 to 0x1 to allow for a \fImalloc()\fP that does not deliver memory on an 8 byte aligned boundry (such as old versions of valgrind). .PP The following example code segment can be used to determine whether or not a pointer points to another JudyL: .PP .PP .nf .ps +1 PValue = (PWord_t)PMultiDimArray; .PP for (Dim = 0; ;Dim++) { if (PValue == (PWord_t)NULL) goto IndexNotFound; .PP /* Advance to next dimension in array */ JLG(PValue, (Pvoid_t)*PValue, Index[Dim]); .PP /* Check if pointer to user buffer: */ if (*PValue & JLAP_INVALID)) break; } UPointer = (UPointer_t) (*PValue & ~JLAP_INVALID); // mask and cast. printf("User object pointer is 0x%lx\\n", (Word_t) UPointer); &.&.&. .ps .fi .PP Note: This works because \fImalloc()\fP guarantees to return a pointer with the least bit(s) == 0x0. You must remove \fBJLAP_INVALID\fP before using the pointer. .PP .SH \fBERRORS:\fP See: \fIJudy_3.htm#ERRORS\fP .PP .SH EXAMPLE Read a series of index/value pairs from the standard input, store in a JudyL array, and then print out in sorted order. .PP .PP .nf .ps +1 #include #include .PP Word_t Index; // array index Word_t Value; // array element value Word_t * PValue; // pointer to array element value int Rc_int; // return code .PP Pvoid_t PJLArray = (Pvoid_t) NULL; // initialize JudyL array .PP while (scanf("%lu %lu", &Index, &Value)) { JLI(PValue, PJLArray, Index); If (PValue == PJERR) goto process_malloc_failure; *PValue = Value; // store new value } // Next, visit all the stored indexes in sorted order, first ascending, // then descending, and delete each index during the descending pass. .PP Index = 0; JLF(PValue, PJLArray, Index); while (PValue != NULL) { printf("%lu %lu\\n", Index, *PValue)); JLN(PValue, PJLArray, Index); } .PP Index = -1; JLL(PValue, PJLArray, Index); while (PValue != NULL) { printf("%lu %lu\\n", Index, *PValue)); .PP JLD(Rc_int, PJLArray, Index); if (Rc_int == JERR) goto process_malloc_failure; .PP JLP(PValue, PJLArray, Index); } .ps .fi .PP .SH AUTHOR Judy was invented by Doug Baskins and implemented \-Packard. .PP .SH SEE ALSO \fIJudy\fP(3), \fIJudy1\fP(3), \fIJudySL\fP(3), \fIJudyHS\fP(3), .br \fImalloc()\fP, .br \fIhttp://judy.sourceforge.net\fP, for more information and Application Notes.