00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "dthdr.h"
00018
00019 #ifdef DMALLOC
00020 #include "dmalloc.h"
00021 #endif
00022
00023
00024
00025
00026
00027
00028
00029
00030 #if __STD_C
00031 static Void_t *dtmemory(Dt_t * dt, Void_t * addr, size_t size,
00032 Dtdisc_t * disc)
00033 #else
00034 static Void_t *dtmemory(dt, addr, size, disc)
00035 Dt_t *dt;
00036 Void_t *addr;
00037 size_t size;
00038 Dtdisc_t *disc;
00039 #endif
00040 {
00041 if (addr) {
00042 if (size == 0) {
00043 free(addr);
00044 return NIL(Void_t *);
00045 } else
00046 return realloc(addr, size);
00047 } else
00048 return size > 0 ? malloc(size) : NIL(Void_t *);
00049 }
00050
00051 #if __STD_C
00052 Dtdisc_t *dtdisc(Dt_t * dt, Dtdisc_t * disc, int type)
00053 #else
00054 Dtdisc_t *dtdisc(dt, disc, type)
00055 Dt_t *dt;
00056 Dtdisc_t *disc;
00057 int type;
00058 #endif
00059 {
00060 reg Dtsearch_f searchf;
00061 reg Dtlink_t *r, *t;
00062 reg char *k;
00063 reg Dtdisc_t *old;
00064
00065 if (!(old = dt->disc)) {
00066 dt->disc = disc;
00067 if (!(dt->memoryf = disc->memoryf))
00068 dt->memoryf = dtmemory;
00069 return disc;
00070 }
00071
00072 if (!disc)
00073 return old;
00074
00075 searchf = dt->meth->searchf;
00076
00077 UNFLATTEN(dt);
00078
00079 if (old->eventf
00080 && (*old->eventf) (dt, DT_DISC, (Void_t *) disc, old) < 0)
00081 return NIL(Dtdisc_t *);
00082
00083 dt->disc = disc;
00084 if (!(dt->memoryf = disc->memoryf))
00085 dt->memoryf = dtmemory;
00086
00087 if (dt->data->type & (DT_STACK | DT_QUEUE | DT_LIST))
00088 goto done;
00089 else if (dt->data->type & DT_BAG) {
00090 if (type & DT_SAMEHASH)
00091 goto done;
00092 else
00093 goto dt_renew;
00094 } else if (dt->data->type & (DT_SET | DT_BAG)) {
00095 if ((type & DT_SAMEHASH) && (type & DT_SAMECMP))
00096 goto done;
00097 else
00098 goto dt_renew;
00099 } else {
00100 if (type & DT_SAMECMP)
00101 goto done;
00102 dt_renew:
00103 r = dtflatten(dt);
00104 dt->data->type &= ~DT_FLATTEN;
00105 dt->data->here = NIL(Dtlink_t *);
00106 dt->data->size = 0;
00107
00108 if (dt->data->type & (DT_SET | DT_BAG)) {
00109 reg Dtlink_t **s, **ends;
00110 ends = (s = dt->data->htab) + dt->data->ntab;
00111 while (s < ends)
00112 *s++ = NIL(Dtlink_t *);
00113 }
00114
00115
00116 while (r) {
00117 t = r->right;
00118 if (!(type & DT_SAMEHASH)) {
00119 k = (char *) OBJ(r, disc->link);
00120 k = KEY((Void_t *) k, disc->key, disc->size);
00121 r->hash = HASH(dt, k, disc, disc->size);
00122 }
00123 (void) (*searchf) (dt, (Void_t *) r, DT_RENEW);
00124 r = t;
00125 }
00126 }
00127
00128 done:
00129 return old;
00130 }