11use super :: super :: build_types:: * ;
22use crate :: helpers;
3+ use ahash:: AHashSet ;
34use std:: collections:: { HashMap , HashSet , VecDeque } ;
45
56pub 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
8788fn 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