SWC-DB  v0.5.12 C++ documentations
SWC-DB© (Super Wide Column Database) - High Performance Scalable Database (https://github.com/kashirin-alex/swc-db)
PageArena.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 #ifndef swcdb_core_PageArena_h
7 #define swcdb_core_PageArena_h
8 
9 
10 #include "swcdb/core/Comparators.h"
11 #include <unordered_set>
12 
13 
14 namespace SWC { namespace Core { namespace Mem {
15 
16 
17 struct Item final {
18  public:
19 
20  typedef Item* Ptr;
21 
23  const uint32_t size_;
24  const uint8_t* data_;
25  const size_t hash_;
26 
27 
28  Item() = delete;
29  Item(const Item&) = delete;
30  Item(Item&& other) = delete;
31  Item& operator=(const Item&) = delete;
32  Item& operator=(Item&&) = delete;
33 
34 
35  static Item::Ptr make(const uint8_t* buf, uint32_t size);
36 
37  Item(const uint8_t* ptr, uint32_t size) noexcept
38  : count(0), size_(size), data_(ptr), hash_(_hash()) {
39  }
40 
41  size_t _hash() const noexcept {
42  size_t ret = 0;
43  const uint8_t* dp = data_;
44  for(uint32_t sz = size_; sz; --sz, ++dp)
45  ret += (ret << 3) + *dp;
46  return ret;
47  //return std::hash<std::string_view>{}(
48  // std::string_view((const char*)data_, size_));
49  }
50 
51  void allocate() {
52  data_ = static_cast<uint8_t*>(memcpy(new uint8_t[size_], data_, size_));
53  }
54 
55  ~Item() noexcept {
56  if(data_)
57  delete[] data_;
58  }
59 
60  uint32_t size() const noexcept {
61  return size_;
62  }
63 
64  const uint8_t* data() const noexcept {
65  return data_;
66  }
67 
68  size_t hash() const noexcept {
69  return hash_;
70  }
71 
72  Ptr use() noexcept {
73  count.fetch_add(1);
74  return this;
75  }
76 
77  bool unused() noexcept {
78  return count.fetch_sub(1) == 1;
79  }
80 
81  void release();
82 
83  std::string_view to_string() const noexcept {
84  return std::string_view(reinterpret_cast<const char*>(data_), size_);
85  }
86 
87  bool less(const Item& other) const noexcept {
88  return size_ < other.size_ ||
89  (size_ == other.size() &&
90  Condition::mem_cmp(data_, other.data(), size_) < 0);
91  }
92 
93  bool equal(const Item& other) const noexcept {
94  return Condition::eq(data_, size_, other.data(), other.size());
95  }
96 
97  struct Equal {
98  bool operator()(const Ptr lhs, const Ptr rhs) const {
99  return lhs->equal(*rhs);
100  }
101  };
102 
103  struct Hash {
104  size_t operator()(const Ptr arr) const noexcept {
105  return arr->hash();
106  }
107  };
108 
109  struct Less {
110  bool operator()(const Ptr lhs, const Ptr rhs) const {
111  return lhs->less(*rhs);
112  }
113  };
114 
115 };
116 
117 
118 
119 
120 typedef std::unordered_set<Item::Ptr, Item::Hash, Item::Equal> PageBase;
121 class Page final : public PageBase {
122  //public std::set<Item::Ptr, Item::Less> {
123  public:
124  Page() : PageBase(8), m_mutex() { }
125 
126  ~Page() noexcept { }
127 
128  Item::Ptr use(const uint8_t* buf, uint32_t size) {
130 
131  auto tmp = new Item(buf, size);
132  auto r = insert(tmp);
133  if(r.second) {
134  (*r.first)->allocate();
135  } else {
136  tmp->data_ = nullptr;
137  delete tmp;
138  }
139  return (*r.first)->use();
140  }
141 
142  void free(Item::Ptr ptr) {
144 
145  auto it = find(ptr);
146  if(it != end() && !ptr->count) {
147  erase(it);
148  delete ptr;
149  }
150  }
151 
152  size_t count() const {
154 
155  size_t sz = size();
156  //for(Page* nxt = m_page; nxt ; nxt->next_page(nxt))
157  // sz += nxt->count();
158  return sz;
159  }
160 
161  /*
162  void next_page(Page*& page) const {
163  Core::ScopedLock lock(m_mutex);
164  page = m_page;
165  }
166  */
167 
168  private:
169  mutable std::mutex m_mutex;
170  //Page* m_page = nullptr; // upper ranges
171 
172 };
173 
174 /* Vector with narrow on hash
175 typedef std::vector<Item::Ptr> PageBase;
176 class Page final : public PageBase {
177  //public std::set<Item::Ptr, Item::Less> {
178  public:
179 
180 
181  Item::Ptr use(const uint8_t* buf, uint32_t sz) {
182  Core::ScopedLock lock(m_mutex);
183 
184  auto ptr = new Item(buf, sz);
185 
186  auto it = begin() + _narrow(*ptr);
187  for(; it != end() && (*it)->hash() <= ptr->hash(); ++it) {
188  if((*it)->hash() == ptr->hash() && (*it)->equal(*ptr)) {
189  ptr->data_ = nullptr;
190  delete ptr;
191  return (*it)->use();
192  }
193  }
194  ptr->allocate();
195  insert(it, ptr);
196  return ptr->use();
197  }
198 
199  void free(Item::Ptr ptr) {
200  Core::ScopedLock lock(m_mutex);
201 
202  for(auto it = begin() + _narrow(*ptr);
203  it != end() && (*it)->hash() <= ptr->hash(); ++it) {
204  if((*it)->hash() == ptr->hash() && (*it)->equal(*ptr)) {
205  delete *it;
206  erase(it);
207  return;
208  }
209  }
210  SWC_ASSERT(!ptr);
211  }
212 
213  size_t count() const {
214  Core::ScopedLock lock(m_mutex);
215  return size();
216  }
217 
218  private:
219 
220  size_t _narrow(const Item& item) const {
221  size_t offset = 0;
222  if(size() < narrow_sz || !item.size())
223  return offset;
224 
225  size_t sz = size() >> 1;
226  offset = sz;
227  for(;;) {
228  if((*(begin() + offset))->hash() < item.hash()) {
229  if(sz < narrow_sz)
230  break;
231  offset += sz >>= 1;
232  continue;
233  }
234  if(!(sz >>= 1))
235  ++sz;
236  if(offset < sz) {
237  offset = 0;
238  break;
239  }
240  offset -= sz;
241  }
242  return offset;
243  }
244 
245  mutable std::mutex m_mutex;
246  static const size_t narrow_sz = 20;
247 
248 };
249 */
250 
251 
252 class Arena final {
253 
254  public:
255  Item::Ptr use(const uint8_t* buf, uint32_t size) {
256  return page_by_sz(size).use(buf, size);
257  }
258 
259  void free(Item::Ptr ptr) {
260  page_by_sz(ptr->size()).free(ptr);
261  }
262 
263  Page& page_by_sz(uint32_t sz) {
264  return _pages[(sz > 1022 ? 1023 : (sz ? sz-1 : 0) ) >> 2];
265  }
266 
267  size_t count() const {
268  size_t sz = 0;
269  for(auto& p : _pages)
270  sz += p.count();
271  return sz;
272  }
273 
274  size_t pages() const {
275  return 256;
276  }
277 
278  const Page& page(uint8_t idx) const {
279  return _pages[idx];
280  }
281 
282  private:
283  Page _pages[256];
284 };
285 
286 } }}
287 
288 
289 
290 
291 namespace SWC { namespace Env {
293 } }
294 
295 
296 
297 namespace SWC { namespace Core { namespace Mem {
298 
299 
300 
301 Item::Ptr Item::make(const uint8_t* buf, uint32_t size) {
302  return Env::PageArena.use(buf, size);
303 }
304 
306  if(unused())
307  Env::PageArena.free(this);
308 }
309 
310 
311 
312 
313 
314 struct ItemPtr final { // Item as SmartPtr
315 
316  ItemPtr() : ptr(nullptr) { }
317 
318  ItemPtr(const ItemPtr& other) noexcept
319  : ptr(other.ptr ? other.ptr->use() : nullptr) {
320  }
321 
322  ItemPtr(ItemPtr&& other) noexcept : ptr(other.ptr) {
323  other.ptr = nullptr;
324  }
325 
326  ItemPtr(const uint8_t* buf, uint32_t size)
327  : ptr(Item::make(buf, size)) {
328  }
329 
330  ItemPtr& operator=(const ItemPtr& other) {
331  ptr = other.ptr->use();
332  return *this;
333  }
334 
336  ptr = other.ptr;
337  other.ptr = nullptr;
338  return *this;
339  }
340 
341  ~ItemPtr() noexcept {
342  if(ptr)
343  ptr->release();
344  }
345 
346  void release() {
347  if(ptr) {
348  ptr->release();
349  ptr = nullptr;
350  }
351  }
352 
353  void use(const ItemPtr& other) {
354  if(ptr)
355  ptr->release();
356  ptr = other.ptr->use();
357  }
358 
359  void use(const uint8_t* buf, uint32_t size) {
360  if(ptr)
361  ptr->release();
362  ptr = Item::make(buf, size);
363  }
364 
365  const uint8_t* data() const {
366  return ptr->data();
367  }
368 
369  uint32_t size() const {
370  return ptr->size();
371  }
372 
373  std::string_view to_string() const {
374  return ptr->to_string();
375  }
376 
377  mutable Item::Ptr ptr = nullptr;
378 };
379 
381  return l.ptr == r.ptr;
382 }
383 
384 
385 
386 }}}
387 
388 
389 #endif // swcdb_core_PageArena_h
SWC::Core::Mem::Arena::free
void free(Item::Ptr ptr)
Definition: PageArena.h:259
SWC::Core::Mem::ItemPtr::use
void use(const uint8_t *buf, uint32_t size)
Definition: PageArena.h:359
SWC::Core::Mem::Item::Ptr
Item * Ptr
Definition: PageArena.h:20
SWC::Env::PageArena
SWC::Core::Mem::Arena PageArena
Definition: PageArena.h:292
SWC::Core::Mem::Page::use
Item::Ptr use(const uint8_t *buf, uint32_t size)
Definition: PageArena.h:128
SWC::Core::Mem::Item::_hash
size_t _hash() const noexcept
Definition: PageArena.h:41
SWC::Core::Mem::Item::count
Core::Atomic< uint64_t > count
Definition: PageArena.h:22
SWC::Core::Mem::ItemPtr
Definition: PageArena.h:314
SWC::Core::Mem::ItemPtr::ItemPtr
ItemPtr()
Definition: PageArena.h:316
SWC::Core::Mem::Item::hash_
const size_t hash_
Definition: PageArena.h:25
SWC::Core::Atomic< uint64_t >
SWC::Core::ScopedLock
Definition: MutexLock.h:41
SWC::Core::Mem::Item::Less
Definition: PageArena.h:109
SWC::Core::Mem::Item::Equal::operator()
bool operator()(const Ptr lhs, const Ptr rhs) const
Definition: PageArena.h:98
SWC::Core::Mem::Item::Less::operator()
bool operator()(const Ptr lhs, const Ptr rhs) const
Definition: PageArena.h:110
SWC::Core::Mem::Arena::page_by_sz
Page & page_by_sz(uint32_t sz)
Definition: PageArena.h:263
SWC::Core::Mem::Page::Page
Page()
Definition: PageArena.h:124
SWC::Core::Mem::ItemPtr::release
void release()
Definition: PageArena.h:346
SWC::Core::Mem::Item::use
Ptr use() noexcept
Definition: PageArena.h:72
SWC::Core::Mem::Item::release
void release()
Definition: PageArena.h:305
SWC::Core::Mem::Item
Definition: PageArena.h:17
SWC::Core::Mem::Page
Definition: PageArena.h:121
SWC::Core::Mem::ItemPtr::use
void use(const ItemPtr &other)
Definition: PageArena.h:353
SWC::Core::Mem::Item::hash
size_t hash() const noexcept
Definition: PageArena.h:68
SWC::Condition::eq
SWC_CAN_INLINE bool eq(const uint8_t *p1, uint32_t p1_len, const uint8_t *p2, uint32_t p2_len) noexcept
Definition: Comparators.h:195
SWC::Core::Mem::Item::Hash::operator()
size_t operator()(const Ptr arr) const noexcept
Definition: PageArena.h:104
SWC::Core::Mem::Item::Item
Item()=delete
SWC::Core::Mem::Item::unused
bool unused() noexcept
Definition: PageArena.h:77
SWC::Core::Mem::Item::operator=
Item & operator=(Item &&)=delete
SWC::Core::Mem::Arena::count
size_t count() const
Definition: PageArena.h:267
SWC::Core::Mem::Item::Hash
Definition: PageArena.h:103
SWC::Condition::mem_cmp
int mem_cmp(const uint8_t *b1, const uint8_t *b2, size_t count) noexcept SWC_ATTRIBS((SWC_ATTRIB_O3))
Definition: Comparators_basic.h:197
SWC::Core::Mem::Page::free
void free(Item::Ptr ptr)
Definition: PageArena.h:142
SWC::Core::Mem::Item::make
static Item::Ptr make(const uint8_t *buf, uint32_t size)
Definition: PageArena.h:301
SWC::Core::Mem::ItemPtr::operator=
ItemPtr & operator=(const ItemPtr &other)
Definition: PageArena.h:330
SWC::Core::Mem::ItemPtr::operator=
ItemPtr & operator=(ItemPtr &&other)
Definition: PageArena.h:335
SWC
The SWC-DB C++ namespace 'SWC'.
Definition: main.cc:12
SWC::Core::Mem::Arena::_pages
Page _pages[256]
Definition: PageArena.h:283
SWC::Core::Mem::ItemPtr::ItemPtr
ItemPtr(ItemPtr &&other) noexcept
Definition: PageArena.h:322
SWC::Core::Mem::ItemPtr::ItemPtr
ItemPtr(const uint8_t *buf, uint32_t size)
Definition: PageArena.h:326
SWC::Core::Mem::Page::count
size_t count() const
Definition: PageArena.h:152
SWC::Core::Mem::PageBase
std::unordered_set< Item::Ptr, Item::Hash, Item::Equal > PageBase
Definition: PageArena.h:120
size
uint32_t size
Buffer size.
Definition: HeaderBufferInfo.h:47
SWC::Core::Mem::operator==
bool SWC_PURE_FUNC operator==(ItemPtr l, ItemPtr r)
Definition: PageArena.h:380
SWC_PURE_FUNC
#define SWC_PURE_FUNC
Definition: Compat.h:108
SWC::Core::Mem::Arena::use
Item::Ptr use(const uint8_t *buf, uint32_t size)
Definition: PageArena.h:255
SWC::Core::Mem::Page::m_mutex
std::mutex m_mutex
Definition: PageArena.h:169
SWC::Core::Mem::Item::size
uint32_t size() const noexcept
Definition: PageArena.h:60
SWC::Core::Mem::Arena::page
const Page & page(uint8_t idx) const
Definition: PageArena.h:278
SWC::Core::Mem::Item::data_
const uint8_t * data_
Definition: PageArena.h:24
SWC::Core::Mem::Item::allocate
void allocate()
Definition: PageArena.h:51
Comparators.h
SWC::Core::Mem::ItemPtr::ptr
Item::Ptr ptr
Definition: PageArena.h:377
SWC::Core::Mem::Arena::pages
size_t pages() const
Definition: PageArena.h:274
SWC::Core::Mem::Arena
Definition: PageArena.h:252
SWC::Core::Mem::Item::equal
bool equal(const Item &other) const noexcept
Definition: PageArena.h:93
SWC::Core::Mem::ItemPtr::to_string
std::string_view to_string() const
Definition: PageArena.h:373
SWC::Core::Mem::ItemPtr::size
uint32_t size() const
Definition: PageArena.h:369
SWC::Core::Mem::Item::Item
Item(const uint8_t *ptr, uint32_t size) noexcept
Definition: PageArena.h:37
SWC::Core::Mem::Item::operator=
Item & operator=(const Item &)=delete
SWC::Core::Mem::Item::data
const uint8_t * data() const noexcept
Definition: PageArena.h:64
SWC::Core::Mem::ItemPtr::data
const uint8_t * data() const
Definition: PageArena.h:365
SWC::Core::Mem::Item::less
bool less(const Item &other) const noexcept
Definition: PageArena.h:87
SWC::Core::Mem::Page::~Page
~Page() noexcept
Definition: PageArena.h:126
SWC::Core::Mem::ItemPtr::~ItemPtr
~ItemPtr() noexcept
Definition: PageArena.h:341
SWC::Core::Mem::Item::Item
Item(const Item &)=delete
SWC::Core::Atomic::fetch_sub
constexpr SWC_CAN_INLINE T fetch_sub(T v) noexcept
Definition: Atomic.h:88
SWC::Core::Atomic::fetch_add
constexpr SWC_CAN_INLINE T fetch_add(T v) noexcept
Definition: Atomic.h:93
SWC::Core::Mem::Item::~Item
~Item() noexcept
Definition: PageArena.h:55
SWC::Core::Mem::ItemPtr::ItemPtr
ItemPtr(const ItemPtr &other) noexcept
Definition: PageArena.h:318
SWC::Core::Mem::Item::Equal
Definition: PageArena.h:97
SWC::Core::Mem::Item::Item
Item(Item &&other)=delete
SWC::Core::Mem::Item::size_
const uint32_t size_
Definition: PageArena.h:23
SWC::Core::Mem::Item::to_string
std::string_view to_string() const noexcept
Definition: PageArena.h:83