ZCPGCKKYDBXUTIYGKGRA7C43CJ2WNWH3L6Q7ETSVLYB6AE4HAGTQC ZDK3GNDBWXJ2OXFDYB72ZCEBGLBF4MKE5K3PVHDZATHJ7HJIDPRQC YUJV2OHL2JRZBT2E25KLIPWO44IFCGJ47IQNQKHMZO5U2FYANQYQC 6YMDOZIB5LVYLFIDGN2WNT5JTHEAMS4TFPVDEZ3OWXWOKJOC5QDAC IIV3EL2XYI2X7HZWKXEXQFAE3R3KC2Q7SGOT3Q332HSENMYVF32QC SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC YN63NUZO4LVJ7XPMURDULTXBVJKW5MVCTZ24R7Z52QMHO3HPDUVQC CCLLB7OIFNFYJZTG3UCI7536TOCWSCSXR67VELSB466R24WLJSDAC 2BKYJ2JM5PTXWO6HTVBKFQANWWSCJ4UHJYKAXWGTVZB35AZJ76CQC HMMMKONLCRAXVT7SO2ITTFDOJIQKKVSRIZPXYVPDC34RCBHWMHVAC // If we're deleting a FOLDER edge, repair_context_deleted// will not repair its potential descendants. Hence, we must// also count as "alive" a FOLDER node with alive descendants.if p.flag().is_folder() {if folder_has_alive_descendants(txn, channel, &mut alive_folder, &mut folder_stack, b)?{continue;}}if a.is_empty() && b_is_alive {// In this case, `a` can be an inode, in which case we// can't simply delete the edge, since b would become// unreachable.//// We test this here:let mut is_inode = false;for e in iter_adjacent(txn,channel,a,EdgeFlags::FOLDER | EdgeFlags::PARENT,EdgeFlags::all(),)? {let e = e?;if e.flag().contains(EdgeFlags::FOLDER | EdgeFlags::PARENT) {is_inode = true;break;}}if is_inode {continue;}}
fn folder_has_alive_descendants<T: GraphMutTxnT + TreeTxnT>(txn: &mut T,channel: &mut T::Graph,alive: &mut HashMap<Vertex<ChangeId>, bool>,stack: &mut Vec<(Vertex<ChangeId>, bool)>,b: Vertex<ChangeId>,) -> Result<bool, LocalApplyError<T>> {if let Some(r) = alive.get(&b) {return Ok(*r);}debug!("alive descendants");stack.clear();stack.push((b, false));while let Some((b, visited)) = stack.pop() {debug!("visiting {:?} {:?}", b, visited);if visited {if !alive.contains_key(&b) {alive.insert(b, false);}continue;}stack.push((b, true));for e in iter_adjacent(txn,channel,b,EdgeFlags::empty(),EdgeFlags::all() - EdgeFlags::DELETED - EdgeFlags::PARENT,)? {let e = e?;if e.flag().contains(EdgeFlags::FOLDER) {let c = txn.find_block(channel, e.dest())?;stack.push((*c, false));} else {// This is a non-deleted non-folder edge.let c = txn.find_block(channel, e.dest())?;if is_alive(txn, channel, &c)? {// The entire path is alive.for (x, on_path) in stack.iter() {if *on_path {alive.insert(*x, true);}}}}}}Ok(*alive.get(&b).unwrap_or(&false))}