first draft of the new allocator with transactions support

This commit is contained in:
Krasimir Angelov
2022-05-20 13:55:45 +02:00
parent 546dc01b5d
commit 5594679a83
24 changed files with 1582 additions and 2372 deletions

View File

@@ -5,6 +5,11 @@ template <class A>
struct PGF_INTERNAL Vector {
size_t len;
A data[];
public:
static void release(ref<Vector> vec) {
PgfDB::free(vec, vec->len*sizeof(A));
}
};
template <class A> inline PGF_INTERNAL
@@ -18,7 +23,6 @@ ref<Vector<A>> vector_new(size_t len)
template <class C, class A> inline PGF_INTERNAL
ref<C> vector_new(Vector<A> C::* field, size_t len)
{
ptrdiff_t offset = (ptrdiff_t) &(((C*) NULL)->*field);
ref<C> res = PgfDB::malloc<C>(len*sizeof(A)).as_object();
(res->*field).len = len;
return res;
@@ -27,19 +31,53 @@ ref<C> vector_new(Vector<A> C::* field, size_t len)
PGF_INTERNAL_DECL size_t
get_next_padovan(size_t min);
/* Resize a vector by creating a new one and copying the old content.
* The new vector is now also safe to update */
template <class A> inline PGF_INTERNAL
ref<Vector<A>> vector_resize(ref<Vector<A>> r, size_t len)
ref<Vector<A>> vector_copy(ref<Vector<A>> vec, size_t len)
{
ref<Vector<A>> res = PgfDB::realloc<Vector<A>>(r,get_next_padovan(len)*sizeof(A)).as_object();
size_t size = len*sizeof(A);
ref<Vector<A>> res = PgfDB::malloc<Vector<A>>(size);
res->len = len;
memcpy(res->data, vec->data, size);
return res;
}
/* Resize a vector by changing its length. If there is no enough space
* the implementation will create a copy, but whenever possible it will
* return the reference of the original vector. In the later case, it
* changes the length in-place which means that the function is safe
* only if the vector was created during the current transaction. */
template <class A> inline PGF_INTERNAL
ref<Vector<A>> vector_unsafe_resize(ref<Vector<A>> vec, size_t len)
{
size_t old_len = get_next_padovan(vec->len);
size_t new_len = get_next_padovan(len);
if (old_len == new_len)
return vec;
ref<Vector<A>> res = PgfDB::realloc<Vector<A>>(vec,old_len*sizeof(A),new_len*sizeof(A)).as_object();
res->len = len;
return res;
}
/* Resize a vector embedded in another structure, by changing its length.
* If there is no enough space the implementation will copy the structure,
* but whenever possible it will return a reference to
* the original structure. In the later case, it changes
* the vector's length in-place which means that the function is safe
* only if the structure was created during the current transaction. */
template <class C, class A> inline PGF_INTERNAL
ref<C> vector_resize(ref<C> r, Vector<A> C::* field, size_t len)
ref<C> vector_unsafe_resize(ref<C> r, Vector<A> C::* field, size_t len)
{
ptrdiff_t offset = (ptrdiff_t) &(((C*) NULL)->*field);
ref<C> res = PgfDB::realloc<C>(r,get_next_padovan(len)*sizeof(A)).as_object();
size_t old_len = get_next_padovan((r->*field).len);
size_t new_len = get_next_padovan(len);
if (old_len == new_len)
return r;
ref<C> res = PgfDB::realloc<C>(r,old_len*sizeof(A),new_len*sizeof(A)).as_object();
(res->*field).len = len;
return res;
}