ZeroBuf  0.5.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  virtual uint8_t* getData() = 0;
26  virtual const uint8_t* getData() const = 0;
27  virtual size_t getSize() const = 0;
28  virtual void copyBuffer(const void* data, size_t size) = 0;
29  virtual void compact(float /*threshold*/)
30  {
31  throw std::runtime_error("Compaction not implemented");
32  }
33  virtual bool isMovable() const { return false; } // allocation is moveable
34  virtual bool isMutable() const { return true; } // data is mutable
44  virtual uint8_t* updateAllocation(size_t /*index*/, bool /*copy*/,
45  size_t /*newSize*/)
46  {
47  throw std::runtime_error("Dynamic allocation not implemented");
48  }
49 
50  template <class T>
51  T* getItemPtr(const size_t offset)
52  {
53  return reinterpret_cast<T*>(getData() + offset);
54  }
55 
56  template <class T>
57  const T* getItemPtr(const size_t offset) const
58  {
59  return reinterpret_cast<const T*>(getData() + offset);
60  }
61 
62  template <class T>
63  T& getItem(const size_t offset)
64  {
65  return *getItemPtr<T>(offset);
66  }
67 
68  template <class T>
69  T getItem(const size_t offset) const
70  {
71  return *getItemPtr<T>(offset);
72  }
73 
74  template <class T>
75  T* getDynamic(const size_t index)
76  {
77  return reinterpret_cast<T*>(getData() + _getOffset(index));
78  }
79 
80  template <class T>
81  const T* getDynamic(const size_t index) const
82  {
83  return reinterpret_cast<const T*>(getData() + _getOffset(index));
84  }
85 
86  uint64_t getDynamicOffset(const size_t index) const
87  {
88  return _getOffset(index);
89  }
90 
91  size_t getDynamicSize(const size_t index) const { return _getSize(index); }
92  void check(const size_t numDynamics) const
93  {
94  for (size_t i = 0; i < numDynamics; ++i)
95  _checkIndex(i);
96  }
97 
98 protected:
99  uint64_t& _getOffset(const size_t i)
100  {
101  _checkIndex(i);
102  return getItem<uint64_t>(4 + i * 16);
103  }
104  uint64_t _getOffset(const size_t i) const
105  {
106  _checkIndex(i);
107  return getItem<uint64_t>(4 + i * 16);
108  }
109  uint64_t& _getSize(const size_t i)
110  {
111  _checkIndex(i);
112  return getItem<uint64_t>(4 + 8 + i * 16);
113  }
114  uint64_t _getSize(const size_t i) const
115  {
116  _checkIndex(i);
117  return getItem<uint64_t>(4 + 8 + i * 16);
118  }
119 
120  void _checkIndex(const size_t i) const
121  {
122  const uint64_t offset = getItem<uint64_t>(4 + i * 16);
123  const uint64_t size = getItem<uint64_t>(4 + 8 + i * 16);
124  if (offset + size > getSize())
125  throw std::runtime_error(
126  "Internal allocator error: dynamic #" + std::to_string(i) +
127  " at " + std::to_string(offset) + " size " +
128  std::to_string(size) + " exceeds allocation size " +
129  std::to_string(getSize()));
130  if (offset != 0 && offset < 4 + (i + 1) * 16)
131  throw std::runtime_error(
132  "Internal allocator error: dynamic #" + std::to_string(i) +
133  " at " + std::to_string(offset) + " is within static section");
134  }
135 };
136 }
137 
138 #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:44
Allocator base class and interface.
Definition: Allocator.h:20