Implement sparse list, implement schema.

This commit is contained in:
yukirij 2023-08-13 17:16:20 -07:00
parent 2cc6263a47
commit 549e8c090b
5 changed files with 129 additions and 59 deletions

View File

@ -12,8 +12,11 @@ fn check<T>(expected:T, actual:T) where T:std::fmt::Display, T:std::cmp::Partial
}
pub fn test() {
let schema = Schema::new();
schema.bind(1);
//unsafe { runtime::test(); }
let mut sch = Schema::new();
sch.assign("x", integer());
sch.bind(0x10);
}
#[cfg(test)]

View File

@ -3,9 +3,11 @@
TypeTree DB_TYPE;
NameTree DB_NAME;
SparseList<bool> DB_SCHEMA;
SparseList<Type::SchemaBinding> DB_SCHEMA;
Pool<Reference> DB_REFERENCE;
extern "C" void test() { }
extern "C" size_t type_outer(size_t type_id, size_t key)
{
return DB_TYPE.outer(type_id, key);
@ -699,7 +701,7 @@ extern "C" size_t schema_index(Reference addr, size_t key)
extern "C" size_t schema_bind(Reference addr, size_t id)
{
/*Type::SchemaBinding binding {0};
Type::SchemaBinding binding {0};
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
// prepare binding
@ -713,12 +715,9 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
binding.size = size + position;
}
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
*/
DB_SCHEMA.set(id, true);
// add binding to pool
//DB_SCHEMA.add(id, binding);
DB_SCHEMA.set(id, binding);
return id;
}

View File

@ -16,9 +16,11 @@ extern "C" struct Str {
extern TypeTree DB_TYPE;
extern NameTree DB_NAME;
extern SparseList<bool> DB_SCHEMA;
extern SparseList<Type::SchemaBinding> DB_SCHEMA;
extern Pool<Reference> DB_REFERENCE;
extern "C" void test();
extern "C" size_t type_outer(size_t id, size_t key);
extern "C" size_t type_inner(size_t id);
extern "C" size_t type_key(size_t id);

View File

@ -21,6 +21,8 @@ pub struct Str {
}
extern "C" {
pub fn test();
pub fn acquire(type_id:usize) -> Reference;
pub fn release(addr:Reference);

View File

@ -12,86 +12,127 @@ public:
~SparseList()
{ }
size_t length() const
{
}
void set(size_t index, const T& value)
{
printf("set(%zu) -begin\n", index);
// find first header with start less than index
size_t data_index = 0;
// find first header with bounds less than index
size_t header_index = 0;
for(; header_index < m_headers.size() && m_headers[header_index].start > index; ++header_index) {
data_index += m_headers[header_index].length;
}
for(; header_index < m_headers.size() && index > (m_headers[header_index].start + m_headers[header_index].length); ++header_index) { }
Header header {0};
// if no header exists, add header starting at index
if(header_index == m_headers.size()) {
Header header {0};
// append header to end
header.start = index;
header.length = 1;
header.index = m_data.size();
m_data.push_back(value);
}
// otherwise, update/append existing or insert new header
else {
size_t offset = index - m_headers[header_index].start;
m_headers.push_back(header);
} else {
if(index < m_headers[header_index].start) {
// insert header before current
header.start = index;
header.length = 1;
header.index = m_headers[header_index].index;
m_data.insert(m_data.begin() + m_headers[header_index].index, value);
m_headers.insert(m_headers.begin() + header_index, header);
if(offset < m_headers[header_index].length) {
// update existing item
size_t data_index = m_headers[header_index].index + offset;
m_data[data_index] = value;
}
else if(offset == m_headers[header_index].length) {
// append value to header
m_headers[header_index].length++;
m_data.insert(m_data.begin() + (m_headers[header_index].index + offset), value);
for(size_t i = header_index + 1; i < m_headers.size(); ++i) {
m_headers[i].index++;
}
} else {
size_t offset = index - m_headers[header_index].start;
if(offset < m_headers[header_index].length) {
// update existing value
m_data[m_headers[header_index].index + offset] = value;
} else {
// append value to current header
m_data.insert(m_data.begin() + (m_headers[header_index].index + offset), value);
m_headers[header_index].length += 1;
// combine headers if intersection is created
if(header_index + 1 != m_headers.size()) {
if(m_headers[header_index + 1].start == m_headers[header_index].start + m_headers[header_index].length) {
m_headers[header_index].length += m_headers[header_index + 1].length;
m_headers.erase(m_headers.begin() + (header_index + 1));
for(size_t i = header_index + 1; i < m_headers.size(); ++i) {
m_headers[i].index++;
}
}
}
else {
// insert new header after current
Header header {0};
header.start = index;
header.length = 1;
header.index = m_headers[header_index].index + 1;
m_data.insert(m_data.begin() + header.index, value);
// join headers if ranges intersect
if(header_index + 1 < m_headers.size()) {
if(m_headers[header_index + 1].start == m_headers[header_index].start + m_headers[header_index].length) {
m_headers[header_index].length += m_headers[header_index + 1].length;
m_headers.erase(m_headers.begin() + (header_index + 1));
}
}
}
printf("set() -end\n");
}
void unset(size_t index)
{
// find first header with start less than index
// find first header with bounds less than index
size_t header_index = 0;
for(; header_index < m_headers.size() && m_headers[header_index].start > index; ++header_index) { }
for(; header_index < m_headers.size() && index > (m_headers[header_index].start + m_headers[header_index].length - 1); ++header_index) { }
if(header_index < m_headers.size()) {
auto& header = m_headers[header_index];
size_t offset = index - header.start;
Header header {0};
if(offset < header.length) {
// remove value from data
if(header_index < m_headers.size() && index >= m_headers[header_index].start) {
size_t offset = index - m_headers[header_index].start;
size_t data_index = m_headers[header_index].index + offset;
if(offset == 0) {
// shift start of range
m_headers[header_index].start++;
} else if(offset < m_headers[header_index].length - 1) {
// split header at index
header.start = index + 1;
header.length = m_headers[header_index].length - offset - 1;
header.index = m_headers[header_index].index + offset + 1;
m_headers[header_index].length = offset + 1;
m_headers.insert(m_headers.begin() + (header_index + 1), header);
}
m_data.erase(m_data.begin() + data_index);
m_headers[header_index].length--;
for(size_t i = header_index + 1; i < m_headers.size(); ++i) {
m_headers[i].index--;
}
if(m_headers[header_index].length == 0) {
m_headers.erase(m_headers.begin() + header_index);
}
}
}
T& get(size_t index)
bool has(size_t index) const
{
size_t bound_lower = 0;
size_t bound_upper = m_headers.size();
size_t header_index = bound_lower + ((bound_upper - bound_lower) / 2);
while(bound_lower != bound_upper) {
}
return find_header(index) != m_headers.size();
}
const T* get(size_t index) const
{
size_t header_index = find_header(index);
if(header_index < m_headers.size()) {
size_t offset = index - m_headers[header_index].start;
return &m_data[m_headers[header_index].index + offset];
}
return nullptr;
}
/* void print() const
{
for(size_t h = 0; h < m_headers.size(); ++h) {
printf("%zu [%zu] @%zu [ ", m_headers[h].start, m_headers[h].length, m_headers[h].index);
for(size_t i = 0; i < m_headers[h].length; ++i) {
printf("%u ", m_data[m_headers[h].index + i]);
}
printf("]\n");
}
printf("---\n");
} */
private:
struct Header {
size_t start;
@ -99,6 +140,29 @@ private:
size_t index;
};
size_t find_header(size_t index) const
{
size_t bound_lower = 0;
size_t bound_upper = m_headers.size();
size_t header_index = 0;
while(bound_lower != bound_upper) {
header_index = bound_lower + ((bound_upper - bound_lower) / 2);
if(index >= m_headers[header_index].start && index < (m_headers[header_index].start + m_headers[header_index].length)) {
return header_index;
} else if(index < m_headers[header_index].start) {
// update upper bound
bound_upper = header_index;
} else {
// update lower bound
bound_lower = header_index + 1;
}
}
return m_headers.size();
}
size_t m_root;
std::vector<Header> m_headers;
std::vector<T> m_data;