/* * @(#) $Revision: 4.2 $ $Source: /judy/src/funcs/Judy1Op.c $ * * Judy1 set operations. * * The name of this function, "Judy1Op", was carefully chosen from * a list of alternatives: * * Judy1Op() - It's hard to see that O is a letter and not a zero. * Judy1Set() - Sounds like you are setting a bit. * Judy1BS() - BS for Bit Set functions. * Judy1SO() - SO for Set Operations * Judy1AndIDontGiveADarn() - too long but goes with * Judy1WhoseOnFirst() - now called Judy1First() and * Judy1WhatsOnSecond() - now called Judy1Next() * * But Judy1SetOp() would conflict with Judy1Set() if we rename Judy1Set(), so * Judy1Op() it is. */ #include "Judy.h" #include "Judy1Op.h" /******************************************************************* * Name: Judy1Op * * Description: * Logical set operations on Judy1 arrays. * * All of these operations can be done on an unbounded array because * the dreaded "NOT" is avoided. The "NOT"'s can be implemented * when Judy1 supports them. * * Parameters: * PPvoid_t PPDest (OUT) * Ptr to the Judy destination array. * Any initial value pointed to by PPDest is ignored. * * Pvoid_t PSet1 (IN) * First Judy1 set. * This will be NULL for an empty Judy1 array. * * Pvoid_t PSet2 (IN) * Second Judy1 set. * This will be NULL for an empty Judy1 array. * * Word_t Operation (IN) * Operation to be performed (ie. PSet1 {Operation} PSet2) * Valid Operation values are: * * JUDY1OP_AND - intersection of two sets * JUDY1OP_OR - union of two sets * JUDY1OP_ANDNOT - set1 with set2 removed * * JError_t * PJError (OUT) * Judy Error struct used to return Judy error. * * Returns: * !JERR if successful * JERR if an error occurs * If the error is a caller error (invalid Operation or no PPDest) * then the PJError error code will be JU_ERRNO_NONE. */ int Judy1Op(PPvoid_t PPDest, Pvoid_t PSet1, Pvoid_t PSet2, Word_t Operation, JError_t * PJError) { Pvoid_t PnewJArray = 0; // empty Judy array Word_t Index1 = 0L; Word_t Index2 = 0L; int Judy_rv; if (!PPDest) return JERR; switch (Operation) { case JUDY1OP_AND: // step through each array looking for index matches Judy_rv = Judy1First(PSet1, &Index1, PJError); Judy_rv += Judy1First(PSet2, &Index2, PJError); while (Judy_rv == 2) { if (Index1 < Index2) { Index1 = Index2; Judy_rv = Judy1First(PSet1, &Index1, PJError); } else if (Index1 > Index2) { Index2 = Index1; Judy_rv = Judy1First(PSet2, &Index2, PJError); } else { // do the AND Judy_rv = Judy1Set(&PnewJArray, Index1, PJError); if (Judy_rv == JERR) return JERR; // bump to the next bits Judy_rv = Judy1Next(PSet1, &Index1, PJError); Judy_rv += Judy1Next(PSet2, &Index2, PJError); } } *PPDest = PnewJArray; break; case JUDY1OP_OR: /* Set all the bits from PSet1 */ for (Index1 = 0L, Judy_rv = Judy1First(PSet1, &Index1, PJError); Judy_rv == 1; Judy_rv = Judy1Next(PSet1, &Index1, PJError)) { if (Judy1Set(&PnewJArray, Index1, PJError) == JERR) return JERR; } /* Set all the bits from PSet2 */ for (Index1 = 0L, Judy_rv = Judy1First(PSet2, &Index1, PJError); Judy_rv == 1; Judy_rv = Judy1Next(PSet2, &Index1, PJError)) { if (Judy1Set(&PnewJArray, Index1, PJError) == JERR) return JERR; } *PPDest = PnewJArray; break; case JUDY1OP_ANDNOT: // PSet1 with PSet2 removed // 0010 = PSet1(1010) ANDNOT PSet2(1100) for (Index1 = 0L, Judy_rv = Judy1First(PSet1, &Index1, PJError); Judy_rv == 1; Judy_rv = Judy1Next(PSet1, &Index1, PJError)) { // if bit doesn't exist in PSet2, then add to result if (0 == Judy1Test(PSet2, Index1, PJError)) { if (Judy1Set(&PnewJArray, Index1, PJError) == JERR) return JERR; } } *PPDest = PnewJArray; break; default: return JERR; } return !JERR; } /* Judy1Op */