| 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 | |