1 | #include "dthdr.h" |
2 | |
3 | /* Change discipline. |
4 | ** dt : dictionary |
5 | ** disc : discipline |
6 | ** |
7 | ** Written by Kiem-Phong Vo (5/26/96) |
8 | */ |
9 | |
10 | static void* dtmemory(Dt_t* dt,void* addr,size_t size,Dtdisc_t* disc) |
11 | { |
12 | if(addr) |
13 | { if(size == 0) |
14 | { free(addr); |
15 | return NIL(void*); |
16 | } |
17 | else return realloc(addr,size); |
18 | } |
19 | else return size > 0 ? malloc(size) : NIL(void*); |
20 | } |
21 | |
22 | Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type) |
23 | { |
24 | reg Dtsearch_f searchf; |
25 | reg Dtlink_t *r, *t; |
26 | reg char* k; |
27 | reg Dtdisc_t* old; |
28 | |
29 | if(!(old = dt->disc) ) /* initialization call from dtopen() */ |
30 | { dt->disc = disc; |
31 | if(!(dt->memoryf = disc->memoryf) ) |
32 | dt->memoryf = dtmemory; |
33 | return disc; |
34 | } |
35 | |
36 | if(!disc) /* only want to know current discipline */ |
37 | return old; |
38 | |
39 | searchf = dt->meth->searchf; |
40 | |
41 | UNFLATTEN(dt); |
42 | |
43 | if(old->eventf && (*old->eventf)(dt,DT_DISC,(void*)disc,old) < 0) |
44 | return NIL(Dtdisc_t*); |
45 | |
46 | dt->disc = disc; |
47 | if(!(dt->memoryf = disc->memoryf) ) |
48 | dt->memoryf = dtmemory; |
49 | |
50 | if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST)) |
51 | goto done; |
52 | else if(dt->data->type&DT_BAG) |
53 | { if(type&DT_SAMEHASH) |
54 | goto done; |
55 | else goto dt_renew; |
56 | } |
57 | else if(dt->data->type&(DT_SET|DT_BAG)) |
58 | { if((type&DT_SAMEHASH) && (type&DT_SAMECMP)) |
59 | goto done; |
60 | else goto dt_renew; |
61 | } |
62 | else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/ |
63 | { if(type&DT_SAMECMP) |
64 | goto done; |
65 | dt_renew: |
66 | r = dtflatten(dt); |
67 | dt->data->type &= ~DT_FLATTEN; |
68 | dt->data->here = NIL(Dtlink_t*); |
69 | dt->data->size = 0; |
70 | |
71 | if(dt->data->type&(DT_SET|DT_BAG)) |
72 | { reg Dtlink_t **s, **ends; |
73 | ends = (s = dt->data->htab) + dt->data->ntab; |
74 | while(s < ends) |
75 | *s++ = NIL(Dtlink_t*); |
76 | } |
77 | |
78 | /* reinsert them */ |
79 | while(r) |
80 | { t = r->right; |
81 | if(!(type&DT_SAMEHASH)) /* new hash value */ |
82 | { k = (char*)_DTOBJ(r,disc->link); |
83 | k = _DTKEY((void*)k,disc->key,disc->size); |
84 | r->hash = _DTHSH(dt,k,disc,disc->size); |
85 | } |
86 | (void)(*searchf)(dt,(void*)r,DT_RENEW); |
87 | r = t; |
88 | } |
89 | } |
90 | |
91 | done: |
92 | return old; |
93 | } |
94 | |