Stitching is when we use pseudo-edges to reconnect alive parts which may have been separated by a deletion. One of our test cases showed that this wasn't working well in the case of cyclic conflicts.
That particular test case is probably the worst thing imaginable, since it manages to create a cyclic + zombie conflict between the empty vertices used to solve regular order conflicts.
FSJBK6CUVMSKZVLD7SWC4L53GMPUKIQESWDBFMV5GLX43WBUZDPQC SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC BD5PC25AB5MKVIYDFSDGRZ4YGX4PKW4SMZ3YAYAPNA5HLDVJUR3QC 6YMDOZIB5LVYLFIDGN2WNT5JTHEAMS4TFPVDEZ3OWXWOKJOC5QDAC CCLLB7OIFNFYJZTG3UCI7536TOCWSCSXR67VELSB466R24WLJSDAC I24UEJQLCH2SOXA4UHIYWTRDCHSOPU7AFTRUOTX7HZIAV4AZKYEQC FXEDPLRI7PXLDXV634ZA6D5Q3ZWG3ESTKJTMRPJ4MAHI7PKU3M6AC 55SCQOOHI4VRYNKPKDV5PVDXZIY4DG6URA2TMBLQGYLNI6YC7XHAC 43SISRQ4CLKXN5YVFAGWUU3OJBT2TX6QXWWER33ONLEITSCFCUBAC ZJWCPRMHAYZYGCPYBTBIPBBFVCVDSFNGUL36HMC2DHCWZZKNA7PAC MQ6ERQ43MWASF2OSG65FHKWHCWT35BJVFJWKHAFPVCTLICCTJWUAC H5DIAL52H2LOXEL4JO7YGBYVNZBFOQFQ2UCGFL2KDUEDLCVGQBSQC HP7CKJIW6TOQZFAZKKJFF76LGE7EMQVDTRH2RWPM4POIG2WRKHBAC impl MutTxnTExt for pristine::sanakirja::MutTxn<()> {}impl TxnTExt for pristine::sanakirja::MutTxn<()> {}impl TxnTExt for pristine::sanakirja::Txn {}
impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error>+ ::sanakirja::RootPageMut+ ::sanakirja::Commit+ ::sanakirja::AllocPage<Error = ::sanakirja::Error>,> MutTxnTExt for pristine::sanakirja::GenericTxn<T>{}impl<T: ::sanakirja::LoadPage<Error = ::sanakirja::Error> + ::sanakirja::RootPage> TxnTExtfor pristine::sanakirja::GenericTxn<T>{}
debug!("descendant {:#?}", r);put_graph_with_rev(txn,channel,EdgeFlags::PSEUDO,elt.last_alive,*r,ChangeId::ROOT,)?;
debug!("put_pseudo, descendant {:?} {:?}", elt.last_alive, r);// If we aren't in a direct cycle, reconnect.if elt.last_alive != *r {put_graph_with_rev(txn,channel,EdgeFlags::PSEUDO,elt.last_alive,*r,ChangeId::ROOT,)?;}}if !elt.is_alive() {continue;
// We need to reconnect, and we can do it now// since we won't have a chance to visit that// edge (because non-PARENT edge we are// inserting now starts from a vertex that is// on the path, which means we've already// pushed all its children onto the stack.).put_graph_with_rev(txn,channel,EdgeFlags::PSEUDO,v.vertex,elt.vertex,ChangeId::ROOT,)?;
if v.vertex != elt.vertex {// We need to reconnect, and we can do it now// since we won't have a chance to visit that// edge (because non-PARENT edge we are// inserting now starts from a vertex that is// on the path, which means we've already// pushed all its children onto the stack.).debug!("alive, put_pseudo {:?} {:?}", v.vertex, elt.vertex);put_graph_with_rev(txn,channel,EdgeFlags::PSEUDO,v.vertex,elt.vertex,ChangeId::ROOT,)?;}
stack[len - 1].vertex,ChangeId::ROOT,)?;
stack[len - 1].vertex);debug!("{:?}", stack);let edge = Edge {dest: stack[len - 1].vertex.start_pos(),flag: EdgeFlags::empty(),introduced_by: ChangeId::ROOT,};match txn.get_graph(channel, &v.last_alive, Some(&edge.into()))? {Some(e) if e.dest() == edge.dest && e.flag() == EdgeFlags::BLOCK => {}_ => {put_graph_with_rev(txn,channel,EdgeFlags::PSEUDO,v.last_alive,stack[len - 1].vertex,ChangeId::ROOT,)?;}}