NAME¶
JudyL macros - C library for creating and accessing a dynamic array of words,
  using a word as an index.
SYNOPSIS¶
cc [flags]  sourcefiles -lJudy
#include <Judy.h>
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
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()
DESCRIPTION¶
A JudyL array is the equivalent of an array of word-sized values. A 
Value
  is addressed by an 
Index (key). The array may be sparse, and the
  
Index 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.
As with an ordinary array, there are no duplicate indexes in a JudyL array.
The value may be used as a scalar, or a pointer to a structure or block of data
  (or even another Judy array).
A JudyL array is allocated with a 
NULL pointer
Pvoid_t PJLArray = (Pvoid_t) NULL;
Using the macros described here, rather than the 
JudyL function calls,
  the default error handling sends a message to the standard error and
  terminates the program with 
exit(1);. For other error handling methods,
  see the 
ERRORS section. 
JLI( PValue, PJLArray, Index); //
  
JudyLIns()
Because the macro forms are sometimes faster and have a simpler error handling
  interface than the equivalent 
JudyL functions, they are the preferred
  way of calling the JudyL functions.
  - 
  
   JLI(PValue, PJLArray, Index) // JudyLIns() 
  - Insert an Index and Value into the JudyL
      array PJLArray. If the Index is successfully inserted, the
      Value is initialized to 0. If the Index was already present,
      the Value is not modified.
 
  
  - Return PValue pointing to Value. Your program
      can use this pointer to read or modify Value until the next
      JLI() (insert), JLD() (delete) or JLFA() (freearray)
      is executed on PJLArray. Examples:
 
  
  - 
    
*PValue = 1234;
Value = *PValue;
    
   
  
  - Return PValue set to PJERR if a
      malloc() fail occured. Note: JLI() and JLD()
      reorganize the JudyL array. Therefore, PValue returned from
      previous JudyL calls become invalid and must be re-acquired.
 
  - 
  
   JLD(Rc_int, PJLArray, Index) // JudyLDel() 
  - Delete the Index/Value pair from the JudyL
      array.
 
  
  - Return Rc_int set to 1 if successful. Return
      Rc_int set to 0 if Index was not present. Return
      Rc_int set to JERR if a malloc() fail occured.
 
  - 
  
   JLG(PValue, PJLArray, Index) // JudyLGet() 
  - Get the pointer PValue associated with Index
      in the PJLArray Judy array.
 
  
  - Return PValue pointing to Value. Return
      PValue set to NULL if the Index was not present.
      Return PValue set to PJERR if a malloc() fail
      occured.
 
  - 
  
   JLC(Rc_word, PJLArray, Index1, Index2) // JudyLCount() 
  - Count the number of indexes present in the JudyL array
      PJLArray between Index1 and Index2 (inclusive).
 
  
  - Return Rc_word set to the count. A return value of 0
      can be valid as a count.
 
  
  - To count all indexes present in a JudyL array, use:
 
  
  - 
    
