Implemented schema and record, fixed bugs.

This commit is contained in:
yukirij 2023-08-14 23:57:38 -07:00
parent 549e8c090b
commit 5d4e6db64b
18 changed files with 566 additions and 171 deletions

View File

@ -36,8 +36,8 @@ While the runtime provides methods for directly acquring and releasing memory, i
|Decimal|x12|--|Floating-point representable numbers|
|Block|x1e|size|Constant-sized series of bytes|
|Sequence|x1f|--|Variable-sized series of bytes|
|Array|x21|size, type|Constant-sized, ordered collection|
|List|x22|type|Variable-sized, ordered collection|
|Array|x22|size, type|Constant-sized, ordered collection|
|List|x23|type|Variable-sized, ordered collection|
|Record|x7e|schema|Instance of a schema|
|Schema|x7f|--|Definition of abstract structure|
@ -82,13 +82,17 @@ release(refer);
---
`encode(refer:Reference) -> Vec<u8>`
`encode_raw(refer:Reference) -> Vec<u8>`
Serializes an object into binary encoding.
The raw variant does not produce a tag prefix for the root object.
> Not implemented
---
`decode(data:Vec<u8>) -> Result<Reference,()>`
`decode_raw(data:Vec<u8>, type_id:usize) -> Result<Reference,()>`
Parses a valid binary encoding and produces the represented object.
The raw variant does not decode a tag prefix on the root object.
> Not implemented
---

View File

@ -15,7 +15,10 @@
"files.associations": {
"xstring": "cpp",
"xmemory": "cpp",
"vector": "cpp"
"vector": "cpp",
"initializer_list": "cpp",
"type_traits": "cpp",
"xutility": "cpp"
}
}
}

View File

