Exemplo n.º 1
0
static int PyJudyIntSet_contains(PyJudyIntSet* self, PyObject* key)
{
	Word_t v;

	if (!pyobject_as_word_t(key, &v))
		return 0;

	JError_t JError;
	int i = Judy1Test(self->s, v, &JError);

	if (i == JERR) {
		judy_set_error(&JError);
		return -1;
	}

	return (i ? 1 : 0);
}
Exemplo n.º 2
0
FUNCTION Word_t JUDY_EXTERN Judy1Count
#else
FUNCTION Word_t JUDY_EXTERN JudyLCount
#endif
        (
	Pcvoid_t  PArray,	// JRP to first branch/leaf in SM.
	Word_t	  Index1,	// starting Index.
	Word_t	  Index2,	// ending Index.
	PJError_t PJError	// optional, for returning error info.
        )
{
	jpm_t	  fakejpm;	// local temporary for small arrays.
	Pjpm_t	  Pjpm;		// top JPM or local temporary for error info.
	jp_t	  fakejp;	// constructed for calling j__udy1LCountSM().
	Pjp_t	  Pjp;		// JP to pass to j__udy1LCountSM().
	Word_t	  pop1;		// total for the array.
	Word_t	  pop1above1;	// indexes at or above Index1, inclusive.
	Word_t	  pop1above2;	// indexes at or above Index2, exclusive.
	int	  retcode;	// from Judy*First() calls.
JUDYLCODE(PPvoid_t PPvalue);	// from JudyLFirst() calls.


// CHECK FOR SHORTCUTS:
//
// As documented, return C_JERR if the Judy array is empty or Index1 > Index2.

	if ((PArray == (Pvoid_t) NULL) || (Index1 > Index2))
	{
	    JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
	    return(C_JERR);
	}

// If Index1 == Index2, simply check if the specified Index is set; pass
// through the return value from Judy1Test() or JudyLGet() with appropriate
// translations.

	if (Index1 == Index2)
	{
#ifdef JUDY1
	    retcode = Judy1Test(PArray, Index1, PJError);

	    if (retcode == JERRI) return(C_JERR);	// pass through error.

	    if (retcode == 0)
	    {
		JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
		return(C_JERR);
	    }
#else
	    PPvalue = JudyLGet(PArray, Index1, PJError);

	    if (PPvalue == PPJERR) return(C_JERR);	// pass through error.

	    if (PPvalue == (PPvoid_t) NULL)		// Index is not set.
	    {
		JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
		return(C_JERR);
	    }
#endif
	    return(1);					// single index is set.
	}


// CHECK JRP TYPE:
//
// Use an if/then for speed rather than a switch, and put the most common cases
// first.
//
// Note:  Since even cJU_LEAFW types require counting between two Indexes,
// prepare them here for common code below that calls j__udy1LCountSM(), rather
// than handling them even more specially here.

	if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
	{
	    Pjlw_t Pjlw	   = P_JLW(PArray);	// first word of leaf.
	    Pjpm	   = & fakejpm;
	    Pjp		   = & fakejp;
	    Pjp->jp_Addr   = (Word_t) Pjlw;
	    Pjp->jp_Type   = cJU_LEAFW;
	    Pjpm->jpm_Pop0 = Pjlw[0];		// from first word of leaf.
	    pop1	   = Pjpm->jpm_Pop0 + 1;
	}
	else
	{
	    Pjpm = P_JPM(PArray);
	    Pjp	 = &(Pjpm->jpm_JP);
	    pop1 = (Pjpm->jpm_Pop0) + 1;	// note: can roll over to 0.

#if (defined(JUDY1) && (! defined(JU_64BIT)))
	    if (pop1 == 0)		// rare special case of full array:
	    {
		Word_t count = Index2 - Index1 + 1;	// can roll over again.

		if (count == 0)
		{
		    JU_SET_ERRNO(PJError, JU_ERRNO_FULL);
		    return(C_JERR);
		}
		return(count);
	    }
#else
	    assert(pop1);	// JudyL or 64-bit cannot create a full array!
#endif
	}


// COUNT POP1 ABOVE INDEX1, INCLUSIVE:

	assert(pop1);		// just to be safe.

	if (Index1 == 0)	// shortcut, pop1above1 is entire population:
	{
	    pop1above1 = pop1;
	}
	else			// find first valid Index above Index1, if any:
	{
#ifdef JUDY1
	    if ((retcode = Judy1First(PArray, & Index1, PJError)) == JERRI)
		return(C_JERR);			// pass through error.
#else
	    if ((PPvalue = JudyLFirst(PArray, & Index1, PJError)) == PPJERR)
		return(C_JERR);			// pass through error.

	    retcode = (PPvalue != (PPvoid_t) NULL);	// found a next Index.
#endif

// If theres no Index at or above Index1, just return C_JERR (early exit):

	    if (retcode == 0)
	    {
		JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
		return(C_JERR);
	    }

// If a first/next Index was found, call the counting motor starting with that
// known valid Index, meaning the return should be positive, not C_JERR except
// in case of a real error:

	    if ((pop1above1 = j__udy1LCountSM(Pjp, Index1, Pjpm)) == C_JERR)
	    {
		JU_COPY_ERRNO(PJError, Pjpm);	// pass through error.
		return(C_JERR);
	    }
	}


// COUNT POP1 ABOVE INDEX2, EXCLUSIVE, AND RETURN THE DIFFERENCE:
//
// In principle, calculate the ordinal of each Index and take the difference,
// with caution about off-by-one errors due to the specified Indexes being set
// or unset.  In practice:
//
// - The ordinals computed here are inverse ordinals, that is, the populations
//   ABOVE the specified Indexes (Index1 inclusive, Index2 exclusive), so
//   subtract pop1above2 from pop1above1, rather than vice-versa.
//
// - Index1s result already includes a count for Index1 and/or Index2 if
//   either is set, so calculate pop1above2 exclusive of Index2.
//
// TBD:  If Index1 and Index2 fall in the same expanse in the top-state
// branch(es), would it be faster to walk the SM only once, to their divergence
// point, before calling j__udy1LCountSM() or equivalent?  Possibly a non-issue
// if a top-state pop1 becomes stored with each Judy1 array.  Also, consider
// whether the first call of j__udy1LCountSM() fills the cache, for common tree
// branches, for the second call.
//
// As for pop1above1, look for shortcuts for special cases when pop1above2 is
// zero.  Otherwise call the counting "motor".

	    assert(pop1above1);		// just to be safe.

	    if (Index2++ == cJU_ALLONES) return(pop1above1); // Index2 at limit.

#ifdef JUDY1
	    if ((retcode = Judy1First(PArray, & Index2, PJError)) == JERRI)
		return(C_JERR);
#else
	    if ((PPvalue = JudyLFirst(PArray, & Index2, PJError)) == PPJERR)
		return(C_JERR);

	    retcode = (PPvalue != (PPvoid_t) NULL);	// found a next Index.
#endif
	    if (retcode == 0) return(pop1above1);  // no Index above Index2.

// Just as for Index1, j__udy1LCountSM() cannot return 0 (locally == C_JERR)
// except in case of a real error:

	    if ((pop1above2 = j__udy1LCountSM(Pjp, Index2, Pjpm)) == C_JERR)
	    {
		JU_COPY_ERRNO(PJError, Pjpm);		// pass through error.
		return(C_JERR);
	    }

	    if (pop1above1 == pop1above2)
	    {
		JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
		return(C_JERR);
	    }

	    return(pop1above1 - pop1above2);

} // Judy1Count() / JudyLCount()
Exemplo n.º 3
0
char get_s_selected(struct symbol *s)
{
int rc = Judy1Test(GLOBALS->s_selected, (Word_t)s, PJE0);

return(rc);
}