JLC(Rc_word, PJLArray, 0, -1);
    
   
  - 
  
   JLBC(PValue, PJLArray, Nth, Index) // JudyLByCount() 
  - Locate the Nth index that is present in the JudyL
      array PJLArray (Nth = 1 returns the first index
    present).
 
  
  - Return PValue pointing to its Value and
      Index set to the Nth index if found, otherwise return
      PValue set to NULL (the value of Index is
    undefined).
 
  - 
  
   JLFA(Rc_word, PJLArray) // JudyLFreeArray() 
  - Given a pointer to a JudyL array, free the entire array
      (much faster than using a JLN(), JLD() loop).
 
  
  - Return Rc_word set to the number of bytes freed and
      PJLArray set to NULL.
 
  - 
  
   JLMU(Rc_word, PJLArray) // JudyLMemUsed() 
  - Return Rc_word set to the number of bytes of memory
      malloc()'ed by PJLArray. This is a very fast routine, and
      may be used before and after a JLI() or JLD() call with
      little performance impact.
 
  - 
  
   JudyL Search Functions 
  - JLF(), JLN(), JLL(), JLP()
      allow you to search for indexes in the array. You may search inclusively
      or exclusively, in either forward or reverse directions. If successful,
      Index is returned set to the found index, and PValue is
      returned set to a pointer to Index's Value. If unsuccessful,
      PValue is returned set to NULL, and Index contains no
      useful information. PValue must be tested for non-NULL prior
      to using Index, since a search failure is possible.
 
  
  - JLFE(), JLNE(), JLLE(), JLPE()
      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, Index is returned set to a
      not present ("empty") index, and Rc_int is returned set
      to 1. If unsuccessful, Rc_int is returned set to 0, and and
      Index contains no useful information. Rc_int must be checked
      prior to using Index, since a search failure is possible.
 
  - 
  
   JLF(PValue, PJLArray, Index) // JudyLFirst() 
  - Search (inclusive) for the first index present that is
      equal to or greater than the passed Index. (Start with Index
      = 0 to find the first index in the array.) JLF() is typically used
      to begin a sorted-order scan of the indexes present in a JudyL
      array.
 
  - 
  
   JLN(PValue, PJLArray, Index) // JudyLNext() 
  - Search (exclusive) for the next index present that is
      greater than the passed Index. JLN() is typically used to
      continue a sorted-order scan of the indexes present in a JudyL
      array, or to locate a "neighbor" of a given index.
 
  - 
  
   JLL(PValue, PJLArray, Index) // JudyLLast() 
  - Search (inclusive) for the last index present that is equal
      to or less than the passed Index. (Start with Index = -1,
      that is, all ones, to find the last index in the array.) JLL() is
      typically used to begin a reverse-sorted-order scan of the indexes
      present in a JudyL array.
 
  - 
  
   JLP(PValue, PJLArray, Index) // JudyLPrev() 
  - Search (exclusive) for the previous index present that is
      less than the passed Index. JLP() is typically used to
      continue a reverse-sorted-order scan of the indexes present in a
      JudyL array, or to locate a "neighbor" of a given index.
 
  - 
  
   JLFE(Rc_int, PJLArray, Index) // JudyLFirstEmpty() 
  - Search (inclusive) for the first index absent that is equal
      to or greater than the passed Index. (Start with Index = 0
      to find the first index absent in the array.)
 
  - 
  
   JLNE(Rc_int, PJLArray, Index) // JudyLNextEmpty() 
  - Search (exclusive) for the next index absent that is
      greater than the passed Index.
 
  - 
  
   JLLE(Rc_int, PJLArray, Index) // JudyLLastEmpty() 
  - Search (inclusive) for the last index absent that is equal
      to or less than the passed Index. (Start with Index = -1,
      that is, all ones, to find the last index absent in the array.)
 
  - 
  
   JLPE(Rc_int, PJLArray, Index) // JudyLPrevEmpty() 
  - Search (exclusive) for the previous index absent that is
      less than the passed Index.
 
Multi-dimensional JudyL Arrays¶
Storing a pointer to another JudyL array in a JudyL array's 
Value 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 
Value pointer is marked to 
NOT point to another Judy
  array. A 
JLAP_INVALID flag is used in the least significant bit(s) of
  the pointer. After the flag 
JLAP_INVALID is removed, it is used as a
  pointer to the users data. The 
Judy.h header file defines
  
JLAP_INVALID. See code fragment below.
Note: The current version of 
Judy.h changed this flag from 0x4 to 0x1 to
  allow for a 
malloc() that does not deliver memory on an 8 byte aligned
  boundry (such as old versions of valgrind).
The following example code segment can be used to determine whether or not a
  pointer points to another JudyL:
PValue = (PWord_t)PMultiDimArray;
for (Dim = 0; ;Dim++)
{
   if (PValue == (PWord_t)NULL) goto IndexNotFound;
   /* Advance to next dimension in array */
   JLG(PValue, (Pvoid_t)*PValue, Index[Dim]);
   /* 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);
       ...
Note: This works because 
malloc() guarantees to return a pointer with the
  least bit(s) == 0x0. You must remove 
JLAP_INVALID before using the
  pointer.
ERRORS: See: Judy_3.htm#ERRORS¶
EXAMPLE¶
Read a series of index/value pairs from the standard input, store in a JudyL
  array, and then print out in sorted order.
#include <stdio.h>
#include <Judy.h>
Word_t   Index;                     // array index
Word_t   Value;                     // array element value
Word_t * PValue;                    // pointer to array element value
int      Rc_int;                    // return code
Pvoid_t  PJLArray = (Pvoid_t) NULL; // initialize JudyL array
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.
Index = 0;
JLF(PValue, PJLArray, Index);
while (PValue != NULL)
{
    printf("%lu %lu\n", Index, *PValue));
    JLN(PValue, PJLArray, Index);
}
Index = -1;
JLL(PValue, PJLArray, Index);
while (PValue != NULL)
{
    printf("%lu %lu\n", Index, *PValue));
    JLD(Rc_int, PJLArray, Index);
    if (Rc_int == JERR) goto process_malloc_failure;
    JLP(PValue, PJLArray, Index);
}
AUTHOR¶
Judy was invented by Doug Baskins and implemented by Hewlett-Packard.
SEE ALSO¶
Judy(3), 
Judy1(3), 
JudySL(3), 
JudyHS(3),
 
malloc(),
 
http://judy.sourceforge.net, for more information and Application
  Notes.