@ -7,11 +7,25 @@ use crate::runtime::{
use crate::tag;
use super::array;
/// Constant-sized, indexed, ordered collection.
pub struct Array {
managed:bool,
addr:Reference,
}
impl Array {
/// Allocates a new array of a given size and type.
///
/// # Arguments
///
/// * `length` - number of elements in the array
/// * `class` - type identifier of the array contents
///
/// # Examples
///
/// ```
/// // Produces an array of 8 integers.
/// let int_array = szun::Array::new(8, szun::integer());
/// ```
pub fn new(length:usize, class:usize) -> Self
{
Self {

View File

@ -5,7 +5,7 @@ use crate::runtime::{
list_capacity, list_length,
list_at,
list_clear,
list_insert, list_update,
list_insert, list_prepend, list_append, list_update,
list_remove,
list_reserve,
};
@ -69,14 +69,24 @@ impl List {
unsafe{list_insert(self.addr, index, source)};
}
pub fn prepend(&mut self, source:Reference)
{
unsafe{list_prepend(self.addr, source)};
}
pub fn append(&mut self, source:Reference)
{
unsafe{list_append(self.addr, source)};
}
pub fn set(&mut self, index:usize, source:Reference)
{
unsafe{list_update(self.addr, index, source)};
}
pub fn remove(&mut self, index:usize, count:usize)
pub fn remove(&mut self, index:usize)
{
unsafe{list_remove(self.addr, index, count)};
unsafe{list_remove(self.addr, index)};
}
pub fn reserve(&mut self, length:usize)

View File

@ -13,6 +13,7 @@ mod sequence; pub use sequence::Sequence;
mod array; pub use array::Array;
mod list; pub use list::List;
mod schema; pub use schema::Schema;
mod record; pub use record::Record;
pub enum Type {
Varying(Varying),

View File

@ -1,6 +1,12 @@
use crate::runtime::{
util::{name_indexof, name_keyof},
Reference,
acquire, release,
schema_has,
type_key,
record_length,
record_at, record_update,
record_indexof, record_keyof,
};
use crate::tag;
use super::record;
@ -12,28 +18,108 @@ pub struct Record {
impl Record {
pub fn new(schema:usize) -> Result<Self,()>
{
//if get_schema(schema) {
Ok(Self {
managed:true,
addr:unsafe {acquire(record())},
})
//} else {
// Err(())
//}
}
pub fn from(addr:Reference) -> Result<Self,()>
{
return if(unsafe {type_key(addr.class)} == tag::Record) {
Ok(Self { managed:false, addr:addr })
}
else {
if unsafe {schema_has(schema)} {
Ok(Self {
managed:true,
addr:unsafe {acquire(record(schema))},
})
} else {
Err(())
}
}
//pub fn set(key, Reference)
//pub fn get(key) -> Reference
pub fn from(addr:Reference) -> Result<Self,()>
{
return if(unsafe {type_key(addr.class)} == tag::RECORD) {
Ok(Self { managed:false, addr:addr })
} else {
Err(())
}
}
pub fn with(schema:usize, data:Vec<(&str, Reference)>) -> Result<Self,()>
{
match Self::new(schema) {
Ok(mut obj) => {
for (key, value) in data {
obj.set(key, value);
}
Ok(obj)
}
Err(_) => Err(())
}
}
pub fn with_values(schema:usize, data:Vec<Reference>) -> Result<Self,()>
{
match Self::new(schema) {
Ok(mut obj) => {
for index in 0..data.len() {
obj.set_at(index, data[index]);
}
Ok(obj)
}
Err(_) => Err(())
}
}
pub fn length(&self) -> usize
{
unsafe {record_length(self.addr)}
}
pub fn set_at(&mut self, index:usize, source:Reference)
{
unsafe { record_update(self.addr, index, source); }
}
pub fn set(&mut self, key:&str, source:Reference)
{
match self.indexof(key) {
Some(index) => {
unsafe { record_update(self.addr, index, source); }
}
None => { }
}
}
pub fn at(&self, index:usize) -> Reference
{
unsafe {record_at(self.addr, index)}
}
pub fn get(&self, key:&str) -> Reference
{
match self.indexof(key) {
Some(index) => {
unsafe {record_at(self.addr, index)}
}
None => Reference::null()
}
}
pub fn keyof(&self, index:usize) -> Option<String>
{
let result = unsafe {record_keyof(self.addr, index)};
if result != 0 {
Some(name_keyof(result))
}
else {
None
}
}
pub fn indexof(&self, key:&str) -> Option<usize>
{
let key_index = name_indexof(key);
let result = unsafe {record_indexof(self.addr, key_index)};
if result != self.length() {
Some(result)
}
else {
None
}
}
}
impl std::ops::Deref for Record {
type Target = Reference;

View File

@ -1,14 +1,12 @@
use crate::runtime::{
//util::{name_indexof, name_keyof},
util::name_indexof,
util::{name_indexof, name_keyof},
Reference,
acquire, release,
type_key,
schema_length,
schema_add,
schema_insert, schema_update, schema_get,
schema_remove,
schema_reorder,
schema_map, schema_unmap, schema_index,
schema_map, schema_unmap, schema_indexof, schema_keyof,
schema_bind,
};
use crate::tag;
@ -68,7 +66,7 @@ impl Schema {
pub fn add(&mut self, type_id:usize) -> usize
{
unsafe {schema_add(self.addr, type_id)}
unsafe {schema_insert(self.addr, usize::MAX, type_id)}
}
pub fn assign(&mut self, key:&str, type_id:usize)
@ -79,7 +77,7 @@ impl Schema {
schema_map(
self.addr,
key_index,
schema_add(self.addr, type_id)
schema_insert(self.addr, usize::MAX, type_id)
);
}
}
@ -88,16 +86,24 @@ impl Schema {
}
}
pub fn set(&mut self, index:usize, type_id:usize)
{
unsafe { schema_update(self.addr, index, type_id); }
}
pub fn get(&self, index:usize) -> Option<usize>
{
match unsafe {schema_get(self.addr, index)} {
0 => None,
value => Some(value),
}
}
pub fn remove(&mut self, index:usize)
{
unsafe { schema_remove(self.addr, index); }
}
pub fn reorder(&mut self, from:usize, to:usize)
{
unsafe { schema_reorder(self.addr, from, to); }
}
pub fn map(&mut self, key:&str, index:usize)
{
let key_index = name_indexof(key);
@ -110,16 +116,28 @@ impl Schema {
unsafe { schema_unmap(self.addr, key_index); }
}
pub fn index(&mut self, key:&str) -> usize
pub fn indexof(&mut self, key:&str) -> Option<usize>
{
let key_index = name_indexof(key);
unsafe {schema_index(self.addr, key_index)}
let result = unsafe {schema_indexof(self.addr, key_index)};
if result != self.length() {
Some(result)
}
else {
None
}
}
//pub fn key(&mut self, index:usize) -> String
//{
// name_keyof(unsafe {schema_key(self.addr, index)})
//}
pub fn keyof(&mut self, index:usize) -> Option<String>
{
let result = unsafe {schema_keyof(self.addr, index)};
if result != 0 {
Some(name_keyof(result))
}
else {
None
}
}
pub fn bind(&self, id:usize) -> usize
{

View File

@ -5,18 +5,58 @@ mod util;
mod runtime;
mod interface; pub use interface::*;
fn check<T>(expected:T, actual:T) where T:std::fmt::Display, T:std::cmp::PartialEq
{
print!(" ({}) ", if expected == actual { " " } else { "!" });
println!("'{}' = '{}'", expected, actual);
}
const SCH_MAGAZINE :usize = 0x110;
const SCH_MAGAZINE_ROW :usize = 0x111;
pub fn test() {
//unsafe { runtime::test(); }
Schema::with(vec![
("type", natural()),
("quantity", natural()),
]).bind(SCH_MAGAZINE_ROW);
Schema::with(vec![
("size", natural()),
("content", list(record(SCH_MAGAZINE_ROW))),
]).bind(SCH_MAGAZINE);
let mut sch = Schema::new();
sch.assign("x", integer());
sch.bind(0x10);
let mag = Record::with(SCH_MAGAZINE, vec![
("size", *Natural::with(30)),
]).unwrap();
let mut contents = List::from(mag.get("content")).unwrap();
contents.append(*Record::with_values(SCH_MAGAZINE_ROW, vec![
*Natural::with(2),
*Natural::with(5),
]).unwrap());
contents.append(*Record::with_values(SCH_MAGAZINE_ROW, vec![
*Natural::with(1),
*Natural::with(25),
]).unwrap());
{
// get and remove bullet
let mut list = List::from(mag.at(1)).unwrap();
if list.length() > 0 {
let row = Record::from(list.at(list.length() - 1)).unwrap();
let mut cell = Natural::from(row.at(1)).unwrap();
let value = cell.get();
if value > 1 {
cell.set(value - 1);
} else {
list.remove(list.length() - 1);
}
}
}
println!("Magazine ({})",
Natural::from(mag.at(0)).unwrap().get(),
);
for i in 0..contents.length() {
let row = Record::from(contents.at(i)).unwrap();
println!(" - {} [{}]",
Natural::from(row.at(0)).unwrap().get(),
Natural::from(row.at(1)).unwrap().get(),
);
}
}
#[cfg(test)]

View File

@ -23,6 +23,11 @@ extern "C" size_t type_key(size_t type_id)
return DB_TYPE.key(type_id);
}
extern "C" size_t type_innerkey(size_t type_id)
{
return DB_TYPE.key(DB_TYPE.inner(type_id));
}
extern "C" size_t type_size(size_t type_id)
{
if(DB_TYPE.has(type_id)) {
@ -43,10 +48,10 @@ extern "C" size_t type_size(size_t type_id)
};
case Type::Tag::List: return sizeof(Type::List);
case Type::Tag::Record: {
//if(DB_SCHEMA.has(type_key(type_inner(type_id)))) {
// return DB_SCHEMA.get().size;
//}
return 0;
auto binding = DB_SCHEMA.get(type_innerkey(type_id));
if(binding != nullptr) {
return binding->size;
}
}
case Type::Tag::Schema: return sizeof(Type::Schema);
default: return 0;
@ -55,6 +60,34 @@ extern "C" size_t type_size(size_t type_id)
return 0;
}
size_t type_alignment(size_t type_id)
{
if(DB_TYPE.has(type_id)) {
size_t type = DB_TYPE.key(type_id);
switch(type) {
case Type::Tag::Null: return 0;
case Type::Tag::Varying: return sizeof(size_t);
case Type::Tag::Boolean: return sizeof(Type::Boolean);
case Type::Tag::Natural: return sizeof(Type::Natural);
case Type::Tag::Integer: return sizeof(Type::Integer);
case Type::Tag::Block: return sizeof(uint8_t);
case Type::Tag::Sequence: return sizeof(size_t);
case Type::Tag::Array: return type_inner(type_id);
case Type::Tag::List: return sizeof(size_t);
case Type::Tag::Record: {
auto binding = DB_SCHEMA.get(type_innerkey(type_id));
if(binding != nullptr) {
return binding->alignment;
}
}
case Type::Tag::Schema: return sizeof(size_t);
default: return 0;
}
}
return 0;
}
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
{
std::string str(reinterpret_cast<const char*>(bytes), length);
@ -87,12 +120,12 @@ extern "C" void name_release(Str data)
}
}
void* allocate(size_t type_id, size_t count)
uint8_t* allocate(size_t type_id, size_t count)
{
void* mem = nullptr;
uint8_t* mem = nullptr;
size_t size = type_size(type_id) * count;
if(size > 0) {
mem = malloc(size);
mem = reinterpret_cast<uint8_t*>(malloc(size));
if(mem != nullptr) {
memset(mem, 0, size);
}
@ -142,6 +175,23 @@ void drop(Reference addr)
}
rawlist_clear(list.data);
} break;
case Type::Tag::Record: {
size_t schema_id = type_innerkey(addr.type);
auto binding = DB_SCHEMA.get(schema_id);
if(binding != nullptr) {
for(size_t i = 0; i < binding->data.size(); ++i) {
auto cell = record_cell(addr, i);
drop(cell);
}
}
} break;
case Type::Tag::Schema: {
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
rawlist_clear(object.data);
rawlist_clear(object.map);
} break;
}
memset(addr.address, 0, type_size(addr.type));
}
@ -205,6 +255,42 @@ bool copy(Reference src, Reference dst)
copy(list_at(source, i), list_at(destination, i));
}
} break;
case Type::Tag::Record: {
size_t schema_id = type_innerkey(source.type);
auto binding = DB_SCHEMA.get(schema_id);
if(binding != nullptr) {
for(size_t i = 0; i < binding->data.size(); ++i) {
auto src_cell = record_cell(source, i);
auto dst_cell = record_cell(destination, i);
copy(src_cell, dst_cell);
}
}
} break;
case Type::Tag::Schema: {
auto& src_schema = *reinterpret_cast<Type::Schema*>(source.address);
auto& dst_schema = *reinterpret_cast<Type::Schema*>(destination.address);
rawlist_reserve(dst_schema.data, sizeof(size_t), src_schema.data.length);
rawlist_reserve(dst_schema.map, sizeof(size_t), src_schema.map.length);
for(size_t i = 0; i < src_schema.data.length; ++i) {
auto src_cell = reinterpret_cast<size_t*>(rawlist_cell(src_schema.data, sizeof(size_t), i));
auto dst_cell = reinterpret_cast<size_t*>(rawlist_cell(dst_schema.data, sizeof(size_t), i));
if(src_cell != nullptr && dst_cell != nullptr) {
*dst_cell = *src_cell;
}
}
for(size_t i = 0; i < src_schema.map.length; ++i) {
auto src_cell = reinterpret_cast<size_t*>(rawlist_cell(src_schema.map, sizeof(size_t), i));
auto dst_cell = reinterpret_cast<size_t*>(rawlist_cell(dst_schema.map, sizeof(size_t), i));
if(src_cell != nullptr && dst_cell != nullptr) {
*dst_cell = *src_cell;
}
}
} break;
}
return true;
@ -297,12 +383,12 @@ extern "C" Type::Integer integer_get(Reference addr)
extern "C" size_t block_length(Reference addr)
{
return type_key(type_inner(addr.type));
return type_innerkey(addr.type);
}
extern "C" uint8_t block_get(Reference addr, size_t index)
{
size_t length = type_key(type_inner(addr.type));
size_t length = type_innerkey(addr.type);
if(index < length) {
return reinterpret_cast<uint8_t*>(addr.address)[index];
}
@ -311,7 +397,7 @@ extern "C" uint8_t block_get(Reference addr, size_t index)
extern "C" void block_set(Reference addr, size_t index, uint8_t value)
{
size_t length = type_key(type_inner(addr.type));
size_t length = type_innerkey(addr.type);
if(index < length) {
reinterpret_cast<uint8_t*>(addr.address)[index] = value;
}
@ -370,7 +456,7 @@ extern "C" void sequence_reserve(Reference addr, size_t capacity)
extern "C" size_t array_length(Reference addr)
{
return type_key(type_inner(addr.type));
return type_innerkey(addr.type);
}
Reference array_cell(Reference addr, size_t index)
@ -384,7 +470,7 @@ Reference array_cell(Reference addr, size_t index)
// validate for overflow
if(addr.address != nullptr && offset > 0 && index < length) {
result.type = type;
result.address = reinterpret_cast<void*>(reinterpret_cast<size_t>(addr.address) + (offset * index));
result.address = addr.address + (offset * index);
}
return result;
}
@ -488,47 +574,6 @@ extern "C" void list_clear(Reference addr)
drop(addr);
}
/*extern "C" void list_prepend(Reference addr, Reference source)
{
if(type_key(addr.type) == Type::Tag::List) {
size_t inner = type_inner(addr.type);
//size_t offset = type_size(inner);
// validate list can store value
if(type_key(inner) == Type::Tag::Varying || source.type == inner) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
if(list.length == list.capacity) {
list_reserve(addr, list.capacity * 2);
}
// copy source to cell
list.length++;
}
}
}*/
/*extern "C" void list_append(Reference addr, Reference source)
{
if(type_key(addr.type) == Type::Tag::List) {
Type::List& list = *reinterpret_cast<Type::List*>(addr.address);
size_t inner = type_inner(addr.type);
//size_t offset = type_size(inner);
// validate list can store value
if(type_key(inner) == Type::Tag::Varying || source.type == inner) {
if(list.length == list.capacity) {
list_reserve(addr, list.capacity * 2);
}
// copy source to cell
list.length++;
}
}
}*/
extern "C" void list_insert(Reference addr, size_t index, Reference source)
{
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
@ -547,6 +592,17 @@ extern "C" void list_insert(Reference addr, size_t index, Reference source)
}
}
extern "C" void list_prepend(Reference addr, Reference source)
{
list_insert(addr, 0, source);
}
extern "C" void list_append(Reference addr, Reference source)
{
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
list_insert(addr, list.data.length, source);
}
extern "C" void list_update(Reference addr, size_t index, Reference source)
{
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
@ -584,10 +640,10 @@ extern "C" void list_remove(Reference addr, size_t index)
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
size_t inner = type_inner(addr.type);
size_t offset = type_size(inner);
drop(list_at(addr, index));
rawlist_remove(list.data, offset, index);
if(index < list.data.length) {
drop(list_at(addr, index));
rawlist_remove(list.data, offset, index);
}
}
extern "C" void list_reserve(Reference addr, size_t capacity)
@ -608,6 +664,79 @@ extern "C" void list_reserve(Reference addr, size_t capacity)
}*/
// Record //
extern "C" size_t record_length(Reference addr)
{
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
if(binding != nullptr) {
return binding->data.size();
}
return 0;
}
Reference record_cell(Reference addr, size_t index)
{
Reference result {0};
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
if(binding != nullptr) {
if(index < binding->data.size()) {
result.type = binding->data[index].type;
result.address = addr.address + binding->data[index].offset;
}
}
return result;
}
extern "C" Reference record_at(Reference addr, size_t index)
{
Reference result = record_cell(addr, index);
if(type_key(result.type) == Type::Tag::Varying) {
result = varying_get(result);
}
return result;
}
extern "C" void record_update(Reference addr, size_t index, Reference source)
{
Reference destination {0};
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
if(binding != nullptr) {
if(index < binding->data.size()) {
destination.type = binding->data[index].type;
destination.address = addr.address + binding->data[index].offset;
copy(source, destination);
}
}
}
extern "C" size_t record_keyof(Reference addr, size_t index)
{
Reference destination {0};
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
if(binding != nullptr) {
if(index < binding->data.size()) {
return binding->data[index].key;
}
}
return 0;
}
extern "C" size_t record_indexof(Reference addr, size_t key)
{
Reference destination {0};
auto binding = DB_SCHEMA.get(type_innerkey(addr.type));
if(binding != nullptr) {
auto result = binding->map.get(key);
if(result != nullptr) {
return *result;
}
return binding->data.size();
}
return 0;
}
// Schema //
extern "C" size_t schema_length(Reference addr)
@ -616,31 +745,55 @@ extern "C" size_t schema_length(Reference addr)
return object.data.length;
}
extern "C" size_t schema_add(Reference addr, size_t type_id)
extern "C" size_t schema_insert(Reference addr, size_t index, size_t type_id)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
void* cell = rawlist_insert(object.data, sizeof(size_t), object.data.length);
if(index >= object.data.length) {
index = object.data.length;
}
void* cell = rawlist_insert(object.data, sizeof(size_t), index);
*reinterpret_cast<size_t*>(cell) = type_id;
return object.data.length - 1;
return index;
}
extern "C" void schema_update(Reference addr, size_t index, size_t type_id)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
if(index < object.data.length) {
auto cell = reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), index));
if(cell != nullptr) {
*cell = type_id;
}
}
}
extern "C" size_t schema_get(Reference addr, size_t index)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
if(index < object.data.length) {
auto cell = reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), index));
if(cell != nullptr) {
return *cell;
}
}
return 0;
}
extern "C" void schema_remove(Reference addr, size_t index)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
if(index < object.data.length) {
}
}
extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
if(index_from < object.data.length && index_to <= object.data.length) {
if(index_from > index_to) {
}
else {
rawlist_remove(object.data, sizeof(size_t), index);
// remove mapping
for(size_t i = 0; i < object.map.length; i++) {
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.data, sizeof(Type::Schema::Mapping), i));
if(cell != nullptr) {
if(cell->index == index) {
rawlist_remove(object.map, sizeof(Type::Schema::Mapping), i);
return;
}
}
}
}
}
@ -685,7 +838,7 @@ extern "C" void schema_unmap(Reference addr, size_t key)
}
}
extern "C" size_t schema_index(Reference addr, size_t key)
extern "C" size_t schema_indexof(Reference addr, size_t key)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
for(size_t i = 0; i < object.map.length; i++) {
@ -699,6 +852,20 @@ extern "C" size_t schema_index(Reference addr, size_t key)
return object.data.length;
}
extern "C" size_t schema_keyof(Reference addr, size_t index)
{
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
for(size_t i = 0; i < object.map.length; i++) {
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
if(cell != nullptr) {
if(cell->index == index) {
return cell->key;
}
}
}
return object.data.length;
}
extern "C" size_t schema_bind(Reference addr, size_t id)
{
Type::SchemaBinding binding {0};
@ -707,17 +874,54 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
// prepare binding
binding.binding = id;
for(size_t i = 0; i < object.data.length; ++i) {
Type::SchemaBinding::Row row {0};
size_t type_id = *reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), i));
size_t size = type_size(type_id);
size_t alignment = size;
size_t alignment = type_alignment(type_id);
binding.alignment = std::max(alignment, binding.alignment);
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
binding.size = size + position;
row.type = type_id;
row.offset = position;
binding.data.push_back(row);
}
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
for(size_t i = 0; i < object.map.length; ++i) {
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
binding.map.set(cell->key, cell->index);
binding.data[cell->index].key = cell->key;
}
/* printf("[Binding]\n");
printf(" Id: %zu\n", binding.binding);
printf(" Size: %zu\n", binding.size);
printf(" Align: %zu\n", binding.alignment);
printf(" Data:\n");
for(size_t i = 0; i < binding.data.size(); ++i) {
printf(" - %zu {%#x} (%zu)\n",
binding.data[i].type,
type_key(binding.data[i].type),
binding.data[i].offset
);
}
printf(" Map:\n");
for(size_t key : binding.map.indices()) {
printf(" - %zu -> %zu\n",
key,
*binding.map.get(key)
);
} */
// add binding to pool
DB_SCHEMA.set(id, binding);
return id;
}
extern "C" bool schema_has(size_t id)
{
return DB_SCHEMA.has(id);
}

