Skip to content

Commit 20daf8a

Browse files
committed
More optimization
1 parent 1aa10f9 commit 20daf8a

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

src/build/compile/dependency_cycle.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::super::build_types::*;
22
use crate::helpers;
3+
use ahash::AHashSet;
34
use std::collections::{HashMap, HashSet, VecDeque};
45

56
pub fn find(modules: &Vec<(&String, &Module)>) -> Vec<String> {
@@ -10,35 +11,35 @@ fn find_shortest_cycle(modules: &Vec<(&String, &Module)>) -> Vec<String> {
1011
let mut shortest_cycle: Vec<String> = Vec::new();
1112

1213
// Build a graph representation for easier traversal
13-
let mut graph: HashMap<String, Vec<String>> = HashMap::new();
14-
let mut in_degrees: HashMap<String, usize> = HashMap::new();
1514

15+
let mut graph: HashMap<&String, &AHashSet<String>> = HashMap::new();
16+
let mut in_degrees: HashMap<&String, usize> = HashMap::new();
17+
18+
let empty = AHashSet::new();
1619
// First pass: collect all nodes and initialize in-degrees
1720
for (name, _) in modules {
18-
graph.insert(name.to_string(), Vec::new());
19-
in_degrees.insert(name.to_string(), 0);
21+
graph.insert(name, &empty);
22+
in_degrees.insert(name, 0);
2023
}
2124

2225
// Second pass: build the graph and count in-degrees
2326
for (name, module) in modules {
24-
let deps: Vec<String> = module.deps.iter().cloned().collect();
25-
2627
// Update in-degrees
27-
for dep in &deps {
28+
for dep in module.deps.iter() {
2829
if let Some(count) = in_degrees.get_mut(dep) {
2930
*count += 1;
3031
}
3132
}
3233

3334
// Update the graph
34-
*graph.get_mut(&name.to_string()).unwrap() = deps.clone();
35+
*graph.get_mut(*name).unwrap() = &module.deps;
3536
}
3637
// Remove all nodes in the graph that have no incoming edges
3738
graph.retain(|_, deps| !deps.is_empty());
3839

3940
// OPTIMIZATION 1: Start with nodes that are more likely to be in cycles
4041
// Sort nodes by their connectivity (in-degree + out-degree)
41-
let mut start_nodes: Vec<String> = graph.keys().cloned().collect();
42+
let mut start_nodes: Vec<&String> = graph.keys().cloned().collect();
4243
start_nodes.sort_by(|a, b| {
4344
let a_connectivity = in_degrees.get(a).unwrap_or(&0) + graph.get(a).map_or(0, |v| v.len());
4445
let b_connectivity = in_degrees.get(b).unwrap_or(&0) + graph.get(b).map_or(0, |v| v.len());
@@ -54,7 +55,7 @@ fn find_shortest_cycle(modules: &Vec<(&String, &Module)>) -> Vec<String> {
5455
// Try BFS from each node to find the shortest cycle
5556
for start_node in start_nodes {
5657
// Skip nodes that we know don't have cycles
57-
if no_cycle_cache.contains(&start_node) {
58+
if no_cycle_cache.contains(start_node) {
5859
continue;
5960
}
6061

@@ -77,7 +78,7 @@ fn find_shortest_cycle(modules: &Vec<(&String, &Module)>) -> Vec<String> {
7778
}
7879
} else {
7980
// Cache this node as not having a cycle
80-
no_cycle_cache.insert(start_node);
81+
no_cycle_cache.insert(start_node.to_string());
8182
}
8283
}
8384

@@ -86,7 +87,7 @@ fn find_shortest_cycle(modules: &Vec<(&String, &Module)>) -> Vec<String> {
8687

8788
fn find_cycle_bfs(
8889
start: &String,
89-
graph: &HashMap<String, Vec<String>>,
90+
graph: &HashMap<&String, &AHashSet<String>>,
9091
max_length: usize,
9192
) -> Option<Vec<String>> {
9293
// Use a BFS to find the shortest cycle
@@ -109,7 +110,7 @@ fn find_cycle_bfs(
109110

110111
// Check all neighbors
111112
if let Some(neighbors) = graph.get(&current) {
112-
for neighbor in neighbors {
113+
for neighbor in neighbors.iter() {
113114
// If we found the start node again, we have a cycle
114115
if neighbor == start {
115116
// Reconstruct the cycle

0 commit comments

Comments
 (0)