1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2009 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #include "dthdr.h" 23 24 /* Change discipline. 25 ** dt : dictionary 26 ** disc : discipline 27 ** 28 ** Written by Kiem-Phong Vo (5/26/96) 29 */ 30 31 #if __STD_C 32 static Void_t* dtmemory(Dt_t* dt,Void_t* addr,size_t size,Dtdisc_t* disc) 33 #else 34 static Void_t* dtmemory(dt, addr, size, disc) 35 Dt_t* dt; /* dictionary */ 36 Void_t* addr; /* address to be manipulate */ 37 size_t size; /* size to obtain */ 38 Dtdisc_t* disc; /* discipline */ 39 #endif 40 { 41 if(addr) 42 { if(size == 0) 43 { free(addr); 44 return NIL(Void_t*); 45 } 46 else return realloc(addr,size); 47 } 48 else return size > 0 ? malloc(size) : NIL(Void_t*); 49 } 50 51 #if __STD_C 52 Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type) 53 #else 54 Dtdisc_t* dtdisc(dt,disc,type) 55 Dt_t* dt; 56 Dtdisc_t* disc; 57 int type; 58 #endif 59 { 60 reg Dtsearch_f searchf; 61 reg Dtlink_t *r, *t; 62 reg char* k; 63 reg Dtdisc_t* old; 64 65 if(!(old = dt->disc) ) /* initialization call from dtopen() */ 66 { dt->disc = disc; 67 if(!(dt->memoryf = disc->memoryf) ) 68 dt->memoryf = dtmemory; 69 return disc; 70 } 71 72 if(!disc) /* only want to know current discipline */ 73 return old; 74 75 searchf = dt->meth->searchf; 76 77 UNFLATTEN(dt); 78 79 if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0) 80 return NIL(Dtdisc_t*); 81 82 dt->disc = disc; 83 if(!(dt->memoryf = disc->memoryf) ) 84 dt->memoryf = dtmemory; 85 86 if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST)) 87 goto done; 88 else if(dt->data->type&DT_BAG) 89 { if(type&DT_SAMEHASH) 90 goto done; 91 else goto dt_renew; 92 } 93 else if(dt->data->type&(DT_SET|DT_BAG)) 94 { if((type&DT_SAMEHASH) && (type&DT_SAMECMP)) 95 goto done; 96 else goto dt_renew; 97 } 98 else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/ 99 { if(type&DT_SAMECMP) 100 goto done; 101 dt_renew: 102 r = dtflatten(dt); 103 dt->data->type &= ~DT_FLATTEN; 104 dt->data->here = NIL(Dtlink_t*); 105 dt->data->size = 0; 106 107 if(dt->data->type&(DT_SET|DT_BAG)) 108 { reg Dtlink_t **s, **ends; 109 ends = (s = dt->data->htab) + dt->data->ntab; 110 while(s < ends) 111 *s++ = NIL(Dtlink_t*); 112 } 113 114 /* reinsert them */ 115 while(r) 116 { t = r->right; 117 if(!(type&DT_SAMEHASH)) /* new hash value */ 118 { k = (char*)_DTOBJ(r,disc->link); 119 k = _DTKEY((Void_t*)k,disc->key,disc->size); 120 r->hash = _DTHSH(dt,k,disc,disc->size); 121 } 122 (void)(*searchf)(dt,(Void_t*)r,DT_RENEW); 123 r = t; 124 } 125 } 126 127 done: 128 return old; 129 } 130