MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / walk_through_dead

Function walk_through_dead

atomic-core/src/output/alive/retrieve/mod.rs:427–581  ·  view source on GitHub ↗

Walk through a dead vertex's forward edges to find live successors. In the additive edge model there are no PSEUDO reconnection edges, so the alive-graph traversal must dynamically skip over dead vertices to find live descendants. This walks the dead vertex's BLOCK edges (including deleted ones, since we may need to skip multiple dead vertices in a row) and pushes any live destinations onto the

(
    txn: &T,
    options: &RetrieveOptions,
    owner_parent: GraphNode<NodeId>,
    dead_vertex: GraphNode<NodeId>,
    stack: &mut Vec<VertexId>,
    cache: &mut std::collections::HashMap<GraphNod

Source from the content-addressed store, hash-verified

425/// list so they appear as proper graph children of the upstream alive
426/// parent.
427fn walk_through_dead<T: GraphTxnT>(
428 txn: &T,
429 options: &RetrieveOptions,
430 owner_parent: GraphNode<NodeId>,
431 dead_vertex: GraphNode<NodeId>,
432 stack: &mut Vec<VertexId>,
433 cache: &mut std::collections::HashMap<GraphNode<NodeId>, VertexId>,
434 result: &mut RetrieveResult,
435) -> Result<Vec<VertexId>, PristineError> {
436 use std::collections::HashSet;
437 let mut live_successors: Vec<VertexId> = Vec::new();
438
439 // BFS through dead vertices, recording live ones we encounter.
440 //
441 // We track three sets separately:
442 // * `dead_visited` — dead vertices we have walked through. This is
443 // the set that an "alive outsider" check should consult: a dead
444 // vertex `D` is claimed by some alive parent `P` only when `P` is
445 // NOT in this set (i.e. `P` is not part of the dead chain).
446 // * `alive_found` — alive vertices reached during this walk. We
447 // remember them only to avoid pushing the same one to the graph
448 // twice, but they must NOT mask the alive-outsider check.
449 // * `seen` — union, used purely to skip re-visiting the
450 // same vertex during BFS.
451 let mut dead_visited: HashSet<GraphNode<NodeId>> = HashSet::new();
452 let mut seen: HashSet<GraphNode<NodeId>> = HashSet::new();
453 let mut queue: Vec<GraphNode<NodeId>> = vec![dead_vertex];
454 seen.insert(dead_vertex);
455 dead_visited.insert(dead_vertex);
456
457 while let Some(current) = queue.pop() {
458 // Walk current's forward edges (include deleted so we can chain
459 // through multiple dead vertices in a row).
460 let edges = txn.iter_forward(current, true)?;
461
462 for edge in edges {
463 let next_pos = edge.dest;
464 let next_vertex = match txn.find_block(next_pos) {
465 Ok(v) => v,
466 Err(_) => continue,
467 };
468
469 if seen.contains(&next_vertex) {
470 continue;
471 }
472 seen.insert(next_vertex);
473
474 // Check change filter
475 if !options.passes_filter(next_vertex.change) {
476 continue;
477 }
478
479 // Is this vertex alive in our view?
480 let alive = if options.has_filter() {
481 options.is_vertex_alive(txn, next_vertex)?
482 } else {
483 classify::is_vertex_alive(txn, &next_vertex)?
484 };

Callers 1

retrieve_graphFunction · 0.85

Calls 15

is_vertex_aliveFunction · 0.85
alive_graph_reachesFunction · 0.85
visible_chain_reachesFunction · 0.85
iter_forwardMethod · 0.80
passes_filterMethod · 0.80
has_filterMethod · 0.80
is_vertex_aliveMethod · 0.80
iter_parentsMethod · 0.80
push_vertexMethod · 0.80
get_vertexMethod · 0.80
getMethod · 0.65
insertMethod · 0.45

Tested by

no test coverage detected