MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / traverse_bfs

Method traverse_bfs

nodedb-graph/src/traversal.rs:28–91  ·  view source on GitHub ↗

BFS traversal. Returns all reachable node IDs within max_depth hops. `max_visited` caps the number of nodes visited to prevent supernode fan-out explosion. Pass [`DEFAULT_MAX_VISITED`] for the standard limit. `frontier_bitmap`: when `Some`, only nodes whose surrogate is present in the bitmap are eligible as traversal targets. Start nodes are not gated — only newly discovered frontier nodes are c

(
        &self,
        start_nodes: &[&str],
        label_filter: Option<&str>,
        direction: Direction,
        max_depth: usize,
        max_visited: usize,
        frontier_bitmap: Option<&

Source from the content-addressed store, hash-verified

26 /// bitmap are eligible as traversal targets. Start nodes are not gated — only
27 /// newly discovered frontier nodes are checked.
28 pub fn traverse_bfs(
29 &self,
30 start_nodes: &[&str],
31 label_filter: Option<&str>,
32 direction: Direction,
33 max_depth: usize,
34 max_visited: usize,
35 frontier_bitmap: Option<&nodedb_types::SurrogateBitmap>,
36 ) -> Vec<String> {
37 let label_id = label_filter.and_then(|l| self.label_id(l));
38 let mut visited: HashSet<u32> = HashSet::new();
39 let mut queue: VecDeque<(u32, usize)> = VecDeque::new();
40
41 for &node in start_nodes {
42 if let Some(&id) = self.node_to_id.get(node)
43 && visited.insert(id)
44 {
45 queue.push_back((id, 0));
46 }
47 }
48
49 while let Some((node_id, depth)) = queue.pop_front() {
50 if depth >= max_depth || visited.len() >= max_visited {
51 continue;
52 }
53
54 // Track access for hot/cold partition decisions.
55 self.record_access(node_id);
56
57 if matches!(direction, Direction::Out | Direction::Both) {
58 for (lid, dst) in self.dense_iter_out(node_id) {
59 if label_id.is_none_or(|f| f == lid)
60 && visited.len() < max_visited
61 && frontier_bitmap.is_none_or(|bm| {
62 bm.contains(nodedb_types::Surrogate::new(self.node_surrogate_raw(dst)))
63 })
64 && visited.insert(dst)
65 {
66 self.prefetch_node(dst);
67 queue.push_back((dst, depth + 1));
68 }
69 }
70 }
71 if matches!(direction, Direction::In | Direction::Both) {
72 for (lid, src) in self.dense_iter_in(node_id) {
73 if label_id.is_none_or(|f| f == lid)
74 && visited.len() < max_visited
75 && frontier_bitmap.is_none_or(|bm| {
76 bm.contains(nodedb_types::Surrogate::new(self.node_surrogate_raw(src)))
77 })
78 && visited.insert(src)
79 {
80 self.prefetch_node(src);
81 queue.push_back((src, depth + 1));
82 }
83 }
84 }
85 }

Callers 6

bfs_traversalFunction · 0.80
bfs_all_labelsFunction · 0.80
bfs_cycleFunction · 0.80
large_graph_bfsFunction · 0.80
execute_graph_hopMethod · 0.80

Calls 13

pop_frontMethod · 0.80
record_accessMethod · 0.80
dense_iter_outMethod · 0.80
node_surrogate_rawMethod · 0.80
prefetch_nodeMethod · 0.80
dense_iter_inMethod · 0.80
collectMethod · 0.80
label_idMethod · 0.45
getMethod · 0.45
insertMethod · 0.45
lenMethod · 0.45
containsMethod · 0.45

Tested by 5

bfs_traversalFunction · 0.64
bfs_all_labelsFunction · 0.64
bfs_cycleFunction · 0.64
large_graph_bfsFunction · 0.64