diff --git a/cozopy/air_routes.py b/cozopy/air_routes.py index c552bebb..0c8deb48 100644 --- a/cozopy/air_routes.py +++ b/cozopy/air_routes.py @@ -108,8 +108,8 @@ if __name__ == '__main__': db = insert_data(False) start_time = time.time() res = db.run([Q(['?c', '?code', '?desc'], - T.country.code('?c', 'VN'), - Unify('?c', 10000239), + Disj(T.country.code('?c', 'CU'), + Unify('?c', 10000239)), T.country.code('?c', '?code'), T.country.desc('?c', '?desc'))]) end_time = time.time() diff --git a/src/query/compile.rs b/src/query/compile.rs index 51c74620..de109bcf 100644 --- a/src/query/compile.rs +++ b/src/query/compile.rs @@ -15,7 +15,7 @@ impl SessionTx { rule: &MagicRule, rule_name: &MagicKeyword, rule_idx: usize, - stores: &BTreeMap, + stores: &BTreeMap, ret_vars: &[Keyword], ) -> Result { let mut ret = Relation::unit(); @@ -58,15 +58,15 @@ impl SessionTx { } } MagicAtom::Rule(rule_app) => { - let (store, arity) = stores + let store = stores .get(&rule_app.name) .ok_or_else(|| anyhow!("undefined rule {:?} encountered", rule_app.name))? .clone(); ensure!( - arity == rule_app.args.len(), + store.key_size == rule_app.args.len(), "arity mismatch in rule application {:?}, expect {}, found {}", rule_app.name, - arity, + store.key_size, rule_app.args.len() ); let mut prev_joiner_vars = vec![]; @@ -129,15 +129,15 @@ impl SessionTx { } } MagicAtom::NegatedRule(rule_app) => { - let (store, arity) = stores + let store = stores .get(&rule_app.name) .ok_or_else(|| anyhow!("undefined rule encountered: {:?}", rule_app.name))? .clone(); ensure!( - arity == rule_app.args.len(), + store.key_size == rule_app.args.len(), "arity mismatch for {:?}, expect {}, got {}", rule_app.name, - arity, + store.key_size, rule_app.args.len() ); diff --git a/src/query/eval.rs b/src/query/eval.rs index 415cae39..338064cc 100644 --- a/src/query/eval.rs +++ b/src/query/eval.rs @@ -20,14 +20,18 @@ impl SessionTx { .0 .iter() .flat_map(|p| p.prog.iter()) - .map(|(k, s)| (k.clone(), (self.new_throwaway(), s[0].head.len()))) + .map(|(k, s)| { + ( + k.clone(), + (self.new_throwaway(s[0].head.len(), 0, k.clone())), + ) + }) .collect::>(); let ret_area = stores .get(&MagicKeyword::Muggle { inner: PROG_ENTRY.clone(), }) .ok_or_else(|| anyhow!("program entry not found in rules"))? - .0 .clone(); debug!("evaluate program with {} strata", prog.0.len()); @@ -40,7 +44,7 @@ impl SessionTx { fn semi_naive_magic_evaluate( &mut self, prog: &MagicProgram, - stores: &BTreeMap, + stores: &BTreeMap, ) -> Result<()> { let compiled: BTreeMap<_, _> = prog .prog @@ -78,7 +82,7 @@ impl SessionTx { debug!("epoch {}", epoch); if epoch == 0 { for (k, rules) in compiled.iter() { - let (store, _arity) = stores.get(k).unwrap(); + let store = stores.get(k).unwrap(); let use_delta = BTreeSet::default(); for (rule_n, (_head, _deriving_rules, relation)) in rules.iter().enumerate() { debug!("initial calculation for rule {:?}.{}", k, rule_n); @@ -97,7 +101,7 @@ impl SessionTx { } for (k, rules) in compiled.iter() { - let (store, _arity) = stores.get(k).unwrap(); + let store = stores.get(k).unwrap(); for (rule_n, (_head, deriving_rules, relation)) in rules.iter().enumerate() { let mut should_do_calculation = false; for d_rule in deriving_rules { @@ -112,7 +116,7 @@ impl SessionTx { // debug!("skip {}.{}", k, rule_n); continue; } - for (delta_key, (delta_store, _)) in stores.iter() { + for (delta_key, delta_store) in stores.iter() { if !deriving_rules.contains(delta_key) { continue; } diff --git a/src/query/relation.rs b/src/query/relation.rs index 7acde3ef..6ac8be99 100644 --- a/src/query/relation.rs +++ b/src/query/relation.rs @@ -196,7 +196,7 @@ impl Debug for Relation { Relation::Derived(r) => f .debug_tuple("Derived") .field(&bindings) - .field(&r.storage.id) + .field(&r.storage.rule_name) .finish(), Relation::Join(r) => { if r.left.is_unit() { @@ -231,9 +231,9 @@ impl Debug for Relation { Relation::Unification(r) => f .debug_tuple("Unify") .field(&bindings) + .field(&r.parent) .field(&r.binding) .field(&r.expr) - .field(&r.parent) .finish(), } } @@ -989,7 +989,7 @@ impl TripleRelation { eliminate_indices: BTreeSet, ) -> TupleIter<'a> { // [f, b] where b is not indexed - let throwaway = tx.new_throwaway(); + let throwaway = tx.temp_area(); for item in tx.triple_a_before_scan(self.attr.id, self.vld) { match item { Err(e) => return Box::new([Err(e)].into_iter()), @@ -1528,7 +1528,7 @@ impl InnerJoin { .sorted_by_key(|(_, b)| **b) .map(|(a, _)| a) .collect_vec(); - let throwaway = tx.new_throwaway(); + let throwaway = tx.temp_area(); for item in self.right.iter(tx, epoch, use_delta) { match item { Ok(tuple) => { diff --git a/src/runtime/temp_store.rs b/src/runtime/temp_store.rs index f971c9a4..b2fb3db3 100644 --- a/src/runtime/temp_store.rs +++ b/src/runtime/temp_store.rs @@ -1,9 +1,10 @@ use std::fmt::{Debug, Formatter}; -use log::{error}; +use log::error; use cozorocks::{DbIter, RawRocksDb, RocksDbStatus}; +use crate::data::program::MagicKeyword; use crate::data::tuple::{EncodedTuple, Tuple}; use crate::data::value::DataValue; @@ -20,6 +21,9 @@ impl Debug for TempStoreId { pub(crate) struct TempStore { pub(crate) db: RawRocksDb, pub(crate) id: TempStoreId, + pub(crate) key_size: usize, + pub(crate) val_size: usize, + pub(crate) rule_name: MagicKeyword, } impl Debug for TempStore { @@ -37,13 +41,13 @@ impl TempStore { let key_encoded = tuple.encode_as_key_for_epoch(self.id, epoch); self.db.exists(&key_encoded) } - pub(crate) fn scan_all(&self) -> impl Iterator> { + pub(crate) fn scan_all(&self) -> impl Iterator> { self.scan_all_for_epoch(0) } pub(crate) fn scan_all_for_epoch( &self, epoch: u32, - ) -> impl Iterator> { + ) -> impl Iterator> { let (lower, upper) = EncodedTuple::bounds_for_prefix_and_epoch(self.id, epoch); let mut it = self .db @@ -57,14 +61,14 @@ impl TempStore { pub(crate) fn scan_prefix( &self, prefix: &Tuple, - ) -> impl Iterator> { + ) -> impl Iterator> { self.scan_prefix_for_epoch(prefix, 0) } pub(crate) fn scan_prefix_for_epoch( &self, prefix: &Tuple, epoch: u32, - ) -> impl Iterator> { + ) -> impl Iterator> { let mut upper = prefix.0.clone(); upper.push(DataValue::Bottom); let upper = Tuple(upper); diff --git a/src/runtime/transact.rs b/src/runtime/transact.rs index 5f5f0a13..ab0822f5 100644 --- a/src/runtime/transact.rs +++ b/src/runtime/transact.rs @@ -16,6 +16,7 @@ use crate::data::encode::{ }; use crate::data::id::{AttrId, EntityId, TxId, Validity}; use crate::data::keyword::Keyword; +use crate::data::program::MagicKeyword; use crate::data::value::DataValue; use crate::runtime::temp_store::{TempStore, TempStoreId}; @@ -66,12 +67,34 @@ impl TxLog { } impl SessionTx { - pub(crate) fn new_throwaway(&self) -> TempStore { + pub(crate) fn new_throwaway( + &self, + key_size: usize, + val_size: usize, + rule_name: MagicKeyword, + ) -> TempStore { let old_count = self.temp_store_id.fetch_add(1, Ordering::AcqRel); let old_count = old_count & 0x00ff_ffffu32; TempStore { db: self.temp_store.clone(), id: TempStoreId(old_count), + key_size, + val_size, + rule_name, + } + } + + pub(crate) fn temp_area(&self) -> TempStore { + let old_count = self.temp_store_id.fetch_add(1, Ordering::AcqRel); + let old_count = old_count & 0x00ff_ffffu32; + TempStore { + db: self.temp_store.clone(), + id: TempStoreId(old_count), + key_size: 0, + val_size: 0, + rule_name: MagicKeyword::Muggle { + inner: Keyword::from(""), + }, } }