KeiSeiKit-1.0/_primitives/_rust/kei-sage/src/bfs.rs
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

50 lines
1.4 KiB
Rust

//! BFS traversal over the edges table, depth-limited, deduplicated.
use crate::edges::list_outgoing;
use crate::store::Store;
use crate::types::Related;
use anyhow::Result;
use std::collections::{HashSet, VecDeque};
const MAX_RESULTS: usize = 500;
const MAX_DEPTH: i64 = 5;
pub fn bfs(store: &Store, start: &str, max_depth: i64) -> Result<Vec<Related>> {
let depth = clamp_depth(max_depth);
let mut visited: HashSet<String> = HashSet::new();
visited.insert(start.to_string());
let mut queue: VecDeque<(String, i64)> = VecDeque::new();
queue.push_back((start.to_string(), 0));
let mut out: Vec<Related> = Vec::new();
while let Some((path, d)) = queue.pop_front() {
if out.len() >= MAX_RESULTS {
break;
}
if d >= depth {
continue;
}
for e in list_outgoing(store, &path)? {
if visited.contains(&e.dst_path) || out.len() >= MAX_RESULTS {
continue;
}
visited.insert(e.dst_path.clone());
out.push(Related {
path: e.dst_path.clone(),
edge_type: e.edge_type,
depth: d + 1,
});
queue.push_back((e.dst_path, d + 1));
}
}
Ok(out)
}
fn clamp_depth(d: i64) -> i64 {
if d <= 0 {
2
} else if d > MAX_DEPTH {
MAX_DEPTH
} else {
d
}
}