1 | #include "dthdr.h" |
2 | |
3 | /* Change search method. |
4 | ** |
5 | ** Written by Kiem-Phong Vo (05/25/96) |
6 | */ |
7 | |
8 | Dtmethod_t* dtmethod(Dt_t* dt, Dtmethod_t* meth) |
9 | { |
10 | reg Dtlink_t *list, *r; |
11 | reg Dtdisc_t* disc = dt->disc; |
12 | reg Dtmethod_t* oldmeth = dt->meth; |
13 | |
14 | if(!meth || meth->type == oldmeth->type) |
15 | return oldmeth; |
16 | |
17 | if(disc->eventf && |
18 | (*disc->eventf)(dt,DT_METH,(void*)meth,disc) < 0) |
19 | return NIL(Dtmethod_t*); |
20 | |
21 | dt->data->minp = 0; |
22 | |
23 | /* get the list of elements */ |
24 | list = dtflatten(dt); |
25 | |
26 | if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE) ) |
27 | dt->data->head = NIL(Dtlink_t*); |
28 | else if(dt->data->type&(DT_SET|DT_BAG) ) |
29 | { if(dt->data->ntab > 0) |
30 | (*dt->memoryf)(dt,(void*)dt->data->htab,0,disc); |
31 | dt->data->ntab = 0; |
32 | dt->data->htab = NIL(Dtlink_t**); |
33 | } |
34 | |
35 | dt->data->here = NIL(Dtlink_t*); |
36 | dt->data->type = (dt->data->type&~(DT_METHODS|DT_FLATTEN)) | meth->type; |
37 | dt->meth = meth; |
38 | if(dt->searchf == oldmeth->searchf) |
39 | dt->searchf = meth->searchf; |
40 | |
41 | if(meth->type&(DT_LIST|DT_STACK|DT_QUEUE) ) |
42 | { if(!(oldmeth->type&(DT_LIST|DT_STACK|DT_QUEUE)) ) |
43 | { if((r = list) ) |
44 | { reg Dtlink_t* t; |
45 | for(t = r->right; t; r = t, t = t->right ) |
46 | t->left = r; |
47 | list->left = r; |
48 | } |
49 | } |
50 | dt->data->head = list; |
51 | } |
52 | else if(meth->type&(DT_OSET|DT_OBAG)) |
53 | { dt->data->size = 0; |
54 | while(list) |
55 | { r = list->right; |
56 | (*meth->searchf)(dt,(void*)list,DT_RENEW); |
57 | list = r; |
58 | } |
59 | } |
60 | else if(!((meth->type&DT_BAG) && (oldmeth->type&DT_SET)) ) |
61 | { int rehash; |
62 | if((meth->type&(DT_SET|DT_BAG)) && !(oldmeth->type&(DT_SET|DT_BAG))) |
63 | rehash = 1; |
64 | else rehash = 0; |
65 | |
66 | dt->data->size = dt->data->loop = 0; |
67 | while(list) |
68 | { r = list->right; |
69 | if(rehash) |
70 | { reg void* key = _DTOBJ(list,disc->link); |
71 | key = _DTKEY(key,disc->key,disc->size); |
72 | list->hash = _DTHSH(dt,key,disc,disc->size); |
73 | } |
74 | (void)(*meth->searchf)(dt,(void*)list,DT_RENEW); |
75 | list = r; |
76 | } |
77 | } |
78 | |
79 | return oldmeth; |
80 | } |
81 | |