Graphviz 2.29.20120208.0545
lib/cdt/dtmethod.c
Go to the documentation of this file.
00001 #include        "dthdr.h"
00002 
00003 /*      Change search method.
00004 **
00005 **      Written by Kiem-Phong Vo (05/25/96)
00006 */
00007 
00008 #if __STD_C
00009 Dtmethod_t* dtmethod(Dt_t* dt, Dtmethod_t* meth)
00010 #else
00011 Dtmethod_t* dtmethod(dt, meth)
00012 Dt_t*           dt;
00013 Dtmethod_t*     meth;
00014 #endif
00015 {
00016         reg Dtlink_t    *list, *r;
00017         reg Dtdisc_t*   disc = dt->disc;
00018         reg Dtmethod_t* oldmeth = dt->meth;
00019 
00020         if(!meth || meth->type == oldmeth->type)
00021                 return oldmeth;
00022 
00023         if(disc->eventf &&
00024            (*disc->eventf)(dt,DT_METH,(Void_t*)meth,disc) < 0)
00025                 return NIL(Dtmethod_t*);
00026 
00027         dt->data->minp = 0;
00028 
00029         /* get the list of elements */
00030         list = dtflatten(dt);
00031 
00032         if(dt->data->type&(DT_LIST|DT_STACK|DT_QUEUE) )
00033                 dt->data->head = NIL(Dtlink_t*);
00034         else if(dt->data->type&(DT_SET|DT_BAG) )
00035         {       if(dt->data->ntab > 0)
00036                         (*dt->memoryf)(dt,(Void_t*)dt->data->htab,0,disc);
00037                 dt->data->ntab = 0;
00038                 dt->data->htab = NIL(Dtlink_t**);
00039         }
00040 
00041         dt->data->here = NIL(Dtlink_t*);
00042         dt->data->type = (dt->data->type&~(DT_METHODS|DT_FLATTEN)) | meth->type;
00043         dt->meth = meth;
00044         if(dt->searchf == oldmeth->searchf)
00045                 dt->searchf = meth->searchf;
00046 
00047         if(meth->type&(DT_LIST|DT_STACK|DT_QUEUE) )
00048         {       if(!(oldmeth->type&(DT_LIST|DT_STACK|DT_QUEUE)) )
00049                 {       if((r = list) )
00050                         {       reg Dtlink_t*   t;
00051                                 for(t = r->right; t; r = t, t = t->right )
00052                                         t->left = r;
00053                                 list->left = r;
00054                         }
00055                 }
00056                 dt->data->head = list;
00057         }
00058         else if(meth->type&(DT_OSET|DT_OBAG))
00059         {       dt->data->size = 0;
00060                 while(list)
00061                 {       r = list->right;
00062                         (*meth->searchf)(dt,(Void_t*)list,DT_RENEW);
00063                         list = r;
00064                 }
00065         }
00066         else if(!((meth->type&DT_BAG) && (oldmeth->type&DT_SET)) )
00067         {       int     rehash;
00068                 if((meth->type&(DT_SET|DT_BAG)) && !(oldmeth->type&(DT_SET|DT_BAG)))
00069                         rehash = 1;
00070                 else    rehash = 0;
00071 
00072                 dt->data->size = dt->data->loop = 0;
00073                 while(list)
00074                 {       r = list->right;
00075                         if(rehash)
00076                         {       reg Void_t* key = _DTOBJ(list,disc->link);
00077                                 key = _DTKEY(key,disc->key,disc->size);
00078                                 list->hash = _DTHSH(dt,key,disc,disc->size);
00079                         }
00080                         (void)(*meth->searchf)(dt,(Void_t*)list,DT_RENEW);
00081                         list = r;
00082                 }
00083         }
00084 
00085         return oldmeth;
00086 }