start storage

main
Ziyang Hu 2 years ago
parent 0f8d3f2414
commit bf8c6db090

1
.gitignore vendored

@ -13,3 +13,4 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
_path*

@ -1,13 +1,15 @@
use pest::iterators::{Pair, Pairs};
use crate::ast::parse_string;
use crate::env::Env;
use crate::env::{Env, StructuredEnvItem};
use crate::error::Result;
use crate::error::CozoError::*;
use crate::eval::Evaluator;
use crate::parser::{Rule};
use crate::typing::{Col, Columns, Edge, Index, Node, Structured, StructuredEnv, StructuredEnvItem, TableId, Typing};
use crate::storage::Storage;
use crate::typing::{Col, Columns, Edge, Index, Node, Structured, TableId, Typing};
use crate::typing::Persistence::{Global, Local};
use crate::typing::StorageStatus::Planned;
use crate::value::Value;
use crate::typing::StorageStatus::{Planned, Stored};
use crate::value::{ByteArrayBuilder, Value};
fn parse_ident(pair: Pair<Rule>) -> String {
pair.as_str().to_string()
@ -41,11 +43,11 @@ fn parse_col_name(pair: Pair<Rule>) -> Result<(String, bool)> {
impl StructuredEnvItem {
pub fn build_edge_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<()> {
pub fn build_edge_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<String> {
let mut inner = pair.into_inner();
let src_name = build_name_in_def(inner.next().unwrap(), true)?;
let src = self.resolve(&src_name).ok_or(UndefinedType)?;
let src_id = if let Structured::Node(n, _) = src {
let src_id = if let Structured::Node(n) = src {
n.id
} else {
return Err(WrongType);
@ -53,7 +55,7 @@ impl StructuredEnvItem {
let name = build_name_in_def(inner.next().unwrap(), true)?;
let dst_name = build_name_in_def(inner.next().unwrap(), true)?;
let dst = self.resolve(&dst_name).ok_or(UndefinedType)?;
let dst_id = if let Structured::Node(n, _) = dst {
let dst_id = if let Structured::Node(n) = dst {
n.id
} else {
return Err(WrongType);
@ -67,34 +69,36 @@ impl StructuredEnvItem {
(vec![], vec![])
};
let edge = Edge {
status: Planned,
src: src_id,
dst: dst_id,
id: table_id,
keys,
cols,
};
if self.define_new(name.to_string(), Structured::Edge(edge, Planned)) {
if let Some(Structured::Node(src, _)) = self.resolve_mut(&src_name) {
if self.define_new(name.to_string(), Structured::Edge(edge)) {
if let Some(Structured::Node(src)) = self.resolve_mut(&src_name) {
src.out_e.push(table_id);
} else {
unreachable!()
}
if let Some(Structured::Node(dst, _)) = self.resolve_mut(&dst_name) {
if let Some(Structured::Node(dst)) = self.resolve_mut(&dst_name) {
dst.in_e.push(table_id);
} else {
unreachable!()
}
Ok(())
Ok(name.to_string())
} else {
Err(NameConflict)
}
}
pub fn build_node_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<()> {
pub fn build_node_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<String> {
let mut inner = pair.into_inner();
let name = build_name_in_def(inner.next().unwrap(), true)?;
let (keys, cols) = self.build_col_defs(inner.next().unwrap())?;
let node = Node {
status: Planned,
id: table_id,
keys,
cols,
@ -102,8 +106,8 @@ impl StructuredEnvItem {
in_e: vec![],
attached: vec![],
};
if self.define_new(name.to_string(), Structured::Node(node, Planned)) {
Ok(())
if self.define_new(name.to_string(), Structured::Node(node)) {
Ok(name.to_string())
} else {
Err(NameConflict)
}
@ -116,38 +120,39 @@ impl StructuredEnvItem {
}
Ok(ret)
}
fn build_columns_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<()> {
fn build_columns_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<String> {
let mut inner = pair.into_inner();
let name = build_name_in_def(inner.next().unwrap(), true)?;
let node_name = build_name_in_def(inner.next().unwrap(), true)?;
let node = self.resolve(&node_name).ok_or(UndefinedType)?;
let node_id = if let Structured::Node(n, _) = node {
let node_id = if let Structured::Node(n) = node {
n.id
} else if let Structured::Edge(n, _) = node {
} else if let Structured::Edge(n) = node {
n.id
} else {
return Err(WrongType);
};
let (keys, cols) = self.build_col_defs(inner.next().unwrap())?;
if !keys.is_empty() {
return Err(UnexpectedIndexColumns)
return Err(UnexpectedIndexColumns);
}
if table_id.0 == Global && node_id.0 == Local {
return Err(IncompatibleEdge);
}
if self.define_new(name, Structured::Columns(Columns {
if self.define_new(name.clone(), Structured::Columns(Columns {
status: Planned,
id: table_id,
attached: node_id,
cols
}, Planned)) {
Ok(())
cols,
})) {
Ok(name)
} else {
Err(NameConflict)
}
}
fn build_index_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<()> {
fn build_index_def(&mut self, pair: Pair<Rule>, table_id: TableId) -> Result<String> {
let mut inner = pair.into_inner();
let mut name = build_name_in_def(inner.next().unwrap(), true)?;
let node_name;
@ -172,7 +177,7 @@ impl StructuredEnvItem {
};
let node = self.resolve(&node_name).ok_or(UndefinedType)?;
let node_id = if let Structured::Node(n, _) = node {
let node_id = if let Structured::Node(n) = node {
n.id
} else {
return Err(WrongType);
@ -183,12 +188,13 @@ impl StructuredEnvItem {
// TODO: make sure cols make sense
if self.define_new(name, Structured::Index(Index {
if self.define_new(name.clone(), Structured::Index(Index {
status: Planned,
id: table_id,
attached: node_id,
cols: col_list,
}, Planned)) {
Ok(())
})) {
Ok(name)
} else {
Err(NameConflict)
}
@ -238,9 +244,9 @@ impl StructuredEnvItem {
let typ = self.build_type(pairs.next().unwrap())?;
let default = if let Some(p) = pairs.next() {
// TODO: check value is suitable for the type
Some(self.build_default_value(p)?)
self.build_default_value(p)?
} else {
None
Value::Null
};
Ok((Col {
name,
@ -265,41 +271,75 @@ impl StructuredEnvItem {
}
}
impl StructuredEnv {
impl Storage {
fn persist_node(&mut self, node: &mut Node) -> Result<()> {
let mut key_writer = ByteArrayBuilder::with_capacity(8);
key_writer.build_varint(0);
key_writer.build_value(&Value::UInt(node.id.1 as u64));
// println!("{:#?}", node);
// println!("{:?}", key_writer.get());
node.status = Stored;
Ok(())
}
fn persist_edge(&mut self, edge: &mut Edge) -> Result<()> {
edge.status = Stored;
Ok(())
}
}
impl Evaluator {
pub fn restore_metadata(&mut self) {}
fn persist_change(&mut self, tname: &str) -> Result<()> {
let tbl = self.s_envs.resolve_mut(tname).unwrap();
match tbl {
Structured::Node(n) => self.storage.persist_node(n),
Structured::Edge(e) => self.storage.persist_edge(e),
Structured::Columns(_) => unimplemented!(),
Structured::Index(_) => unimplemented!(),
Structured::Typing(_) => panic!(),
}
}
pub fn build_table(&mut self, pairs: Pairs<Rule>) -> Result<()> {
let mut new_tables = vec![];
for pair in pairs {
match pair.as_rule() {
r @ (Rule::global_def | Rule::local_def) => {
let inner = pair.into_inner().next().unwrap();
let is_local = r == Rule::local_def;
let next_id = self.get_next_table_id(is_local);
let next_id = self.s_envs.get_next_table_id(is_local);
let env_to_build = if is_local {
self.root_mut()
self.s_envs.root_mut()
} else {
self.cur_mut()
self.s_envs.cur_mut()
};
// println!("{:?} {:?}", r, inner.as_rule());
match inner.as_rule() {
new_tables.push(match inner.as_rule() {
Rule::node_def => {
env_to_build.build_node_def(inner, next_id)?;
env_to_build.build_node_def(inner, next_id)?
}
Rule::edge_def => {
env_to_build.build_edge_def(inner, next_id)?;
env_to_build.build_edge_def(inner, next_id)?
}
Rule::columns_def => {
env_to_build.build_columns_def(inner, next_id)?;
env_to_build.build_columns_def(inner, next_id)?
}
Rule::index_def => {
env_to_build.build_index_def(inner, next_id)?;
env_to_build.build_index_def(inner, next_id)?
}
_ => todo!()
}
});
}
Rule::EOI => {}
_ => unreachable!()
}
}
for tname in &new_tables {
self.persist_change(tname).unwrap(); // TODO proper error handling
}
Ok(())
}
}
@ -326,9 +366,9 @@ mod tests {
}
"#;
let parsed = Parser::parse(Rule::file, s).unwrap();
let mut env = StructuredEnv::new();
env.build_table(parsed).unwrap();
println!("{:#?}", env.resolve("Person"));
println!("{:#?}", env.resolve("Friend"));
let mut eval = Evaluator::new("_path_for_rocksdb_storagex".to_string()).unwrap();
eval.build_table(parsed).unwrap();
// println!("{:#?}", eval.s_envs.resolve("Person"));
// println!("{:#?}", eval.s_envs.resolve("Friend"));
}
}

@ -1,3 +1,6 @@
use std::collections::BTreeMap;
use crate::typing::{define_base_types, Persistence, Structured, TableId};
pub trait Env<V> {
fn define(&mut self, name: String, value: V) -> Option<V>;
fn define_new(&mut self, name: String, value: V) -> bool;
@ -12,4 +15,169 @@ pub trait LayeredEnv<V> : Env<V> {
fn root_resolve(&self, name: &str) -> Option<&V>;
fn root_resolve_mut(&mut self, name: &str) -> Option<&mut V>;
fn root_undef(&mut self, name: &str) -> Option<V>;
}
}
pub struct StructuredEnvItem {
map: BTreeMap<String, Structured>,
}
pub struct StructuredEnv {
stack: Vec<StructuredEnvItem>,
}
impl StructuredEnv {
pub fn new() -> Self {
let mut root = StructuredEnvItem { map: BTreeMap::new() };
define_base_types(&mut root);
Self { stack: vec![root] }
}
pub fn root(&self) -> &StructuredEnvItem {
&self.stack[0]
}
pub fn root_mut(&mut self) -> &mut StructuredEnvItem {
&mut self.stack[0]
}
pub fn cur(&self) -> &StructuredEnvItem {
self.stack.last().unwrap()
}
pub fn cur_mut(&mut self) -> &mut StructuredEnvItem {
self.stack.last_mut().unwrap()
}
pub fn push(&mut self) {
self.stack.push(StructuredEnvItem { map: BTreeMap::new() })
}
pub fn pop(&mut self) -> bool {
if self.stack.len() <= 1 {
false
} else {
self.stack.pop();
true
}
}
pub fn get_next_table_id(&self, local: bool) -> TableId {
let mut id = 0;
let persistence = if local { Persistence::Local } else { Persistence::Global };
for env in &self.stack {
for item in env.map.values() {
if let Some(TableId(p, eid)) = item.storage_id() {
if p == persistence {
id = id.max(eid);
}
}
}
}
TableId(persistence, id + 1)
}
}
impl LayeredEnv<Structured> for StructuredEnv {
fn root_define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.root_mut().define(name, value)
}
fn root_define_new(&mut self, name: String, value: Structured) -> bool {
self.root_mut().define_new(name, value)
}
fn root_resolve(&self, name: &str) -> Option<&Structured> {
self.root().resolve(name)
}
fn root_resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
self.root_mut().resolve_mut(name)
}
fn root_undef(&mut self, name: &str) -> Option<Structured> {
self.root_mut().undef(name)
}
}
impl Env<Structured> for StructuredEnv {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.stack.last_mut().unwrap().define(name, value)
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
self.stack.last_mut().unwrap().define_new(name, value)
}
fn resolve(&self, name: &str) -> Option<&Structured> {
let mut res = None;
for item in self.stack.iter().rev() {
res = item.resolve(name);
if res.is_some() {
return res;
}
}
res
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
let mut res = None;
for item in self.stack.iter_mut().rev() {
res = item.resolve_mut(name);
if res.is_some() {
return res;
}
}
res
}
fn undef(&mut self, name: &str) -> Option<Structured> {
let mut res = None;
for item in self.stack.iter_mut().rev() {
res = item.undef(name);
if res.is_some() {
return res;
}
}
res
}
}
impl Env<Structured> for StructuredEnvItem {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
let old = self.map.remove(&name);
self.map.insert(name, value);
old
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
if let std::collections::btree_map::Entry::Vacant(e) = self.map.entry(name) {
e.insert(value);
true
} else {
false
}
}
fn resolve(&self, name: &str) -> Option<&Structured> {
self.map.get(name)
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
self.map.get_mut(name)
}
fn undef(&mut self, name: &str) -> Option<Structured> {
self.map.remove(name)
}
}
impl Default for StructuredEnv {
fn default() -> Self {
StructuredEnv::new()
}
}

@ -39,6 +39,9 @@ pub enum CozoError {
#[error(transparent)]
Parse(#[from] pest::error::Error<Rule>),
#[error(transparent)]
Storage(#[from] rocksdb::Error)
}
pub type Result<T> = result::Result<T, CozoError>;

@ -5,23 +5,20 @@ use crate::error::CozoError;
use crate::error::CozoError::*;
use crate::value::Value::*;
use crate::ast::*;
use crate::typing::StructuredEnv;
use crate::env::StructuredEnv;
use crate::storage::Storage;
pub struct Evaluator {
pub s_envs: StructuredEnv,
pub storage: Storage,
}
impl Evaluator {
pub fn new() -> Self {
Self { s_envs: StructuredEnv::new() }
pub fn new(path: String) -> Result<Self> {
Ok(Self { s_envs: StructuredEnv::new(), storage: Storage::new(path)? })
}
}
impl Default for Evaluator {
fn default() -> Self {
Evaluator::new()
}
}
impl<'a> ExprVisitor<'a, Result<Expr<'a>>> for Evaluator {
fn visit_expr(&mut self, ex: &Expr<'a>) -> Result<Expr<'a>> {
@ -135,7 +132,6 @@ impl Evaluator {
}
}
fn div_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -183,7 +179,6 @@ impl Evaluator {
}
}
fn eq_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -201,7 +196,6 @@ impl Evaluator {
}
}
fn ne_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -219,7 +213,6 @@ impl Evaluator {
}
}
fn gt_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -245,7 +238,6 @@ impl Evaluator {
}
}
fn ge_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -271,7 +263,6 @@ impl Evaluator {
}
}
fn lt_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -322,7 +313,6 @@ impl Evaluator {
}
}
fn pow_exprs<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
match exprs {
[a, b] => {
@ -391,7 +381,6 @@ impl Evaluator {
})
}
fn minus_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
Ok(match exprs {
[a] => {
@ -408,7 +397,6 @@ impl Evaluator {
})
}
fn test_null_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
Ok(match exprs {
[a] => {
@ -467,7 +455,6 @@ impl Evaluator {
}
}
fn and_expr<'a>(&mut self, exprs: &[Expr<'a>]) -> Result<Expr<'a>> {
let mut unevaluated = vec![];
let mut no_null = true;
@ -507,7 +494,7 @@ mod tests {
#[test]
fn operators() {
let mut ev = Evaluator::new();
let mut ev = Evaluator::new("_path_for_rocksdb_storage".to_string()).unwrap();
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("1/10+(-2+3)*4^5").unwrap()).unwrap());
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("true && false").unwrap()).unwrap());
@ -515,5 +502,6 @@ mod tests {
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("true || null").unwrap()).unwrap());
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("null || true").unwrap()).unwrap());
println!("{:#?}", ev.visit_expr(&parse_expr_from_str("true && null").unwrap()).unwrap());
ev.storage.delete().unwrap();
}
}

@ -6,4 +6,5 @@ pub mod parser;
pub mod eval;
pub mod function;
pub mod error;
pub mod definition;
pub mod definition;
pub mod storage;

@ -10,24 +10,24 @@ pub struct Parser;
mod tests {
use super::*;
use pest::Parser as PestParser;
#[test]
fn db() {
use rocksdb::{DB, Options};
// NB: db is automatically closed at end of lifetime
let path = "_path_for_rocksdb_storage";
{
let db = DB::open_default(path).unwrap();
db.put("真二", "你好👋").unwrap();
match db.get_pinned("真二") {
Ok(Some(value)) => println!("retrieved value {}", std::str::from_utf8(&value).unwrap()),
Ok(None) => println!("value not found"),
Err(e) => println!("operational problem encountered: {}", e),
}
db.delete(b"my key").unwrap();
}
let _ = DB::destroy(&Options::default(), path);
}
//
// #[test]
// fn db() {
// use rocksdb::{DB, Options};
// // NB: db is automatically closed at end of lifetime
// let path = "_path_for_rocksdb_storage";
// {
// let db = DB::open_default(path).unwrap();
// db.put("真二", "你好👋").unwrap();
// match db.get_pinned("真二") {
// Ok(Some(value)) => println!("retrieved value {}", std::str::from_utf8(&value).unwrap()),
// Ok(None) => println!("value not found"),
// Err(e) => println!("operational problem encountered: {}", e),
// }
// db.delete(b"my key").unwrap();
// }
// let _ = DB::destroy(&Options::default(), path);
// }
#[test]
fn identifiers() {

@ -0,0 +1,42 @@
use rocksdb::{DB, Options, ColumnFamilyDescriptor};
use crate::error::Result;
use crate::value::cozo_comparator_v1;
pub struct Storage {
db: Option<DB>,
options: Options,
path: String,
}
impl Storage {
pub fn new(path: String) -> Result<Self> {
let mut options = Options::default();
options.create_missing_column_families(true);
options.create_if_missing(true);
options.set_comparator("cozo_comparator_v1", cozo_comparator_v1);
let main_cf = ColumnFamilyDescriptor::new("main", options.clone());
let temp_cf = ColumnFamilyDescriptor::new("temp", options.clone());
let db = DB::open_cf_descriptors(&options, &path, vec![main_cf, temp_cf])?;
Ok(Storage { db: Some(db), options, path })
}
pub fn delete(&mut self) -> Result<()> {
drop(self.db.take());
DB::destroy(&self.options, &self.path)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn storage() {
let mut s = Storage::new("_path_for_rocksdb_storage".to_string()).unwrap();
s.delete().unwrap();
}
}

@ -1,5 +1,6 @@
use std::collections::BTreeMap;
use crate::env::{Env, LayeredEnv};
use std::fmt::{Debug, Display, Formatter, Write};
use crate::env::{Env};
use crate::value::Value;
#[derive(Debug, Eq, PartialEq, Clone)]
@ -37,175 +38,12 @@ pub enum BaseType {
Crs,
}
pub struct StructuredEnvItem {
map: BTreeMap<String, Structured>,
}
pub struct StructuredEnv {
stack: Vec<StructuredEnvItem>,
}
impl StructuredEnv {
pub fn new() -> Self {
let mut root = StructuredEnvItem { map: BTreeMap::new() };
define_base_types(&mut root);
Self { stack: vec![root] }
}
pub fn root(&self) -> &StructuredEnvItem {
&self.stack[0]
}
pub fn root_mut(&mut self) -> &mut StructuredEnvItem {
&mut self.stack[0]
}
pub fn cur(&self) -> &StructuredEnvItem {
self.stack.last().unwrap()
}
pub fn cur_mut(&mut self) -> &mut StructuredEnvItem {
self.stack.last_mut().unwrap()
}
pub fn push(&mut self) {
self.stack.push(StructuredEnvItem { map: BTreeMap::new() })
}
pub fn pop(&mut self) -> bool {
if self.stack.len() <= 1 {
false
} else {
self.stack.pop();
true
}
}
pub fn get_next_table_id(&self, local: bool) -> TableId {
let mut id = 0;
let persistence = if local { Persistence::Local } else { Persistence::Global };
for env in &self.stack {
for item in env.map.values() {
if let Some(TableId(p, eid)) = item.storage_id() {
if p == persistence {
id = id.max(eid);
}
}
}
}
TableId(persistence, id + 1)
}
}
impl LayeredEnv<Structured> for StructuredEnv {
fn root_define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.root_mut().define(name, value)
}
fn root_define_new(&mut self, name: String, value: Structured) -> bool {
self.root_mut().define_new(name, value)
}
fn root_resolve(&self, name: &str) -> Option<&Structured> {
self.root().resolve(name)
}
fn root_resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
self.root_mut().resolve_mut(name)
}
fn root_undef(&mut self, name: &str) -> Option<Structured> {
self.root_mut().undef(name)
}
}
impl Env<Structured> for StructuredEnv {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
self.stack.last_mut().unwrap().define(name, value)
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
self.stack.last_mut().unwrap().define_new(name, value)
}
fn resolve(&self, name: &str) -> Option<&Structured> {
let mut res = None;
for item in self.stack.iter().rev() {
res = item.resolve(name);
if res.is_some() {
return res;
}
}
res
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
let mut res = None;
for item in self.stack.iter_mut().rev() {
res = item.resolve_mut(name);
if res.is_some() {
return res;
}
}
res
}
fn undef(&mut self, name: &str) -> Option<Structured> {
let mut res = None;
for item in self.stack.iter_mut().rev() {
res = item.undef(name);
if res.is_some() {
return res;
}
}
res
}
}
impl Env<Structured> for StructuredEnvItem {
fn define(&mut self, name: String, value: Structured) -> Option<Structured> {
let old = self.map.remove(&name);
self.map.insert(name, value);
old
}
fn define_new(&mut self, name: String, value: Structured) -> bool {
if let std::collections::btree_map::Entry::Vacant(e) = self.map.entry(name) {
e.insert(value);
true
} else {
false
}
}
fn resolve(&self, name: &str) -> Option<&Structured> {
self.map.get(name)
}
fn resolve_mut(&mut self, name: &str) -> Option<&mut Structured> {
self.map.get_mut(name)
}
fn undef(&mut self, name: &str) -> Option<Structured> {
self.map.remove(name)
}
}
impl Default for StructuredEnv {
fn default() -> Self {
StructuredEnv::new()
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Col {
pub name: String,
pub typ: Typing,
pub default: Option<Value<'static>>,
pub default: Value<'static>,
}
#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Clone, Copy)]
@ -229,6 +67,7 @@ pub struct ColumnId(TableId, usize);
#[derive(Debug, PartialEq, Clone)]
pub struct Node {
pub status: StorageStatus,
pub id: TableId,
pub keys: Vec<Col>,
pub cols: Vec<Col>,
@ -239,6 +78,7 @@ pub struct Node {
#[derive(Debug, PartialEq, Clone)]
pub struct Edge {
pub status: StorageStatus,
pub src: TableId,
pub dst: TableId,
pub id: TableId,
@ -248,6 +88,7 @@ pub struct Edge {
#[derive(Debug, PartialEq, Clone)]
pub struct Columns {
pub status: StorageStatus,
pub attached: TableId,
pub id: TableId,
pub cols: Vec<Col>,
@ -255,13 +96,14 @@ pub struct Columns {
#[derive(Debug, PartialEq, Clone)]
pub struct Index {
pub status: StorageStatus,
pub id: TableId,
pub attached: TableId,
pub cols: Vec<String>,
}
#[derive(Debug, Eq, PartialEq, Clone)]
#[derive(Eq, PartialEq, Clone)]
pub enum Typing {
Any,
Base(BaseType),
@ -271,23 +113,84 @@ pub enum Typing {
NamedTuple(BTreeMap<String, Typing>),
}
impl Display for Typing {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Typing::Any => f.write_str("Any")?,
Typing::Base(b) => {
match b {
BaseType::Bool => f.write_str("Bool")?,
BaseType::Int => f.write_str("Int")?,
BaseType::UInt => f.write_str("UInt")?,
BaseType::Float => f.write_str("Float")?,
BaseType::String => f.write_str("String")?,
BaseType::BitArr => f.write_str("BitArr")?,
BaseType::U8Arr => f.write_str("U8Arr")?,
BaseType::I8Arr => f.write_str("I8Arr")?,
BaseType::I16Arr => f.write_str("I16Arr")?,
BaseType::U16Arr => f.write_str("U16Arr")?,
BaseType::I32Arr => f.write_str("I32Arr")?,
BaseType::U32Arr => f.write_str("U32Arr")?,
BaseType::I64Arr => f.write_str("I64Arr")?,
BaseType::U64Arr => f.write_str("U64Arr")?,
BaseType::F16Arr => f.write_str("F16Arr")?,
BaseType::F32Arr => f.write_str("F32Arr")?,
BaseType::F64Arr => f.write_str("F64Arr")?,
BaseType::C32Arr => f.write_str("C32Arr")?,
BaseType::C64Arr => f.write_str("C64Arr")?,
BaseType::C128Arr => f.write_str("C128Arr")?,
BaseType::Uuid => f.write_str("Uuid")?,
BaseType::Timestamp => f.write_str("Timestamp")?,
BaseType::Datetime => f.write_str("Datetime")?,
BaseType::Timezone => f.write_str("Timezone")?,
BaseType::Date => f.write_str("Date")?,
BaseType::Time => f.write_str("Time")?,
BaseType::Duration => f.write_str("Duration")?,
BaseType::BigInt => f.write_str("BigInt")?,
BaseType::BigDecimal => f.write_str("BigDecimal")?,
BaseType::Inet => f.write_str("Inet")?,
BaseType::Crs => f.write_str("Crs")?
}
}
Typing::HList(l) => {
f.write_char('[')?;
Display::fmt(l, f)?;
f.write_char(']')?;
}
Typing::Nullable(d) => {
f.write_char('?')?;
Display::fmt(d, f)?;
}
Typing::Tuple(_) => todo!(),
Typing::NamedTuple(_) => todo!()
}
Ok(())
}
}
impl Debug for Typing {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(self, f)
}
}
#[derive(Debug, PartialEq, Clone)]
pub enum Structured {
Typing(Typing),
Node(Node, StorageStatus),
Edge(Edge, StorageStatus),
Columns(Columns, StorageStatus),
Index(Index, StorageStatus),
Node(Node),
Edge(Edge),
Columns(Columns),
Index(Index),
}
impl Structured {
fn storage_id(&self) -> Option<TableId> {
pub fn storage_id(&self) -> Option<TableId> {
match self {
Structured::Typing(_) => None,
Structured::Node(n, _) => Some(n.id),
Structured::Edge(e, _) => Some(e.id),
Structured::Columns(c, _) => Some(c.id),
Structured::Index(i, _) => Some(i.id)
Structured::Node(n) => Some(n.id),
Structured::Edge(e) => Some(e.id),
Structured::Columns(c) => Some(c.id),
Structured::Index(i) => Some(i.id)
}
}
}

@ -327,7 +327,17 @@ pub struct ByteArrayBuilder<T: Write> {
byte_writer: T,
}
impl ByteArrayBuilder<Vec<u8>> {
pub fn with_capacity(size: usize) -> Self {
Self::new(Vec::with_capacity(size))
}
}
impl<T: Write> ByteArrayBuilder<T> {
pub fn get(self) -> T {
self.byte_writer
}
pub fn new(byte_writer: T) -> Self {
Self { byte_writer }
}
@ -448,6 +458,11 @@ pub fn cmp_keys<'a>(pa: &mut ByteArrayParser<'a>, pb: &mut ByteArrayParser<'a>)
cmp_data(pa, pb)
}
pub fn cozo_comparator_v1(a: &[u8], b: &[u8]) -> Ordering {
cmp_keys(&mut ByteArrayParser { bytes: a, current: 0 },
&mut ByteArrayParser { bytes: b, current: 0 })
}
pub fn cmp_data<'a>(pa: &mut ByteArrayParser<'a>, pb: &mut ByteArrayParser<'a>) -> Ordering {
loop {
match (pa.at_end(), pb.at_end()) {

Loading…
Cancel
Save