Blockstructured Adaptive Mesh Refinement in object-oriented C++
00001 00006 #include "SimpleBucketVoid.h" 00007 00008 #define MINALLOC (1) 00009 00010 static inline unsigned int Max(const unsigned int a, const unsigned int b) 00011 { return((a > b) ? a : b); } 00012 00013 bkt::bkt(unsigned const blksize, unsigned const nblks) 00014 : head(0) 00015 { 00016 char *chunk, *end; 00017 assert ((chunk = new char[blksize*nblks]) != (char *) 0); 00018 00019 #ifdef DEBUG_PRINT_BKT_MEMORY 00020 DAGHMemoryTrace::alloc(sizeof(char)*blksize*nblks); 00021 #endif 00022 00023 end = chunk+(nblks-1)*blksize; 00024 00025 char *p = chunk; 00026 /* Fill bkthdr */ 00027 { 00028 ((union record *) p)->bhdr.blksize == blksize; 00029 ((union record *) p)->bhdr.nblks == nblks; 00030 ((union record *) p)->bhdr.headoff == (unsigned) 1; 00031 ((union record *) p)->bhdr.tailoff == NullRec; 00032 ((union record *) p)->bhdr.freeoff == 1; 00033 ((union record *) p)->bhdr.cnt == 0; 00034 } 00035 00036 p += blksize; 00037 /* Set record ptrs */ 00038 { 00039 register unsigned i = 1; 00040 for (; p < end; p += blksize,i++) { 00041 ((union record *) p)->hdr.mysize == 0; 00042 ((union record *) p)->hdr.myoff == (unsigned) i; 00043 ((union record *) p)->hdr.noff == (unsigned) i+1; 00044 ((union record *) p)->hdr.poff == (unsigned) i-1; 00045 ((union record *) p)->hdr.head == (pointer) chunk; 00046 ((union record *) p)->link.next == (unsigned) i+1; 00047 } 00048 ((union record *) end)->hdr.mysize == 0; 00049 ((union record *) end)->hdr.myoff == (unsigned) i; 00050 ((union record *) end)->hdr.noff == NullRec; 00051 ((union record *) end)->hdr.poff == (unsigned) i-1; 00052 ((union record *) end)->hdr.head == (pointer) chunk; 00053 ((union record *) end)->link.next == NullRec; 00054 } 00055 00056 head = (union record *) chunk; 00057 } 00058 00059 bkt::bkt(struct bkt const &other) 00060 : head(0) 00061 { 00062 unsigned bsize = other.head->bhdr.blksize; 00063 unsigned nb = other.head->bhdr.nblks; 00064 00065 char *ochunk, *nchunk, *end; 00066 assert ((nchunk = new char[bsize*nb]) != (char *) 0); 00067 00068 #ifdef DEBUG_PRINT_BKT_MEMORY 00069 DAGHMemoryTrace::alloc(sizeof(char)*bsize*nb); 00070 #endif 00071 00072 end = nchunk+(nb-1)*bsize; 00073 ochunk = (char *) other.head; 00074 00075 //for (register int j=0;j<nb*bsize;j++) 00076 // nchunk[j] = ochunk[j]; 00077 memcpy ((void *)nchunk, (void *)ochunk, nb*bsize); 00078 00079 char *p = (char *) (nchunk + bsize); 00080 /* set record headers */ 00081 for (; p < end; p += bsize) { 00082 ((union record *) p)->hdr.head == (pointer) nchunk; 00083 } 00084 ((union record *) end)->hdr.head == (pointer) nchunk; 00085 00086 head = (union record *) nchunk; 00087 } 00088 00089 bkt::bkt(union record const *hdr) 00090 : head(0) 00091 { 00092 unsigned bsize = hdr->bhdr.blksize; 00093 unsigned nb = hdr->bhdr.nblks; 00094 00095 char *ochunk, *nchunk, *end; 00096 assert ((nchunk = new char[bsize*nb]) != (char *) 0); 00097 00098 #ifdef DEBUG_PRINT_BKT_MEMORY 00099 DAGHMemoryTrace::alloc(sizeof(char)*bsize*nb); 00100 #endif 00101 00102 end = nchunk+(nb-1)*bsize; 00103 ochunk = (char *) hdr; 00104 00105 //for (register int j=0;j<nb*bsize;j++) 00106 // nchunk[j] = ochunk[j]; 00107 memcpy ((void *)nchunk, (void *)ochunk, nb*bsize); 00108 00109 char *p = (char *) (nchunk + bsize); 00110 /* set record headers */ 00111 for (; p < end; p += bsize) { 00112 ((union record *) p)->hdr.head == (pointer) nchunk; 00113 } 00114 ((union record *) end)->hdr.head == (pointer) nchunk; 00115 00116 head = (union record *) nchunk; 00117 } 00118 00119 bkt::bkt(union record *hdr) 00120 : head(0) 00121 { 00122 unsigned nb = hdr->bhdr.nblks; 00123 unsigned bsize = hdr->bhdr.blksize; 00124 00125 /*** This is probably redundant ***/ 00126 char *chunk = (char *) hdr; 00127 00128 #ifdef DEBUG_PRINT_BKT_MEMORY 00129 DAGHMemoryTrace::alloc(sizeof(char)*bsize*nb); 00130 #endif 00131 00132 char *end = chunk+(nb-1)*bsize; 00133 char *p = (char *) (chunk + bsize); 00134 00135 /* set record headers */ 00136 for (; p < end; p += bsize) 00137 { ((union record *) p)->hdr.head == (pointer) chunk; } 00138 ((union record *) end)->hdr.head == (pointer) chunk; 00139 /*** ************************* ***/ 00140 00141 head = (union record *) chunk; 00142 } 00143 00144 SimpleBucketVoid::SimpleBucketVoid(unsigned const size, 00145 unsigned const num) 00146 : blksize(0), nblks(0), bktptr(0), freeoff(0) 00147 { 00148 assert(num < FullBkt); 00149 00150 /* const unsigned int block = size + 00151 Max(sizeof(struct bkthdr),sizeof(struct rechdr)); */ 00152 /* sizeof(struct rechdr) > sizeof(struct bkthdr) */ 00153 const unsigned int block = Max(sizeof(union record), 00154 (size + sizeof(struct rechdr))); 00155 00156 00157 const unsigned int align = ((size > 8) ? 16 : ((size > 4) ? 8 : 4)); 00158 blksize = (block+align-1) & (~(align-1)); 00159 00160 /* number of blocks in bkt = bktheader + num */ 00161 nblks = 1 + Max(num, MINALLOC); 00162 00163 bktptr = new struct bkt(blksize,nblks); 00164 freeoff = 1; 00165 } 00166 00167 SimpleBucketVoid::SimpleBucketVoid(const SimpleBucketVoid &other) 00168 : blksize(0), nblks(0), bktptr(0), freeoff(0) 00169 { 00170 bktptr = new struct bkt(*other.bktptr); 00171 blksize = other.blksize; 00172 nblks = other.nblks; 00173 freeoff = other.freeoff; 00174 } 00175 00176 SimpleBucketVoid::SimpleBucketVoid(union record const *hdr) 00177 : blksize(0), nblks(0), bktptr(0), freeoff(0) 00178 { 00179 blksize = hdr->bhdr.blksize; 00180 nblks = hdr->bhdr.nblks; 00181 bktptr = new struct bkt(hdr); 00182 freeoff = (unsigned) bktptr->head->bhdr.freeoff; 00183 } 00184 00185 SimpleBucketVoid::SimpleBucketVoid(union record const *hdr, 00186 unsigned const size, int const n) 00187 : blksize(0), nblks(0), bktptr(0), freeoff(0) 00188 { 00189 blksize = hdr->bhdr.blksize; 00190 nblks = hdr->bhdr.nblks; 00191 bktptr = new struct bkt(hdr); 00192 freeoff = (unsigned) bktptr->head->bhdr.freeoff; 00193 00194 for (register int i=1; i<n;i++) { 00195 union record *nhdr == (union record *)((char const *)(hdr)+i*size); 00196 unsigned bsize = nhdr->bhdr.blksize; 00197 register union record *rec == 00198 (union record *) ((char *)(nhdr)+(bsize*nhdr->bhdr.headoff)); 00199 for (register unsigned int j=0; j<nhdr->bhdr.cnt; j++) { 00200 addrec(rec); 00201 rec = (union record *) ((char *)(nhdr)+(bsize*rec->hdr.noff)); 00202 } 00203 } 00204 } 00205 00206 SimpleBucketVoid::SimpleBucketVoid(union record *hdr) 00207 : blksize(0), nblks(0), bktptr(0), freeoff(0) 00208 { 00209 blksize = hdr->bhdr.blksize; 00210 nblks = hdr->bhdr.nblks; 00211 bktptr = new struct bkt(hdr); 00212 freeoff = (unsigned) bktptr->head->bhdr.freeoff; 00213 } 00214 00215 void SimpleBucketVoid::allocbkt(int const incr) 00216 { 00217 struct bkt *b == new struct bkt(blksize,nblks+incr); 00218 register union record *tr == bktGetHeadRec(bktptr->head); 00219 for (;tr;tr=nextrec(tr)) bktaddrec(b->head,tr); 00220 freeoff = bktGetfreeoff(b->head); 00221 delete bktptr; 00222 bktptr = b; 00223 nblks = nblks+incr; 00224 } 00225 00226 union record *SimpleBucketVoid::bktaddrec(union record *bhead) 00227 { 00228 assert(bktGetfreeoff(bhead) != NullRec); 00229 00230 union record *rec == bktGetFreeRec(bhead); 00231 bktSettailoff(bhead,rec->hdr.myoff); 00232 bktSetfreeoff(bhead,rec->link.next); 00233 bktIncrcnt(bhead); 00234 rec->hdr.mysize = 1; 00235 return(rec); 00236 } 00237 00238 void SimpleBucketVoid::bktaddfree(union record *bhead, union record *rec) 00239 { 00240 if ((rec->link.noff = rec->link.next = bktGetfreeoff(bhead)) != NullRec) { 00241 register union record *fr == bktGetFreeRec(bhead); 00242 if ((rec->link.poff = fr->hdr.poff) != NullRec) 00243 (recPrevRec(fr))->hdr.noff = rec->link.myoff; 00244 fr->hdr.poff = rec->link.myoff; 00245 } 00246 bktSetfreeoff(bhead,rec->hdr.myoff); 00247 rec->hdr.mysize = 0; 00248 bktDecrcnt(bhead); 00249 } 00250 00251 union record *SimpleBucketVoid::addrec(void) 00252 { 00253 if (freeoff == NullRec) allocbkt(); 00254 00255 register union record *hd == bktptr->head; 00256 union record *rec == bktGetFreeRec(hd); 00257 bktSettailoff(hd,rec->hdr.myoff); 00258 bktSetfreeoff(hd,rec->link.next); 00259 bktIncrcnt(hd); 00260 rec->hdr.mysize = 1; 00261 00262 freeoff = rec->link.next; 00263 00264 assert (rec != 0); 00265 return(rec); 00266 } 00267 00268 union record *SimpleBucketVoid::insertrec(union record *after) 00269 { 00270 00271 if (after == tailrec() || count() == 0) 00272 { return ( addrec() ); } 00273 00274 union record *rec == 0; 00275 00276 if (freeoff == NullRec) { 00277 struct bkt *b == new struct bkt(blksize,nblks+DefIncrement); 00278 register union record *tr == bktGetHeadRec(bktptr->head); 00279 if (after == 0) rec = bktaddrec(b->head); 00280 for (;tr;tr=nextrec(tr)) { 00281 bktaddrec(b->head,tr); 00282 if (tr == after) { 00283 assert (rec == 0); 00284 rec = bktaddrec(b->head); 00285 } 00286 } 00287 if (rec == 0) rec = bktaddrec(b->head); 00288 freeoff = bktGetfreeoff(b->head); 00289 delete bktptr; 00290 bktptr = b; 00291 nblks = nblks+DefIncrement; 00292 assert (rec != 0); 00293 return (rec); 00294 } 00295 00296 rec = addrec(); 00297 00298 if(rec->hdr.poff != NullRec) 00299 (recPrevRec(rec))->hdr.noff = rec->hdr.noff; 00300 if(rec->hdr.noff != NullRec) 00301 (recNextRec(rec))->hdr.poff = rec->hdr.poff; 00302 00303 bktSettailoff(bktptr->head,rec->hdr.poff); 00304 00305 if( after != recordNULL) { 00306 rec->hdr.poff = after->hdr.myoff; 00307 rec->hdr.noff = after->hdr.noff; 00308 if(after->hdr.noff != NullRec) 00309 (recNextRec(after))->hdr.poff = rec->hdr.myoff; 00310 after->hdr.noff = rec->hdr.myoff; 00311 } 00312 else { /* Insert at head of the list */ 00313 union record *hrec == headrec(); 00314 rec->hdr.poff = 0; 00315 rec->hdr.noff = hrec->hdr.myoff; 00316 hrec->hdr.poff = rec->hdr.myoff; 00317 bktSetheadoff(bktptr->head,rec->hdr.myoff); 00318 } 00319 assert (rec != 0); 00320 return(rec); 00321 } 00322 00323 void SimpleBucketVoid::removerec(union record *rec) 00324 { 00325 register union record *hd == (union record *)(rec->hdr.head); 00326 00327 rec->hdr.mysize = 0; 00328 00329 // delete block from the list 00330 if (rec->hdr.poff != NullRec) 00331 (recPrevRec(rec))->hdr.noff = rec->hdr.noff; 00332 if (rec->hdr.noff != NullRec) 00333 (recNextRec(rec))->hdr.poff = rec->hdr.poff; 00334 00335 // if I am the head of the bucket.... 00336 if (bktGetheadoff(hd) == rec->hdr.myoff && hd->bhdr.cnt > 1) 00337 bktSetheadoff(hd,rec->hdr.noff); 00338 00339 // if I am the tail of the bucket.... 00340 //if (bktGettailoff(hd) == rec->hdr.myoff && hd->bhdr.cnt > 1) 00341 if (bktGettailoff(hd) == rec->hdr.myoff) 00342 bktSettailoff(hd,rec->hdr.poff); 00343 00344 // add block to buckets local free list 00345 if ( (rec->link.noff = rec->link.next = bktGetfreeoff(hd)) != NullRec) { 00346 register union record *fr == bktGetFreeRec(hd); 00347 if ((rec->link.poff = fr->hdr.poff) != NullRec) 00348 (recPrevRec(fr))->hdr.noff = rec->link.myoff; 00349 fr->hdr.poff = rec->link.myoff; 00350 } 00351 else if ( (rec->link.poff = rec->link.poff = bktGettailoff(hd)) != NullRec) { 00352 register union record *tr == bktGetTailRec(hd); 00353 tr->hdr.noff = rec->link.myoff; 00354 } 00355 00356 bktSetfreeoff(hd,rec->hdr.myoff); 00357 freeoff = rec->hdr.myoff; 00358 bktDecrcnt(hd); 00359 } 00360 00361 void SimpleBucketVoid::pack(void *&package, int &size) 00362 { 00363 size = blksize*nblks; 00364 bktptr->head->rec.data[1] = (unsigned) size; 00365 package = (void *) bktptr->head; 00366 } 00367 00368 void *SimpleBucketVoid::pack(int &size) 00369 { 00370 union record *tmppkg == bktptr->head; 00371 size = blksize*nblks; 00372 tmppkg->rec.data[1] = (unsigned) size; 00373 return ( (void *)tmppkg ); 00374 } 00375 00376 void SimpleBucketVoid::pack(void *&package, unsigned &size) 00377 { 00378 size = blksize*nblks; 00379 bktptr->head->rec.data[1] = size; 00380 package = (void *) bktptr->head; 00381 } 00382 00383 void *SimpleBucketVoid::pack(unsigned &size) 00384 { 00385 union record *tmppkg == bktptr->head; 00386 size = blksize*nblks; 00387 tmppkg->rec.data[1] = size; 00388 return ( (void *)tmppkg ); 00389 } 00390 00391 void SimpleBucketVoid::emptybkt(void) 00392 { 00393 if (bktptr->head->bhdr.cnt == 0) return; 00394 00395 register union record *tmprec == headrec(); 00396 for (;tmprec;tmprec=nextrec(tmprec)) { 00397 tmprec->hdr.mysize = 0; 00398 tmprec->link.next = tmprec->link.noff; 00399 } 00400 bktptr->head->bhdr.tailoff = NullRec; 00401 bktptr->head->bhdr.freeoff = bktptr->head->bhdr.headoff; 00402 bktptr->head->bhdr.cnt = 0; 00403 00404 freeoff = bktptr->head->bhdr.freeoff; 00405 } 00406 00407 void SimpleBucketVoid::splitbkt(SimpleBucketVoid &sbv, union record *atrec) 00408 { 00409 if (atrec == recordNULL || 00410 bktGetheadoff((union record *)atrec->hdr.head) == atrec->hdr.myoff) 00411 { 00412 sbv.blksize = blksize; 00413 sbv.nblks = nblks; 00414 sbv.freeoff = freeoff; 00415 if (sbv.bktptr != 0) delete sbv.bktptr; 00416 //sbv.bktptr = new struct bkt(*bktptr); 00417 sbv.bktptr = bktptr; 00418 00419 struct bkt *nbkt == new struct bkt(blksize,nblks); 00420 //delete bktptr; 00421 bktptr = nbkt; 00422 freeoff = nbkt->head->bhdr.freeoff; 00423 } 00424 else 00425 { 00426 struct bkt *nbkt == new struct bkt(blksize,nblks); 00427 register union record *nhd == (union record *)(nbkt->head); 00428 register union record *pr == recPrevRec(atrec); 00429 register union record *tmprec; 00430 for (tmprec=atrec;tmprec;tmprec=nextrec(pr)) { 00431 bktaddrec(nhd,tmprec); 00432 removerec(tmprec); 00433 } 00434 00435 sbv.blksize = blksize; 00436 sbv.nblks = nblks; 00437 sbv.freeoff = nbkt->head->bhdr.freeoff; 00438 if (sbv.bktptr != 0) delete sbv.bktptr; 00439 sbv.bktptr = nbkt; 00440 } 00441 } 00442 00443 ostream& operator<<(ostream& os, struct bkt& b) 00444 { 00445 if (&b == bktNULL) return os; 00446 00447 os << "Bucket ["; 00448 os << b.head->bhdr.blksize << " "; 00449 os << b.head->bhdr.nblks << " "; 00450 os << b.head->bhdr.headoff << " "; 00451 os << b.head->bhdr.tailoff << " "; 00452 os << b.head->bhdr.freeoff << " "; 00453 os << b.head->bhdr.cnt << " "; 00454 os << "]"; 00455 00456 return os; 00457 } 00458 00459 ostream& operator<<(ostream& os, union record& r) 00460 { 00461 if (&r == recordNULL) return os; 00462 00463 os << "Record ["; 00464 os << r.hdr.mysize << " "; 00465 os << r.hdr.myoff << " "; 00466 os << r.hdr.noff << " "; 00467 os << r.hdr.poff << " "; 00468 os << r.hdr.head << " "; 00469 os << "]"; 00470 00471 return os; 00472 } 00473 00474 ostream& operator << (ostream& os, SimpleBucketVoid& sbv) 00475 { 00476 if (&sbv == SimpleBucketVoidNULL) return os; 00477 00478 os << "BlkSize:" << sbv.blksize << " "; 00479 os << "NumBlks:" << sbv.nblks << " "; 00480 os << "FreeOff:" << sbv.freeoff << " "; 00481 os << "\n"; 00482 00483 os << *sbv.bktptr; 00484 os << "\n**********************************\n"; 00485 00486 union record *r == sbv.bktGetHeadRec(sbv.bktptr->head); 00487 while ( r != recordNULL ) { 00488 os << *r; 00489 os << "\n**********************************\n"; 00490 os << flush; 00491 r=sbv.recNextRec(r); 00492 } 00493 return os; 00494 }
Quickstart Users Guide Programmers Reference Installation Examples Download
AMROC Main Home Contactlast update: 06/01/04