• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

typed_block.h

00001 /***************************************************************************
00002  *  include/stxxl/bits/mng/typed_block.h
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002-2004 Roman Dementiev <dementiev@mpi-sb.mpg.de>
00007  *  Copyright (C) 2008-2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
00012  **************************************************************************/
00013 
00014 #ifndef STXXL_TYPED_BLOCK_HEADER
00015 #define STXXL_TYPED_BLOCK_HEADER
00016 
00017 #include <stxxl/bits/io/request.h>
00018 #include <stxxl/bits/common/aligned_alloc.h>
00019 #include <stxxl/bits/common/debug.h>
00020 #include <stxxl/bits/mng/bid.h>
00021 
00022 #ifndef STXXL_VERBOSE_TYPED_BLOCK
00023 #define STXXL_VERBOSE_TYPED_BLOCK STXXL_VERBOSE2
00024 #endif
00025 
00026 
00027 __STXXL_BEGIN_NAMESPACE
00028 
00031 
00032 
00033 template <unsigned bytes>
00034 class filler_struct__
00035 {
00036     typedef unsigned char byte_type;
00037     byte_type filler_array_[bytes];
00038 
00039 public:
00040     filler_struct__() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] filler_struct__ is constructed"); }
00041 };
00042 
00043 template <>
00044 class filler_struct__<0>
00045 {
00046     typedef unsigned char byte_type;
00047 
00048 public:
00049     filler_struct__() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] filler_struct__<> is constructed"); }
00050 };
00051 
00053 template <class T, unsigned Size_>
00054 class element_block
00055 {
00056 public:
00057     typedef T type;
00058     typedef T value_type;
00059     typedef T & reference;
00060     typedef const T & const_reference;
00061     typedef type * pointer;
00062     typedef pointer iterator;
00063     typedef const type * const_iterator;
00064 
00065     enum
00066     {
00067         size = Size_ 
00068     };
00069 
00071     T elem[size];
00072 
00073     element_block() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] element_block is constructed"); }
00074 
00076     reference operator [] (int i)
00077     {
00078         return elem[i];
00079     }
00080 
00082     iterator begin()
00083     {
00084         return elem;
00085     }
00086 
00088     const_iterator begin() const
00089     {
00090         return elem;
00091     }
00092 
00094     const_iterator cbegin() const
00095     {
00096         return begin();
00097     }
00098 
00100     iterator end()
00101     {
00102         return elem + size;
00103     }
00104 
00106     const_iterator end() const
00107     {
00108         return elem + size;
00109     }
00110 
00112     const_iterator cend() const
00113     {
00114         return end();
00115     }
00116 };
00117 
00119 template <class T, unsigned Size_, unsigned RawSize_, unsigned NBids_ = 0>
00120 class block_w_bids : public element_block<T, Size_>
00121 {
00122 public:
00123     enum
00124     {
00125         raw_size = RawSize_,
00126         nbids = NBids_
00127     };
00128 
00129     typedef BID<raw_size> bid_type;
00130 
00132     bid_type ref[nbids];
00133 
00135     bid_type & operator () (int i)
00136     {
00137         return ref[i];
00138     }
00139 
00140     block_w_bids() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_bids is constructed"); }
00141 };
00142 
00143 template <class T, unsigned Size_, unsigned RawSize_>
00144 class block_w_bids<T, Size_, RawSize_, 0>: public element_block<T, Size_>
00145 {
00146 public:
00147     enum
00148     {
00149         raw_size = RawSize_,
00150         nbids = 0
00151     };
00152 
00153     typedef BID<raw_size> bid_type;
00154 
00155     block_w_bids() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_bids<> is constructed"); }
00156 };
00157 
00159 template <class T_, unsigned RawSize_, unsigned NBids_, class InfoType_ = void>
00160 class block_w_info :
00161     public block_w_bids<T_, ((RawSize_ - sizeof(BID<RawSize_>) * NBids_ - sizeof(InfoType_)) / sizeof(T_)), RawSize_, NBids_>
00162 {
00163 public:
00165     typedef InfoType_ info_type;
00166 
00168     info_type info;
00169 
00170     enum
00171     {
00172         size = ((RawSize_ - sizeof(BID<RawSize_>) * NBids_ - sizeof(InfoType_)) / sizeof(T_))
00173     };
00174 
00175 public:
00176     block_w_info() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_info is constructed"); }
00177 };
00178 
00179 template <class T_, unsigned RawSize_, unsigned NBids_>
00180 class block_w_info<T_, RawSize_, NBids_, void>:
00181     public block_w_bids<T_, ((RawSize_ - sizeof(BID<RawSize_>) * NBids_) / sizeof(T_)), RawSize_, NBids_>
00182 {
00183 public:
00184     typedef void info_type;
00185     enum
00186     {
00187         size = ((RawSize_ - sizeof(BID<RawSize_>) * NBids_) / sizeof(T_))
00188     };
00189 
00190 public:
00191     block_w_info() { STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] block_w_info<> is constructed"); }
00192 };
00193 
00195 
00208 template <unsigned RawSize_, class T_, unsigned NRef_ = 0, class InfoType_ = void>
00209 class typed_block :
00210     public block_w_info<T_, RawSize_, NRef_, InfoType_>,
00211     public filler_struct__<(RawSize_ - sizeof(block_w_info<T_, RawSize_, NRef_, InfoType_>))>
00212 {
00213 public:
00214     typedef T_ type;
00215     typedef T_ value_type;
00216     typedef T_ & reference;
00217     typedef const T_ & const_reference;
00218     typedef type * pointer;
00219     typedef pointer iterator;
00220     typedef type const * const_iterator;
00221 
00222     enum constants
00223     {
00224         raw_size = RawSize_,                                        
00225         size = block_w_info<T_, RawSize_, NRef_, InfoType_>::size,  
00226         has_only_data = (raw_size == (size * sizeof(value_type)))   
00227     };
00228 
00229     typedef BID<raw_size> bid_type;
00230 
00231     typed_block()
00232     {
00233         STXXL_STATIC_ASSERT(sizeof(typed_block) == raw_size);
00234         STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] typed_block is constructed");
00235 #if 0
00236         assert(((long)this) % BLOCK_ALIGN == 0);
00237 #endif
00238     }
00239 
00240 #if 0
00241     typed_block(const typed_block & tb)
00242     {
00243         STXXL_STATIC_ASSERT(sizeof(typed_block) == raw_size);
00244         STXXL_MSG("[" << (void *)this << "] typed_block is copy constructed from [" << (void *)&tb << "]");
00245         STXXL_UNUSED(tb);
00246     }
00247 #endif
00248 
00254     request_ptr write(const bid_type & bid,
00255                       completion_handler on_cmpl = default_completion_handler())
00256     {
00257         STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:write  " << FMT_BID(bid));
00258         return bid.storage->awrite(this, bid.offset, raw_size, on_cmpl);
00259     }
00260 
00266     request_ptr read(const bid_type & bid,
00267                      completion_handler on_cmpl = default_completion_handler())
00268     {
00269         STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:read   " << FMT_BID(bid));
00270         return bid.storage->aread(this, bid.offset, raw_size, on_cmpl);
00271     }
00272 
00273     static void * operator new (size_t bytes)
00274     {
00275         unsigned_type meta_info_size = bytes % raw_size;
00276         STXXL_VERBOSE1("typed::block operator new: Meta info size: " << meta_info_size);
00277 
00278         void * result = aligned_alloc<BLOCK_ALIGN>(bytes - meta_info_size, meta_info_size);
00279         #ifdef STXXL_VALGRIND_TYPED_BLOCK_INITIALIZE_ZERO
00280         memset(result, 0, bytes);
00281         #endif
00282         // FIXME: these STXXL_DEBUGMON_DO calls do not look sane w.r.t. meta_info_size != 0
00283         char * tmp = (char *)result;
00284         STXXL_DEBUGMON_DO(block_allocated(tmp, tmp + bytes, RawSize_));
00285         tmp += RawSize_;
00286         while (tmp < ((char *)result) + bytes)
00287         {
00288             STXXL_DEBUGMON_DO(block_allocated(tmp, ((char *)result) + bytes, RawSize_));
00289             tmp += RawSize_;
00290         }
00291         return result;
00292     }
00293 
00294     static void * operator new[] (size_t bytes)
00295     {
00296         unsigned_type meta_info_size = bytes % raw_size;
00297         STXXL_VERBOSE1("typed::block operator new[]: Meta info size: " << meta_info_size);
00298 
00299         void * result = aligned_alloc<BLOCK_ALIGN>(bytes - meta_info_size, meta_info_size);
00300         #ifdef STXXL_VALGRIND_TYPED_BLOCK_INITIALIZE_ZERO
00301         memset(result, 0, bytes);
00302         #endif
00303         // FIXME: these STXXL_DEBUGMON_DO calls do not look sane w.r.t. meta_info_size != 0
00304         char * tmp = (char *)result;
00305         STXXL_DEBUGMON_DO(block_allocated(tmp, tmp + bytes, RawSize_));
00306         tmp += RawSize_;
00307         while (tmp < ((char *)result) + bytes)
00308         {
00309             STXXL_DEBUGMON_DO(block_allocated(tmp, ((char *)result) + bytes, RawSize_));
00310             tmp += RawSize_;
00311         }
00312         return result;
00313     }
00314 
00315     static void * operator new (size_t /*bytes*/, void * ptr)     // construct object in existing memory
00316     {
00317         return ptr;
00318     }
00319 
00320     static void operator delete (void * ptr)
00321     {
00322         STXXL_DEBUGMON_DO(block_deallocated(ptr));
00323         aligned_dealloc<BLOCK_ALIGN>(ptr);
00324     }
00325 
00326     static void operator delete[] (void * ptr)
00327     {
00328         STXXL_DEBUGMON_DO(block_deallocated(ptr));
00329         aligned_dealloc<BLOCK_ALIGN>(ptr);
00330     }
00331 
00332     static void operator delete (void *, void *)
00333     { }
00334 
00335 #if 1
00336     // STRANGE: implementing destructor makes g++ allocate
00337     // additional 4 bytes in the beginning of every array
00338     // of this type !? makes aligning to 4K boundaries difficult
00339     //
00340     // http://www.cc.gatech.edu/grads/j/Seung.Won.Jun/tips/pl/node4.html :
00341     // "One interesting thing is the array allocator requires more memory
00342     //  than the array size multiplied by the size of an element, by a
00343     //  difference of delta for metadata a compiler needs. It happens to
00344     //  be 8 bytes long in g++."
00345     ~typed_block()
00346     {
00347         STXXL_VERBOSE_TYPED_BLOCK("[" << (void *)this << "] typed_block is destructed");
00348     }
00349 #endif
00350 };
00351 
00353 
00354 __STXXL_END_NAMESPACE
00355 
00356 #endif // !STXXL_TYPED_BLOCK_HEADER
00357 // vim: et:ts=4:sw=4

Generated on Sun Oct 17 2010 06:13:45 for Stxxl by  doxygen 1.7.1