View File

@ -32,7 +32,7 @@ extern "C" size_t name_indexof(const uint8_t* bytes, size_t length);
std::string name_keyof_internal(size_t index);
extern "C" Str name_keyof(size_t index);
void* allocate(size_t type_id, size_t count);
uint8_t* allocate(size_t type_id, size_t count);
extern "C" Reference acquire(size_t type_id);
extern "C" void release(Reference id);
extern "C" bool copy(Reference src, Reference dst);
@ -74,7 +74,6 @@ extern "C" Reference array_at(Reference addr, size_t index);
extern "C" void array_update(Reference addr, size_t index, Reference source);
// List //
extern "C" size_t list_capacity(Reference addr);
extern "C" size_t list_length(Reference addr);
Reference list_cell(Reference addr, size_t index);
@ -82,9 +81,9 @@ extern "C" Reference list_at(Reference addr, size_t index);
//extern "C" Reference list_first(Reference addr);
//extern "C" Reference list_last(Reference addr);
extern "C" void list_clear(Reference addr);
//extern "C" void list_prepend(Reference addr, Reference source);
//extern "C" void list_append(Reference addr, Reference source);
extern "C" void list_insert(Reference addr, size_t index, Reference source);
extern "C" void list_prepend(Reference addr, Reference source);
extern "C" void list_append(Reference addr, Reference source);
extern "C" void list_update(Reference addr, size_t index, Reference source);
//extern "C" void list_truncate(Reference addr, size_t maximum);
//extern "C" void list_shift(Reference addr);
@ -93,22 +92,24 @@ extern "C" void list_reserve(Reference addr, size_t capacity);
//extern "C" void list_resize(Reference addr, size_t length);
// Record //
/*
- set_at(index, value)
- set(key, value)
- get_at(index) value
- get(key) value
- key(index) key
- index(key) index
*/
extern "C" size_t record_length(Reference addr);
Reference record_cell(Reference addr, size_t index);
extern "C" Reference record_at(Reference addr, size_t index);
extern "C" void record_update(Reference addr, size_t index, Reference source);
extern "C" size_t record_keyof(Reference addr, size_t index);
extern "C" size_t record_indexof(Reference addr, size_t key);
// Schema //
extern "C" size_t schema_length(Reference addr);
extern "C" size_t schema_add(Reference addr, size_t type_id);
extern "C" size_t schema_insert(Reference addr, size_t index, size_t type_id);
extern "C" void schema_update(Reference addr, size_t index, size_t type_id);
extern "C" size_t schema_get(Reference addr, size_t index);
extern "C" void schema_remove(Reference addr, size_t index);
extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to);
//extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to);
extern "C" void schema_map(Reference addr, size_t key, size_t index);
extern "C" void schema_unmap(Reference addr, size_t key);
extern "C" size_t schema_index(Reference addr, size_t key);
extern "C" size_t schema_indexof(Reference addr, size_t key);
extern "C" size_t schema_keyof(Reference addr, size_t index);
extern "C" size_t schema_bind(Reference addr, size_t key);
extern "C" size_t schema_binding(size_t key);
extern "C" bool schema_has(size_t id);

