Implement sparse list, implement schema.
This commit is contained in:
parent
2cc6263a47
commit
549e8c090b
@ -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)]
|
||||
|
@ -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
|
||||
@ -712,13 +714,10 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
|
||||
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
|
||||
binding.size = size + position;
|
||||
}
|
||||
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
||||
*/
|
||||
|
||||
DB_SCHEMA.set(id, true);
|
||||
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
||||
|
||||
// add binding to pool
|
||||
//DB_SCHEMA.add(id, binding);
|
||||
DB_SCHEMA.set(id, binding);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -21,6 +21,8 @@ pub struct Str {
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn test();
|
||||
|
||||
pub fn acquire(type_id:usize) -> Reference;
|
||||
pub fn release(addr:Reference);
|
||||
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user