diff --git a/rebacs_core/src/lib.rs b/rebacs_core/src/lib.rs index 8badb83..cc08c32 100644 --- a/rebacs_core/src/lib.rs +++ b/rebacs_core/src/lib.rs @@ -1,10 +1,9 @@ use std::{ borrow::Borrow, cmp::Ordering, - collections::{BTreeSet, BinaryHeap, HashSet}, + collections::{BTreeSet, HashSet}, fmt::Debug, hash::Hash, - ops::Deref, sync::Arc, }; @@ -29,12 +28,6 @@ pub struct Node { pub edges_out: RwLock>>, } -#[derive(Debug, PartialEq, Eq)] -struct Distanced { - distance: u32, - data: T, -} - #[derive(Default)] pub struct RelationGraph { nodes: RwLock>>, @@ -112,6 +105,7 @@ impl RelationGraph { } } + /// checks if there is a path between src and dst using BFS pub async fn has_recursive<'a>( &self, src: impl Into, @@ -127,34 +121,40 @@ impl RelationGraph { return false; }; - let src_neighbors = src + let mut distance = 1; + + let mut neighbors = src .edges_out .read() .await .iter() - .map(|x| Distanced::one(x.clone())) + .cloned() .collect::>(); - let mut q: BinaryHeap>> = BinaryHeap::from(src_neighbors); let mut visited: HashSet> = HashSet::new(); - while let Some(distanced) = q.pop() { - if distanced.id == dst { - return true; - } - if let Some(limit) = limit { - if distanced.distance() > limit { - return false; + while !neighbors.is_empty() { + let mut next_neighbors = vec![]; + for neighbor in neighbors { + if distance > 1 && visited.contains(&neighbor) { + continue; } - } - - for neighbor in distanced.edges_out.read().await.iter() { - if !visited.contains(neighbor) { - q.push(Distanced::new(neighbor.clone(), distanced.distance() + 1)) + if neighbor.id == dst { + return true; + } + if let Some(limit) = limit { + if distance > limit { + return false; + } } - } - visited.insert(distanced.clone()); + let mut node_neighbors = neighbor.edges_out.read().await.clone(); + next_neighbors.append(&mut node_neighbors); + + visited.insert(neighbor); + } + neighbors = next_neighbors; + distance += 1; } false } @@ -292,37 +292,6 @@ impl Hash for Node { } } -impl Distanced { - pub fn new(data: T, distance: u32) -> Self { - Self { distance, data } - } - pub fn one(data: T) -> Self { - Self { distance: 1, data } - } - pub fn distance(&self) -> u32 { - self.distance - } -} - -impl Deref for Distanced { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.data - } -} - -impl PartialOrd for Distanced { - fn partial_cmp(&self, other: &Self) -> Option { - self.distance.partial_cmp(&other.distance) - } -} -impl Ord for Distanced { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.distance.cmp(&other.distance) - } -} - impl From<(&str, &str)> for NodeId { fn from(value: (&str, &str)) -> Self { Self {