SWC-DB  v0.5.12 C++ documentations
SWC-DB© (Super Wide Column Database) - High Performance Scalable Database (https://github.com/kashirin-alex/swc-db)
Buffer.h
Go to the documentation of this file.
1 /*
2  * SWC-DB© Copyright since 2019 Alex Kashirin <kashirin.alex@gmail.com>
3  * License details at <https://github.com/kashirin-alex/swc-db/#license>
4  */
5 
6 
7 #ifndef swcdb_core_Buffer_h
8 #define swcdb_core_Buffer_h
9 
10 #include "swcdb/core/Compat.h"
11 #include "swcdb/core/Exception.h"
12 
13 
14 namespace SWC { namespace Core {
15 
16 
17 template<typename T>
18 struct Buffer {
19 
20  typedef T value_type;
22  typedef std::shared_ptr<BufferT> Ptr;
23 
24 
26  static value_type* allocate(size_t sz) {
28  return new value_type[sz];
29  }
30 
31  constexpr SWC_CAN_INLINE
32  explicit Buffer() noexcept
33  : own(false), size(0), base(nullptr) {
34  }
35 
37  Buffer(size_t sz)
38  : own(sz), size(sz), base(size ? allocate(size) : nullptr) {
39  }
40 
41  constexpr SWC_CAN_INLINE
42  Buffer(value_type* data, size_t sz, bool take_ownership) noexcept
43  : own(take_ownership), size(sz), base(data) {
44  }
45 
46  constexpr SWC_CAN_INLINE
47  Buffer(BufferT& other) noexcept
48  : own(other.own), size(other.size), base(other.base) {
49  if(own) {
50  other.own = false;
51  other.base = nullptr;
52  }
53  }
54 
55  constexpr SWC_CAN_INLINE
56  Buffer(BufferT&& other) noexcept
57  : own(other.own), size(other.size), base(other.base) {
58  if(own) {
59  other.own = false;
60  other.size = 0;
61  other.base = nullptr;
62  }
63  }
64 
65  template<typename OtherT>
66  constexpr
67  Buffer(OtherT& other) noexcept;
68 
69  Buffer& operator=(const Buffer&) = delete;
70 
71  Buffer& operator=(Buffer&&) = delete;
72 
74  virtual ~Buffer() noexcept {
75  _free();
76  }
77 
79  void _free() noexcept {
80  if(own)
81  delete [] base;
82  }
83 
85  void free() noexcept {
86  _free();
87  base = nullptr;
88  size = 0;
89  }
90 
92  void reallocate(size_t len) {
93  if(len) {
94  _free();
95  own = true;
96  base = allocate(size = len);
97  } else {
98  free();
99  }
100  }
101 
103  void assign(const value_type* data, size_t len) {
104  reallocate(len);
105  if(len)
106  memcpy(base, data, len);
107  }
108 
109  void set(value_type* data, size_t len, bool take_ownership) noexcept {
110  _free();
111  own = take_ownership;
112  size = len;
113  base = data;
114  }
115 
116  void set(BufferT& other) noexcept {
117  _free();
118  base = other.base;
119  size = other.size;
120  if((own = other.own)) {
121  other.own = false;
122  other.base = nullptr;
123  }
124  }
125 
126  template<typename OtherT>
127  void set(OtherT& other) noexcept;
128 
129  bool own;
130  size_t size : 56;
132 
133 };
134 
135 
136 
137 template<typename BufferT>
138 struct BufferDyn : BufferT {
139 
140  using value_type = typename BufferT::value_type;
141  typedef std::shared_ptr<BufferDyn> Ptr;
142 
143 
144  constexpr SWC_CAN_INLINE
145  explicit BufferDyn() noexcept
146  : ptr(nullptr), mark(nullptr) {
147  }
148 
149  constexpr SWC_CAN_INLINE
150  BufferDyn(size_t sz)
151  : BufferT(sz), ptr(BufferT::base), mark(BufferT::base) {
152  }
153 
154  constexpr SWC_CAN_INLINE
155  BufferDyn(BufferDyn&& other) noexcept
156  : BufferT(std::move(other)), ptr(other.ptr), mark(other.mark) {
157  other.ptr = other.mark = nullptr;
158  }
159 
160 
161  BufferDyn(const BufferDyn&) = delete;
162 
163  BufferDyn& operator=(const BufferDyn&) = delete;
164 
166 
167 
168  ~BufferDyn() noexcept { }
169 
171  void free() {
172  BufferT::free();
173  ptr = mark = nullptr;
174  }
175 
176  constexpr
177  value_type* release(size_t* lenp) noexcept {
178  value_type* rbuf = BufferT::base;
179  if(lenp)
180  *lenp = fill();
181  BufferT::size = 0;
182  BufferT::base = ptr = mark = nullptr;
183  return rbuf;
184  }
185 
186  constexpr SWC_CAN_INLINE
187  size_t remaining() const noexcept {
188  return ptr ? BufferT::size - fill() : 0;
189  }
190 
191  constexpr SWC_CAN_INLINE
192  size_t fill() const noexcept {
193  return ptr - BufferT::base;
194  }
195 
196  constexpr SWC_CAN_INLINE
197  bool empty() const noexcept {
198  return ptr == BufferT::base;
199  }
200 
201  constexpr SWC_CAN_INLINE
202  void set_mark() noexcept {
203  mark = ptr;
204  }
205 
206  constexpr SWC_CAN_INLINE
207  void clear() noexcept {
208  ptr = BufferT::base;
209  }
210 
212  void ensure(size_t len) {
213  if(!len)
214  return;
215  if(!BufferT::base) {
216  BufferT::own = true;
217  ptr = mark = BufferT::base = BufferT::allocate(BufferT::size = len);
218 
219  } else {
220  size_t ptr_offset = ptr - BufferT::base;
221  size_t remain = BufferT::size - ptr_offset;
222  if(len > remain) {
223  len -= remain;
224  const value_type* base_old = BufferT::base;
225  size_t size_old = BufferT::size;
226  BufferT::size += len;
227  BufferT::base = BufferT::allocate(BufferT::size);
228  memcpy(BufferT::base, base_old, size_old);
229  if(BufferT::own)
230  delete [] base_old;
231  else
232  BufferT::own = true;
233  mark = BufferT::base + (mark - base_old);
234  ptr = BufferT::base + ptr_offset;
235  }
236  }
237  }
238 
240  value_type* add_unchecked(const value_type* data, size_t len) noexcept {
241  value_type* rptr = ptr;
242  if(len) {
243  memcpy(ptr, data, len);
244  ptr += len;
245  }
246  return rptr;
247  }
248 
249  value_type* add(const value_type* data, size_t len) {
250  ensure(len);
251  return add_unchecked(data, len);
252  }
253 
255  value_type* add(const std::string& data) {
256  return add(
257  reinterpret_cast<const value_type*>(data.c_str()), data.length());
258  }
259 
260  void add(const value_type data) {
261  ensure(1);
262  *ptr = data;
263  ++ptr;
264  }
265 
266  void set(const value_type* data, size_t len) {
267  clear();
268  ensure(len);
269  add_unchecked(data, len);
270  }
271 
272  void take_ownership(BufferDyn<BufferT>& other) noexcept {
273  BufferT::_free();
274  BufferT::own = other.own;
275  BufferT::size = other.size;
276  other.size = 0;
277  BufferT::base = other.base;
278  ptr = other.ptr;
279  mark = other.mark;
280  other.base = other.ptr = other.mark = nullptr;
281  }
282 
283  void take_ownership(BufferT& other) noexcept {
284  BufferT::_free();
285  BufferT::own = other.own;
286  BufferT::size = other.size;
287  BufferT::base = ptr = mark = other.base;
288  ptr += other.size;
289  other.base = nullptr;
290  other.size = 0;
291  }
292 
295 };
296 
297 
300 
301 
302 
303 // StaticBuffer specializations to DynamicBuffer
304 template<>
305 template<>
306 constexpr SWC_CAN_INLINE
307 StaticBuffer::Buffer(DynamicBuffer& other) noexcept
308  : own(other.own), size(other.fill()), base(other.base) {
309  if(own) {
310  other.own = false;
311  other.size = 0;
312  other.base = other.ptr = other.mark = nullptr;
313  }
314 }
315 
316 template<>
317 template<>
319 void StaticBuffer::set(DynamicBuffer& other) noexcept {
320  _free();
321  base = other.base;
322  size = other.fill();
323  if((own = other.own)) {
324  other.own = false;
325  other.size = 0;
326  other.base = other.ptr = other.mark = nullptr;
327  }
328 }
329 
330 } // namespace Core
331 
332 
333 
334 
342 
347 } // namespace SWC
348 
349 
350 #endif // swcdb_core_Buffer_h
SWC::Core::Buffer::Buffer
constexpr SWC_CAN_INLINE Buffer(BufferT &&other) noexcept
Definition: Buffer.h:56
SWC::Core::BufferDyn::set
void set(const value_type *data, size_t len)
Definition: Buffer.h:266
SWC::Core::BufferDyn::ptr
value_type * ptr
Definition: Buffer.h:293
SWC::Core::Buffer::~Buffer
virtual SWC_CAN_INLINE ~Buffer() noexcept
Definition: Buffer.h:74
SWC::Core::Buffer::reallocate
SWC_CAN_INLINE void reallocate(size_t len)
Definition: Buffer.h:92
SWC::Core::BufferDyn::add
value_type * add(const value_type *data, size_t len)
Definition: Buffer.h:249
SWC::Core::Buffer::Buffer
constexpr SWC_CAN_INLINE Buffer() noexcept
Definition: Buffer.h:32
data
T data
Definition: BitFieldInt.h:1
SWC::Core::Buffer::Buffer
constexpr SWC_CAN_INLINE Buffer(value_type *data, size_t sz, bool take_ownership) noexcept
Definition: Buffer.h:42
SWC::Core::BufferDyn::mark
value_type * mark
Definition: Buffer.h:294
SWC::Core::DynamicBuffer
BufferDyn< StaticBuffer > DynamicBuffer
Definition: Buffer.h:299
SWC::Core::Buffer::operator=
Buffer & operator=(const Buffer &)=delete
SWC::Core::BufferDyn::ensure
SWC_CAN_INLINE void ensure(size_t len)
Definition: Buffer.h:212
SWC::Core::BufferDyn::value_type
typename BufferT::value_type value_type
Definition: Buffer.h:140
SWC::Core::Buffer::Buffer
SWC_CAN_INLINE Buffer(size_t sz)
Definition: Buffer.h:37
SWC::Core::Buffer::_free
SWC_CAN_INLINE void _free() noexcept
Definition: Buffer.h:79
SWC::Core::BufferDyn::BufferDyn
BufferDyn(const BufferDyn &)=delete
SWC::Core::Buffer::Buffer
constexpr Buffer(OtherT &other) noexcept
SWC::Core::BufferDyn::take_ownership
void take_ownership(BufferT &other) noexcept
Definition: Buffer.h:283
SWC::Core::BufferDyn::add_unchecked
SWC_CAN_INLINE value_type * add_unchecked(const value_type *data, size_t len) noexcept
Definition: Buffer.h:240
SWC::Core::Buffer::allocate
static SWC_CAN_INLINE value_type * allocate(size_t sz)
Definition: Buffer.h:26
SWC::Core::Buffer::Buffer
constexpr SWC_CAN_INLINE Buffer(BufferT &other) noexcept
Definition: Buffer.h:47
SWC::Core::BufferDyn::clear
constexpr SWC_CAN_INLINE void clear() noexcept
Definition: Buffer.h:207
SWC::Core::Buffer::set
void set(OtherT &other) noexcept
SWC::Core::BufferDyn::~BufferDyn
~BufferDyn() noexcept
Definition: Buffer.h:168
SWC::Core::BufferDyn::BufferDyn
constexpr SWC_CAN_INLINE BufferDyn(size_t sz)
Definition: Buffer.h:150
SWC_CAN_INLINE
#define SWC_CAN_INLINE
Definition: Compat.h:102
Exception.h
SWC::Core::Buffer::operator=
Buffer & operator=(Buffer &&)=delete
SWC::Core::Buffer::base
value_type * base
Definition: Buffer.h:131
SWC
The SWC-DB C++ namespace 'SWC'.
Definition: main.cc:12
SWC::Core::BufferDyn::set_mark
constexpr SWC_CAN_INLINE void set_mark() noexcept
Definition: Buffer.h:202
SWC::Core::BufferDyn::add
void add(const value_type data)
Definition: Buffer.h:260
SWC::Core::BufferDyn
Definition: Buffer.h:138
SWC::Core::Buffer
Definition: Buffer.h:18
size
uint32_t size
Buffer size.
Definition: HeaderBufferInfo.h:47
Compat.h
SWC::Core::BufferDyn::add
SWC_CAN_INLINE value_type * add(const std::string &data)
Definition: Buffer.h:255
SWC::Core::Buffer::size
size_t size
Definition: Buffer.h:130
SWC::Core::Buffer::value_type
T value_type
Definition: Buffer.h:20
SWC::Core::Buffer::free
SWC_CAN_INLINE void free() noexcept
Definition: Buffer.h:85
SWC::Core::BufferDyn::free
SWC_CAN_INLINE void free()
Definition: Buffer.h:171
SWC::Core::BufferDyn::operator=
BufferDyn & operator=(const BufferDyn &)=delete
SWC::Core::Buffer::set
void set(BufferT &other) noexcept
Definition: Buffer.h:116
SWC::Core::StaticBuffer
Buffer< uint8_t > StaticBuffer
Definition: Buffer.h:298
SWC::Core::Buffer::BufferT
Buffer< value_type > BufferT
Definition: Buffer.h:21
SWC::Core::BufferDyn::take_ownership
void take_ownership(BufferDyn< BufferT > &other) noexcept
Definition: Buffer.h:272
SWC::Core::BufferDyn::fill
constexpr SWC_CAN_INLINE size_t fill() const noexcept
Definition: Buffer.h:192
SWC::Core::BufferDyn::operator=
BufferDyn & operator=(BufferDyn &&)=delete
SWC::Config::T
const uint64_t T
Definition: Property.h:27
SWC_EXPECT
#define SWC_EXPECT(_e_, _code_)
Definition: Exception.h:158
SWC::Core::BufferDyn::BufferDyn
constexpr SWC_CAN_INLINE BufferDyn(BufferDyn &&other) noexcept
Definition: Buffer.h:155
SWC::Core::BufferDyn::empty
constexpr SWC_CAN_INLINE bool empty() const noexcept
Definition: Buffer.h:197
SWC::Core::BufferDyn::release
constexpr value_type * release(size_t *lenp) noexcept
Definition: Buffer.h:177
SWC::Core::Buffer::Ptr
std::shared_ptr< BufferT > Ptr
Definition: Buffer.h:22
SWC::Core::BufferDyn::Ptr
std::shared_ptr< BufferDyn > Ptr
Definition: Buffer.h:141
SWC::Core::BufferDyn::remaining
constexpr SWC_CAN_INLINE size_t remaining() const noexcept
Definition: Buffer.h:187
SWC::Core::Buffer::own
bool own
Definition: Buffer.h:129
SWC::Core::BufferDyn::BufferDyn
constexpr SWC_CAN_INLINE BufferDyn() noexcept
Definition: Buffer.h:145
SWC::Core::Buffer::assign
SWC_CAN_INLINE void assign(const value_type *data, size_t len)
Definition: Buffer.h:103
SWC::Error::BAD_MEMORY_ALLOCATION
@ BAD_MEMORY_ALLOCATION
Definition: Error.h:48
SWC::Core::Buffer::set
void set(value_type *data, size_t len, bool take_ownership) noexcept
Definition: Buffer.h:109