Skip to content

Commit 0a13b63

Browse files
committed
use Vec in find_shortest_cycle to get deterministic outputs
1 parent b1804b0 commit 0a13b63

File tree

2 files changed

+38
-28
lines changed

2 files changed

+38
-28
lines changed

rust/src/graph/cycles.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@ impl Graph {
1010
module: ModuleToken,
1111
as_package: bool,
1212
) -> GrimpResult<Option<Vec<ModuleToken>>> {
13-
if as_package {
14-
pathfinding::find_shortest_cycle(
15-
self,
16-
&module.conv::<FxHashSet<_>>().with_descendants(self),
17-
&FxHashSet::default(),
18-
&FxHashMap::default(),
19-
)
13+
let modules: Vec<ModuleToken> = if as_package {
14+
let mut vec = module.conv::<Vec<_>>().with_descendants(self);
15+
vec.sort();
16+
vec
2017
} else {
21-
pathfinding::find_shortest_cycle(
22-
self,
23-
&module.conv::<FxHashSet<_>>(),
24-
&FxHashSet::default(),
25-
&FxHashMap::default(),
26-
)
27-
}
18+
let vec: Vec<_> = module.conv::<Vec<ModuleToken>>();
19+
vec
20+
};
21+
pathfinding::find_shortest_cycle(
22+
self,
23+
&modules,
24+
&FxHashSet::default(),
25+
&FxHashMap::default(),
26+
)
2827
}
2928
}

rust/src/graph/pathfinding.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,18 @@ pub fn find_shortest_path(
4141
return Err(GrimpError::SharedDescendants);
4242
}
4343

44+
let predecessors: FxIndexMap<ModuleToken, Option<ModuleToken>> = from_modules
45+
.clone()
46+
.into_iter()
47+
.map(|m| (m, None))
48+
.collect();
49+
let successors: FxIndexMap<ModuleToken, Option<ModuleToken>> =
50+
to_modules.clone().into_iter().map(|m| (m, None)).collect();
51+
4452
_find_shortest_path(
4553
graph,
46-
from_modules,
47-
to_modules,
54+
predecessors,
55+
successors,
4856
excluded_modules,
4957
excluded_imports,
5058
)
@@ -53,7 +61,7 @@ pub fn find_shortest_path(
5361
/// Finds the shortest cycle from `modules` to `modules`, via a bidirectional BFS.
5462
pub fn find_shortest_cycle(
5563
graph: &Graph,
56-
modules: &FxHashSet<ModuleToken>,
64+
modules: &Vec<ModuleToken>,
5765
excluded_modules: &FxHashSet<ModuleToken>,
5866
excluded_imports: &FxHashMap<ModuleToken, FxHashSet<ModuleToken>>,
5967
) -> GrimpResult<Option<Vec<ModuleToken>>> {
@@ -64,23 +72,26 @@ pub fn find_shortest_cycle(
6472
excluded_imports.entry(*m2).or_default().insert(*m1);
6573
}
6674

67-
_find_shortest_path(graph, modules, modules, excluded_modules, &excluded_imports)
75+
let predecessors: FxIndexMap<ModuleToken, Option<ModuleToken>> = modules
76+
.clone()
77+
.into_iter()
78+
.map(|m| (m, None))
79+
.collect();
80+
81+
let successors: FxIndexMap<ModuleToken, Option<ModuleToken>> = predecessors
82+
.clone();
83+
84+
_find_shortest_path(graph, predecessors, successors, excluded_modules, &excluded_imports)
6885
}
6986

7087
fn _find_shortest_path(
7188
graph: &Graph,
72-
from_modules: &FxHashSet<ModuleToken>,
73-
to_modules: &FxHashSet<ModuleToken>,
89+
mut predecessors: FxIndexMap<ModuleToken, Option<ModuleToken>>,
90+
mut successors: FxIndexMap<ModuleToken, Option<ModuleToken>>,
7491
excluded_modules: &FxHashSet<ModuleToken>,
7592
excluded_imports: &FxHashMap<ModuleToken, FxHashSet<ModuleToken>>,
7693
) -> GrimpResult<Option<Vec<ModuleToken>>> {
77-
let mut predecessors: FxIndexMap<ModuleToken, Option<ModuleToken>> = from_modules
78-
.clone()
79-
.into_iter()
80-
.map(|m| (m, None))
81-
.collect();
82-
let mut successors: FxIndexMap<ModuleToken, Option<ModuleToken>> =
83-
to_modules.clone().into_iter().map(|m| (m, None)).collect();
94+
8495

8596
let mut i_forwards = 0;
8697
let mut i_backwards = 0;
@@ -250,7 +261,7 @@ mod test_find_shortest_cycle {
250261

251262
let path = find_shortest_cycle(
252263
&graph,
253-
&FxHashSet::from_iter([red, blue]),
264+
&Vec::from_iter([red, blue]),
254265
&FxHashSet::default(),
255266
&FxHashMap::default(),
256267
)?;

0 commit comments

Comments
 (0)