diff --git a/src/lib.rs b/src/lib.rs index cbe60e6..67e00cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,8 +12,11 @@ fn check(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)] diff --git a/src/runtime/lib.cc b/src/runtime/lib.cc index aaf6c33..433cce6 100644 --- a/src/runtime/lib.cc +++ b/src/runtime/lib.cc @@ -3,9 +3,11 @@ TypeTree DB_TYPE; NameTree DB_NAME; -SparseList DB_SCHEMA; +SparseList DB_SCHEMA; Pool 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(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; } diff --git a/src/runtime/lib.h b/src/runtime/lib.h index 459b6b1..5c8f9cb 100644 --- a/src/runtime/lib.h +++ b/src/runtime/lib.h @@ -16,9 +16,11 @@ extern "C" struct Str { extern TypeTree DB_TYPE; extern NameTree DB_NAME; -extern SparseList DB_SCHEMA; +extern SparseList DB_SCHEMA; extern Pool 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); diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 0c8a612..eaaa1c2 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -21,6 +21,8 @@ pub struct Str { } extern "C" { + pub fn test(); + pub fn acquire(type_id:usize) -> Reference; pub fn release(addr:Reference); diff --git a/src/runtime/sparselist.h b/src/runtime/sparselist.h index e727100..7f43a7b 100644 --- a/src/runtime/sparselist.h +++ b/src/runtime/sparselist.h @@ -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
m_headers; std::vector m_data;