BXD3IQYNMKMI5BTANCF6NZHZP4CKPWADGJMBT2R3WTMKVKONT5QAC
/// Check that each alive vertex in the graph is reachable, and vice-versa.
fn check_alive<T: TxnT, C: libpijul::changestore::ChangeStore>(
changes: &C,
txn: &T,
channel: &ChannelRef<T>,
line: u32,
) -> Result<(), anyhow::Error> {
let (alive, reachable) = txn.check_alive(&channel);
let mut h = BTreeSet::new();
if !alive.is_empty() {
for (k, file) in alive.iter() {
debug!("alive = {:?}, file = {:?}", k, file);
h.insert(file);
}
}
if !reachable.is_empty() {
for (k, file) in reachable.iter() {
debug!("reachable = {:?}, file = {:?}", k, file);
h.insert(file);
}
}
for file in h.iter() {
let file_ = file.unwrap().start_pos();
let mut f = std::fs::File::create(&format!("debug_{:?}", file_))?;
let graph = libpijul::alive::retrieve::retrieve(txn, &channel.borrow(), file_);
graph.debug(changes, txn, &channel.borrow(), false, false, &mut f)?;
let mut f = std::fs::File::create(&format!("debug_all_{:?}", file_))?;
txn.debug_root(channel, file.unwrap(), &mut f)?;
}
if !h.is_empty() {
panic!("alive call line {}", line);
}
Ok(())
}
/// Check that each inode in the inodes table maps to an alive vertex,
/// and that each inode in the tree table is reachable by only one
/// path.
fn check_tree_inodes<T: TxnT>(txn: &T, channel: &Channel<T>) {
// Sanity check
for (inode, vertex) in txn.iter_inodes() {
let mut inode_ = inode;
while !inode_.is_root() {
if let Some(next) = txn.get_revtree(inode_, None) {
inode_ = next.parent_inode;
} else {
panic!("inode = {:?}, inode_ = {:?}", inode, inode_);
}
}
if !txn.is_alive(&channel, vertex.inode_vertex()) {
for e in txn.iter_adjacent(
&channel,
vertex.inode_vertex(),
EdgeFlags::empty(),
EdgeFlags::all(),
) {
error!("{:?} {:?} {:?}", inode, vertex, e)
}
panic!(
"inode {:?}, vertex {:?}, is not alive, {:?}",
inode,
vertex,
txn.tree_path(vertex)
)
}
}
let mut h = HashMap::new();
let id0 = OwnedPathId {
parent_inode: Inode::ROOT,
basename: libpijul::small_string::SmallString::new(),
};
for (id, inode) in txn.iter_tree(id0, None) {
if let Some(inode_) = h.insert(id.clone(), inode) {
panic!("id {:?} maps to two inodes: {:?} {:?}", id, inode, inode_);
}
}
}
/// Check that each inode in the inodes table maps to an alive vertex,
/// and that each inode in the tree table is reachable by only one
/// path.
pub fn check_tree_inodes<T: TxnT>(txn: &T, channel: &Channel<T>) {
// Sanity check
for (inode, vertex) in txn.iter_inodes() {
let mut inode_ = inode;
while !inode_.is_root() {
if let Some(next) = txn.get_revtree(inode_, None) {
inode_ = next.parent_inode;
} else {
panic!("inode = {:?}, inode_ = {:?}", inode, inode_);
}
}
if !is_alive(txn, &channel, vertex.inode_vertex()) {
for e in iter_adjacent(
txn,
&channel,
vertex.inode_vertex(),
EdgeFlags::empty(),
EdgeFlags::all(),
) {
error!("{:?} {:?} {:?}", inode, vertex, e)
}
panic!(
"inode {:?}, vertex {:?}, is not alive, {:?}",
inode,
vertex,
tree_path(txn, vertex)
)
}
}
let mut h = HashMap::new();
let id0 = OwnedPathId {
parent_inode: Inode::ROOT,
basename: crate::small_string::SmallString::new(),
};
for (id, inode) in txn.iter_tree(id0, None) {
if let Some(inode_) = h.insert(id.clone(), inode) {
panic!("id {:?} maps to two inodes: {:?} {:?}", id, inode, inode_);
}
}
}
/// Check that each alive vertex in the graph is reachable, and vice-versa.
pub fn check_alive_debug<T: TxnT, C: crate::changestore::ChangeStore>(
changes: &C,
txn: &T,
channel: &ChannelRef<T>,
line: u32,
) -> Result<(), anyhow::Error> {
let (alive, reachable) = crate::pristine::check_alive(txn, &channel);
let mut h = HashSet::new();
if !alive.is_empty() {
for (k, file) in alive.iter() {
debug!("alive = {:?}, file = {:?}", k, file);
h.insert(file);
}
}
if !reachable.is_empty() {
for (k, file) in reachable.iter() {
debug!("reachable = {:?}, file = {:?}", k, file);
h.insert(file);
}
}
for file in h.iter() {
let file_ = file.unwrap().start_pos();
let mut f = std::fs::File::create(&format!("debug_{:?}", file_))?;
let graph = crate::alive::retrieve::retrieve(txn, &channel.borrow(), file_);
graph.debug(changes, txn, &channel.borrow(), false, false, &mut f)?;
let mut f = std::fs::File::create(&format!("debug_all_{:?}", file_))?;
let channel = channel.borrow();
debug_root(txn, &channel, file.unwrap(), &mut f)?;
}
if !h.is_empty() {
panic!("alive call line {}", line);
}
Ok(())
}