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() {
|
pub fn test() {
|
||||||
let schema = Schema::new();
|
//unsafe { runtime::test(); }
|
||||||
schema.bind(1);
|
|
||||||
|
let mut sch = Schema::new();
|
||||||
|
sch.assign("x", integer());
|
||||||
|
sch.bind(0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
|
|
||||||
TypeTree DB_TYPE;
|
TypeTree DB_TYPE;
|
||||||
NameTree DB_NAME;
|
NameTree DB_NAME;
|
||||||
SparseList<bool> DB_SCHEMA;
|
SparseList<Type::SchemaBinding> DB_SCHEMA;
|
||||||
Pool<Reference> DB_REFERENCE;
|
Pool<Reference> DB_REFERENCE;
|
||||||
|
|
||||||
|
extern "C" void test() { }
|
||||||
|
|
||||||
extern "C" size_t type_outer(size_t type_id, size_t key)
|
extern "C" size_t type_outer(size_t type_id, size_t key)
|
||||||
{
|
{
|
||||||
return DB_TYPE.outer(type_id, 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)
|
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));
|
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||||
|
|
||||||
// prepare binding
|
// prepare binding
|
||||||
@ -713,12 +715,9 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
|
|||||||
binding.size = size + position;
|
binding.size = size + position;
|
||||||
}
|
}
|
||||||
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
|
||||||
*/
|
|
||||||
|
|
||||||
DB_SCHEMA.set(id, true);
|
|
||||||
|
|
||||||
// add binding to pool
|
// add binding to pool
|
||||||
//DB_SCHEMA.add(id, binding);
|
DB_SCHEMA.set(id, binding);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,11 @@ extern "C" struct Str {
|
|||||||
|
|
||||||
extern TypeTree DB_TYPE;
|
extern TypeTree DB_TYPE;
|
||||||
extern NameTree DB_NAME;
|
extern NameTree DB_NAME;
|
||||||
extern SparseList<bool> DB_SCHEMA;
|
extern SparseList<Type::SchemaBinding> DB_SCHEMA;
|
||||||
extern Pool<Reference> DB_REFERENCE;
|
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_outer(size_t id, size_t key);
|
||||||
extern "C" size_t type_inner(size_t id);
|
extern "C" size_t type_inner(size_t id);
|
||||||
extern "C" size_t type_key(size_t id);
|
extern "C" size_t type_key(size_t id);
|
||||||
|
@ -21,6 +21,8 @@ pub struct Str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
pub fn test();
|
||||||
|
|
||||||
pub fn acquire(type_id:usize) -> Reference;
|
pub fn acquire(type_id:usize) -> Reference;
|
||||||
pub fn release(addr:Reference);
|
pub fn release(addr:Reference);
|
||||||
|
|
||||||
|
@ -12,86 +12,127 @@ public:
|
|||||||
~SparseList()
|
~SparseList()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
size_t length() const
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void set(size_t index, const T& value)
|
void set(size_t index, const T& value)
|
||||||
{
|
{
|
||||||
printf("set(%zu) -begin\n", index);
|
// find first header with bounds less than index
|
||||||
// find first header with start less than index
|
|
||||||
size_t data_index = 0;
|
|
||||||
size_t header_index = 0;
|
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); ++header_index) { }
|
||||||
data_index += m_headers[header_index].length;
|
|
||||||
}
|
Header header {0};
|
||||||
|
|
||||||
// if no header exists, add header starting at index
|
|
||||||
if(header_index == m_headers.size()) {
|
if(header_index == m_headers.size()) {
|
||||||
Header header {0};
|
// append header to end
|
||||||
header.start = index;
|
header.start = index;
|
||||||
header.length = 1;
|
header.length = 1;
|
||||||
header.index = m_data.size();
|
header.index = m_data.size();
|
||||||
m_data.push_back(value);
|
m_data.push_back(value);
|
||||||
}
|
m_headers.push_back(header);
|
||||||
// otherwise, update/append existing or insert new header
|
} else {
|
||||||
else {
|
if(index < m_headers[header_index].start) {
|
||||||
size_t offset = 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) {
|
for(size_t i = header_index + 1; i < m_headers.size(); ++i) {
|
||||||
// update existing item
|
m_headers[i].index++;
|
||||||
size_t data_index = m_headers[header_index].index + offset;
|
}
|
||||||
m_data[data_index] = value;
|
} else {
|
||||||
}
|
size_t offset = index - m_headers[header_index].start;
|
||||||
else if(offset == m_headers[header_index].length) {
|
if(offset < m_headers[header_index].length) {
|
||||||
// append value to header
|
// update existing value
|
||||||
m_headers[header_index].length++;
|
m_data[m_headers[header_index].index + offset] = value;
|
||||||
m_data.insert(m_data.begin() + (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
|
for(size_t i = header_index + 1; i < m_headers.size(); ++i) {
|
||||||
if(header_index + 1 != m_headers.size()) {
|
m_headers[i].index++;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// insert new header after current
|
// join headers if ranges intersect
|
||||||
Header header {0};
|
if(header_index + 1 < m_headers.size()) {
|
||||||
header.start = index;
|
if(m_headers[header_index + 1].start == m_headers[header_index].start + m_headers[header_index].length) {
|
||||||
header.length = 1;
|
m_headers[header_index].length += m_headers[header_index + 1].length;
|
||||||
header.index = m_headers[header_index].index + 1;
|
m_headers.erase(m_headers.begin() + (header_index + 1));
|
||||||
m_data.insert(m_data.begin() + header.index, value);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("set() -end\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unset(size_t index)
|
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;
|
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()) {
|
Header header {0};
|
||||||
auto& header = m_headers[header_index];
|
|
||||||
size_t offset = index - header.start;
|
|
||||||
|
|
||||||
if(offset < header.length) {
|
if(header_index < m_headers.size() && index >= m_headers[header_index].start) {
|
||||||
// remove value from data
|
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;
|
return find_header(index) != m_headers.size();
|
||||||
size_t bound_upper = m_headers.size();
|
|
||||||
size_t header_index = bound_lower + ((bound_upper - bound_lower) / 2);
|
|
||||||
|
|
||||||
while(bound_lower != bound_upper) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
private:
|
||||||
struct Header {
|
struct Header {
|
||||||
size_t start;
|
size_t start;
|
||||||
@ -99,6 +140,29 @@ private:
|
|||||||
size_t index;
|
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;
|
size_t m_root;
|
||||||
std::vector<Header> m_headers;
|
std::vector<Header> m_headers;
|
||||||
std::vector<T> m_data;
|
std::vector<T> m_data;
|
||||||
|
Reference in New Issue
Block a user