00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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 , void * ptr)
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
00337
00338
00339
00340
00341
00342
00343
00344
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