use super::{Graph, VertexId};
use crate::changestore::*;
use crate::pristine::{Base32, GraphTxnT, Position};
use std::collections::{HashMap, HashSet};
use std::io::Write;
impl Graph {
#[allow(dead_code)]
pub fn debug<W: Write, T: GraphTxnT, P: ChangeStore>(
&self,
changes: &P,
txn: &T,
channel: &T::Graph,
add_others: bool,
introduced_by: bool,
mut w: W,
) -> Result<(), std::io::Error> {
writeln!(w, "digraph {{")?;
let mut buf = Vec::new();
let mut cache = HashMap::new();
if add_others {
for (line, i) in self.lines.iter().zip(0..) {
cache.insert(
Position {
change: line.vertex.change,
pos: line.vertex.start,
},
i,
);
}
}
let mut others = HashSet::new();
for (line, i) in self.lines.iter().zip(0..) {
changes
.get_contents(|h| txn.get_external(h).unwrap(), line.vertex, &mut buf)
.unwrap();
let contents = &buf;
let contents = format!(
"{:?}",
if let Ok(contents) = std::str::from_utf8(contents) {
contents.chars().take(100).collect()
} else {
"<INVALID UTF8>".to_string()
}
);
let contents = contents.split_at(contents.len() - 1).0.split_at(1).1;
writeln!(
w,
"n_{}[label=\"{}({}): {}.[{};{}[: {}\"];",
i,
i,
line.scc,
line.vertex.change.to_base32(),
line.vertex.start.0,
line.vertex.end.0,
contents
)?;
if add_others && !line.vertex.is_root() {
for v in crate::pristine::iter_adj_all(txn, &channel, line.vertex).unwrap() {
let v = v.unwrap();
if let Some(dest) = cache.get(&v.dest) {
writeln!(
w,
"n_{} -> n_{}[color=red,label=\"{:?}{}{}\"];",
i,
dest,
v.flag.bits(),
if introduced_by { " " } else { "" },
if introduced_by {
v.introduced_by.to_base32()
} else {
String::new()
}
)?;
} else {
if !others.contains(&v.dest) {
others.insert(v.dest);
writeln!(
w,
"n_{}_{}[label=\"{}.{}\",color=red];",
v.dest.change.to_base32(),
v.dest.pos.0,
v.dest.change.to_base32(),
v.dest.pos.0
)?;
}
writeln!(
w,
"n_{} -> n_{}_{}[color=red,label=\"{:?}{}{}\"];",
i,
v.dest.change.to_base32(),
v.dest.pos.0,
v.flag.bits(),
if introduced_by { " " } else { "" },
if introduced_by {
v.introduced_by.to_base32()
} else {
String::new()
}
)?;
}
}
}
for &(edge, VertexId(j)) in
&self.children[line.children..line.children + line.n_children]
{
if let Some(ref edge) = edge {
writeln!(
w,
"n_{}->n_{}[label=\"{:?}{}{}\"];",
i,
j,
edge.flag.bits(),
if introduced_by { " " } else { "" },
if introduced_by {
edge.introduced_by.to_base32()
} else {
String::new()
}
)?
} else {
writeln!(w, "n_{}->n_0[label=\"none\"];", i)?
}
}
}
writeln!(w, "}}")?;
Ok(())
}
#[allow(dead_code)]
pub fn debug_raw<W: Write>(&self, mut w: W) -> Result<(), std::io::Error> {
writeln!(w, "digraph {{")?;
for (line, i) in self.lines.iter().zip(0..) {
writeln!(
w,
"n_{}[label=\"{}(scc {}): {}.[{};{}[\"];",
i,
i,
line.scc,
line.vertex.change.to_base32(),
line.vertex.start.0,
line.vertex.end.0,
)?;
for &(edge, VertexId(j)) in
&self.children[line.children..line.children + line.n_children]
{
if let Some(ref edge) = edge {
writeln!(
w,
"n_{}->n_{}[label=\"{:?} {}\"];",
i,
j,
edge.flag.bits(),
edge.introduced_by.to_base32()
)?
} else {
writeln!(w, "n_{}->n_0[label=\"none\"];", i)?
}
}
}
writeln!(w, "}}")?;
Ok(())
}
}