main
Ziyang Hu 2 years ago
parent d6dd698ea4
commit e3bd5cd8c7

@ -6,47 +6,55 @@ 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 stores = prog
.0
.iter()
.flat_map(|p| p.prog.iter())
.map(|(k, s)| {
(
k.clone(),
(self.new_throwaway(s[0].head.len(), 0, k.clone())),
)
})
.collect::<BTreeMap<_, _>>();
let ret_area = stores let ret_area = stores
.get(&MagicKeyword::Muggle { .get(&MagicKeyword::Muggle {
inner: PROG_ENTRY.clone(), inner: PROG_ENTRY.clone(),
}) })
.ok_or_else(|| anyhow!("program entry not found in rules"))? .ok_or_else(|| anyhow!("program entry not found in rules"))?
.clone(); .clone();
debug!("evaluate program with {} strata", prog.0.len());
for (idx, cur_prog) in prog.0.iter().rev().enumerate() { for (idx, cur_prog) in strata.iter().rev().enumerate() {
debug!("stratum {}", idx); debug!("stratum {}", idx);
self.semi_naive_magic_evaluate(cur_prog, &stores)?; self.semi_naive_magic_evaluate(cur_prog, &stores)?;
} }
Ok(ret_area) Ok(ret_area)
} }
fn semi_naive_magic_evaluate( pub(crate) fn stratified_magic_compile(
&mut self, &mut self,
prog: &MagicProgram, prog: &StratifiedMagicProgram,
stores: &BTreeMap<MagicKeyword, TempStore>, ) -> Result<(Vec<CompiledProgram>, BTreeMap<MagicKeyword, TempStore>)> {
) -> Result<()> { let stores = prog
let compiled: BTreeMap<_, _> = prog .0
.iter()
.flat_map(|p| p.prog.iter())
.map(|(k, s)| {
(
k.clone(),
(self.new_throwaway(s[0].head.len(), 0, k.clone())),
)
})
.collect::<BTreeMap<_, _>>();
let compiled: Vec<_> = prog
.0
.iter()
.rev()
.map(|cur_prog| -> Result<CompiledProgram> {
cur_prog
.prog .prog
.iter() .iter()
.map( .map(
@ -57,31 +65,44 @@ impl SessionTx {
let mut collected = Vec::with_capacity(body.len()); let mut collected = Vec::with_capacity(body.len());
for (rule_idx, rule) in body.iter().enumerate() { for (rule_idx, rule) in body.iter().enumerate() {
let header = &rule.head; let header = &rule.head;
let mut relation = let mut relation = self.compile_magic_rule_body(
self.compile_magic_rule_body(&rule, k, rule_idx, &stores, &header)?; &rule, k, rule_idx, &stores, &header,
)?;
relation.fill_predicate_binding_indices(); relation.fill_predicate_binding_indices();
collected.push((rule.head.clone(), rule.contained_rules(), relation)); collected.push((
rule.head.clone(),
rule.contained_rules(),
relation,
));
} }
Ok((k.clone(), collected)) Ok((k.clone(), collected))
}, },
) )
.try_collect()
})
.try_collect()?; .try_collect()?;
Ok((compiled, stores))
}
fn semi_naive_magic_evaluate(
&mut self,
prog: &CompiledProgram,
stores: &BTreeMap<MagicKeyword, TempStore>,
) -> Result<()> {
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