Blame src/lib/libast/cdt/dthash.c

Packit Service a8c26c
/***********************************************************************
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*               This software is part of the ast package               *
Packit Service a8c26c
*          Copyright (c) 1985-2012 AT&T Intellectual Property          *
Packit Service a8c26c
*                      and is licensed under the                       *
Packit Service a8c26c
*                 Eclipse Public License, Version 1.0                  *
Packit Service a8c26c
*                    by AT&T Intellectual Property                     *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                A copy of the License is available at                 *
Packit Service a8c26c
*          http://www.eclipse.org/org/documents/epl-v10.html           *
Packit Service a8c26c
*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*              Information and Software Systems Research               *
Packit Service a8c26c
*                            AT&T Research                             *
Packit Service a8c26c
*                           Florham Park NJ                            *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                 Glenn Fowler <gsf@research.att.com>                  *
Packit Service a8c26c
*                  David Korn <dgk@research.att.com>                   *
Packit Service a8c26c
*                   Phong Vo <kpv@research.att.com>                    *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
***********************************************************************/
Packit Service a8c26c
#include	"dthdr.h"
Packit Service a8c26c
Packit Service a8c26c
/*	Hash table with chaining for collisions.
Packit Service a8c26c
**
Packit Service a8c26c
**      Written by Kiem-Phong Vo (05/25/96)
Packit Service a8c26c
*/
Packit Service a8c26c
Packit Service a8c26c
/* these bits should be outside the scope of DT_METHODS */
Packit Service a8c26c
#define H_FIXED		0100000	/* table size is fixed	*/
Packit Service a8c26c
#define	H_FLATTEN	0200000	/* table was flattened	*/
Packit Service a8c26c
Packit Service a8c26c
#define HLOAD(n)	(n)	/* load one-to-one	*/
Packit Service a8c26c
Packit Service a8c26c
/* internal data structure for hash table with chaining */
Packit Service a8c26c
typedef struct _dthash_s
Packit Service a8c26c
{	Dtdata_t	data;
Packit Service a8c26c
	int		type; 
Packit Service a8c26c
	Dtlink_t*	here;	/* fingered object	*/
Packit Service a8c26c
	Dtlink_t**	htbl;	/* hash table slots 	*/
Packit Service a8c26c
	ssize_t		tblz;	/* size of hash table 	*/
Packit Service a8c26c
} Dthash_t;
Packit Service a8c26c
Packit Service a8c26c
/* make/resize hash table */
Packit Service a8c26c
static int htable(Dt_t* dt)
Packit Service a8c26c
{
Packit Service a8c26c
	Dtlink_t	**htbl, **t, **endt, *l, *next;
Packit Service a8c26c
	ssize_t		n, k;
Packit Service a8c26c
	Dtdisc_t	*disc = dt->disc;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	if((n = hash->tblz) > 0 && (hash->type&H_FIXED) )
Packit Service a8c26c
		return 0; /* fixed size table */
Packit Service a8c26c
Packit Service a8c26c
	if(n == 0 && disc && disc->eventf) /* let user have input */
Packit Service a8c26c
	{	if((*disc->eventf)(dt, DT_HASHSIZE, &n, disc) > 0 )
Packit Service a8c26c
		{	if(n < 0) /* fix table size */
Packit Service a8c26c
			{	hash->type |= H_FIXED;
Packit Service a8c26c
				n = -n;
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	/* table size should be a power of 2 */
Packit Service a8c26c
	n = n < HLOAD(hash->data.size) ? HLOAD(hash->data.size) : n;
Packit Service a8c26c
	for(k = (1<
Packit Service a8c26c
		k *= 2;
Packit Service a8c26c
	if((n = k) <= hash->tblz)
Packit Service a8c26c
		return 0;
Packit Service a8c26c
Packit Service a8c26c
	/* allocate new table */
Packit Service a8c26c
	if(!(htbl = (Dtlink_t**)(*dt->memoryf)(dt, 0, n*sizeof(Dtlink_t*), disc)) )
Packit Service a8c26c
	{	DTERROR(dt, "Error in allocating an extended hash table");
Packit Service a8c26c
		return -1;
Packit Service a8c26c
	}
Packit Service a8c26c
	memset(htbl, 0, n*sizeof(Dtlink_t*));
Packit Service a8c26c
Packit Service a8c26c
	/* move objects into new table */
Packit Service a8c26c
	for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
Packit Service a8c26c
	{	for(l = *t; l; l = next)
Packit Service a8c26c
		{	next = l->_rght;
Packit Service a8c26c
			l->_rght = htbl[k = l->_hash&(n-1)];
Packit Service a8c26c
			htbl[k] = l;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	if(hash->htbl) /* free old table and set new table */
Packit Service a8c26c
		(void)(*dt->memoryf)(dt, hash->htbl, 0, disc);
Packit Service a8c26c
	hash->htbl = htbl;
Packit Service a8c26c
	hash->tblz = n;
Packit Service a8c26c
Packit Service a8c26c
	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Void_t* hclear(Dt_t* dt)
Packit Service a8c26c
{
Packit Service a8c26c
	Dtlink_t	**t, **endt, *l, *next;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	hash->here = NIL(Dtlink_t*);
Packit Service a8c26c
	hash->data.size = 0;
Packit Service a8c26c
Packit Service a8c26c
	for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
Packit Service a8c26c
	{	for(l = *t; l; l = next)
Packit Service a8c26c
		{	next = l->_rght;
Packit Service a8c26c
			_dtfree(dt, l, DT_DELETE);
Packit Service a8c26c
		}
Packit Service a8c26c
		*t = NIL(Dtlink_t*);
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	return NIL(Void_t*);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Void_t* hfirst(Dt_t* dt)
Packit Service a8c26c
{
Packit Service a8c26c
	Dtlink_t	**t, **endt, *l;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
Packit Service a8c26c
	{	if(!(l = *t) )
Packit Service a8c26c
			continue;
Packit Service a8c26c
		hash->here = l;
Packit Service a8c26c
		return _DTOBJ(dt->disc, l);
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	return NIL(Void_t*);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Void_t* hnext(Dt_t* dt, Dtlink_t* l)
Packit Service a8c26c
{
Packit Service a8c26c
	Dtlink_t	**t, **endt, *next;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	if((next = l->_rght) )
Packit Service a8c26c
	{	hash->here = next;
Packit Service a8c26c
		return _DTOBJ(dt->disc, next);
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
	{	t = hash->htbl + (l->_hash & (hash->tblz-1)) + 1;
Packit Service a8c26c
		endt = hash->htbl + hash->tblz;
Packit Service a8c26c
		for(; t < endt; ++t)
Packit Service a8c26c
		{	if(!(l = *t) )
Packit Service a8c26c
				continue;
Packit Service a8c26c
			hash->here = l;
Packit Service a8c26c
			return _DTOBJ(dt->disc, l);
Packit Service a8c26c
		}
Packit Service a8c26c
		return NIL(Void_t*);
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Void_t* hflatten(Dt_t* dt, int type)
Packit Service a8c26c
{
Packit Service a8c26c
	Dtlink_t	**t, **endt, *head, *tail, *l;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	if(type == DT_FLATTEN || type == DT_EXTRACT)
Packit Service a8c26c
	{	head = tail = NIL(Dtlink_t*);
Packit Service a8c26c
		for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
Packit Service a8c26c
		{	for(l = *t; l; l = l->_rght)
Packit Service a8c26c
			{	if(tail)
Packit Service a8c26c
					tail = (tail->_rght = l);
Packit Service a8c26c
				else	head = tail = l;
Packit Service a8c26c
Packit Service a8c26c
				*t = type == DT_FLATTEN ? tail : NIL(Dtlink_t*);
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
Packit Service a8c26c
		if(type == DT_FLATTEN)
Packit Service a8c26c
		{	hash->here = head;
Packit Service a8c26c
			hash->type |= H_FLATTEN;
Packit Service a8c26c
		}
Packit Service a8c26c
		else	hash->data.size = 0;
Packit Service a8c26c
Packit Service a8c26c
		return (Void_t*)head;
Packit Service a8c26c
	}
Packit Service a8c26c
	else /* restoring a previous flattened list */
Packit Service a8c26c
	{	head = hash->here;
Packit Service a8c26c
		for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
Packit Service a8c26c
		{	if(*t == NIL(Dtlink_t*))
Packit Service a8c26c
				continue;
Packit Service a8c26c
Packit Service a8c26c
			/* find the tail of the list for this slot */
Packit Service a8c26c
			for(l = head; l && l != *t; l = l->_rght)
Packit Service a8c26c
				;
Packit Service a8c26c
			if(!l) /* something is seriously wrong */
Packit Service a8c26c
				return NIL(Void_t*);
Packit Service a8c26c
Packit Service a8c26c
			*t = head; /* head of list for this slot */
Packit Service a8c26c
			head = l->_rght; /* head of next list */
Packit Service a8c26c
			l->_rght = NIL(Dtlink_t*);
Packit Service a8c26c
		}
Packit Service a8c26c
Packit Service a8c26c
		hash->here = NIL(Dtlink_t*);
Packit Service a8c26c
		hash->type &= ~H_FLATTEN;
Packit Service a8c26c
Packit Service a8c26c
		return NIL(Void_t*);
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Void_t* hlist(Dt_t* dt, Dtlink_t* list, int type)
Packit Service a8c26c
{
Packit Service a8c26c
	Void_t		*obj;
Packit Service a8c26c
	Dtlink_t	*l, *next;
Packit Service a8c26c
	Dtdisc_t	*disc = dt->disc;
Packit Service a8c26c
Packit Service a8c26c
	if(type&DT_FLATTEN)
Packit Service a8c26c
		return hflatten(dt, DT_FLATTEN);
Packit Service a8c26c
	else if(type&DT_EXTRACT)
Packit Service a8c26c
		return hflatten(dt, DT_EXTRACT);
Packit Service a8c26c
	else /* if(type&DT_RESTORE) */
Packit Service a8c26c
	{	dt->data->size = 0;
Packit Service a8c26c
		for(l = list; l; l = next)
Packit Service a8c26c
		{	next = l->_rght;
Packit Service a8c26c
			obj = _DTOBJ(disc,l);
Packit Service a8c26c
			if((*dt->meth->searchf)(dt, (Void_t*)l, DT_RELINK) == obj)
Packit Service a8c26c
				dt->data->size += 1;
Packit Service a8c26c
		}
Packit Service a8c26c
		return (Void_t*)list;
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Void_t* hstat(Dt_t* dt, Dtstat_t* st)
Packit Service a8c26c
{
Packit Service a8c26c
	ssize_t		n;
Packit Service a8c26c
	Dtlink_t	**t, **endt, *l;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	if(st)
Packit Service a8c26c
	{	memset(st, 0, sizeof(Dtstat_t));
Packit Service a8c26c
		st->meth  = dt->meth->type;
Packit Service a8c26c
		st->size  = hash->data.size;
Packit Service a8c26c
		st->space = sizeof(Dthash_t) + hash->tblz*sizeof(Dtlink_t*) +
Packit Service a8c26c
			    (dt->disc->link >= 0 ? 0 : hash->data.size*sizeof(Dthold_t));
Packit Service a8c26c
Packit Service a8c26c
		for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
Packit Service a8c26c
		{	for(n = 0, l = *t; l; l = l->_rght)
Packit Service a8c26c
				n += 1;
Packit Service a8c26c
			st->mlev = n > st->mlev ? n : st->mlev;
Packit Service a8c26c
			if(n < DT_MAXSIZE) /* if chain length is small */
Packit Service a8c26c
			{	st->msize = n > st->msize ? n : st->msize;
Packit Service a8c26c
				st->lsize[n] += n;
Packit Service a8c26c
			}
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	return (Void_t*)hash->data.size;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#if __STD_C
Packit Service a8c26c
static Void_t* dthashchain(Dt_t* dt, Void_t* obj, int type)
Packit Service a8c26c
#else
Packit Service a8c26c
static Void_t* dthashchain(dt,obj,type)
Packit Service a8c26c
Dt_t*	dt;
Packit Service a8c26c
Void_t*	obj;
Packit Service a8c26c
int	type;
Packit Service a8c26c
#endif
Packit Service a8c26c
{
Packit Service a8c26c
	Dtlink_t	*lnk, *pp, *ll, *p, *l, **tbl;
Packit Service a8c26c
	Void_t		*key, *k, *o;
Packit Service a8c26c
	uint		hsh;
Packit Service a8c26c
	Dtdisc_t	*disc = dt->disc;
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	type = DTTYPE(dt,type); /* map type for upward compatibility */
Packit Service a8c26c
	if(!(type&DT_OPERATIONS) )
Packit Service a8c26c
		return NIL(Void_t*);
Packit Service a8c26c
Packit Service a8c26c
	DTSETLOCK(dt);
Packit Service a8c26c
Packit Service a8c26c
	if(!hash->htbl && htable(dt) < 0 ) /* initialize hash table */
Packit Service a8c26c
		DTRETURN(obj, NIL(Void_t*));
Packit Service a8c26c
Packit Service a8c26c
	if(hash->type&H_FLATTEN) /* restore flattened list */
Packit Service a8c26c
		hflatten(dt, 0);
Packit Service a8c26c
Packit Service a8c26c
	if(type&(DT_FIRST|DT_LAST|DT_CLEAR|DT_EXTRACT|DT_RESTORE|DT_FLATTEN|DT_STAT) )
Packit Service a8c26c
	{	if(type&(DT_FIRST|DT_LAST) )
Packit Service a8c26c
			DTRETURN(obj, hfirst(dt));
Packit Service a8c26c
		else if(type&DT_CLEAR)
Packit Service a8c26c
			DTRETURN(obj, hclear(dt));
Packit Service a8c26c
		else if(type&DT_STAT)
Packit Service a8c26c
			DTRETURN(obj, hstat(dt, (Dtstat_t*)obj));
Packit Service a8c26c
		else /*if(type&(DT_EXTRACT|DT_RESTORE|DT_FLATTEN))*/
Packit Service a8c26c
			DTRETURN(obj, hlist(dt, (Dtlink_t*)obj, type));
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	lnk = hash->here; /* fingered object */
Packit Service a8c26c
	hash->here = NIL(Dtlink_t*);
Packit Service a8c26c
Packit Service a8c26c
	if(lnk && obj == _DTOBJ(disc,lnk))
Packit Service a8c26c
	{	if(type&DT_SEARCH)
Packit Service a8c26c
			DTRETURN(obj, obj);
Packit Service a8c26c
		else if(type&(DT_NEXT|DT_PREV) )
Packit Service a8c26c
			DTRETURN(obj, hnext(dt,lnk));
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
	if(type&DT_RELINK)
Packit Service a8c26c
	{	lnk = (Dtlink_t*)obj;
Packit Service a8c26c
		obj = _DTOBJ(disc,lnk);
Packit Service a8c26c
		key = _DTKEY(disc,obj);
Packit Service a8c26c
	}
Packit Service a8c26c
	else 
Packit Service a8c26c
	{	lnk = NIL(Dtlink_t*);
Packit Service a8c26c
		if((type&DT_MATCH) )
Packit Service a8c26c
		{	key = obj;
Packit Service a8c26c
			obj = NIL(Void_t*);
Packit Service a8c26c
		}
Packit Service a8c26c
		else	key = _DTKEY(disc,obj);
Packit Service a8c26c
	}
Packit Service a8c26c
	hsh = _DTHSH(dt,key,disc);
Packit Service a8c26c
Packit Service a8c26c
	tbl = hash->htbl + (hsh & (hash->tblz-1));
Packit Service a8c26c
	pp = ll = NIL(Dtlink_t*);
Packit Service a8c26c
	for(p = NIL(Dtlink_t*), l = *tbl; l; p = l, l = l->_rght)
Packit Service a8c26c
	{	if(hsh == l->_hash)
Packit Service a8c26c
		{	o = _DTOBJ(disc,l); k = _DTKEY(disc,o);
Packit Service a8c26c
			if(_DTCMP(dt, key, k, disc) != 0 )
Packit Service a8c26c
				continue;
Packit Service a8c26c
			else if((type&(DT_REMOVE|DT_NEXT|DT_PREV)) && o != obj )
Packit Service a8c26c
			{	if(type&(DT_NEXT|DT_PREV) )
Packit Service a8c26c
					{ pp = p; ll = l; }
Packit Service a8c26c
				continue;
Packit Service a8c26c
			}
Packit Service a8c26c
			else	break;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	if(l) /* found an object, use it */ 
Packit Service a8c26c
		{ pp = p; ll = l; }
Packit Service a8c26c
Packit Service a8c26c
	if(ll) /* found object */
Packit Service a8c26c
	{	if(type&(DT_SEARCH|DT_MATCH|DT_ATLEAST|DT_ATMOST) )
Packit Service a8c26c
		{	hash->here = ll;
Packit Service a8c26c
			DTRETURN(obj, _DTOBJ(disc,ll));
Packit Service a8c26c
		}
Packit Service a8c26c
		else if(type & (DT_NEXT|DT_PREV) )
Packit Service a8c26c
			DTRETURN(obj, hnext(dt, ll));
Packit Service a8c26c
		else if(type & (DT_DELETE|DT_DETACH|DT_REMOVE) )
Packit Service a8c26c
		{	hash->data.size -= 1;
Packit Service a8c26c
			if(pp)
Packit Service a8c26c
				pp->_rght = ll->_rght;
Packit Service a8c26c
			else	*tbl = ll->_rght;
Packit Service a8c26c
			_dtfree(dt, ll, type);
Packit Service a8c26c
			DTRETURN(obj, _DTOBJ(disc,ll));
Packit Service a8c26c
		}
Packit Service a8c26c
		else
Packit Service a8c26c
		{	/**/DEBUG_ASSERT(type&(DT_INSERT|DT_ATTACH|DT_APPEND|DT_RELINK));
Packit Service a8c26c
			if(!(dt->meth->type&DT_BAG) )
Packit Service a8c26c
			{	if(type&(DT_INSERT|DT_APPEND|DT_ATTACH) )
Packit Service a8c26c
					type |= DT_SEARCH; /* for announcement */
Packit Service a8c26c
				else if(lnk && (type&DT_RELINK) )
Packit Service a8c26c
					_dtfree(dt, lnk, DT_DELETE);
Packit Service a8c26c
				DTRETURN(obj, _DTOBJ(disc,ll));
Packit Service a8c26c
			}
Packit Service a8c26c
			else	goto do_insert;
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	else /* no matching object */
Packit Service a8c26c
	{	if(!(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_RELINK)) )
Packit Service a8c26c
			DTRETURN(obj, NIL(Void_t*));
Packit Service a8c26c
Packit Service a8c26c
	do_insert: /* inserting a new object */
Packit Service a8c26c
		if(hash->tblz < HLOAD(hash->data.size) )
Packit Service a8c26c
		{	htable(dt); /* resize table */
Packit Service a8c26c
			tbl = hash->htbl + (hsh & (hash->tblz-1));
Packit Service a8c26c
		}
Packit Service a8c26c
Packit Service a8c26c
		if(!lnk) /* inserting a new object */
Packit Service a8c26c
		{	if(!(lnk = _dtmake(dt, obj, type)) )
Packit Service a8c26c
				DTRETURN(obj, NIL(Void_t*));
Packit Service a8c26c
			hash->data.size += 1;
Packit Service a8c26c
		}
Packit Service a8c26c
Packit Service a8c26c
		lnk->_hash = hsh; /* memoize the hash value */
Packit Service a8c26c
		lnk->_rght = *tbl; *tbl = lnk;
Packit Service a8c26c
Packit Service a8c26c
		hash->here = lnk;
Packit Service a8c26c
		DTRETURN(obj, _DTOBJ(disc,lnk));
Packit Service a8c26c
	}
Packit Service a8c26c
Packit Service a8c26c
dt_return:
Packit Service a8c26c
	DTANNOUNCE(dt, obj, type);
Packit Service a8c26c
	DTCLRLOCK(dt);
Packit Service a8c26c
	return obj;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static int hashevent(Dt_t* dt, int event, Void_t* arg)
Packit Service a8c26c
{
Packit Service a8c26c
	Dthash_t	*hash = (Dthash_t*)dt->data;
Packit Service a8c26c
Packit Service a8c26c
	if(event == DT_OPEN)
Packit Service a8c26c
	{	if(hash)
Packit Service a8c26c
			return 0;
Packit Service a8c26c
		if(!(hash = (Dthash_t*)(*dt->memoryf)(dt, 0, sizeof(Dthash_t), dt->disc)) )
Packit Service a8c26c
		{	DTERROR(dt, "Error in allocating a hash table with chaining");
Packit Service a8c26c
			return -1;
Packit Service a8c26c
		}
Packit Service a8c26c
		memset(hash, 0, sizeof(Dthash_t));
Packit Service a8c26c
		dt->data = (Dtdata_t*)hash;
Packit Service a8c26c
		return 1;
Packit Service a8c26c
	}
Packit Service a8c26c
	else if(event == DT_CLOSE)
Packit Service a8c26c
	{	if(!hash)
Packit Service a8c26c
			return 0;
Packit Service a8c26c
		if(hash->data.size > 0 )
Packit Service a8c26c
			(void)hclear(dt);
Packit Service a8c26c
		if(hash->htbl)
Packit Service a8c26c
			(void)(*dt->memoryf)(dt, hash->htbl, 0, dt->disc);
Packit Service a8c26c
		(void)(*dt->memoryf)(dt, hash, 0, dt->disc);
Packit Service a8c26c
		dt->data = NIL(Dtdata_t*);
Packit Service a8c26c
		return 0;
Packit Service a8c26c
	}
Packit Service a8c26c
	else	return 0;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static Dtmethod_t	_Dtset = { dthashchain, DT_SET, hashevent, "Dtset" };
Packit Service a8c26c
static Dtmethod_t	_Dtbag = { dthashchain, DT_BAG, hashevent, "Dtbag" };
Packit Service a8c26c
__DEFINE__(Dtmethod_t*,Dtset,&_Dtset);
Packit Service a8c26c
__DEFINE__(Dtmethod_t*,Dtbag,&_Dtbag);
Packit Service a8c26c
Packit Service a8c26c
/* backwards compatibility */
Packit Service a8c26c
#undef	Dthash
Packit Service a8c26c
#if defined(__EXPORT__)
Packit Service a8c26c
__EXPORT__
Packit Service a8c26c
#endif
Packit Service a8c26c
__DEFINE__(Dtmethod_t*,Dthash,&_Dtset);
Packit Service a8c26c
Packit Service a8c26c
#ifdef NoF
Packit Service a8c26c
NoF(dthashchain)
Packit Service a8c26c
#endif