use sanakirja_core::btree;
use sanakirja_core::btree::*;
use sanakirja_core::*;
use std::collections::HashSet;
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;
pub fn debug<
P: AsRef<Path>,
T: LoadPage,
K: Representable + ?Sized + std::fmt::Debug,
V: Representable + ?Sized + std::fmt::Debug,
PP: BTreePage<K, V>,
>(
t: &T,
db: &[&Db_<K, V, PP>],
p: P,
recurse: bool,
) where
T::Error: std::fmt::Debug,
{
let f = File::create(p.as_ref()).unwrap();
let mut buf = BufWriter::new(f);
writeln!(&mut buf, "digraph{{").unwrap();
let mut h = HashSet::new();
for db in db {
print_page::<T, K, V, PP>(t, &mut h, &mut buf, &db.db.as_page(), recurse);
}
writeln!(&mut buf, "}}").unwrap();
}
fn print_page<
T: LoadPage,
K: Representable + ?Sized + std::fmt::Debug,
V: Representable + ?Sized + std::fmt::Debug,
P: btree::BTreePage<K, V>,
>(
txn: &T,
pages: &mut HashSet<u64>,
buf: &mut BufWriter<File>,
p: &Page,
print_children: bool,
) where
T::Error: std::fmt::Debug,
{
if !pages.contains(&p.offset) {
pages.insert(p.offset);
writeln!(
buf,
"subgraph cluster{} {{\nlabel=\"Page {}, rc \
{}\";\ncolor=black;",
p.offset,
p.offset,
txn.rc(p.offset).unwrap()
)
.unwrap();
let mut h = Vec::new();
let mut edges = Vec::new();
print_cursor::<T, K, V, P>(txn, buf, &mut edges, &mut h, p);
writeln!(buf, "}}").unwrap();
for p in edges.iter() {
writeln!(buf, "{}", p).unwrap()
}
if print_children {
for p in h.iter() {
print_page::<T, K, V, P>(txn, pages, buf, &p.as_page(), print_children)
}
}
}
}
fn print_cursor<
T: LoadPage,
K: Representable + ?Sized + std::fmt::Debug,
V: Representable + ?Sized + std::fmt::Debug,
P: btree::BTreePage<K, V>,
>(
txn: &T,
buf: &mut dyn std::io::Write,
edges: &mut Vec<String>,
pages: &mut Vec<CowPage>,
p: &Page,
) where
T::Error: std::fmt::Debug,
{
let mut cursor = P::first_cursor(*p);
let mut i = 0;
let l = P::left_child(*p, &cursor);
if l > 0 {
pages.push(txn.load_page(l).unwrap());
edges.push(format!(
"n_{}_{}->n_{}_0[color=\"ForestGreen\"];",
p.offset, i, l
))
}
while let Some((key, _, r)) = P::next(txn, *p, &mut cursor) {
if i > 0 {
writeln!(
buf,
"n_{}_{}->n_{}_{}[color=\"blue\"];",
p.offset,
i - 1,
p.offset,
i
)
.unwrap();
}
writeln!(buf, "n_{}_{}[label=\"{}: {:?}\"];", p.offset, i, i, key).unwrap();
if r > 0 {
pages.push(txn.load_page(r).unwrap());
edges.push(format!("n_{}_{}->n_{}_0[color=\"red\"];", p.offset, i, r))
};
i += 1
}
}