14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #include "dthdr.h"
234887Schin
244887Schin /* Change discipline.
254887Schin ** dt : dictionary
264887Schin ** disc : discipline
274887Schin **
284887Schin ** Written by Kiem-Phong Vo (5/26/96)
294887Schin */
304887Schin
314887Schin #if __STD_C
dtmemory(Dt_t * dt,Void_t * addr,size_t size,Dtdisc_t * disc)324887Schin static Void_t* dtmemory(Dt_t* dt,Void_t* addr,size_t size,Dtdisc_t* disc)
334887Schin #else
344887Schin static Void_t* dtmemory(dt, addr, size, disc)
354887Schin Dt_t* dt; /* dictionary */
364887Schin Void_t* addr; /* address to be manipulate */
374887Schin size_t size; /* size to obtain */
384887Schin Dtdisc_t* disc; /* discipline */
394887Schin #endif
404887Schin {
414887Schin if(addr)
424887Schin { if(size == 0)
434887Schin { free(addr);
444887Schin return NIL(Void_t*);
454887Schin }
464887Schin else return realloc(addr,size);
474887Schin }
484887Schin else return size > 0 ? malloc(size) : NIL(Void_t*);
494887Schin }
504887Schin
514887Schin #if __STD_C
dtdisc(Dt_t * dt,Dtdisc_t * disc,int type)524887Schin Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type)
534887Schin #else
544887Schin Dtdisc_t* dtdisc(dt,disc,type)
554887Schin Dt_t* dt;
564887Schin Dtdisc_t* disc;
574887Schin int type;
584887Schin #endif
594887Schin {
604887Schin reg Dtsearch_f searchf;
614887Schin reg Dtlink_t *r, *t;
624887Schin reg char* k;
634887Schin reg Dtdisc_t* old;
644887Schin
654887Schin if(!(old = dt->disc) ) /* initialization call from dtopen() */
664887Schin { dt->disc = disc;
674887Schin if(!(dt->memoryf = disc->memoryf) )
684887Schin dt->memoryf = dtmemory;
694887Schin return disc;
704887Schin }
714887Schin
724887Schin if(!disc) /* only want to know current discipline */
734887Schin return old;
744887Schin
754887Schin searchf = dt->meth->searchf;
764887Schin
774887Schin UNFLATTEN(dt);
784887Schin
794887Schin if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0)
804887Schin return NIL(Dtdisc_t*);
814887Schin
824887Schin dt->disc = disc;
834887Schin if(!(dt->memoryf = disc->memoryf) )
844887Schin dt->memoryf = dtmemory;
854887Schin
864887Schin if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST))
874887Schin goto done;
884887Schin else if(dt->data->type&DT_BAG)
894887Schin { if(type&DT_SAMEHASH)
904887Schin goto done;
914887Schin else goto dt_renew;
924887Schin }
934887Schin else if(dt->data->type&(DT_SET|DT_BAG))
944887Schin { if((type&DT_SAMEHASH) && (type&DT_SAMECMP))
954887Schin goto done;
964887Schin else goto dt_renew;
974887Schin }
984887Schin else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/
994887Schin { if(type&DT_SAMECMP)
1004887Schin goto done;
1014887Schin dt_renew:
1024887Schin r = dtflatten(dt);
1034887Schin dt->data->type &= ~DT_FLATTEN;
1044887Schin dt->data->here = NIL(Dtlink_t*);
1054887Schin dt->data->size = 0;
1064887Schin
1074887Schin if(dt->data->type&(DT_SET|DT_BAG))
1084887Schin { reg Dtlink_t **s, **ends;
1094887Schin ends = (s = dt->data->htab) + dt->data->ntab;
1104887Schin while(s < ends)
1114887Schin *s++ = NIL(Dtlink_t*);
1124887Schin }
1134887Schin
1144887Schin /* reinsert them */
1154887Schin while(r)
1164887Schin { t = r->right;
1174887Schin if(!(type&DT_SAMEHASH)) /* new hash value */
1184887Schin { k = (char*)_DTOBJ(r,disc->link);
1194887Schin k = _DTKEY((Void_t*)k,disc->key,disc->size);
1204887Schin r->hash = _DTHSH(dt,k,disc,disc->size);
1214887Schin }
1224887Schin (void)(*searchf)(dt,(Void_t*)r,DT_RENEW);
1234887Schin r = t;
1244887Schin }
1254887Schin }
1264887Schin
1274887Schin done:
1284887Schin return old;
1294887Schin }
130