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

Function walk_through_dead

atomic-core/src/output/alive/retrieve/mod.rs:424–568  ·  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

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

Callers 1

retrieve_graphFunction · 0.85

Calls 15

alive_graph_reachesFunction · 0.85
visible_chain_reachesFunction · 0.85
iter_forwardMethod · 0.80
passes_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
find_blockMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected