Line data Source code
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 : {
14 : /**
15 : * Allocator base class and interface.
16 : *
17 : * Implements part of the binary data layout by providing access to the stored
18 : * elements. Not intended to be used by application code.
19 : */
20 : class Allocator
21 : {
22 : public:
23 614 : Allocator() {}
24 614 : 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 0 : virtual void compact(float /*threshold*/)
30 : {
31 0 : throw std::runtime_error("Compaction not implemented");
32 : }
33 3 : virtual bool isMovable() const { return false; } // allocation is moveable
34 63 : virtual bool isMutable() const { return true; } // data is mutable
35 : /**
36 : * Update allocation of the dynamic elem at index to have newSize bytes.
37 : *
38 : * The offset and size fields in the static section are updated as needed.
39 : * Does not copy the old data to the new location.
40 : *
41 : * @return the pointer to the elem at the new place, or nullptr if it was
42 : * not moved.
43 : */
44 0 : virtual uint8_t* updateAllocation(size_t /*index*/, bool /*copy*/,
45 : size_t /*newSize*/)
46 : {
47 0 : throw std::runtime_error("Dynamic allocation not implemented");
48 : }
49 :
50 : template <class T>
51 20180 : T* getItemPtr(const size_t offset)
52 : {
53 20180 : return reinterpret_cast<T*>(getData() + offset);
54 : }
55 :
56 : template <class T>
57 46334 : const T* getItemPtr(const size_t offset) const
58 : {
59 46334 : return reinterpret_cast<const T*>(getData() + offset);
60 : }
61 :
62 : template <class T>
63 20026 : T& getItem(const size_t offset)
64 : {
65 20026 : return *getItemPtr<T>(offset);
66 : }
67 :
68 : template <class T>
69 46125 : T getItem(const size_t offset) const
70 : {
71 46125 : return *getItemPtr<T>(offset);
72 : }
73 :
74 : template <class T>
75 59 : T* getDynamic(const size_t index)
76 : {
77 59 : return reinterpret_cast<T*>(getData() + _getOffset(index));
78 : }
79 :
80 : template <class T>
81 704 : const T* getDynamic(const size_t index) const
82 : {
83 704 : return reinterpret_cast<const T*>(getData() + _getOffset(index));
84 : }
85 :
86 695 : uint64_t getDynamicOffset(const size_t index) const
87 : {
88 695 : return _getOffset(index);
89 : }
90 :
91 859 : size_t getDynamicSize(const size_t index) const { return _getSize(index); }
92 120 : void check(const size_t numDynamics) const
93 : {
94 332 : for (size_t i = 0; i < numDynamics; ++i)
95 212 : _checkIndex(i);
96 120 : }
97 :
98 : protected:
99 12541 : uint64_t& _getOffset(const size_t i)
100 : {
101 12541 : _checkIndex(i);
102 12541 : return getItem<uint64_t>(4 + i * 16);
103 : }
104 1399 : uint64_t _getOffset(const size_t i) const
105 : {
106 1399 : _checkIndex(i);
107 1399 : return getItem<uint64_t>(4 + i * 16);
108 : }
109 6370 : uint64_t& _getSize(const size_t i)
110 : {
111 6370 : _checkIndex(i);
112 6370 : return getItem<uint64_t>(4 + 8 + i * 16);
113 : }
114 859 : uint64_t _getSize(const size_t i) const
115 : {
116 859 : _checkIndex(i);
117 859 : return getItem<uint64_t>(4 + 8 + i * 16);
118 : }
119 :
120 21381 : void _checkIndex(const size_t i) const
121 : {
122 21381 : const uint64_t offset = getItem<uint64_t>(4 + i * 16);
123 21381 : const uint64_t size = getItem<uint64_t>(4 + 8 + i * 16);
124 21381 : if (offset + size > getSize())
125 : throw std::runtime_error(
126 0 : "Internal allocator error: dynamic #" + std::to_string(i) +
127 0 : " at " + std::to_string(offset) + " size " +
128 0 : std::to_string(size) + " exceeds allocation size " +
129 0 : std::to_string(getSize()));
130 21381 : if (offset != 0 && offset < 4 + (i + 1) * 16)
131 : throw std::runtime_error(
132 0 : "Internal allocator error: dynamic #" + std::to_string(i) +
133 0 : " at " + std::to_string(offset) + " is within static section");
134 21381 : }
135 : };
136 : }
137 :
138 : #endif
|