Esempio n. 1
0
File: subreq.c Progetto: dimarik/ugh
ugh_header_t *ugh_subreq_header_get(ugh_subreq_t *r, const char *data, size_t size)
{
	void **dest = JudyLGet(r->headers_hash, aux_hash_key_lc_header(data, size), PJE0);
	if (PJERR == dest || NULL == dest) return &ugh_empty_header;

	return *dest;
}
Esempio n. 2
0
strp ugh_client_getvar_nt(ugh_client_t *c, const char *data)
{
	void **dest = JudyLGet(c->vars_hash, aux_hash_key_nt(data), PJE0);
	if (PJERR == dest || NULL == dest) return &aux_empty_string;

	return *dest;
}
Esempio n. 3
0
ugh_header_t *ugh_client_header_get_nt(ugh_client_t *c, const char *data)
{
	void **dest = JudyLGet(c->headers_hash, aux_hash_key_lc_header_nt(data), PJE0);
	if (PJERR == dest || NULL == dest) return &ugh_empty_header;

	return *dest;
}
Esempio n. 4
0
strp ugh_client_body_getarg(ugh_client_t *c, const char *data, size_t size)
{
	void **dest = JudyLGet(c->body_hash, aux_hash_key(data, size), PJE0);
	if (PJERR == dest || NULL == dest) return &aux_empty_string;

	return *dest;
}
Esempio n. 5
0
gc_shape_t *flx_collector_t::get_shape(void *memory)
{
  assert(memory);
  //fprintf(stderr, "Get shape of %p\n",memory);
  Word_t *pshape= (Word_t*)JudyLGet(j_shape,(Word_t)memory,&je);
  if(pshape==(Word_t*)PPJERR)judyerror("get_shape");
  if(pshape==NULL) abort();
  return (gc_shape_t*)(*pshape & (~1ul));
}
Esempio n. 6
0
// max number of available slots in an array
unsigned long flx_collector_t::get_count(void *memory)
{
  assert(memory);
  //fprintf(stderr, "Get count of %p\n",memory);
  Word_t *p = (Word_t*)(void*)JudyLGet(j_nalloc,(Word_t)memory,&je);
  if(p==(Word_t*)PPJERR)judyerror("get_count");
  //fprintf(stderr, "Count slot at address %p\n",p);
  unsigned long z = p!=NULL?*p:1; // defaults to 1 for non-array support
  //fprintf(stderr,"Count of %p is %ld\n",memory,z);
  return z;
}
Esempio n. 7
0
static
strp ugh_variable_map_handle(ugh_client_t *c, const char *name, size_t size, void *data)
{
	ugh_module_map_conf_t *conf = data;
	strp vv = ugh_get_varvalue(c, conf->key.data, conf->key.size);

	void **dest;

	dest = JudyLGet(conf->hash, aux_hash_key(vv->data, vv->size), PJE0);
	if (PJERR == dest || NULL == dest) return &conf->default_value;

	return *dest;
}
Esempio n. 8
0
void flx_collector_t::incr_used(void *memory, unsigned long n)
{
  assert(memory);
  assert(n>=0);
  //fprintf(stderr,"Incr used of %p by %ld\n",memory,n);
  assert(get_used(memory) + n <= get_count(memory));
  Word_t *p = (Word_t*)(void*)JudyLGet(j_nused,(Word_t)memory,&je);
  if(p==(Word_t*)PPJERR)judyerror("incr_used");
  if(p==NULL)
  {
    //fprintf(stderr,"incr_used: No recorded usage! Creating store for data\n");
    p = (Word_t*)(void*)JudyLIns(&j_nused,(Word_t)memory,&je);
    if(p==(Word_t*)PPJERR)judyerror("incr_used: new slot");
    *p = n;
  }
  else *p+=n;
}
Esempio n. 9
0
void flx_collector_t::set_used(void *memory, unsigned long n)
{
  assert(memory);
  assert(n>=0);

  // this check is expensive, but set_used is not used often
  assert(n<=get_count(memory));
  //fprintf(stderr,"Set used of %p to %ld\n",memory,n);
  Word_t *p = (Word_t*)(void*)JudyLGet(j_nused,(Word_t)memory,&je);
  if(p==(Word_t*)PPJERR)judyerror("set_used");
  if(p==NULL)
  {
    //fprintf(stderr,"set_used: No recorded usage! Creating store for data\n");
    p = (Word_t*)(void*)JudyLIns(&j_nused,(Word_t)memory,&je);
  }
  //fprintf(stderr,"Slot for %p usage is address %p\n",memory,p);
  *p = (Word_t)n;
}
Esempio n. 10
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()
Esempio n. 11
0
int JudyLDel(void **PPArray, uint32_t Index, void **PPvalue)
{
	Word_t pop1;
	int offset;
	void **PPret;

	if (PPArray == NULL) {
		JL_SET_ERRNO(JLE_NULLPPARRAY);
		return JERR;
	}

	if ((PPret = JudyLGet(*PPArray, Index)) == PPJERR)
		return JERR;

	if (PPret == NULL)
		return 0;

	if (PPvalue)
		*PPvalue = *PPret;

	if (JL_LEAFW_POP0(*PPArray) < cJL_LEAFW_MAXPOP1) {
		Pjv_t Pjv;
		Pjv_t Pjvnew;
		Pjlw_t Pjlw = P_JLW(*PPArray);
		Pjlw_t Pjlwnew;
		pop1 = Pjlw[0] + 1;

		if (pop1 == 1) {
			judyLFreeJLW(Pjlw, /* pop1 = */ 1, NULL);
			*PPArray = NULL;
			return 1;
		}

		offset = judySearchLeafW(Pjlw + 1, pop1, Index);
		assert(offset >= 0);

		Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);

		if (JL_LEAFWGROWINPLACE(pop1 - 1)) {
			JL_DELETEINPLACE(Pjlw + 1, pop1, offset, ignore);
			JL_DELETEINPLACE(Pjv, pop1, offset, ignore);
			--(Pjlw[0]);
			return 1;
		}

		Pjlwnew = judyLAllocJLW(pop1 - 1);
		JL_CHECKALLOC(Pjlw_t, Pjlwnew, JERR);

		Pjlwnew[0] = (pop1 - 1) - 1;
		JL_DELETECOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, ignore);

		Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 - 1);
		JL_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);

		judyLFreeJLW(Pjlw, pop1, NULL);

		*PPArray = (void *) Pjlwnew;
		return 1;
	} else {
		Word_t digit;
		Pjv_t Pjv;
		Pjlw_t Pjlwnew;
		Pjpm_t Pjpm = P_JPM(*PPArray);
		Pjp_t Pjp = &(Pjpm->jpm_JP);

		assert(((Pjpm->jpm_JP.jp_Type) == cJL_JPBRANCH_L)
		       || ((Pjpm->jpm_JP.jp_Type) == cJL_JPBRANCH_B)
		       || ((Pjpm->jpm_JP.jp_Type) == cJL_JPBRANCH_U));

		if (judyDelWalk(Pjp, Index, cJL_ROOTSTATE, Pjpm) == -1)
			return JERR;

		--(Pjpm->jpm_Pop0);

		if ((Pjpm->jpm_Pop0 + 1) != cJL_LEAFW_MAXPOP1)
			return 1;

		Pjlwnew = judyLAllocJLW(cJL_LEAFW_MAXPOP1);
		JL_CHECKALLOC(Pjlw_t, Pjlwnew, JERR);

		*PPArray = (void *) Pjlwnew;
		Pjv = JL_LEAFWVALUEAREA(Pjlwnew, cJL_LEAFW_MAXPOP1);
		*Pjlwnew++ = cJL_LEAFW_MAXPOP1 - 1;

		switch (JL_JPTYPE(Pjp)) {
		case cJL_JPBRANCH_L: {
			Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
			Pjbl_t Pjbl = P_JBL(PjblRaw);

			for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset) {
				pop1 = judyLeafM1ToLeafW(Pjlwnew, Pjv, (Pjbl->jbl_jp) + offset,
					JL_DIGITTOSTATE(Pjbl->jbl_Expanse [offset],
					cJL_BYTESPERWORD), (void *) Pjpm);
				Pjlwnew += pop1;
				Pjv += pop1;
			}
			judyLFreeJBL(PjblRaw, Pjpm);

			break;
		}
		case cJL_JPBRANCH_B: {
			Pjbb_t PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
			Pjbb_t Pjbb = P_JBB(PjbbRaw);
			Word_t subexp;
			BITMAPB_t bitmap;
			Pjp_t Pjp2Raw, Pjp2;

			for (subexp = 0; subexp < cJL_NUMSUBEXPB; ++subexp) {
				if ((bitmap = JL_JBB_BITMAP(Pjbb, subexp)) == 0)
					continue;

				digit = subexp * cJL_BITSPERSUBEXPB;
				Pjp2Raw = JL_JBB_PJP(Pjbb, subexp);
				Pjp2 = P_JP(Pjp2Raw);
				assert(Pjp2 != NULL);

				for (offset = 0; bitmap != 0;
				     bitmap >>= 1, ++digit) {
					if (!(bitmap & 1))
						continue;
					pop1 = judyLeafM1ToLeafW(Pjlwnew, Pjv, Pjp2 + offset,
						JL_DIGITTOSTATE(digit, cJL_BYTESPERWORD), (void *) Pjpm);
					Pjlwnew += pop1;
					Pjv += pop1;
					++offset;
				}
				judyLFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm);
			}
			judyLFreeJBB(PjbbRaw, Pjpm);

			break;
		}
		case cJL_JPBRANCH_U: {
			Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr);
			Pjbu_t Pjbu = P_JBU(PjbuRaw);
			Word_t ldigit;

			for (Pjp = Pjbu->jbu_jp, ldigit = 0; ldigit < cJL_BRANCHUNUMJPS; ++Pjp, ++ldigit) {
				if ((JL_JPTYPE(Pjp)) == cJL_JPNULLMAX)
					continue;
				if ((JL_JPTYPE(Pjp)) == cJL_JPIMMED_3_01) {
					*Pjlwnew++ = JL_DIGITTOSTATE(ldigit, cJL_BYTESPERWORD)
							| JL_JPDCDPOP0(Pjp);
					*Pjv++ = Pjp->jp_Addr;
					continue;
				}

				pop1 = judyLeafM1ToLeafW(Pjlwnew, Pjv, Pjp,
					JL_DIGITTOSTATE(ldigit, cJL_BYTESPERWORD), (void *) Pjpm);
				Pjlwnew += pop1;
				Pjv += pop1;
			}
			judyLFreeJBU(PjbuRaw, Pjpm);
			break;
		}
		default:
			JL_SET_ERRNO(JLE_CORRUPT);
			return JERR;
		}
		judyLFreeJPM(Pjpm, NULL);
		return 1;
	}
}