Graphviz 2.29.20120208.0545
lib/cdt/dtdisc.c
Go to the documentation of this file.
00001 #include        "dthdr.h"
00002 
00003 /*      Change discipline.
00004 **      dt :    dictionary
00005 **      disc :  discipline
00006 **
00007 **      Written by Kiem-Phong Vo (5/26/96)
00008 */
00009 
00010 #if __STD_C
00011 static Void_t* dtmemory(Dt_t* dt,Void_t* addr,size_t size,Dtdisc_t* disc)
00012 #else
00013 static Void_t* dtmemory(dt, addr, size, disc)
00014 Dt_t*           dt;     /* dictionary                   */
00015 Void_t*         addr;   /* address to be manipulate     */
00016 size_t          size;   /* size to obtain               */
00017 Dtdisc_t*       disc;   /* discipline                   */
00018 #endif
00019 {
00020         if(addr)
00021         {       if(size == 0)
00022                 {       free(addr);
00023                         return NIL(Void_t*);
00024                 }
00025                 else    return realloc(addr,size);
00026         }
00027         else    return size > 0 ? malloc(size) : NIL(Void_t*);
00028 }
00029 
00030 #if __STD_C
00031 Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type)
00032 #else
00033 Dtdisc_t* dtdisc(dt,disc,type)
00034 Dt_t*           dt;
00035 Dtdisc_t*       disc;
00036 int             type;
00037 #endif
00038 {
00039         reg Dtsearch_f  searchf;
00040         reg Dtlink_t    *r, *t;
00041         reg char*       k;
00042         reg Dtdisc_t*   old;
00043 
00044         if(!(old = dt->disc) )  /* initialization call from dtopen() */
00045         {       dt->disc = disc;
00046                 if(!(dt->memoryf = disc->memoryf) )
00047                         dt->memoryf = dtmemory;
00048                 return disc;
00049         }
00050 
00051         if(!disc)       /* only want to know current discipline */
00052                 return old;
00053 
00054         searchf = dt->meth->searchf;
00055 
00056         UNFLATTEN(dt);
00057 
00058         if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0)
00059                 return NIL(Dtdisc_t*);
00060 
00061         dt->disc = disc;
00062         if(!(dt->memoryf = disc->memoryf) )
00063                 dt->memoryf = dtmemory;
00064 
00065         if(dt->data->type&(DT_STACK|DT_QUEUE|DT_LIST))
00066                 goto done;
00067         else if(dt->data->type&DT_BAG)
00068         {       if(type&DT_SAMEHASH)
00069                         goto done;
00070                 else    goto dt_renew;
00071         }
00072         else if(dt->data->type&(DT_SET|DT_BAG))
00073         {       if((type&DT_SAMEHASH) && (type&DT_SAMECMP))
00074                         goto done;
00075                 else    goto dt_renew;
00076         }
00077         else /*if(dt->data->type&(DT_OSET|DT_OBAG))*/
00078         {       if(type&DT_SAMECMP)
00079                         goto done;
00080         dt_renew:
00081                 r = dtflatten(dt);
00082                 dt->data->type &= ~DT_FLATTEN;
00083                 dt->data->here = NIL(Dtlink_t*);
00084                 dt->data->size = 0;
00085 
00086                 if(dt->data->type&(DT_SET|DT_BAG))
00087                 {       reg Dtlink_t    **s, **ends;
00088                         ends = (s = dt->data->htab) + dt->data->ntab;
00089                         while(s < ends)
00090                                 *s++ = NIL(Dtlink_t*);
00091                 }
00092 
00093                 /* reinsert them */
00094                 while(r)
00095                 {       t = r->right;
00096                         if(!(type&DT_SAMEHASH)) /* new hash value */
00097                         {       k = (char*)_DTOBJ(r,disc->link);
00098                                 k = _DTKEY((Void_t*)k,disc->key,disc->size);
00099                                 r->hash = _DTHSH(dt,k,disc,disc->size);
00100                         }
00101                         (void)(*searchf)(dt,(Void_t*)r,DT_RENEW);
00102                         r = t;
00103                 }
00104         }
00105 
00106 done:
00107         return old;
00108 }