From 672fe188fcb2dce2ecca9916f2fb2c78243c7999 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Tue, 12 Apr 2022 16:05:41 +0800 Subject: [PATCH] tables use string ID --- src/definition.rs | 118 +++++++++++++++++++++++----------------------- src/env.rs | 16 +------ src/storage.rs | 2 +- src/typing.rs | 31 +++++------- src/value.rs | 17 +------ 5 files changed, 74 insertions(+), 110 deletions(-) diff --git a/src/definition.rs b/src/definition.rs index 6e8d53bd..3f6ce924 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -43,12 +43,12 @@ fn parse_col_name(pair: Pair) -> Result<(String, bool)> { impl StructuredEnvItem { - pub fn build_edge_def(&mut self, pair: Pair, table_id: TableId) -> Result { + pub fn build_edge_def(&mut self, pair: Pair, global: bool) -> Result { 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 { - n.id + n.id.clone() } else { return Err(WrongType); }; @@ -56,11 +56,11 @@ impl StructuredEnvItem { 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 { - n.id + n.id.clone() } else { return Err(WrongType); }; - if table_id.is_global() && (src_id.is_local() || dst_id.is_local()) { + if global && (!src_id.global || !dst_id.global) { return Err(IncompatibleEdge); } let (keys, cols) = if let Some(p) = inner.next() { @@ -68,24 +68,24 @@ impl StructuredEnvItem { } else { (vec![], vec![]) }; + let table_id = TableId { name: name.clone(), global }; let edge = Edge { status: Planned, src: src_id, dst: dst_id, - id: table_id, - name: name.clone(), + id: table_id.clone(), keys, cols, }; - if self.define_new(name.to_string(), Structured::Edge(edge)) { + if self.define_new(name.clone(), Structured::Edge(edge)) { if let Some(Structured::Node(src)) = self.resolve_mut(&src_name) { - src.out_e.push(table_id); + src.out_e.push(table_id.clone()); } else { unreachable!() } if let Some(Structured::Node(dst)) = self.resolve_mut(&dst_name) { - dst.in_e.push(table_id); + dst.in_e.push(table_id.clone()); } else { unreachable!() } @@ -94,21 +94,21 @@ impl StructuredEnvItem { Err(NameConflict) } } - pub fn build_node_def(&mut self, pair: Pair, table_id: TableId) -> Result { + pub fn build_node_def(&mut self, pair: Pair, global: bool) -> Result { 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 table_id = TableId { name: name.clone(), global }; let node = Node { status: Planned, id: table_id, - name: name.to_string(), keys, cols, out_e: vec![], in_e: vec![], attached: vec![], }; - if self.define_new(name.to_string(), Structured::Node(node)) { + if self.define_new(name.clone(), Structured::Node(node)) { Ok(name.to_string()) } else { Err(NameConflict) @@ -122,15 +122,15 @@ impl StructuredEnvItem { } Ok(ret) } - fn build_columns_def(&mut self, pair: Pair, table_id: TableId) -> Result { + fn build_columns_def(&mut self, pair: Pair, global: bool) -> Result { 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 { - n.id + n.id.clone() } else if let Structured::Edge(n) = node { - n.id + n.id.clone() } else { return Err(WrongType); }; @@ -138,14 +138,14 @@ impl StructuredEnvItem { if !keys.is_empty() { return Err(UnexpectedIndexColumns); } - if table_id.is_global() && node_id.is_local() { + let table_id = TableId { name: name.clone(), global }; + if table_id.global && !node_id.global { return Err(IncompatibleEdge); } if self.define_new(name.clone(), Structured::Columns(Columns { status: Planned, id: table_id, - name: name.to_string(), attached: node_id, cols, })) { @@ -155,7 +155,7 @@ impl StructuredEnvItem { } } - fn build_index_def(&mut self, pair: Pair, table_id: TableId) -> Result { + fn build_index_def(&mut self, pair: Pair, global: bool) -> Result { let mut inner = pair.into_inner(); let mut name = build_name_in_def(inner.next().unwrap(), true)?; let node_name; @@ -181,11 +181,13 @@ impl StructuredEnvItem { let node = self.resolve(&node_name).ok_or(UndefinedType)?; let node_id = if let Structured::Node(n) = node { - n.id + n.id.clone() } else { return Err(WrongType); }; - if table_id.is_global() && node_id.is_local() { + let table_id = TableId { name: name.clone(), global }; + + if table_id.global && !node_id.global { return Err(IncompatibleEdge); } @@ -194,7 +196,6 @@ impl StructuredEnvItem { if self.define_new(name.clone(), Structured::Index(Index { status: Planned, id: table_id, - name: name.clone(), attached: node_id, cols: col_list, })) { @@ -298,11 +299,11 @@ impl Storage { for (k, v) in it { let mut key_parser = ByteArrayParser::new(&k); key_parser.parse_zigzag(); - let table_id = key_parser.parse_value().unwrap().get_table_id().unwrap(); + let table_name = key_parser.parse_value().unwrap().get_string().unwrap(); let mut data_parser = ByteArrayParser::new(&v); let table_kind = data_parser.parse_value().unwrap(); - let table_name = data_parser.parse_value().unwrap().get_string().unwrap(); + let table_id = TableId { name: table_name, global: true }; match table_kind { Value::UInt(i) if i == TableKind::Node as u64 => { let keys: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap() @@ -334,7 +335,6 @@ impl Storage { let node = Node { status: StorageStatus::Stored, id: table_id, - name: table_name, keys, cols, out_e: vec![], // TODO fix these @@ -344,8 +344,10 @@ impl Storage { ret.push(Structured::Node(node)); } Value::UInt(i) if i == TableKind::Edge as u64 => { - let src_id = data_parser.parse_value().unwrap().get_table_id().unwrap(); - let dst_id = data_parser.parse_value().unwrap().get_table_id().unwrap(); + let src_name = data_parser.parse_value().unwrap().get_string().unwrap(); + let dst_name = data_parser.parse_value().unwrap().get_string().unwrap(); + let src_id = TableId { name: src_name, global: true }; + let dst_id = TableId { name: dst_name, global: true }; let keys: Vec<_> = data_parser.parse_value().unwrap().get_list().unwrap() .into_iter().map(|v| { let mut vs = v.get_list().unwrap().into_iter(); @@ -377,7 +379,6 @@ impl Storage { src: src_id, dst: dst_id, id: table_id, - name: table_name, keys, cols, }; @@ -398,10 +399,9 @@ impl Storage { fn persist_node(&mut self, node: &mut Node) -> Result<()> { let mut key_writer = ByteArrayBuilder::with_capacity(8); key_writer.build_zigzag(0); - key_writer.build_value(&Value::Int(node.id.0)); + key_writer.build_value(&Value::RefString(&node.id.name)); let mut val_writer = ByteArrayBuilder::with_capacity(128); val_writer.build_value(&Value::UInt(TableKind::Node as u64)); - val_writer.build_value(&Value::RefString(&node.name)); val_writer.build_value(&Value::List(Box::new(node.keys.iter().map(|k| { Value::List(Box::new(vec![ Value::RefString(&k.name), @@ -417,7 +417,7 @@ impl Storage { ])) }).collect()))); - self.put(&key_writer.get(), &val_writer.get(), TableId(0))?; + self.put(&key_writer.get(), &val_writer.get(), TableId { name: "_sys".to_string(), global: true })?; node.status = Stored; Ok(()) } @@ -425,12 +425,12 @@ impl Storage { fn persist_edge(&mut self, edge: &mut Edge) -> Result<()> { let mut key_writer = ByteArrayBuilder::with_capacity(8); key_writer.build_zigzag(0); - key_writer.build_value(&Value::Int(edge.id.0)); + key_writer.build_value(&Value::RefString(&edge.id.name)); + let mut val_writer = ByteArrayBuilder::with_capacity(128); val_writer.build_value(&Value::UInt(TableKind::Edge as u64)); - val_writer.build_value(&Value::RefString(&edge.name)); - val_writer.build_value(&Value::Int(edge.src.0)); - val_writer.build_value(&Value::Int(edge.dst.0)); + val_writer.build_value(&Value::RefString(&edge.src.name)); + val_writer.build_value(&Value::RefString(&edge.dst.name)); val_writer.build_value(&Value::List(Box::new(edge.keys.iter().map(|k| { Value::List(Box::new(vec![ Value::RefString(&k.name), @@ -446,7 +446,7 @@ impl Storage { ])) }).collect()))); - self.put(&key_writer.get(), &val_writer.get(), TableId(0))?; + self.put(&key_writer.get(), &val_writer.get(), TableId { name: "_sys".to_string(), global: true })?; edge.status = Stored; Ok(()) } @@ -459,10 +459,10 @@ impl Evaluator { match md { v @ Structured::Node(n) => { // TODO: check if they are the same if one already exists - self.s_envs.root_define(n.name.clone(), v.clone()); + self.s_envs.root_define(n.id.name.clone(), v.clone()); } v @ Structured::Edge(e) => { - self.s_envs.root_define(e.name.clone(), v.clone()); + self.s_envs.root_define(e.id.name.clone(), v.clone()); } Structured::Columns(_) => {} Structured::Index(_) => {} @@ -490,29 +490,29 @@ impl Evaluator { 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.s_envs.get_next_table_id(is_local); - let env_to_build = if is_local { + let global = r == Rule::global_def; + let env_to_build = if global { self.s_envs.root_mut() } else { self.s_envs.cur_mut() }; - - new_tables.push(match inner.as_rule() { - Rule::node_def => { - env_to_build.build_node_def(inner, next_id)? - } - Rule::edge_def => { - env_to_build.build_edge_def(inner, next_id)? - } - Rule::columns_def => { - env_to_build.build_columns_def(inner, next_id)? - } - Rule::index_def => { - env_to_build.build_index_def(inner, next_id)? - } - _ => todo!() - }); + if global { + new_tables.push(match inner.as_rule() { + Rule::node_def => { + env_to_build.build_node_def(inner, global)? + } + Rule::edge_def => { + env_to_build.build_edge_def(inner, global)? + } + Rule::columns_def => { + env_to_build.build_columns_def(inner, global)? + } + Rule::index_def => { + env_to_build.build_index_def(inner, global)? + } + _ => todo!() + }); + } } Rule::EOI => {} _ => unreachable!() @@ -535,14 +535,14 @@ mod tests { #[test] fn definitions() { let s = r#" - local node "Person" { + create node "Person" { *id: Int, name: String, email: ?String, habits: ?[?String] } - local edge (Person)-[Friend]->(Person) { + create edge (Person)-[Friend]->(Person) { relation: ?String } "#; @@ -550,7 +550,7 @@ mod tests { let mut eval = Evaluator::new("_path_for_rocksdb_storagex".to_string()).unwrap(); eval.build_table(parsed).unwrap(); eval.restore_metadata().unwrap(); - // eval.storage.delete().unwrap(); + eval.storage.delete().unwrap(); println!("{:#?}", eval.s_envs.resolve("Person")); println!("{:#?}", eval.s_envs.resolve("Friend")); } diff --git a/src/env.rs b/src/env.rs index 26aed0a3..955c3f77 100644 --- a/src/env.rs +++ b/src/env.rs @@ -1,5 +1,5 @@ use std::collections::BTreeMap; -use crate::typing::{define_base_types, Structured, TableId}; +use crate::typing::{define_base_types, Structured}; pub trait Env { fn define(&mut self, name: String, value: V) -> Option; @@ -62,20 +62,6 @@ impl StructuredEnv { true } } - - pub fn get_next_table_id(&self, local: bool) -> TableId { - let mut id = 0; - for env in &self.stack { - for item in env.map.values() { - if let Some(c_id) = item.storage_id() { - if c_id.is_local() == local { - id = id.max(c_id.0.abs()); - } - } - } - } - TableId((1 + id) * if local { -1 } else { 1 }) - } } impl LayeredEnv for StructuredEnv { diff --git a/src/storage.rs b/src/storage.rs index ceb54299..3d517bc6 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -31,7 +31,7 @@ impl Storage { } pub fn put(&self, k: &[u8], v: &[u8], table_id: TableId) -> Result<()> { let db = self.db.as_ref().ok_or(DatabaseClosed)?; - if table_id.is_global() { + if table_id.global { db.put(k, v)?; } else { let cf = db.cf_handle("temp").ok_or(DatabaseClosed)?; diff --git a/src/typing.rs b/src/typing.rs index 8305f0db..41ae51e8 100644 --- a/src/typing.rs +++ b/src/typing.rs @@ -54,22 +54,17 @@ pub enum StorageStatus { Stored, } -#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Copy)] -pub struct TableId(pub i64); - -impl TableId { - pub fn is_global(&self) -> bool { - self.0 >= 0 - } - pub fn is_local(&self) -> bool { - self.0 < 0 - } +#[derive(PartialEq, Eq, Ord, PartialOrd, Clone)] +pub struct TableId{ + pub name: String, + pub global: bool } + impl Debug for TableId { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str( if self.is_global() { "G+" } else {"L"})?; - f.write_str(&format!("{}", self.0))?; + f.write_str( if self.global { "+" } else {"-"})?; + f.write_str(&format!("{}", self.name))?; Ok(()) } } @@ -89,7 +84,6 @@ impl Debug for ColumnId { pub struct Node { pub status: StorageStatus, pub id: TableId, - pub name: String, pub keys: Vec, pub cols: Vec, pub out_e: Vec, @@ -103,7 +97,6 @@ pub struct Edge { pub src: TableId, pub dst: TableId, pub id: TableId, - pub name: String, pub keys: Vec, pub cols: Vec, } @@ -113,7 +106,6 @@ pub struct Columns { pub status: StorageStatus, pub attached: TableId, pub id: TableId, - pub name: String, pub cols: Vec, } @@ -121,7 +113,6 @@ pub struct Columns { pub struct Index { pub status: StorageStatus, pub id: TableId, - pub name: String, pub attached: TableId, pub cols: Vec, } @@ -211,10 +202,10 @@ impl Structured { pub fn storage_id(&self) -> Option { 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.clone()), + Structured::Edge(e) => Some(e.id.clone()), + Structured::Columns(c) => Some(c.id.clone()), + Structured::Index(i) => Some(i.id.clone()) } } } diff --git a/src/value.rs b/src/value.rs index 1075d96a..aa6b14c8 100644 --- a/src/value.rs +++ b/src/value.rs @@ -4,7 +4,7 @@ use std::collections::{BTreeMap}; use std::io::{Write}; use ordered_float::OrderedFloat; use uuid::Uuid; -use crate::typing::{TableId, Typing}; +use crate::typing::{Typing}; use Ordering::{Greater, Less, Equal}; // TODO: array types, alignment of values @@ -85,14 +85,6 @@ impl <'a> Value<'a> { _ => None } } - - pub fn get_table_id(self) -> Option { - if let Value::Int(id) = self { - Some(TableId(id)) - } else { - None - } - } } impl<'a> PartialEq for Value<'a> { @@ -477,13 +469,8 @@ impl ByteArrayBuilder { } } -pub fn cmp_keys<'a>(pa: &mut ByteArrayParser<'a>, pb: &mut ByteArrayParser<'a>) -> Ordering { - if let x @ (Greater | Less) = pa.compare_zigzag(pb) { return x; } - cmp_data(pa, pb) -} - pub fn cozo_comparator_v1(a: &[u8], b: &[u8]) -> Ordering { - cmp_keys(&mut ByteArrayParser { bytes: a, current: 0 }, + cmp_data(&mut ByteArrayParser { bytes: a, current: 0 }, &mut ByteArrayParser { bytes: b, current: 0 }) }