1#ifndef joedb_Freedom_Keeper_declared
2#define joedb_Freedom_Keeper_declared
17 virtual ptrdiff_t
size()
const = 0;
20 virtual ptrdiff_t
get_next(ptrdiff_t index)
const = 0;
22 virtual bool is_free(ptrdiff_t index)
const = 0;
23 virtual bool is_used(ptrdiff_t index)
const = 0;
28 virtual void resize(ptrdiff_t new_size) = 0;
29 virtual bool use(ptrdiff_t index) = 0;
30 virtual bool free(ptrdiff_t index) = 0;
34 for (ptrdiff_t i = 0; i <
size; i++)
41 for (ptrdiff_t i = 0; i <
size; i++)
62 Record(
bool is_free, ptrdiff_t next, ptrdiff_t previous):
70 std::vector<Record> records;
71 enum {used_list = 0, free_list = 1};
76 records[used_list].is_free =
false;
77 records[used_list].next = used_list;
78 records[used_list].previous = used_list;
80 records[free_list].is_free =
true;
81 records[free_list].next = free_list;
82 records[free_list].previous = free_list;
85 bool is_empty()
const override {
return used_count == 0;}
87 ptrdiff_t
size()
const override {
return ptrdiff_t(records.size() - 2);}
90 ptrdiff_t
get_next(ptrdiff_t index)
const override {
return records[index].next;}
91 ptrdiff_t
get_previous(ptrdiff_t index)
const override {
return records[index].previous;}
92 bool is_free(ptrdiff_t index)
const override {
return records[index].is_free;}
93 bool is_used(ptrdiff_t index)
const override
96 index < ptrdiff_t(records.size()) &&
97 !records[index].is_free;
104 ptrdiff_t result = records[free_list].next;
105 if (result == free_list)
108 result = records[free_list].next;
116 const ptrdiff_t index = records.size();
117 records.emplace_back(
true, records[free_list].next, free_list);
119 records[records[free_list].next].previous = index;
120 records[free_list].next = index;
128 while(
size() < new_size)
133 bool use(ptrdiff_t index)
override
139 Record &record = records[index];
140 record.is_free =
false;
142 records[record.previous].next = record.next;
143 records[record.next].previous = record.previous;
145 record.previous = records[used_list].previous;
146 record.next = used_list;
148 records[record.previous].next = index;
149 records[record.next].previous = index;
157 bool free(ptrdiff_t index)
override
163 Record &record = records[index];
164 record.is_free =
true;
166 records[record.previous].next = record.next;
167 records[record.next].previous = record.previous;
169 record.next = records[free_list].next;
172 records[records[free_list].next].previous = index;
173 records[free_list].next = index;
184 ptrdiff_t used_size = 0;
185 ptrdiff_t free_size = 0;
188 bool is_empty()
const override {
return used_size == 0;}
190 ptrdiff_t
size()
const override {
return free_size;}
194 if (used_size == free_size)
197 return used_size + 2;
216 const ptrdiff_t result = index + 1;
218 if (result == used_size + 2)
221 if (index == free_size + 2)
234 return used_size + 1;
239 if (used_size == free_size)
242 return free_size + 1;
245 const ptrdiff_t result = index - 1;
249 if (result == used_size + 1)
254 bool is_free(ptrdiff_t index)
const override {
return index - 2 >= used_size;}
255 bool is_used(ptrdiff_t index)
const override {
return index - 2 < used_size;}
260 if (free_size == used_size)
262 return used_size + 2;
265 ptrdiff_t
push_back()
override {
return ++free_size + 1;}
269 if (free_size <
size)
273 bool use(ptrdiff_t index)
override
275 if (index == used_size + 2 && used_size < free_size)
284 bool free(ptrdiff_t index)
override
286 if (index == used_size + 1 && index > 1)
297 if (index == used_size + 2 && used_size +
size <= free_size)
308 if (free_size == used_size)
327 void lose_compactness()
347 ptrdiff_t
size()
const override {
return fk->
size();}
360 bool use(ptrdiff_t index)
override
370 bool free(ptrdiff_t index)
override
372 if (!fk->
free(index))
bool use(ptrdiff_t index) override
bool is_used(ptrdiff_t index) const override
ptrdiff_t get_used_count() const override
ptrdiff_t get_free_record() override
Compact_Freedom_Keeper(const Compact_Freedom_Keeper &)=delete
ptrdiff_t get_first_free() const override
bool is_compact() const override
ptrdiff_t get_first_used() const override
ptrdiff_t get_previous(ptrdiff_t index) const override
void resize(ptrdiff_t new_size) override
ptrdiff_t push_back() override
bool is_empty() const override
Compact_Freedom_Keeper & operator=(const Compact_Freedom_Keeper &)=delete
bool free(ptrdiff_t index) override
bool use_vector(ptrdiff_t index, ptrdiff_t size) override
bool is_free(ptrdiff_t index) const override
ptrdiff_t size() const override
bool append_vector(ptrdiff_t size) override
ptrdiff_t get_next(ptrdiff_t index) const override
ptrdiff_t push_back() override
bool append_vector(ptrdiff_t size) override
ptrdiff_t get_next(ptrdiff_t index) const override
bool is_empty() const override
ptrdiff_t size() const override
bool is_free(ptrdiff_t index) const override
bool is_compact() const override
ptrdiff_t get_previous(ptrdiff_t index) const override
bool free(ptrdiff_t index) override
bool use_vector(ptrdiff_t index, ptrdiff_t size) override
void resize(ptrdiff_t size) override
ptrdiff_t get_used_count() const override
ptrdiff_t get_first_free() const override
bool is_used(ptrdiff_t index) const override
bool use(ptrdiff_t index) override
ptrdiff_t get_first_used() const override
ptrdiff_t get_free_record() override
virtual bool is_used(ptrdiff_t index) const =0
virtual bool use_vector(ptrdiff_t index, ptrdiff_t size)
virtual ptrdiff_t get_previous(ptrdiff_t index) const =0
virtual bool append_vector(ptrdiff_t size)
virtual bool is_empty() const =0
virtual ptrdiff_t size() const =0
virtual void resize(ptrdiff_t new_size)=0
virtual ~Freedom_Keeper()=default
virtual ptrdiff_t get_used_count() const =0
virtual bool is_free(ptrdiff_t index) const =0
virtual ptrdiff_t get_next(ptrdiff_t index) const =0
virtual ptrdiff_t get_first_free() const =0
virtual bool use(ptrdiff_t index)=0
virtual ptrdiff_t push_back()=0
virtual ptrdiff_t get_free_record()=0
virtual bool is_compact() const =0
virtual ptrdiff_t get_first_used() const =0
virtual bool free(ptrdiff_t index)=0
ptrdiff_t get_first_used() const override
ptrdiff_t get_first_free() const override
bool is_used(ptrdiff_t index) const override
ptrdiff_t get_used_count() const override
void resize(ptrdiff_t new_size) override
ptrdiff_t get_previous(ptrdiff_t index) const override
bool is_empty() const override
bool is_free(ptrdiff_t index) const override
ptrdiff_t get_next(ptrdiff_t index) const override
ptrdiff_t size() const override
ptrdiff_t get_free_record() override
ptrdiff_t push_back() override
bool is_compact() const override
bool free(ptrdiff_t index) override
bool use(ptrdiff_t index) override
#define JOEDB_DEBUG_ASSERT(x)
#define JOEDB_RELEASE_ASSERT(x)