00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define FDP_PRIVATE 1
00029
00030 #include <fdp.h>
00031 #include <grid.h>
00032 #include <macros.h>
00033
00034
00035 typedef struct _block {
00036 cell *mem;
00037 cell *cur;
00038 cell *endp;
00039 struct _block *next;
00040 } block_t;
00041
00042
00043
00044
00045 static block_t *newBlock(int size)
00046 {
00047 block_t *newb;
00048
00049 newb = GNEW(block_t);
00050 newb->next = 0;
00051 newb->mem = N_GNEW(size, cell);
00052 newb->endp = newb->mem + size;
00053 newb->cur = newb->mem;
00054
00055 return newb;
00056 }
00057
00058
00059
00060
00061
00062 static void freeBlock(block_t * b)
00063 {
00064 if (b) {
00065 block_t *next = b->next;
00066 free(b->mem);
00067 free(b);
00068 freeBlock(next);
00069 }
00070 }
00071
00072 struct _grid {
00073 Dt_t *data;
00074 block_t *cellMem;
00075 block_t *cellCur;
00076 int listSize;
00077 node_list *listMem;
00078 node_list *listCur;
00079 };
00080
00081
00082
00083
00084 static cell *getCell(Grid * g)
00085 {
00086 cell *cp;
00087 block_t *bp = g->cellCur;
00088
00089 if (bp->cur == bp->endp) {
00090 if (bp->next == 0) {
00091 bp->next = newBlock(2 * (bp->endp - bp->mem));
00092 }
00093 bp = g->cellCur = bp->next;
00094 bp->cur = bp->mem;
00095 }
00096 cp = bp->cur++;
00097 return cp;
00098 }
00099
00100 #ifndef offsetof
00101 #define offsetof(typ,fld) ((int)(&(((typ*)0)->fld)))
00102 #endif
00103
00104
00105 static int ijcmpf(Dt_t * d, gridpt * p1, gridpt * p2, Dtdisc_t * disc)
00106 {
00107 int diff;
00108
00109 NOTUSED(d);
00110 NOTUSED(disc);
00111 if ((diff = (p1->i - p2->i)))
00112 return diff;
00113 else
00114 return (p1->j - p2->j);
00115 }
00116
00117 static Grid *_grid;
00118
00119
00120
00121
00122
00123 static void *newCell(Dt_t * d, void *obj, Dtdisc_t * disc)
00124 {
00125 cell *cellp = (cell *) obj;
00126 cell *newp;
00127
00128 NOTUSED(disc);
00129 newp = getCell(_grid);
00130 newp->p.i = cellp->p.i;
00131 newp->p.j = cellp->p.j;
00132 newp->nodes = 0;
00133
00134 return newp;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 static node_list *newNode(Grid * g, Agnode_t * n, node_list * nxt)
00144 {
00145 node_list *newp;
00146
00147 newp = g->listCur++;
00148 newp->node = n;
00149 newp->next = nxt;
00150
00151 return newp;
00152 }
00153
00154 static Dtdisc_t gridDisc = {
00155 offsetof(cell, p),
00156 sizeof(gridpt),
00157 offsetof(cell, link),
00158 (Dtmake_f) newCell,
00159 NIL(Dtfree_f),
00160 (Dtcompar_f) ijcmpf,
00161 NIL(Dthash_f),
00162 NIL(Dtmemory_f),
00163 NIL(Dtevent_f)
00164 };
00165
00166
00167
00168
00169
00170
00171 Grid *mkGrid(int cellHint)
00172 {
00173 Grid *g;
00174
00175 g = GNEW(Grid);
00176 _grid = g;
00177 g->data = dtopen(&gridDisc, Dtoset);
00178 g->listMem = 0;
00179 g->listSize = 0;
00180 g->cellMem = newBlock(cellHint);
00181 return g;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 void adjustGrid(Grid * g, int nnodes)
00191 {
00192 int nsize;
00193
00194 if (nnodes > g->listSize) {
00195 nsize = MAX(nnodes, 2 * (g->listSize));
00196 if (g->listMem)
00197 free(g->listMem);
00198 g->listMem = N_GNEW(nsize, node_list);
00199 g->listSize = nsize;
00200 }
00201 }
00202
00203
00204
00205
00206
00207 void clearGrid(Grid * g)
00208 {
00209 dtclear(g->data);
00210 g->listCur = g->listMem;
00211 g->cellCur = g->cellMem;
00212 g->cellCur->cur = g->cellCur->mem;
00213 }
00214
00215
00216
00217
00218 void delGrid(Grid * g)
00219 {
00220 dtclose(g->data);
00221 freeBlock(g->cellMem);
00222 free(g->listMem);
00223 free(g);
00224 }
00225
00226
00227
00228
00229 void addGrid(Grid * g, int i, int j, Agnode_t * n)
00230 {
00231 cell *cellp;
00232 cell key;
00233
00234 key.p.i = i;
00235 key.p.j = j;
00236 cellp = dtinsert(g->data, &key);
00237 cellp->nodes = newNode(g, n, cellp->nodes);
00238 if (Verbose >= 3) {
00239 fprintf(stderr, "grid(%d,%d): %s\n", i, j, n->name);
00240 }
00241 }
00242
00243 typedef int (*walkfn_t) (Dt_t *, Void_t *, Void_t *);
00244
00245
00246
00247
00248
00249
00250
00251 void walkGrid(Grid * g, int (*walkf) (Dt_t *, cell *, Grid *))
00252 {
00253 dtwalk(g->data, (walkfn_t) walkf, g);
00254 }
00255
00256
00257
00258
00259
00260 cell *findGrid(Grid * g, int i, int j)
00261 {
00262 cell key;
00263
00264 key.p.i = i;
00265 key.p.j = j;
00266 return ((cell *) dtsearch(g->data, &key));
00267 }
00268
00269
00270
00271
00272 int gLength(cell * p)
00273 {
00274 int len = 0;
00275 node_list *nodes = p->nodes;
00276
00277 while (nodes) {
00278 len++;
00279 nodes = nodes->next;
00280 }
00281 return len;
00282 }