main
Ziyang Hu 2 years ago
parent d6dd698ea4
commit e3bd5cd8c7

@ -6,16 +6,37 @@ use itertools::Itertools;
use log::{debug, log_enabled, trace, Level}; use log::{debug, log_enabled, trace, Level};
use crate::data::keyword::{Keyword, PROG_ENTRY}; use crate::data::keyword::{Keyword, PROG_ENTRY};
use crate::data::program::{MagicKeyword, MagicProgram, StratifiedMagicProgram}; use crate::data::program::{MagicKeyword, StratifiedMagicProgram};
use crate::query::relation::Relation; use crate::query::relation::Relation;
use crate::runtime::temp_store::TempStore; use crate::runtime::temp_store::TempStore;
use crate::runtime::transact::SessionTx; use crate::runtime::transact::SessionTx;
pub(crate) type CompiledProgram =
BTreeMap<MagicKeyword, Vec<(Vec<Keyword>, BTreeSet<MagicKeyword>, Relation)>>;
impl SessionTx { impl SessionTx {
pub(crate) fn stratified_magic_evaluate( pub(crate) fn stratified_magic_evaluate(
&mut self, &mut self,
prog: &StratifiedMagicProgram, strata: &[CompiledProgram],
stores: &BTreeMap<MagicKeyword, TempStore>,
) -> Result<TempStore> { ) -> Result<TempStore> {
let ret_area = stores
.get(&MagicKeyword::Muggle {
inner: PROG_ENTRY.clone(),
})
.ok_or_else(|| anyhow!("program entry not found in rules"))?
.clone();
for (idx, cur_prog) in strata.iter().rev().enumerate() {
debug!("stratum {}", idx);
self.semi_naive_magic_evaluate(cur_prog, &stores)?;
}
Ok(ret_area)
}
pub(crate) fn stratified_magic_compile(
&mut self,
prog: &StratifiedMagicProgram,
) -> Result<(Vec<CompiledProgram>, BTreeMap<MagicKeyword, TempStore>)> {
let stores = prog let stores = prog
.0 .0
.iter() .iter()
@ -27,61 +48,61 @@ impl SessionTx {
) )
}) })
.collect::<BTreeMap<_, _>>(); .collect::<BTreeMap<_, _>>();
let ret_area = stores
.get(&MagicKeyword::Muggle {
inner: PROG_ENTRY.clone(),
})
.ok_or_else(|| anyhow!("program entry not found in rules"))?
.clone();
debug!("evaluate program with {} strata", prog.0.len());
for (idx, cur_prog) in prog.0.iter().rev().enumerate() { let compiled: Vec<_> = prog
debug!("stratum {}", idx); .0
self.semi_naive_magic_evaluate(cur_prog, &stores)?; .iter()
} .rev()
Ok(ret_area) .map(|cur_prog| -> Result<CompiledProgram> {
cur_prog
.prog
.iter()
.map(
|(k, body)| -> Result<(
MagicKeyword,
Vec<(Vec<Keyword>, BTreeSet<MagicKeyword>, Relation)>,
)> {
let mut collected = Vec::with_capacity(body.len());
for (rule_idx, rule) in body.iter().enumerate() {
let header = &rule.head;
let mut relation = self.compile_magic_rule_body(
&rule, k, rule_idx, &stores, &header,
)?;
relation.fill_predicate_binding_indices();
collected.push((
rule.head.clone(),
rule.contained_rules(),
relation,
));
}
Ok((k.clone(), collected))
},
)
.try_collect()
})
.try_collect()?;
Ok((compiled, stores))
} }
fn semi_naive_magic_evaluate( fn semi_naive_magic_evaluate(
&mut self, &mut self,
prog: &MagicProgram, prog: &CompiledProgram,
stores: &BTreeMap<MagicKeyword, TempStore>, stores: &BTreeMap<MagicKeyword, TempStore>,
) -> Result<()> { ) -> Result<()> {
let compiled: BTreeMap<_, _> = prog
.prog
.iter()
.map(
|(k, body)| -> Result<(
MagicKeyword,
Vec<(Vec<Keyword>, BTreeSet<MagicKeyword>, Relation)>,
)> {
let mut collected = Vec::with_capacity(body.len());
for (rule_idx, rule) in body.iter().enumerate() {
let header = &rule.head;
let mut relation =
self.compile_magic_rule_body(&rule, k, rule_idx, &stores, &header)?;
relation.fill_predicate_binding_indices();
collected.push((rule.head.clone(), rule.contained_rules(), relation));
}
Ok((k.clone(), collected))
},
)
.try_collect()?;
if log_enabled!(Level::Debug) { if log_enabled!(Level::Debug) {
for (k, vs) in compiled.iter() { for (k, vs) in prog.iter() {
for (i, (binding, _, rel)) in vs.iter().enumerate() { for (i, (binding, _, rel)) in vs.iter().enumerate() {
debug!("{:?}.{} {:?}: {:#?}", k, i, binding, rel) debug!("{:?}.{} {:?}: {:#?}", k, i, binding, rel)
} }
} }
} }
let mut changed: BTreeMap<_, _> = compiled.keys().map(|k| (k, false)).collect(); let mut changed: BTreeMap<_, _> = prog.keys().map(|k| (k, false)).collect();
let mut prev_changed = changed.clone(); let mut prev_changed = changed.clone();
for epoch in 0u32.. { for epoch in 0u32.. {
debug!("epoch {}", epoch); debug!("epoch {}", epoch);
if epoch == 0 { if epoch == 0 {
for (k, rules) in compiled.iter() { for (k, rules) in prog.iter() {
let store = stores.get(k).unwrap(); let store = stores.get(k).unwrap();
let use_delta = BTreeSet::default(); let use_delta = BTreeSet::default();
for (rule_n, (_head, _deriving_rules, relation)) in rules.iter().enumerate() { for (rule_n, (_head, _deriving_rules, relation)) in rules.iter().enumerate() {
@ -100,7 +121,7 @@ impl SessionTx {
*v = false; *v = false;
} }
for (k, rules) in compiled.iter() { for (k, rules) in prog.iter() {
let store = stores.get(k).unwrap(); let store = stores.get(k).unwrap();
for (rule_n, (_head, deriving_rules, relation)) in rules.iter().enumerate() { for (rule_n, (_head, deriving_rules, relation)) in rules.iter().enumerate() {
let mut should_do_calculation = false; let mut should_do_calculation = false;

@ -285,10 +285,21 @@ impl Db {
.to_normalized_program()? .to_normalized_program()?
.stratify()? .stratify()?
.magic_sets_rewrite(); .magic_sets_rewrite();
let result = tx.stratified_magic_evaluate(&program)?; let (compiled, stores) = tx.stratified_magic_compile(&program)?;
let result = tx.stratified_magic_evaluate(&compiled, &stores)?;
let ret: Vec<_> = tx let ret: Vec<_> = tx
.run_pull_on_query_results(result, out_spec, vld)? .run_pull_on_query_results(result, out_spec, vld)?
.try_collect()?; .try_collect()?;
Ok(json!(ret)) Ok(json!(ret))
} }
pub fn explain_query(&self, payload: &JsonValue) -> Result<JsonValue> {
let mut tx = self.transact()?;
let (input_program, out_spec, vld) = tx.parse_query(payload)?;
let normalized_program = input_program.to_normalized_program()?;
let stratified_program = normalized_program.stratify()?;
let magic_program = stratified_program.magic_sets_rewrite();
let (compiled_strata, _) = tx.stratified_magic_compile(&magic_program)?;
todo!()
}
} }

Loading…
Cancel
Save