fn diff_binary<T: GraphTxnT, C: ChangeStore>(
&mut self,
changes: &C,
txn: &T,
channel: &T::Graph,
path: String,
inode: Position<Option<ChangeId>>,
ret: &crate::alive::Graph,
b: &[u8],
) -> Result<(), TxnErr<T::GraphError>> {
self.has_binary_files = true;
use crate::change::{Atom, EdgeMap, Hunk, Local, NewEdge, NewVertex};
let mut contents = self.contents.lock().unwrap();
let pos = contents.len();
contents.extend_from_slice(&b[..]);
let pos_end = contents.len();
contents.push(0);
std::mem::drop(contents);
let mut edges = Vec::new();
let mut deleted = Vec::new();
for v in ret.lines.iter() {
debug!("v.vertex = {:?}, inode = {:?}", v.vertex, inode);
if Some(v.vertex.change) == inode.change && v.vertex.end == inode.pos {
continue;
}
for e in iter_adjacent(txn, channel, v.vertex, EdgeFlags::PARENT, EdgeFlags::all())? {
let e = e?;
if e.flag().contains(EdgeFlags::PSEUDO) {
continue;
}
if e.flag().contains(EdgeFlags::FOLDER) {
if log_enabled!(log::Level::Debug) {
let f = std::fs::File::create("debug_diff_binary").unwrap();
ret.debug(changes, txn, channel, false, true, f).unwrap();
}
panic!("e.flag.contains(EdgeFlags::FOLDER)");
}
if e.flag().contains(EdgeFlags::PARENT) {
if e.flag().contains(EdgeFlags::DELETED) {
deleted.push(NewEdge {
previous: e.flag() - EdgeFlags::PARENT,
flag: e.flag() - EdgeFlags::PARENT,
from: e.dest().to_option(),
to: v.vertex.to_option(),
introduced_by: Some(e.introduced_by()),
})
} else {
let previous = e.flag() - EdgeFlags::PARENT;
edges.push(NewEdge {
previous,
flag: previous | EdgeFlags::DELETED,
from: e.dest().to_option(),
to: v.vertex.to_option(),
introduced_by: Some(e.introduced_by()),
})
}
}
}
}
// Kill all of `ret`, add `b` instead.
if !deleted.is_empty() {
self.actions.push(Hunk::Edit {
local: Local {
line: 0,
path: path.clone(),
},
change: Atom::EdgeMap(EdgeMap {
edges: deleted,
inode,
}),
encoding: None,
})
}
self.actions.push(Hunk::Replacement {
local: Local { line: 0, path },
change: Atom::EdgeMap(EdgeMap { edges, inode }),
replacement: Atom::NewVertex(NewVertex {
up_context: vec![inode],
down_context: Vec::new(),
flag: EdgeFlags::empty(),
start: ChangePosition(pos.into()),
end: ChangePosition(pos_end.into()),
inode,
}),
encoding: None,
});
Ok(())
}