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

Method traverse_bfs_with_depth_multi

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

BFS traversal with multi-label filter. Empty labels = all edges. `max_visited` caps the number of nodes visited to prevent supernode fan-out explosion. Pass [`DEFAULT_MAX_VISITED`] for the standard limit.

(
        &self,
        start_nodes: &[&str],
        label_filters: &[&str],
        direction: Direction,
        max_depth: usize,
        max_visited: usize,
    )

Source from the content-addressed store, hash-verified

111 /// `max_visited` caps the number of nodes visited to prevent supernode fan-out
112 /// explosion. Pass [`DEFAULT_MAX_VISITED`] for the standard limit.
113 pub fn traverse_bfs_with_depth_multi(
114 &self,
115 start_nodes: &[&str],
116 label_filters: &[&str],
117 direction: Direction,
118 max_depth: usize,
119 max_visited: usize,
120 ) -> Vec<(String, u8)> {
121 let label_ids: Vec<u32> = label_filters
122 .iter()
123 .filter_map(|l| self.label_id(l))
124 .collect();
125 let match_label = |lid: u32| label_ids.is_empty() || label_ids.contains(&lid);
126 let mut visited: HashMap<u32, u8> = HashMap::new();
127 let mut queue: VecDeque<(u32, u8)> = VecDeque::new();
128
129 for &node in start_nodes {
130 if let Some(&id) = self.node_to_id.get(node) {
131 visited.insert(id, 0);
132 queue.push_back((id, 0));
133 }
134 }
135
136 while let Some((node_id, depth)) = queue.pop_front() {
137 if depth as usize >= max_depth || visited.len() >= max_visited {
138 continue;
139 }
140
141 let next_depth = depth + 1;
142
143 if matches!(direction, Direction::Out | Direction::Both) {
144 for (lid, dst) in self.dense_iter_out(node_id) {
145 if match_label(lid)
146 && visited.len() < max_visited
147 && !visited.contains_key(&dst)
148 {
149 visited.insert(dst, next_depth);
150 queue.push_back((dst, next_depth));
151 }
152 }
153 }
154 if matches!(direction, Direction::In | Direction::Both) {
155 for (lid, src) in self.dense_iter_in(node_id) {
156 if match_label(lid)
157 && visited.len() < max_visited
158 && !visited.contains_key(&src)
159 {
160 visited.insert(src, next_depth);
161 queue.push_back((src, next_depth));
162 }
163 }
164 }
165 }
166
167 visited
168 .into_iter()
169 .map(|(id, depth)| (self.id_to_node[id as usize].clone(), depth))
170 .collect()

Callers 1

Calls 12

collectMethod · 0.80
pop_frontMethod · 0.80
dense_iter_outMethod · 0.80
dense_iter_inMethod · 0.80
iterMethod · 0.45
label_idMethod · 0.45
is_emptyMethod · 0.45
containsMethod · 0.45
getMethod · 0.45
insertMethod · 0.45
lenMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected