use serde::{Deserialize, Serialize};
use std::collections::HashSet;
type PlanTreeInfo = [((u64, Option<u64>), u64)];
#[derive(Serialize, Deserialize, Debug, Clone)]
struct PlanTreeNodeProfile {
fingerprint: String,
parents: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub(super) struct RuleProfile {
text: String,
plan_tree: Vec<PlanTreeNodeProfile>,
}
impl RuleProfile {
pub(super) fn new(text: String, plan_tree_info: Vec<((u64, Option<u64>), u64)>) -> Self {
let plan_tree = Self::render_plan_tree(&plan_tree_info);
Self { text, plan_tree }
}
fn render_plan_tree(plan_tree_info: &PlanTreeInfo) -> Vec<PlanTreeNodeProfile> {
let outputs: HashSet<u64> = plan_tree_info.iter().map(|(_, fp)| *fp).collect();
plan_tree_info
.iter()
.map(|((fp1, fp2), output_fp)| {
let parents = std::iter::once(*fp1)
.chain(fp2.iter().copied())
.filter(|fp| outputs.contains(fp))
.map(Self::format_fingerprint)
.collect();
PlanTreeNodeProfile {
fingerprint: Self::format_fingerprint(*output_fp),
parents,
}
})
.collect()
}
#[inline]
fn format_fingerprint(fp: u64) -> String {
format!("0x{:016x}", fp)
}
}