/* This software may only be used by you under license from AT&T Corp. ("AT&T"). A copy of AT&T's Source Code Agreement is available at AT&T's Internet website having the URL: If you received this software without first entering into a license with AT&T, you have an infringing copy of this software and cannot use it without violating AT&T's intellectual property rights. */ #include "dthdr.h" #ifdef DMALLOC #include "dmalloc.h" #endif /* Change discipline. ** dt : dictionary ** disc : discipline ** ** Written by Kiem-Phong Vo (5/26/96) */ #if __STD_C static Void_t* dtmemory(Dt_t* dt,Void_t* addr,size_t size,Dtdisc_t* disc) #else static Void_t* dtmemory(dt, addr, size, disc) Dt_t* dt; /* dictionary */ Void_t* addr; /* address to be manipulate */ size_t size; /* size to obtain */ Dtdisc_t* disc; /* discipline */ #endif { if(addr) { if(size == 0) { free(addr); return NIL(Void_t*); } else return realloc(addr,size); } else return size > 0 ? malloc(size) : NIL(Void_t*); } #if __STD_C Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type) #else Dtdisc_t* dtdisc(dt,disc,type) Dt_t* dt; Dtdisc_t* disc; int type; #endif { reg Dtsearch_f searchf; reg Dtlink_t *r, *t; reg char* k; reg Dtdisc_t* old; if(!(old = dt->disc) ) /* initialization call from dtopen() */ { dt->disc = disc; if(!(dt->memoryf = disc->memoryf) ) dt->memoryf = dtmemory; return disc; } if(!disc) /* only want to know current discipline */ return old; searchf = dt->meth->searchf; UNFLATTEN(dt); if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0) return NIL(Dtdisc_t*); dt->disc = disc; if(!(dt->memoryf = disc->memoryf) ) dt->memoryf = dtmemory; if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST)) goto done; else if(dt->data->type&DT_BAG) { if(type&DT_SAMEHASH) goto done; else goto dt_renew; } else if(dt->data->type&(DT_SET|DT_BAG)) { if((type&DT_SAMEHASH) && (type&DT_SAMECMP)) goto done; else goto dt_renew; } else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/ { if(type&DT_SAMECMP) goto done; dt_renew: r = dtflatten(dt); dt->data->type &= ~DT_FLATTEN; dt->data->here = NIL(Dtlink_t*); dt->data->size = 0; if(dt->data->type&(DT_SET|DT_BAG)) { reg Dtlink_t **s, **ends; ends = (s = dt->data->htab) + dt->data->ntab; while(s < ends) *s++ = NIL(Dtlink_t*); } /* reinsert them */ while(r) { t = r->right; if(!(type&DT_SAMEHASH)) /* new hash value */ { k = (char*)OBJ(r,disc->link); k = KEY((Void_t*)k,disc->key,disc->size); r->hash = HASH(dt,k,disc,disc->size); } (void)(*searchf)(dt,(Void_t*)r,DT_RENEW); r = t; } } done: return old; }