Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
typed_block.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/mng/typed_block.hpp
3  *
4  * Constructs a typed_block object containing as many elements elements plus
5  * some metadata as fits into the given block size.
6  *
7  * Part of FOXXLL. See http://foxxll.org
8  *
9  * Copyright (C) 2002-2004 Roman Dementiev <[email protected]>
10  * Copyright (C) 2008-2010 Andreas Beckmann <[email protected]>
11  * Copyright (C) 2013 Timo Bingmann <[email protected]>
12  *
13  * Distributed under the Boost Software License, Version 1.0.
14  * (See accompanying file LICENSE_1_0.txt or copy at
15  * http://www.boost.org/LICENSE_1_0.txt)
16  **************************************************************************/
17 
18 #ifndef FOXXLL_MNG_TYPED_BLOCK_HEADER
19 #define FOXXLL_MNG_TYPED_BLOCK_HEADER
20 
22 #include <foxxll/config.hpp>
23 #include <foxxll/io/request.hpp>
24 #include <foxxll/mng/bid.hpp>
25 
26 namespace foxxll {
27 
28 #ifdef FOXXLL_VERBOSE_TYPED_BLOCK
29 constexpr bool debug_typed_block = true;
30 #else
31 constexpr bool debug_typed_block = false;
32 #endif
33 
34 //! \addtogroup foxxll_mnglayer
35 //! \{
36 
37 //! Block Manager Internals \internal
38 namespace mng_local {
39 
40 //! \defgroup foxxll_mnglayer_internals Internals
41 //! \ingroup foxxll_mnglayer
42 //! Internals and support classes
43 //! \{
44 
45 template <size_t Bytes>
47 {
48  using byte_type = unsigned char;
50 
51 public:
53  {
54  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] filler_struct is constructed";
55  }
56 };
57 
58 template <>
59 class filler_struct<0>
60 {
61  using byte_type = unsigned char;
62 
63 public:
65  {
66  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] filler_struct<> is constructed";
67  }
68 };
69 
70 //! Contains data elements for \c foxxll::typed_block , not intended for direct use.
71 template <typename Type, size_t kSize>
73 {
74 public:
75  using type = Type;
76  using value_type = Type;
77  using reference = Type &;
78  using const_reference = const Type &;
79  using pointer = type *;
80  using iterator = pointer;
81  using const_iterator = const type *;
82 
83  static constexpr size_t size = kSize; //!< number of elements in the block
84 
85  //! Array of elements of type Type
86  value_type elem[kSize];
87 
89  {
90  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] element_block is constructed";
91  }
92 
93  //! An operator to access elements in the block
95  {
96  return elem[i];
97  }
98 
99  //! Returns \c iterator pointing to the first element.
101  {
102  return elem;
103  }
104 
105  //! Returns \c const_iterator pointing to the first element.
107  {
108  return elem;
109  }
110 
111  //! Returns \c const_iterator pointing to the first element.
113  {
114  return begin();
115  }
116 
117  //! Returns \c iterator pointing to the end element.
119  {
120  return elem + size;
121  }
122 
123  //! Returns \c const_iterator pointing to the end element.
125  {
126  return elem + size;
127  }
128 
129  //! Returns \c const_iterator pointing to the end element.
131  {
132  return end();
133  }
134 };
135 
136 //! Contains BID references for \c foxxll::typed_block , not intended for direct use.
137 template <typename Type, size_t Size, size_t RawSize, size_t NBids = 0>
138 class block_w_bids : public element_block<Type, Size>
139 {
140 public:
141  static constexpr size_t raw_size = RawSize;
142  static constexpr size_t kNBIDs = NBids;
143 
145 
146  //! Array of BID references
148 
149  //! An operator to access bid references
151  {
152  return ref[i];
153  }
154 
156  {
157  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] block_w_bids is constructed";
158  }
159 };
160 
161 template <typename Type, size_t Size, size_t RawSize>
162 class block_w_bids<Type, Size, RawSize, 0>
163  : public element_block<Type, Size>
164 {
165 public:
166  static constexpr size_t raw_size = RawSize;
167  static constexpr size_t kNBIDs = 0;
168 
170 
172  {
173  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] block_w_bids<> is constructed";
174  }
175 };
176 
177 //! Contains per block information for \c foxxll::typed_block , not intended for direct use.
178 template <typename Type, size_t RawSize, size_t NBids, typename MetaInfoType = void>
180  : public block_w_bids<Type, ((RawSize - sizeof(BID<RawSize>)* NBids - sizeof(MetaInfoType)) / sizeof(Type)), RawSize, NBids>
181 {
182 public:
183  //! Type of per block information element.
184  using info_type = MetaInfoType;
185 
186  //! Per block information element.
188 
190  {
191  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] block_w_info is constructed";
192  }
193 };
194 
195 template <typename Type, size_t RawSize, size_t NBids>
196 class block_w_info<Type, RawSize, NBids, void>
197  : public block_w_bids<Type, ((RawSize - sizeof(BID<RawSize>)* NBids) / sizeof(Type)), RawSize, NBids>
198 {
199 public:
200  using info_type = void;
201 
203  {
204  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] block_w_info<> is constructed";
205  }
206 };
207 
208 //! Contains per block filler for \c foxxll::typed_block , not intended for direct use.
209 template <typename BaseType, size_t FillSize = 0>
210 class add_filler : public BaseType
211 {
212 private:
213  //! Per block filler element.
215 
216 public:
218  {
219  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] add_filler is constructed";
220  }
221 };
222 
223 template <typename BaseType>
224 class add_filler<BaseType, 0>
225  : public BaseType
226 {
227 public:
229  {
230  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] add_filler<> is constructed";
231  }
232 };
233 
234 //! Helper to compute the size of the filler , not intended for direct use.
235 template <typename Type, size_t RawSize>
236 class expand_struct : public add_filler<Type, RawSize - sizeof(Type)>
237 { };
238 
239 //! \}
240 
241 } // namespace mng_local
242 
243 //! Block containing elements of fixed length.
244 //!
245 //! \tparam RawSize size of block in bytes
246 //! \tparam Type type of block's records
247 //! \tparam NRef number of block references (BIDs) that can be stored in the block (default is 0)
248 //! \tparam MetaInfoType type of per block information (default is no information - void)
249 //!
250 //! The data array of type Type is contained in the parent class \c foxxll::element_block, see related information there.
251 //! The BID array of references is contained in the parent class \c foxxll::block_w_bids, see related information there.
252 //! The "per block information" is contained in the parent class \c foxxll::block_w_info, see related information there.
253 //! \warning If \c RawSize > 2MB object(s) of this type can not be allocated on the stack (as a
254 //! function variable for example), because Linux POSIX library limits the stack size for the
255 //! main thread to (2MB - system page size)
256 template <size_t RawSize, typename Type, size_t NRef = 0, typename MetaInfoType = void>
258  : public mng_local::expand_struct<mng_local::block_w_info<Type, RawSize, NRef, MetaInfoType>, RawSize>
259 {
261 
262  constexpr static bool debug_block_life_cycle = false;
263 
264 public:
265  using value_type = Type;
267  using const_reference = const value_type &;
268  using pointer = value_type *;
269  using iterator = pointer;
270  using const_pointer = const value_type *;
272 
273  static constexpr size_t raw_size = RawSize; //!< size of block in bytes
274  static constexpr size_t size = Base::size; //!< number of elements in block
275  static constexpr bool has_only_data = (raw_size == (size * sizeof(value_type))); //!< no meta info, bids or (non-empty) fillers included in the block, allows value_type array addressing across block boundaries
276 
278 
280  {
281  static_assert(
282  sizeof(typed_block) == raw_size,
283  "sizeof(typed_block) == raw_size"
284  );
285  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] typed_block is constructed";
286 #if 0
287  assert(((long)this) % BlockAlignment == 0);
288 #endif
289  }
290 
291  /*!
292  * Writes block to the disk(s).
293  * \param bid block identifier, points the file(disk) and position
294  * \param on_complete completion handler
295  * \return \c pointer_ptr object to track status I/O operation after the call
296  */
298  completion_handler on_complete = completion_handler())
299  {
300  LOGC(debug_block_life_cycle) << "BLC:write " << bid;
301  return bid.storage->awrite(this, bid.offset, raw_size, on_complete);
302  }
303 
304  /*!
305  * Reads block from the disk(s).
306  * \param bid block identifier, points the file(disk) and position
307  * \param on_complete completion handler
308  * \return \c pointer_ptr object to track status I/O operation after the call
309  */
311  completion_handler on_complete = completion_handler())
312  {
313  LOGC(debug_block_life_cycle) << "BLC:read " << bid;
314  return bid.storage->aread(this, bid.offset, raw_size, on_complete);
315  }
316 
317  /*!
318  * Writes block to the disk(s).
319  * \param bid block identifier, points the file(disk) and position
320  * \param on_complete completion handler
321  * \return \c pointer_ptr object to track status I/O operation after the call
322  */
324  completion_handler on_complete = completion_handler())
325  {
326  LOGC(debug_block_life_cycle) << "BLC:write " << bid;
327  assert(bid.size >= raw_size);
328  return bid.storage->awrite(this, bid.offset, raw_size, on_complete);
329  }
330 
331  /*!
332  * Reads block from the disk(s).
333  * \param bid block identifier, points the file(disk) and position
334  * \param on_complete completion handler
335  * \return \c pointer_ptr object to track status I/O operation after the call
336  */
337  request_ptr read(const BID<0>& bid,
338  completion_handler on_complete = completion_handler())
339  {
340  LOGC(debug_block_life_cycle) << "BLC:read " << bid;
341  assert(bid.size >= raw_size);
342  return bid.storage->aread(this, bid.offset, raw_size, on_complete);
343  }
344 
345  static void* operator new (size_t bytes)
346  {
347  size_t meta_info_size = bytes % raw_size;
348  LOGC(debug_typed_block) << "typed::block operator new[]: bytes=" << bytes << ", meta_info_size=" << meta_info_size;
349 
350  void* result = aligned_alloc<BlockAlignment>(
351  bytes - meta_info_size, meta_info_size
352  );
353 
354 #if FOXXLL_WITH_VALGRIND
355  memset(result, 0, bytes);
356 #endif
357  return result;
358  }
359 
360  static void* operator new[] (size_t bytes)
361  {
362  size_t meta_info_size = bytes % raw_size;
363  LOGC(debug_typed_block) << "typed::block operator new[]: bytes=" << bytes << ", meta_info_size=" << meta_info_size;
364 
365  void* result = aligned_alloc<BlockAlignment>(
366  bytes - meta_info_size, meta_info_size
367  );
368 
369 #if FOXXLL_WITH_VALGRIND
370  memset(result, 0, bytes);
371 #endif
372  return result;
373  }
374 
375  static void* operator new (size_t /*bytes*/, void* ptr) // construct object in existing memory
376  {
377  return ptr;
378  }
379 
380  static void operator delete (void* ptr)
381  {
382  aligned_dealloc<BlockAlignment>(ptr);
383  }
384 
385  static void operator delete[] (void* ptr)
386  {
387  aligned_dealloc<BlockAlignment>(ptr);
388  }
389 
390  static void operator delete (void*, void*)
391  { }
392 
393 #if 1
394  // STRANGE: implementing destructor makes g++ allocate
395  // additional 4 bytes in the beginning of every array
396  // of this type !? makes aligning to 4K boundaries difficult
397  //
398  // http://www.cc.gatech.edu/grads/j/Seung.Won.Jun/tips/pl/node4.html :
399  // "One interesting thing is the array allocator requires more memory
400  // than the array size multiplied by the size of an element, by a
401  // difference of delta for metadata a compiler needs. It happens to
402  // be 8 bytes long in g++."
404  {
405  LOGC(debug_typed_block) << "[" << static_cast<void*>(this) << "] typed_block is destructed";
406  }
407 #endif
408 };
409 
410 //! \}
411 
412 } // namespace foxxll
413 
414 #endif // !FOXXLL_MNG_TYPED_BLOCK_HEADER
415 
416 /**************************************************************************/
value_type & reference
external_size_type offset
offset within the file of the block (uint64_t)
Definition: bid.hpp:118
reference operator[](size_t i)
An operator to access elements in the block.
Definition: typed_block.hpp:94
Helper to compute the size of the filler , not intended for direct use.
static constexpr bool debug_block_life_cycle
const value_type * const_pointer
iterator end()
Returns iterator pointing to the end element.
Type
VFS object type.
Definition: file_io.hpp:52
Specialization of block identifier class (BID) for variable size block size.
Definition: bid.hpp:112
virtual request_ptr awrite(void *buffer, offset_type pos, size_type bytes, const completion_handler &on_complete=completion_handler())=0
external_size_type offset
offset within the file of the block (uint64_t)
Definition: bid.hpp:50
const_pointer const_iterator
MetaInfoType info_type
Type of per block information element.
iterator begin()
Returns iterator pointing to the first element.
virtual request_ptr aread(void *buffer, offset_type pos, size_type bytes, const completion_handler &on_complete=completion_handler())=0
constexpr bool debug_typed_block
Definition: typed_block.hpp:31
constexpr size_t BlockAlignment
Definition: request.hpp:34
const_iterator end() const
Returns const_iterator pointing to the end element.
tlx::delegate< void(request *r, bool success)> completion_handler
completion handler
Definition: request.hpp:46
Contains per block information for foxxll::typed_block , not intended for direct use.
static constexpr size_t raw_size
static constexpr bool has_only_data
no meta info, bids or (non-empty) fillers included in the block, allows value_type array addressing a...
request_ptr read(const BID< 0 > &bid, completion_handler on_complete=completion_handler())
Reads block from the disk(s).
Contains per block filler for foxxll::typed_block , not intended for direct use.
bid_type & operator()(size_t i)
An operator to access bid references.
file * storage
pointer to the file of the block
Definition: bid.hpp:116
const_iterator begin() const
Returns const_iterator pointing to the first element.
High-performance smart pointer used as a wrapping reference counting pointer.
static const size_t bytes
number of bytes in uint_pair
Definition: uint_types.hpp:75
const_iterator cend() const
Returns const_iterator pointing to the end element.
Contains BID references for foxxll::typed_block , not intended for direct use.
const value_type & const_reference
request_ptr write(const BID< 0 > &bid, completion_handler on_complete=completion_handler())
Writes block to the disk(s).
filler_struct< FillSize > filler
Per block filler element.
request_ptr write(const bid_type &bid, completion_handler on_complete=completion_handler())
Writes block to the disk(s).
bid_type ref[kNBIDs]
Array of BID references.
static constexpr size_t size
number of elements in the block
Definition: typed_block.hpp:83
value_type * pointer
size_t size
size of the block in bytes
Definition: bid.hpp:120
file * storage
pointer to the file of the block
Definition: bid.hpp:48
value_type elem[kSize]
Array of elements of type Type.
Definition: typed_block.hpp:86
Contains data elements for foxxll::typed_block , not intended for direct use.
Definition: typed_block.hpp:72
request_ptr read(const bid_type &bid, completion_handler on_complete=completion_handler())
Reads block from the disk(s).
const_iterator cbegin() const
Returns const_iterator pointing to the first element.
info_type info
Per block information element.
static constexpr size_t raw_size
size of block in bytes
#define LOGC(cond)
Explicitly specify the condition for logging.
Definition: logger.hpp:137
static constexpr size_t kNBIDs
static constexpr size_t size
number of elements in block