use crate::catalog::Catalog;
use std::collections::HashMap;
use std::fmt;
use tracing::debug;
#[derive(Debug, Clone)]
pub struct PlanTree {
root: usize,
tree: HashMap<usize, Vec<usize>>, }
impl PlanTree {
pub fn from_catalog(catalog: &Catalog) -> Self {
let core_atoms: Vec<usize> = (0..catalog.core_atom_number()).collect();
let root = *core_atoms.last().unwrap();
let mut tree: HashMap<usize, Vec<usize>> = HashMap::new();
for pair in core_atoms.windows(2).rev() {
let parent = pair[1];
let child = pair[0];
tree.insert(parent, vec![child]);
}
if let Some(&first) = core_atoms.first() {
tree.insert(first, vec![]);
}
let plan_tree = Self { root, tree };
debug!("\nRule:\n {:?}\nPlan tree:\n{}", catalog.rule(), plan_tree);
plan_tree
}
pub fn get_first_join_tuple_index(&self) -> (usize, usize) {
(0, 1)
}
}
impl fmt::Display for PlanTree {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fn print_tree(
f: &mut fmt::Formatter<'_>,
tree: &HashMap<usize, Vec<usize>>,
current: usize,
prefix: &str,
last: bool,
) -> fmt::Result {
writeln!(
f,
"{}{}{}",
prefix,
if last { "└── " } else { "├── " },
current
)?;
let new_prefix = format!("{}{}", prefix, if last { " " } else { "│ " });
if let Some(children) = tree.get(¤t) {
let len = children.len();
for (i, child) in children.iter().enumerate() {
print_tree(f, tree, *child, &new_prefix, i == len - 1)?;
}
}
Ok(())
}
print_tree(f, &self.tree, self.root, "", true)
}
}