18 #ifndef __HERMES_COMMON_ARRAY_H
19 #define __HERMES_COMMON_ARRAY_H
22 #include "../util/memory_handling.h"
25 #define INVALID_IDX INT_MAX
38 #define HERMES_PAGE_BITS 8
39 #define HERMES_PAGE_SIZE (1 << HERMES_PAGE_BITS)
40 #define HERMES_PAGE_MASK (HERMES_PAGE_SIZE - 1)
49 unsigned int page_count, size, nitems, unused_size, nunused;
53 Array(
int initial_page_count = 0) : pages(nullptr), unused(nullptr)
55 size = nitems = nunused = 0;
56 page_count = initial_page_count;
57 unused_size = initial_page_count;
61 this->pages = malloc_with_check<Array<TYPE>, TYPE*>(page_count,
this,
true);
62 for (
unsigned i = 0; i < this->page_count; i++)
63 this->pages[i] = malloc_with_check<
Array<TYPE>, TYPE>(HERMES_PAGE_SIZE,
this);
64 this->unused = malloc_with_check<Array<TYPE>,
int>(unused_size,
this,
true);
68 this->pages =
nullptr;
69 this->unused =
nullptr;
79 free_with_check(this->pages,
true);
80 free_with_check(this->unused,
true);
88 this->pages = realloc_with_check<Array, TYPE*>(this->
pages, array.page_count,
this);
89 this->unused = realloc_with_check<Array, int>(this->unused, array.unused_size,
this);
91 memcpy(this->unused, array.unused, array.unused_size *
sizeof(
int));
93 this->page_count = array.page_count;
94 this->size = array.size;
95 this->nitems = array.nitems;
96 this->unused_size = array.unused_size;
97 this->nunused = array.nunused;
98 this->append_only = array.append_only;
100 for (
unsigned i = 0; i < this->page_count; i++)
102 TYPE* new_page = malloc_with_check<Array<TYPE>, TYPE>(HERMES_PAGE_SIZE,
this);
103 memcpy(new_page, array.
pages[i],
sizeof(TYPE)* HERMES_PAGE_SIZE);
104 this->pages[i] = new_page;
111 for (
unsigned i = 0; i < this->page_count; i++)
112 free_with_check(pages[i]);
113 size = nitems = nunused = page_count = unused_size = 0;
123 this->append_only = append_only;
129 TYPE* ptr = this->
add();
141 if (!nunused || append_only)
143 if (!(size & HERMES_PAGE_MASK))
145 this->pages = realloc_with_check <Array<TYPE>, TYPE*>(this->
pages, this->page_count + 1,
this);
146 TYPE* new_page = malloc_with_check<Array<TYPE>, TYPE>(HERMES_PAGE_SIZE,
this);
147 pages[this->page_count++] = new_page;
155 int id = unused[nunused-- - 1];
171 if (nunused >= unused_size)
173 this->unused_size = std::max<int>(unused_size + 1, (int)(unused_size * 1.5));
174 this->unused = realloc_with_check<Array, int>(this->unused, this->unused_size,
this);
176 unused[nunused++] = id;
191 while (
get(index).used ==
false)
194 if (index >= nitems)
return INVALID_IDX;
208 while (
get(index).used ==
false)
211 if (index >= nitems)
return INVALID_IDX;
225 if (index > nitems - 1) index = nitems - 1;
226 while (
get(index).used ==
false)
229 if (index < 0)
return INVALID_IDX;
243 if (index > nitems - 1) index = nitems - 1;
244 while (
get(index).used ==
false)
247 if (index < 0)
return INVALID_IDX;
255 if (
get(idx).used ==
true)
return true;
263 if (!(size & HERMES_PAGE_MASK))
265 int local_page_count = this->page_count;
266 this->page_count = std::max<int>(this->page_count + 1, (int)(this->page_count * 1.5));
267 this->pages = realloc_with_check<Array, TYPE*>(this->
pages, this->page_count,
this);
268 for (
int new_i = local_page_count; new_i < this->page_count; new_i++)
269 pages[new_i] = malloc_with_check<Array, TYPE>(HERMES_PAGE_SIZE,
this);
278 int get_size()
const {
return size; }
279 int get_num_items()
const {
return nitems; }
281 TYPE&
get(
int id)
const {
return pages[
id >>
HERMES_PAGE_BITS][
id & HERMES_PAGE_MASK]; }
282 TYPE& operator[] (
int id)
const {
return get(id); }
296 const unsigned int page_bits;
297 const unsigned int page_size;
298 const unsigned int page_mask;
302 LightArray(
unsigned int page_bits = 9,
unsigned int default_page_count = 512) : page_bits(page_bits), page_size(1 << page_bits), page_mask((1 << page_bits) - 1), page_count(default_page_count), pages(
nullptr), presence(
nullptr)
305 pages = malloc_with_check<LightArray<TYPE>, TYPE*>(page_count,
this,
true);
306 presence = malloc_with_check<LightArray<TYPE>,
bool*>(page_count,
this,
true);
308 for (
int i = 0; i < page_count; i++)
310 pages[i] = malloc_with_check<LightArray<TYPE>, TYPE>(page_size,
this);
311 presence[i] = calloc_with_check<LightArray<TYPE>,
bool>(page_size,
this);
317 for (
unsigned int i = 0; i < page_count; i++)
319 memset(presence[i], 0, page_size *
sizeof(
bool));
330 for (
unsigned int i = 0; i < page_count; i++)
332 free_with_check(pages[i]);
333 free_with_check(presence[i]);
335 free_with_check(pages,
true);
336 free_with_check(presence,
true);
340 void add(TYPE item,
unsigned int id)
344 if (
id >= page_count * page_size)
346 int new_page_count = page_count + ((
id - (page_count * page_size)) / page_size) + 2;
348 pages = realloc_with_check<LightArray<TYPE>, TYPE*>(pages, new_page_count,
this);
349 presence = realloc_with_check<LightArray<TYPE>,
bool*>(presence, new_page_count,
this);
351 for (
int i = page_count; i < new_page_count; i++)
353 pages[i] = malloc_with_check<LightArray<TYPE>, TYPE>(page_size,
this);
354 presence[i] = calloc_with_check<LightArray<TYPE>,
bool>(page_size,
this);
357 page_count = new_page_count;
360 temp = pages[
id >> page_bits] + (
id & page_mask);
363 presence[
id >> page_bits][
id & page_mask] =
true;
370 unsigned int get_size()
const
380 return presence[
id >> page_bits][
id & page_mask];
384 TYPE&
get(
unsigned int id)
const
386 return pages[
id >> page_bits][
id & page_mask];
General namespace for the Hermes library.
void set_append_only(bool append_only)
int last(int idx=INT_MAX)
bool exists(int idx)
Checks whether an element exists at position idx.
void copy(const Array &array)
Makes this array to hold a copy of another one.
int prev(int idx=INT_MAX)
int add(TYPE item)
Wrapper function for std::vector::add() for compatibility purposes.
void add(TYPE item, unsigned int id)
Adds a new_ item to the array.
A light version of the array. For ordinal types or pointers, does not provide memory handling...
File containing common definitions, and basic global enums etc. for HermesCommon. ...
bool present(unsigned int id) const
Checks the id position for presence.
#define HERMES_PAGE_BITS
A generic, inflatable array.
void free()
Removes all elements from the array.