#include "Judy.h"#define TRUE 1L#define CHNULL '\0'#define PCNULL ((char *) NULL)#define PPVNULL ((PPvoid_t) NULL)#define WORDSIZE (sizeof (ulong_t)) // bytes in a word = JudyL index.// Copy a word from one location to another; typically one of which is not// word-aligned://// Like strncpy(), null-pad the destination, but based on performance// measurements don't use strncpy(). Instead hardwire the code based on a// parameter from JudyL.h; assume only two machine word sizes exist.#define CH(P,I) (((char *) (P)) [I]) // shorthand for below.#define CPY(P1,P2,I) (CH (P1, I) = CH (P2, I))#define IFCPY(P1,P2,I) if (CPY (P1, P2, I) != CHNULL)#define WORDCPY(P1,P2) \ { *((ulong_t *) (P1)) = 0L; \ IFCPY(P1,P2,0L) IFCPY(P1,P2,1L) IFCPY(P1,P2,2L) CPY(P1,P2,3L); }#define LASTWORD(indexword) (((char *) (& indexword)) [WORDSIZE - 1L] == CHNULL)// ****************************************************************************// J U D Y S L G E TPPvoid_t JudySLGet ( const void * PArray, const char * Index, JError_t * PJError){ char * pos = (char *)Index; // place in Index. ulong_t indexword; // next word to find. PPvoid_t PPvalue; // from JudyL array.assert (Index != PCNULL);// SEARCH NEXT LEVEL OF JUDYL ARRAY IN TREE://// Copy each word from the Index string and check for it in the next level// JudyL array in the array tree. while (TRUE) // until return. {// Since strings can begin on arbitrary byte boundaries, copy each // chunk of N bytes from Index into a word-aligned object (a ulong_t)// before using it as a Judy index. WORDCPY (& indexword, pos); if ((PPvalue = JudyLGet (PArray, indexword, PJError)) == PPJERR) return (PPVNULL); // Index not in array tree.// CHECK FOR END OF STRING IN CURRENT indexword: if (LASTWORD (indexword)) return (PPvalue); // is value for whole Index string.// CONTINUE TO NEXT LEVEL DOWN JUDYL ARRAY TREE://// If a previous JudySLIns() ran out of memory partway down the tree, it left a// null *PPvalue; this is automatically treated here as a dead-end. pos += WORDSIZE; PArray = *PPvalue; // each value -> next array. } // while /*NOTREACHED*/} // JudySLGet()// ****************************************************************************// J U D Y S L I N SPPvoid_t JudySLIns ( PPvoid_t PPArray, const char * Index, JError_t * PJError){ char * pos = (char *)Index; ulong_t indexword; PPvoid_t PPvalue;assert (PPArray != PPVNULL);assert (Index != PCNULL); while (TRUE) // until return. { WORDCPY (& indexword, pos); if ((PPvalue = JudyLIns (PPArray, indexword, PJError)) == PPJERR) return (PPVNULL); // Index cannot be stored. if (LASTWORD (indexword)) return (PPvalue); // is value for whole Index string. pos += WORDSIZE; PPArray = PPvalue; // each value -> next array. } /*NOTREACHED*/} // JudySLIns()In summary
This chapter contains an example that
illustrates a Judy multi-dimensional array. Excellent memory efficiency
makes multi-dimensional arrays a practical application of the Judy technology
that may be "best in class". |