View File

@ -7,6 +7,14 @@ pub struct Reference {
pub(crate) address:usize,
}
impl Reference {
pub fn null() -> Self
{
Self {
class:0,
address:0,
}
}
pub fn is_null(&self) -> bool
{
self.address != 0
@ -66,27 +74,35 @@ extern "C" {
//pub fn list_last(addr:Reference) -> Reference;
pub fn list_at(addr:Reference, index:usize) -> Reference;
pub fn list_clear(addr:Reference);
//pub fn list_prepend(addr:Reference, src:Reference);
//pub fn list_append(addr:Reference, src:Reference);
pub fn list_insert(addr:Reference, index:usize, src:Reference);
pub fn list_prepend(addr:Reference, src:Reference);
pub fn list_append(addr:Reference, src:Reference);
pub fn list_update(addr:Reference, index:usize, src:Reference);
//pub fn list_truncate(addr:Reference, maximum:usize);
//pub fn list_shift(addr:Reference, maximum:usize);
pub fn list_remove(addr:Reference, index:usize, count:usize);
pub fn list_remove(addr:Reference, index:usize);
pub fn list_reserve(addr:Reference, capacity:usize);
//pub fn list_resize(addr:Reference, length:usize);
//pub fn list_cut(addr:Reference, index:usize, length:usize) -> Reference;
//pub fn list_find(addr:Reference, target:Reference, start:usize) -> usize;
//pub fn list_count(addr:Reference, target:Reference, start:usize) -> usize;
pub fn record_length(addr:Reference) -> usize;
pub fn record_at(addr:Reference, index:usize) -> Reference;
pub fn record_update(addr:Reference, index:usize, source:Reference);
pub fn record_keyof(addr:Reference, index:usize) -> usize;
pub fn record_indexof(addr:Reference, key:usize) -> usize;
pub fn schema_length(addr:Reference) -> usize;
pub fn schema_add(addr:Reference, type_id:usize) -> usize;
pub fn schema_insert(addr:Reference, index:usize, type_id:usize) -> usize;
pub fn schema_update(addr:Reference, index:usize, type_id:usize);
pub fn schema_get(addr:Reference, index:usize) -> usize;
pub fn schema_remove(addr:Reference, index:usize);
pub fn schema_reorder(addr:Reference, from:usize, to:usize);
//pub fn schema_reorder(addr:Reference, from:usize, to:usize);
pub fn schema_map(addr:Reference, key:usize, index:usize);
pub fn schema_unmap(addr:Reference, key:usize);
pub fn schema_index(addr:Reference, key:usize) -> usize;
pub fn schema_indexof(addr:Reference, key:usize) -> usize;
pub fn schema_keyof(addr:Reference, index:usize) -> usize;
pub fn schema_bind(addr:Reference, id:usize) -> usize;
pub fn schema_has(id:usize) -> bool;
}

View File

@ -55,10 +55,10 @@ void rawlist_reorder(RawList& list, size_t offset, size_t from, size_t to)
}
}
inline void* rawlist_cell(RawList& list, size_t offset, size_t index)
inline uint8_t* rawlist_cell(RawList& list, size_t offset, size_t index)
{
if(index < list.capacity) {
return reinterpret_cast<void*>(reinterpret_cast<size_t>(list.data) + (offset * index));
return list.data + (offset * index);
}
else {
return nullptr;
@ -71,7 +71,7 @@ void rawlist_reserve(RawList& list, size_t offset, size_t capacity)
size_t block_size = offset * capacity;
void* old_data = list.data;
list.data = malloc(block_size);
list.data = reinterpret_cast<uint8_t*>(malloc(block_size));
memset(list.data, 0, block_size);
if(old_data != nullptr) {
memcpy(list.data, old_data, offset * list.length);

View File

@ -8,12 +8,12 @@ struct RawList {
size_t offset;
size_t capacity;
size_t length;
void* data;
uint8_t* data;
};
void* rawlist_insert(RawList& list, size_t offset, size_t index);
void rawlist_remove(RawList& list, size_t offset, size_t index);
inline void* rawlist_cell(RawList& list, size_t offset, size_t index);
inline uint8_t* rawlist_cell(RawList& list, size_t offset, size_t index);
void rawlist_reserve(RawList& list, size_t offset, size_t capacity);
void rawlist_clear(RawList& list);

View File

@ -121,17 +121,16 @@ public:
return nullptr;
}
/* void print() const
std::vector<size_t> indices() const
{
std::vector<size_t> result;
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]);
result.push_back(m_headers[h].start + i);
}
printf("]\n");
}
printf("---\n");
} */
return result;
}
private:
struct Header {

View File

@ -1,10 +1,11 @@
#include <cstdint>
#include <vector>
#include "sparselist.h"
#include "rawlist.h"
extern "C" struct Reference {
size_t type;
void* address;
size_t type;
uint8_t* address;
};
namespace Type {
@ -16,12 +17,12 @@ namespace Tag {
Boolean = 0x02,
Natural = 0x10,
Integer = 0x11,
Decimal = 0x12,
//Decimal = 0x12,
Block = 0x1e,
Sequence = 0x1f,
Array = 0x22,
List = 0x23,
Sparse = 0x24,
//Sparse = 0x24,
Record = 0x7e,
Schema = 0x7f,
};
@ -68,6 +69,7 @@ struct Schema {
struct SchemaBinding {
struct Row {
size_t key;
size_t type;
size_t offset;
};
@ -75,6 +77,8 @@ struct SchemaBinding {
size_t binding;
size_t alignment;
size_t size;
SparseList<size_t> map;
std::vector<Row> data;
};

View File

@ -45,10 +45,6 @@ bool TypeTree::has(size_t id)
size_t TypeTree::outer(size_t id, size_t key)
{
size_t find = 0;
//for(size_t i = 0; i < m_nodes.size(); ++i) {
// printf(" - [%u] : %u -> %u [%u]\n", i, m_nodes[i].parent, m_nodes[i].key, m_nodes[i].children.size());
//}
if(key != 0 && id < m_nodes.size()) {
Node& node = m_nodes[id];
for(size_t child : node.children) {

View File

@ -5,7 +5,7 @@ pub const VARYING :usize = 0x01;
pub const BOOLEAN :usize = 0x02;
pub const NATURAL :usize = 0x10;
pub const INTEGER :usize = 0x11;
pub const DECIMAL :usize = 0x12;
//pub const DECIMAL :usize = 0x12;
//pub const FLOAT :usize = 0x13;
//pub const COMPLEX :usize = 0x14;
//pub const RANGE :usize = 0x1c;
@ -16,7 +16,7 @@ pub const SEQUENCE :usize = 0x1f;
//pub const SET :usize = 0x21;
pub const ARRAY :usize = 0x22;
pub const LIST :usize = 0x23;
pub const SPARSE :usize = 0x24;
//pub const SPARSE :usize = 0x24;
//pub const TRIE :usize = 0x25;
//pub const MAP :usize = 0x26;
//pub const TREE :usize = 0x27;

View File

@ -83,7 +83,6 @@ fn unpack_data(data:&Vec<u8>, index:&mut usize, signed:bool) -> u64
result = (((data[*index] as u64) << pack_size) & 0xFF) >> pack_size;
if signed {
let sign_mask = 1 << (6 - pack_size);
println!("data: {}, mask: {}", result, sign_mask);
negative = (result & sign_mask) != 0;
result &= !sign_mask;
}