vtf-logo

BucketType.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #ifndef _included_BucketType_h
00004 #define _included_BucketType_h
00005 
00011 /*
00012 *************************************************************************
00013 * If a bucket is filled completely with records, insertrec() and        *
00014 * addrec() copy the WHOLE list to a NEW bucket. The old list is deleted.*
00015 * All references to the old list become invalid during insertrec() and  *
00016 * addrec(). The data is simply copied bevore insertrec() and addrec().  *
00017 *************************************************************************
00018 */
00019 
00020 #include <list>
00021 #include <cstring>
00022 #include <cstdlib>
00023 
00024 /* Assemble elements of type "Type" in a consecutive memory block.
00025  * The dynamic list for type "Type" is implemented using std::list.
00026  * Various list-manipulation routines are supplied. 
00027  * @author Manish Parashar, Ralf Deiterding (minor corrections)
00028  * Julian Cummings (modified to use std::list)
00029  */
00030 
00031 template <class Type>
00032 class Bucket
00033 {
00034 private:
00035     typedef std::list<Type> list_type;
00036     list_type theList;
00037     typename list_type::iterator cur;
00038 public:
00039     typedef typename list_type::iterator iterator;
00040 
00041     // constructors
00042     inline Bucket() { cur = theList.end(); }
00043 
00044     // Make one-argument constructors explicit to avoid unwanted conversions
00045     // ignore maxnum argument, since there is no pre-allocation with std::list
00046     explicit Bucket(const unsigned int) { cur = theList.end(); }
00047 
00048     inline Bucket(const void *package, const unsigned int size, const int n)
00049     {
00050         unsigned int cnt;
00051         for (int i=0; i<n; ++i) {
00052             const char* hdr = reinterpret_cast<const char*>(package)+i*size;
00053             std::memcpy(reinterpret_cast<char*>(&cnt), hdr, 
00054                         sizeof(unsigned int));
00055             if (cnt) {
00056                 const Type* beg = 
00057                     reinterpret_cast<const Type*>(hdr+sizeof(unsigned int));
00058                 const Type* end = beg + cnt;
00059                 theList.insert(theList.end(), beg, end);
00060             }
00061         }
00062         cur = theList.end(); 
00063     }
00064 
00065     inline Bucket(const Bucket<Type> &other)
00066         : theList(other.theList) { cur = theList.end(); }
00067 
00068     // query function
00069     inline int number() const { return theList.size(); }
00070     inline bool isempty() const { return theList.empty(); }
00071 
00072     // current record accessors
00073     inline Type* first(void)
00074     {
00075         if (!theList.empty()) {
00076             cur = theList.begin();
00077             return &(*cur);
00078         }
00079         else {
00080             return NULL;
00081         }
00082     }
00083 
00084     inline Type* last(void) 
00085     {
00086         if (!theList.empty()) {
00087             cur = --theList.end();
00088             return &(*cur);
00089         }
00090         else {
00091             return NULL;
00092         }
00093     }
00094 
00095     inline Type* current(void)
00096     {
00097         if (cur != theList.end())
00098             return &(*cur);
00099         else
00100             return NULL;
00101     }
00102 
00103     inline Type* prev(void)
00104     {
00105         if (cur != theList.begin()) {
00106             --cur;
00107             return &(*cur);
00108         }
00109         else {
00110             cur = theList.end();
00111             return NULL;
00112         }
00113     }
00114 
00115     inline Type* next(void)
00116     {
00117         if (cur == theList.end()) 
00118             return first();
00119         ++cur;
00120         if (cur != theList.end())
00121             return &(*cur);
00122         else
00123             return NULL;
00124     }
00125 
00126    inline iterator currec(void) { return cur; }
00127 
00128    inline void setcurrec(iterator c) { cur = c; }
00129 
00130     // list manipulators
00131     // add item to end of list
00132     inline Type* add(void)
00133     { 
00134         theList.push_back(Type()); 
00135         cur = --theList.end();
00136         return &(*cur); 
00137     }
00138     inline Type* add(const Type &t)
00139     { 
00140         theList.push_back(t); 
00141         cur = --theList.end();
00142         return &(*cur); 
00143     }
00144 
00145     // insert item after current position
00146     inline Type* insert(void)
00147     {
00148         if (cur == --theList.end() || theList.empty()) return add();
00149         cur = theList.insert(++cur,Type()); 
00150         return &(*cur); 
00151     }
00152     inline Type* insert(const Type &t)
00153     {
00154         if (cur == --theList.end() || theList.empty()) return add(t);
00155         cur = theList.insert(++cur,t); 
00156         return &(*cur); 
00157     }
00158 
00159     // remove current item and set pointer to previous item
00160     inline Type* remove(void)
00161     { 
00162         if (!theList.empty()) { 
00163             if (cur == theList.begin()) {
00164                 theList.erase(cur);
00165                 cur = theList.end();
00166             }
00167             else {
00168                 iterator r = cur--;
00169                 theList.erase(r);
00170             }
00171         }
00172         return current();
00173     }
00174 
00175     // clear all items from the list
00176     inline void empty(void)
00177     { 
00178         theList.clear(); 
00179         cur = theList.end(); 
00180     }
00181 
00182     // swap storage with another bucket
00183     inline void swap(Bucket<Type>& bkt)
00184     { 
00185         iterator bktcur = bkt.cur;
00186         theList.swap(bkt.theList); 
00187         bkt.cur = cur;
00188         cur = bktcur;
00189     }
00190 
00191     // split the list at the current item
00192     inline void split(Bucket<Type>& bkt)
00193     {
00194         if (!theList.empty()) { 
00195             if (cur == theList.begin()) {
00196                 bkt.theList.splice(bkt.theList.end(), theList);
00197                 bkt.cur = bkt.theList.end();
00198                 cur = theList.end();
00199             }
00200             else {
00201                 iterator r = cur--;
00202                 bkt.theList.splice(bkt.theList.end(), theList,
00203                     r, theList.end());
00204                 bkt.cur = bkt.theList.end();
00205             }
00206         }
00207     }
00208 
00209     // utility routines
00210     // These routines copy items from std::list into a contiguous buffer.
00211     // The new buffer should be deleted after it is used.
00212     void *pack(int &size)
00213     {
00214         const unsigned int cnt = theList.size();
00215         size = cnt * sizeof(Type) + sizeof(unsigned int);
00216         char* pkg = new char[size];
00217         std::memcpy(pkg, reinterpret_cast<const char*>(&cnt), 
00218                     sizeof(unsigned int));
00219         if (cnt) {
00220             Type* t = reinterpret_cast<Type*>(pkg + sizeof(unsigned int));
00221             iterator it, iend = theList.end();
00222             for (it = theList.begin(); it != iend; ++it, ++t)
00223                 std::memcpy(reinterpret_cast<char*>(t),
00224                             reinterpret_cast<char*>(&(*it)), sizeof(Type));
00225         }
00226         return pkg;
00227     }
00228     void pack(void *&package, int &size)
00229     {
00230         const unsigned int cnt = theList.size();
00231         size = cnt * sizeof(Type) + sizeof(unsigned int);
00232         char* pkg = new char[size];
00233         std::memcpy(pkg, reinterpret_cast<const char*>(&cnt), 
00234                     sizeof(unsigned int));
00235         if (cnt) {
00236             Type* t = reinterpret_cast<Type*>(pkg + sizeof(unsigned int));
00237             iterator it, iend = theList.end();
00238             for (it = theList.begin(); it != iend; ++it, ++t)
00239                 std::memcpy(reinterpret_cast<char*>(t),
00240                             reinterpret_cast<char*>(&(*it)), sizeof(Type));
00241         }
00242         package = pkg;
00243         return;
00244     }
00245 };
00246 
00247 #endif

Generated on Fri Aug 24 13:00:28 2007 for AMROC's Hierachical Data Structures - by  doxygen 1.4.7