1#include "dthdr.h"
2
3/* Change search method.
4**
5** Written by Kiem-Phong Vo (05/25/96)
6*/
7
8Dtmethod_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