AMROC Main     Blockstructured Adaptive Mesh Refinement in object-oriented C++


Main Page   Class Hierarchy   Compound List   File List  

SimpleBucketVoid.C

Go to the documentation of this file.
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      Contact
last update: 06/01/04