ZeroBuf  0.4.0
Zero-copy, zero-serialize, zero-hassle protocol buffers
Allocator.h
1 
2 /* Copyright (c) 2015-2016, Human Brain Project
3  * Stefan.Eilemann@epfl.ch
4  * grigori.chevtchenko@epfl.ch
5  */
6 
7 #ifndef ZEROBUF_ALLOCATOR_H
8 #define ZEROBUF_ALLOCATOR_H
9 
10 #include <zerobuf/types.h>
11 
12 namespace zerobuf
13 {
20 class Allocator
21 {
22 public:
23  Allocator() {}
24  virtual ~Allocator() {}
25 
26  virtual uint8_t* getData() = 0;
27  virtual const uint8_t* getData() const = 0;
28  virtual size_t getSize() const = 0;
29  virtual void copyBuffer( const void* data, size_t size ) = 0;
30  virtual void compact( float /*threshold*/ )
31  { throw std::runtime_error( "Compaction not implemented" ); }
32  virtual bool isMovable() const { return false; } // allocation is moveable
33  virtual bool isMutable() const { return true; } // data is mutable
34 
43  virtual uint8_t* updateAllocation( size_t /*index*/, bool /*copy*/,
44  size_t /*newSize*/ )
45  { throw std::runtime_error( "Dynamic allocation not implemented" ); }
46 
47 
48  template< class T > T* getItemPtr( const size_t offset )
49  { return reinterpret_cast< T* >( getData() + offset ); }
50 
51  template< class T > const T* getItemPtr( const size_t offset ) const
52  { return reinterpret_cast< const T* >( getData() + offset ); }
53 
54  template< class T > T& getItem( const size_t offset )
55  { return *getItemPtr< T >( offset ); }
56 
57  template< class T > T getItem( const size_t offset ) const
58  { return *getItemPtr< T >( offset ); }
59 
60  template< class T > T* getDynamic( const size_t index )
61  { return reinterpret_cast< T* >( getData() + _getOffset( index )); }
62 
63  template< class T > const T* getDynamic( const size_t index ) const
64  { return reinterpret_cast< const T* >( getData() + _getOffset(index)); }
65 
66  uint64_t getDynamicOffset( const size_t index ) const
67  { return _getOffset( index ); }
68 
69  size_t getDynamicSize( const size_t index ) const
70  { return _getSize( index ); }
71 
72  void check( const size_t numDynamics ) const
73  {
74  for( size_t i = 0; i < numDynamics; ++i )
75  _checkIndex( i );
76  }
77 
78 protected:
79  uint64_t& _getOffset( const size_t i )
80  { _checkIndex( i ); return getItem< uint64_t >( 4 + i * 16 ); }
81  uint64_t _getOffset( const size_t i ) const
82  { _checkIndex( i ); return getItem< uint64_t >( 4 + i * 16 ); }
83  uint64_t& _getSize( const size_t i )
84  { _checkIndex( i ); return getItem< uint64_t >( 4 + 8 + i * 16 ); }
85  uint64_t _getSize( const size_t i ) const
86  { _checkIndex( i ); return getItem< uint64_t >( 4 + 8 + i * 16 ); }
87 
88  void _checkIndex( const size_t i ) const
89  {
90  const uint64_t offset = getItem< uint64_t >( 4 + i * 16 );
91  const uint64_t size = getItem< uint64_t >( 4 + 8 + i * 16 );
92  if( offset + size > getSize( ))
93  throw std::runtime_error(
94  "Internal allocator error: dynamic #" + std::to_string( i ) +
95  " at " + std::to_string( offset ) + " size " +
96  std::to_string( size ) + " exceeds allocation size " +
97  std::to_string( getSize( )));
98  if( offset != 0 && offset < 4 + (i+1) * 16 )
99  throw std::runtime_error(
100  "Internal allocator error: dynamic #" + std::to_string( i ) +
101  " at " + std::to_string(offset) + " is within static section" );
102  }
103 };
104 }
105 
106 #endif
Zero-copy, zero-serialize, zero-hassle protocol buffers.
Definition: Allocator.h:12
virtual uint8_t * updateAllocation(size_t, bool, size_t)
Update allocation of the dynamic elem at index to have newSize bytes.
Definition: Allocator.h:43
Allocator base class and interface.
Definition: Allocator.h:20