Pool.h
Go to the documentation of this file.
1 /****
2  * ConfigDB/Pool.h
3  *
4  * Copyright 2024 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the ConfigDB Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  ****/
19 
20 #pragma once
21 
22 #include "Object.h"
23 
24 namespace ConfigDB
25 {
29 class PoolData
30 {
31 public:
33  {
34  assert(itemSize > 0 && itemSize <= 255);
35  }
36 
37  PoolData(const PoolData& other)
38  {
39  *this = other;
40  }
41 
42  PoolData(PoolData&& other);
43 
44  PoolData& operator=(const PoolData& other);
45 
46  size_t getCount() const
47  {
48  return count;
49  }
50 
51  size_t getCapacity() const
52  {
53  return count + space;
54  }
55 
56  size_t getItemSize() const
57  {
58  return itemSize;
59  }
60 
61  size_t getItemSize(size_t count) const
62  {
63  return count * itemSize;
64  }
65 
66  void* operator[](unsigned index)
67  {
68  return getItemPtr(index);
69  }
70 
71  const void* operator[](unsigned index) const
72  {
73  return getItemPtr(index);
74  }
75 
76  void clear()
77  {
78  free(buffer);
79  buffer = nullptr;
80  count = space = 0;
81  }
82 
83  bool ensureCapacity(size_t capacity);
84 
85  size_t usage() const
86  {
87  return getCapacity() * itemSize;
88  }
89 
90 protected:
91  void* allocate(size_t itemCount);
92  void deallocate(size_t itemCount);
93 
94  void* getItemPtr(unsigned index)
95  {
96  assert(index < count);
97  return static_cast<uint8_t*>(buffer) + getItemSize(index);
98  }
99 
100  const void* getItemPtr(unsigned index) const
101  {
102  assert(index < count);
103  return static_cast<const uint8_t*>(buffer) + getItemSize(index);
104  }
105 
106  void* buffer{};
107  uint16_t count{0};
108  uint8_t space{0};
109  uint8_t itemSize;
110 };
111 
116 public:
117  const char* value{};
118  uint16_t length{};
119 
120  CountedString() = default;
121 
122  CountedString(const char* value, uint16_t length) : value(value), length(length)
123  {
124  }
125 
126  explicit CountedString(const String& s) : value(s.c_str()), length(s.length())
127  {
128  }
129 
130  bool operator==(const CountedString& other) const
131  {
132  return length == other.length && memcmp(value, other.value, length) == 0;
133  }
134 
138  explicit operator bool() const
139  {
140  return value;
141  }
142 
143  explicit operator String() const
144  {
145  return String(value, length);
146  }
147 
151  uint16_t getStorageSize() const
152  {
153  return 1 + (length > 0x80) + length;
154  }
155 };
156 
178 class StringPool : public PoolData
179 {
180 public:
182  {
183  }
184 
186  {
187  clear();
188  }
189 
194  StringId find(const CountedString& string) const;
195 
196  StringId add(const CountedString& string);
197 
199  {
200  return find(string) ?: add(string);
201  }
202 
204  {
205  unsigned offset = ref - 1;
206  return offset < count ? getString(offset) : CountedString{};
207  }
208 
209  const char* getBuffer() const
210  {
211  return static_cast<const char*>(buffer);
212  }
213 
214 private:
215  CountedString getString(unsigned offset) const;
216 };
217 
224 class ArrayData : public PoolData
225 {
226 public:
227  using PoolData::PoolData;
228 
229  void* insert(unsigned index, const void* data = nullptr, size_t itemCount = 1);
230 
231  void* add(const void* data = nullptr, size_t itemCount = 1)
232  {
233  return insert(getCount(), data, itemCount);
234  }
235 
236  bool remove(unsigned index);
237 
241  void dispose()
242  {
243  clear();
244  itemSize = 0;
245  }
246 };
247 
253 class ArrayPool : public PoolData
254 {
255 public:
257  {
258  }
259 
260  ArrayPool(const ArrayPool& other);
261 
263  {
264  clear();
265  }
266 
267  ArrayId add(const ObjectInfo& object)
268  {
269  return add(object.structSize);
270  }
271 
272  ArrayId add(const PropertyInfo& prop)
273  {
274  return add(prop.getSize());
275  }
276 
278  {
279  return *static_cast<ArrayData*>(getItemPtr(id - 1));
280  }
281 
282  const ArrayData& operator[](ArrayId id) const
283  {
284  return *static_cast<const ArrayData*>(getItemPtr(id - 1));
285  }
286 
287  void clear();
288 
289  size_t usage() const
290  {
291  size_t n = PoolData::usage();
292  auto data = static_cast<const ArrayData*>(buffer);
293  for(unsigned i = 0; i < count; ++i) {
294  n += data->usage();
295  ++data;
296  }
297  return n;
298  }
299 
300 private:
301  ArrayId add(size_t itemSize);
302 };
303 
304 } // namespace ConfigDB
An array of fixed-sized items.
Definition: Pool.h:225
void dispose()
Clear and mark this array as 'not in use' so it can be re-used.
Definition: Pool.h:241
void * insert(unsigned index, const void *data=nullptr, size_t itemCount=1)
void * add(const void *data=nullptr, size_t itemCount=1)
Definition: Pool.h:231
bool remove(unsigned index)
This pool stores array data.
Definition: Pool.h:254
ArrayId add(const PropertyInfo &prop)
Definition: Pool.h:272
ArrayPool()
Definition: Pool.h:256
~ArrayPool()
Definition: Pool.h:262
ArrayId add(const ObjectInfo &object)
Definition: Pool.h:267
const ArrayData & operator[](ArrayId id) const
Definition: Pool.h:282
size_t usage() const
Definition: Pool.h:289
ArrayPool(const ArrayPool &other)
ArrayData & operator[](ArrayId id)
Definition: Pool.h:277
Base allocator, designed for good reallocation performance and low RAM footprint.
Definition: Pool.h:30
uint16_t count
Definition: Pool.h:107
size_t getCount() const
Definition: Pool.h:46
PoolData(const PoolData &other)
Definition: Pool.h:37
bool ensureCapacity(size_t capacity)
void * allocate(size_t itemCount)
void * getItemPtr(unsigned index)
Definition: Pool.h:94
void * buffer
Definition: Pool.h:106
PoolData(PoolData &&other)
PoolData & operator=(const PoolData &other)
uint8_t space
Definition: Pool.h:108
void clear()
Definition: Pool.h:76
size_t getCapacity() const
Definition: Pool.h:51
size_t usage() const
Definition: Pool.h:85
const void * operator[](unsigned index) const
Definition: Pool.h:71
PoolData(size_t itemSize)
Definition: Pool.h:32
size_t getItemSize(size_t count) const
Definition: Pool.h:61
void deallocate(size_t itemCount)
void * operator[](unsigned index)
Definition: Pool.h:66
uint8_t itemSize
Definition: Pool.h:109
size_t getItemSize() const
Definition: Pool.h:56
const void * getItemPtr(unsigned index) const
Definition: Pool.h:100
Pool for string data.
Definition: Pool.h:179
StringPool()
Definition: Pool.h:181
const char * getBuffer() const
Definition: Pool.h:209
~StringPool()
Definition: Pool.h:185
StringId add(const CountedString &string)
StringId find(const CountedString &string) const
Search for a string.
CountedString operator[](StringId ref) const
Definition: Pool.h:203
StringId findOrAdd(const CountedString &string)
Definition: Pool.h:198
The String class.
Definition: WString.h:133
Definition: Array.h:26
uint16_t StringId
Defines contained string data using index into string pool.
Definition: PropertyInfo.h:59
Identifies array storage within array pool.
Definition: PropertyData.h:31
Used by StringPool.
Definition: Pool.h:115
CountedString(const char *value, uint16_t length)
Definition: Pool.h:122
bool operator==(const CountedString &other) const
Definition: Pool.h:130
uint16_t length
Definition: Pool.h:118
CountedString(const String &s)
Definition: Pool.h:126
const char * value
Definition: Pool.h:117
uint16_t getStorageSize() const
Get buffer size required to store this string.
Definition: Pool.h:151
Definition: ObjectInfo.h:38
Property metadata.
Definition: PropertyInfo.h:126
uint8_t getSize() const
Get number of bytes required to store this property value within a structure.
Definition: PropertyInfo.h:177