main
Ziyang Hu 2 years ago
parent cb8239897b
commit 419c4c3328

@ -5,3 +5,4 @@ pub mod mutation;
pub mod table;
pub mod plan;
pub mod ddl;
pub mod env;

@ -0,0 +1,217 @@
use std::collections::BTreeMap;
use cozorocks::SlicePtr;
use crate::db::engine::Session;
use crate::relation::value::Value;
use crate::error::{CozoError, Result};
use crate::relation::data::DataKind;
use crate::relation::tuple::{OwnTuple, Tuple};
/// # layouts for sector 0
///
/// `[Null]`: stores information about table_ids
/// `[Text, Int]`: contains definable data and depth info
/// `[Int, Text]`: inverted index for depth info
/// `[Null, Text, Int, Int, Text]` inverted index for related tables
/// `[Null, Int, Text, Int, Text]` inverted index for related tables
/// `[True, Int]` table info, value is key
// type TableEnv = BTreeMap<String, ()>;
#[derive(Debug, Default)]
pub struct TableEnv<'a> {
pub parent: Option<&'a TableEnv<'a>>,
pub current: BTreeMap<String, ()>,
}
impl<'a> TableEnv<'a> {
pub fn derive(&'a self) -> TableEnv<'a> {
TableEnv {
parent: Some(self),
current: Default::default(),
}
}
pub fn resolve(&self, key: &str) -> Option<&()> {
match self.current.get(key) {
None => match self.parent {
None => None,
Some(t) => t.resolve(key)
}
v => v
}
}
}
impl<'s> Session<'s> {
pub fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
let mut data = Tuple::with_data_prefix(DataKind::Value);
data.push_value(val);
self.define_data(name, data, in_root)
}
pub fn define_data(&mut self, name: &str, data: OwnTuple, in_root: bool) -> Result<()> {
let key = self.encode_definable_key(name, in_root);
if in_root {
self.txn.put(true, &self.perm_cf, key, data)?;
} else {
let mut ikey = Tuple::with_null_prefix();
ikey.push_int(self.stack_depth as i64);
ikey.push_str(name);
self.txn.put(false, &self.temp_cf, key, data)?;
self.txn.put(false, &self.temp_cf, ikey, "")?;
}
Ok(())
}
pub fn key_exists(&self, key: &OwnTuple, in_root: bool) -> Result<bool> {
let res = self.txn.get(in_root, if in_root { &self.perm_cf } else { &self.temp_cf }, key)?;
Ok(res.is_some())
}
pub fn del_key(&self, key: &OwnTuple, in_root: bool) -> Result<()> {
self.txn.del(in_root, if in_root { &self.perm_cf } else { &self.temp_cf }, key)?;
Ok(())
}
pub fn define_raw_key(&self, key: &OwnTuple, value: Option<&OwnTuple>, in_root: bool) -> Result<()> {
if in_root {
match value {
None => {
self.txn.put(true, &self.perm_cf, key, "")?;
}
Some(v) => {
self.txn.put(true, &self.perm_cf, key, &v)?;
}
}
} else {
match value {
None => {
self.txn.put(false, &self.temp_cf, key, "")?;
}
Some(v) => {
self.txn.put(false, &self.temp_cf, key, &v)?;
}
}
}
Ok(())
}
pub fn resolve_value(&self, name: &str) -> Result<Option<Value>> {
match self.resolve(name)? {
None => Ok(None),
Some(t) => {
match t.data_kind()? {
DataKind::Value => Ok(Some(t.get(0)
.ok_or_else(|| CozoError::LogicError("Corrupt".to_string()))?
.to_static())),
k => Err(CozoError::UnexpectedDataKind(k))
}
}
}
}
pub fn get_stack_depth(&self) -> i32 {
self.stack_depth
}
pub fn push_env(&mut self) -> Result<()> {
if self.stack_depth <= -1024 {
return Err(CozoError::LogicError("Stack overflow in env".to_string()));
}
self.stack_depth -= 1;
Ok(())
}
pub fn pop_env(&mut self) -> Result<()> {
// Remove all stuff starting with the stack depth from the temp session
let mut prefix = Tuple::with_null_prefix();
prefix.push_int(self.stack_depth as i64);
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&prefix);
let mut to_delete = vec![];
for val in it.keys() {
let cur = Tuple::new(val);
if cur.starts_with(&prefix) {
if let Some(name) = cur.get(1) {
let mut ikey = Tuple::with_null_prefix();
ikey.push_value(&name);
ikey.push_int(self.stack_depth as i64);
let data = self.txn.get(false, &self.temp_cf, &ikey)?
.ok_or_else(|| CozoError::LogicError("Bad format for ikey".to_string()))?;
let data = Tuple::new(data);
match data.data_kind()? {
DataKind::Node |
DataKind::Edge |
DataKind::Assoc |
DataKind::Index => {
let id = data.get_int(1).ok_or_else(|| CozoError::LogicError("Bad table index".to_string()))?;
let mut rkey = Tuple::with_null_prefix();
rkey.push_bool(true);
rkey.push_int(id);
self.txn.del(false, &self.temp_cf, rkey)?;
let range_start = Tuple::with_prefix(id as u32);
let mut range_end = Tuple::with_prefix(id as u32);
range_end.seal_with_sentinel();
self.txn.del_range(&self.temp_cf, range_start, range_end)?;
}
_ => {}
}
to_delete.push(cur.data.as_ref().to_vec());
to_delete.push(ikey.data.to_vec());
}
} else {
break;
}
}
let mut prefix = Tuple::with_null_prefix();
prefix.push_null();
prefix.push_int(self.stack_depth as i64);
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&prefix);
for val in it.keys() {
let cur = Tuple::new(val);
if cur.starts_with(&prefix) {
let mut ikey = Tuple::with_prefix(cur.get_prefix());
ikey.push_null();
ikey.push_str(cur.get_text(2).unwrap());
ikey.push_int(cur.get_int(1).unwrap());
for k in cur.iter().skip(3) {
ikey.push_value(&k);
}
to_delete.push(cur.data.as_ref().to_vec());
to_delete.push(ikey.data.to_vec());
} else {
break;
}
}
if self.stack_depth != 0 {
self.stack_depth += 1;
}
for d in to_delete {
self.txn.del(false, &self.temp_cf, &d)?;
}
Ok(())
}
pub fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> {
let mut tuple = Tuple::with_null_prefix();
tuple.push_str(name);
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&tuple);
if let Some((tk, vk)) = it.pair() {
let k = Tuple::new(tk);
if k.starts_with(&tuple) {
return Ok(Some(Tuple::new(vk)));
}
}
let root_key = self.encode_definable_key(name, true);
let res = self.txn.get(true, &self.perm_cf, root_key).map(|v| v.map(Tuple::new))?;
Ok(res)
}
}

@ -1,116 +1,13 @@
use std::borrow::Cow;
use std::collections::{BTreeMap};
use cozorocks::{SlicePtr};
use crate::db::engine::{Session};
use crate::relation::tuple::{OwnTuple, Tuple};
use crate::db::env::TableEnv;
use crate::relation::value::{Value};
use crate::error::{CozoError, Result};
use crate::error::CozoError::LogicError;
use crate::relation::data::DataKind;
use crate::relation::value;
/// # layouts for sector 0
///
/// `[Null]`: stores information about table_ids
/// `[Text, Int]`: contains definable data and depth info
/// `[Int, Text]`: inverted index for depth info
/// `[Null, Text, Int, Int, Text]` inverted index for related tables
/// `[Null, Int, Text, Int, Text]` inverted index for related tables
/// `[True, Int]` table info, value is key
// type TableEnv = BTreeMap<String, ()>;
#[derive(Debug, Default)]
pub struct TableEnv<'a> {
pub parent: Option<&'a TableEnv<'a>>,
pub current: BTreeMap<String, ()>,
}
impl<'a> TableEnv<'a> {
pub fn derive(&'a self) -> TableEnv<'a> {
TableEnv {
parent: Some(self),
current: Default::default(),
}
}
pub fn resolve(&self, key: &str) -> Option<&()> {
match self.current.get(key) {
None => match self.parent {
None => None,
Some(t) => t.resolve(key)
}
v => v
}
}
}
impl<'s> Session<'s> {
pub fn define_variable(&mut self, name: &str, val: &Value, in_root: bool) -> Result<()> {
let mut data = Tuple::with_data_prefix(DataKind::Value);
data.push_value(val);
self.define_data(name, data, in_root)
}
pub fn define_data(&mut self, name: &str, data: OwnTuple, in_root: bool) -> Result<()> {
let key = self.encode_definable_key(name, in_root);
if in_root {
self.txn.put(true, &self.perm_cf, key, data)?;
} else {
let mut ikey = Tuple::with_null_prefix();
ikey.push_int(self.stack_depth as i64);
ikey.push_str(name);
self.txn.put(false, &self.temp_cf, key, data)?;
self.txn.put(false, &self.temp_cf, ikey, "")?;
}
Ok(())
}
pub fn key_exists(&self, key: &OwnTuple, in_root: bool) -> Result<bool> {
let res = self.txn.get(in_root, if in_root { &self.perm_cf } else { &self.temp_cf }, key)?;
Ok(res.is_some())
}
pub fn del_key(&self, key: &OwnTuple, in_root: bool) -> Result<()> {
self.txn.del(in_root, if in_root { &self.perm_cf } else { &self.temp_cf }, key)?;
Ok(())
}
pub fn define_raw_key(&self, key: &OwnTuple, value: Option<&OwnTuple>, in_root: bool) -> Result<()> {
if in_root {
match value {
None => {
self.txn.put(true, &self.perm_cf, key, "")?;
}
Some(v) => {
self.txn.put(true, &self.perm_cf, key, &v)?;
}
}
} else {
match value {
None => {
self.txn.put(false, &self.temp_cf, key, "")?;
}
Some(v) => {
self.txn.put(false, &self.temp_cf, key, &v)?;
}
}
}
Ok(())
}
fn resolve_value(&self, name: &str) -> Result<Option<Value>> {
match self.resolve(name)? {
None => Ok(None),
Some(t) => {
match t.data_kind()? {
DataKind::Value => Ok(Some(t.get(0)
.ok_or_else(|| CozoError::LogicError("Corrupt".to_string()))?
.to_static())),
k => Err(CozoError::UnexpectedDataKind(k))
}
}
}
}
pub fn partial_eval<'a>(&self, value: Value<'a>, params: &BTreeMap<String, Value<'a>>,
table_bindings: &TableEnv) -> Result<(bool, Value<'a>)> {
match value {
@ -740,111 +637,6 @@ impl<'s> Session<'s> {
Err(Err(e)) => Err(e)
}
}
pub fn get_stack_depth(&self) -> i32 {
self.stack_depth
}
pub fn push_env(&mut self) -> Result<()> {
if self.stack_depth <= -1024 {
return Err(CozoError::LogicError("Stack overflow in env".to_string()));
}
self.stack_depth -= 1;
Ok(())
}
pub fn pop_env(&mut self) -> Result<()> {
// Remove all stuff starting with the stack depth from the temp session
let mut prefix = Tuple::with_null_prefix();
prefix.push_int(self.stack_depth as i64);
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&prefix);
let mut to_delete = vec![];
for val in it.keys() {
let cur = Tuple::new(val);
if cur.starts_with(&prefix) {
if let Some(name) = cur.get(1) {
let mut ikey = Tuple::with_null_prefix();
ikey.push_value(&name);
ikey.push_int(self.stack_depth as i64);
let data = self.txn.get(false, &self.temp_cf, &ikey)?
.ok_or_else(|| CozoError::LogicError("Bad format for ikey".to_string()))?;
let data = Tuple::new(data);
match data.data_kind()? {
DataKind::Node |
DataKind::Edge |
DataKind::Assoc |
DataKind::Index => {
let id = data.get_int(1).ok_or_else(|| CozoError::LogicError("Bad table index".to_string()))?;
let mut rkey = Tuple::with_null_prefix();
rkey.push_bool(true);
rkey.push_int(id);
self.txn.del(false, &self.temp_cf, rkey)?;
let range_start = Tuple::with_prefix(id as u32);
let mut range_end = Tuple::with_prefix(id as u32);
range_end.seal_with_sentinel();
self.txn.del_range(&self.temp_cf, range_start, range_end)?;
}
_ => {}
}
to_delete.push(cur.data.as_ref().to_vec());
to_delete.push(ikey.data.to_vec());
}
} else {
break;
}
}
let mut prefix = Tuple::with_null_prefix();
prefix.push_null();
prefix.push_int(self.stack_depth as i64);
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&prefix);
for val in it.keys() {
let cur = Tuple::new(val);
if cur.starts_with(&prefix) {
let mut ikey = Tuple::with_prefix(cur.get_prefix());
ikey.push_null();
ikey.push_str(cur.get_text(2).unwrap());
ikey.push_int(cur.get_int(1).unwrap());
for k in cur.iter().skip(3) {
ikey.push_value(&k);
}
to_delete.push(cur.data.as_ref().to_vec());
to_delete.push(ikey.data.to_vec());
} else {
break;
}
}
if self.stack_depth != 0 {
self.stack_depth += 1;
}
for d in to_delete {
self.txn.del(false, &self.temp_cf, &d)?;
}
Ok(())
}
pub fn resolve(&self, name: &str) -> Result<Option<Tuple<SlicePtr>>> {
let mut tuple = Tuple::with_null_prefix();
tuple.push_str(name);
let it = self.txn.iterator(false, &self.temp_cf);
it.seek(&tuple);
if let Some((tk, vk)) = it.pair() {
let k = Tuple::new(tk);
if k.starts_with(&tuple) {
return Ok(Some(Tuple::new(vk)));
}
}
let root_key = self.encode_definable_key(name, true);
let res = self.txn.get(true, &self.perm_cf, root_key).map(|v| v.map(Tuple::new))?;
Ok(res)
}
}
@ -855,6 +647,7 @@ mod tests {
use crate::parser::{Parser, Rule};
use pest::Parser as PestParser;
use crate::db::engine::Engine;
use crate::relation::tuple::Tuple;
#[test]
fn node() {

Loading…
Cancel
Save