From aa72c921ac265f6f714cb0b7e19971752a218482 Mon Sep 17 00:00:00 2001 From: David Seddon Date: Wed, 15 Jan 2025 08:52:57 +0000 Subject: [PATCH] Use faster hash library This is faster, but not cryptographically safe. That shouldn't matter for our purposes. --- rust/Cargo.lock | 7 ++ rust/Cargo.toml | 1 + rust/src/graph.rs | 228 ++++++++++++++++++++++++++------------------ rust/src/lib.rs | 38 ++++---- rust/tests/large.rs | 4 +- 5 files changed, 161 insertions(+), 117 deletions(-) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 37709188..9773fef5 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "pyo3", "pyo3-log", "rayon", + "rustc-hash", "serde_json", ] @@ -277,6 +278,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rustc-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" + [[package]] name = "ryu" version = "1.0.18" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 09e0e5ec..00f48bc5 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -14,6 +14,7 @@ serde_json = "1.0.103" rayon = "1.10" petgraph = "0.6.5" bimap = "0.6.3" +rustc-hash = "2.1.0" [dependencies.pyo3] version = "0.23.4" diff --git a/rust/src/graph.rs b/rust/src/graph.rs index ae9cf237..248e84d6 100644 --- a/rust/src/graph.rs +++ b/rust/src/graph.rs @@ -6,7 +6,7 @@ use petgraph::stable_graph::{NodeIndex, StableGraph}; use petgraph::visit::{Bfs, Walker}; use petgraph::Direction; use rayon::prelude::*; -use std::collections::{HashMap, HashSet}; +use rustc_hash::{FxHashMap, FxHashSet}; use std::fmt; use std::time::Instant; @@ -93,10 +93,10 @@ pub struct Graph { hierarchy: StableGraph, imports_module_indices: BiMap, imports: StableGraph, - squashed_modules: HashSet, + squashed_modules: FxHashSet, // Invisible modules exist in the hierarchy but haven't been explicitly added to the graph. - invisible_modules: HashSet, - detailed_imports_map: HashMap<(Module, Module), HashSet>, + invisible_modules: FxHashSet, + detailed_imports_map: FxHashMap<(Module, Module), FxHashSet>, } #[derive(PartialEq, Eq, Hash, Debug, PartialOrd, Ord)] @@ -245,7 +245,7 @@ impl Graph { }; } - pub fn get_modules(&self) -> HashSet<&Module> { + pub fn get_modules(&self) -> FxHashSet<&Module> { self.hierarchy_module_indices .left_values() .filter(|module| !self.invisible_modules.contains(module)) @@ -260,23 +260,23 @@ impl Graph { &self, importer: &Module, imported: &Module, - ) -> HashSet { + ) -> FxHashSet { let key = (importer.clone(), imported.clone()); match self.detailed_imports_map.get(&key) { Some(import_details) => import_details.clone(), - None => HashSet::new(), + None => FxHashSet::default(), } } - pub fn find_children(&self, module: &Module) -> HashSet<&Module> { + pub fn find_children(&self, module: &Module) -> FxHashSet<&Module> { if self.invisible_modules.contains(module) { - return HashSet::new(); + return FxHashSet::default(); } let module_index = match self.hierarchy_module_indices.get_by_left(module) { Some(index) => index, // Module does not exist. // TODO: should this return a result, to handle if module is not in graph? - None => return HashSet::new(), + None => return FxHashSet::default(), }; self.hierarchy .neighbors(*module_index) @@ -285,7 +285,10 @@ impl Graph { .collect() } - pub fn find_descendants(&self, module: &Module) -> Result, ModuleNotPresent> { + pub fn find_descendants( + &self, + module: &Module, + ) -> Result, ModuleNotPresent> { let module_index = match self.hierarchy_module_indices.get_by_left(module) { Some(index) => index, None => { @@ -343,7 +346,7 @@ impl Graph { let key = (import.importer.clone(), import.imported.clone()); self.detailed_imports_map .entry(key) - .or_insert_with(HashSet::new) + .or_insert_with(FxHashSet::default) .insert(import.clone()); self.add_import(&import.importer, &import.imported); } @@ -411,17 +414,17 @@ impl Graph { .contains_edge(importer_index, imported_index) } - pub fn find_modules_that_directly_import(&self, imported: &Module) -> HashSet<&Module> { + pub fn find_modules_that_directly_import(&self, imported: &Module) -> FxHashSet<&Module> { let imported_index = match self.imports_module_indices.get_by_left(imported) { Some(imported_index) => *imported_index, - None => return HashSet::new(), + None => return FxHashSet::default(), }; - let importer_indices: HashSet = self + let importer_indices: FxHashSet = self .imports .neighbors_directed(imported_index, Direction::Incoming) .collect(); - let importers: HashSet<&Module> = importer_indices + let importers: FxHashSet<&Module> = importer_indices .iter() .map(|importer_index| { self.imports_module_indices @@ -432,17 +435,17 @@ impl Graph { importers } - pub fn find_modules_directly_imported_by(&self, importer: &Module) -> HashSet<&Module> { + pub fn find_modules_directly_imported_by(&self, importer: &Module) -> FxHashSet<&Module> { let importer_index = match self.imports_module_indices.get_by_left(importer) { Some(importer_index) => *importer_index, - None => return HashSet::new(), + None => return FxHashSet::default(), }; - let imported_indices: HashSet = self + let imported_indices: FxHashSet = self .imports .neighbors_directed(importer_index, Direction::Outgoing) .collect(); - let importeds: HashSet<&Module> = imported_indices + let importeds: FxHashSet<&Module> = imported_indices .iter() .map(|imported_index| { self.imports_module_indices @@ -453,12 +456,14 @@ impl Graph { importeds } - pub fn find_upstream_modules(&self, module: &Module, as_package: bool) -> HashSet<&Module> { - let mut upstream_modules = HashSet::new(); + pub fn find_upstream_modules(&self, module: &Module, as_package: bool) -> FxHashSet<&Module> { + let mut upstream_modules = FxHashSet::default(); - let mut modules_to_check: HashSet<&Module> = HashSet::from([module]); + let mut modules_to_check: FxHashSet<&Module> = FxHashSet::from_iter([module]); if as_package { - let descendants = self.find_descendants(&module).unwrap_or(HashSet::new()); + let descendants = self + .find_descendants(&module) + .unwrap_or(FxHashSet::default()); modules_to_check.extend(descendants.into_iter()); }; @@ -479,12 +484,14 @@ impl Graph { upstream_modules } - pub fn find_downstream_modules(&self, module: &Module, as_package: bool) -> HashSet<&Module> { - let mut downstream_modules = HashSet::new(); + pub fn find_downstream_modules(&self, module: &Module, as_package: bool) -> FxHashSet<&Module> { + let mut downstream_modules = FxHashSet::default(); - let mut modules_to_check: HashSet<&Module> = HashSet::from([module]); + let mut modules_to_check: FxHashSet<&Module> = FxHashSet::from_iter([module]); if as_package { - let descendants = self.find_descendants(&module).unwrap_or(HashSet::new()); + let descendants = self + .find_descendants(&module) + .unwrap_or(FxHashSet::default()); modules_to_check.extend(descendants.into_iter()); }; @@ -551,12 +558,12 @@ impl Graph { importer: &Module, imported: &Module, as_packages: bool, - ) -> Result>, String> { - let mut chains = HashSet::new(); + ) -> Result>, String> { + let mut chains = FxHashSet::default(); let mut temp_graph = self.clone(); - let mut downstream_modules: HashSet = HashSet::from([importer.clone()]); - let mut upstream_modules: HashSet = HashSet::from([imported.clone()]); + let mut downstream_modules: FxHashSet = FxHashSet::from_iter([importer.clone()]); + let mut upstream_modules: FxHashSet = FxHashSet::from_iter([imported.clone()]); // TODO don't do this if module is squashed? if as_packages { @@ -597,9 +604,10 @@ impl Graph { } // Keep track of imports into/out of upstream/downstream packages, and remove them. - let mut map_of_imports: HashMap> = HashMap::new(); + let mut map_of_imports: FxHashMap> = + FxHashMap::default(); for module in upstream_modules.union(&downstream_modules) { - let mut imports_to_or_from_module = HashSet::new(); + let mut imports_to_or_from_module = FxHashSet::default(); for imported_module in temp_graph.find_modules_directly_imported_by(&module) { imports_to_or_from_module.insert((module.clone(), imported_module.clone())); } @@ -661,7 +669,7 @@ impl Graph { pub fn find_illegal_dependencies_for_layers( &self, levels: Vec, - containers: HashSet, + containers: FxHashSet, ) -> Result, NoSuchContainer> { // Check that containers exist. let modules = self.get_modules(); @@ -714,7 +722,7 @@ impl Graph { fn _generate_module_permutations( &self, levels: &Vec, - containers: &HashSet, + containers: &FxHashSet, ) -> Vec<(Module, Module, Option)> { let mut permutations: Vec<(Module, Module, Option)> = vec![]; @@ -869,9 +877,9 @@ impl Graph { } // Set up importer/imported package contents. - let mut importer_modules: HashSet<&Module> = HashSet::from([importer_package]); + let mut importer_modules: FxHashSet<&Module> = FxHashSet::from_iter([importer_package]); importer_modules.extend(self.find_descendants(&importer_package).unwrap()); - let mut imported_modules: HashSet<&Module> = HashSet::from([imported_package]); + let mut imported_modules: FxHashSet<&Module> = FxHashSet::from_iter([imported_package]); imported_modules.extend(self.find_descendants(&imported_package).unwrap()); // Build routes from middles. @@ -934,10 +942,10 @@ impl Graph { &mut self, lower_layer_module: &Module, higher_layer_module: &Module, - ) -> HashSet<(Module, Module)> { - let mut imports = HashSet::new(); + ) -> FxHashSet<(Module, Module)> { + let mut imports = FxHashSet::default(); - let mut lower_layer_modules = HashSet::from([lower_layer_module.clone()]); + let mut lower_layer_modules = FxHashSet::from_iter([lower_layer_module.clone()]); for descendant in self .find_descendants(lower_layer_module) .unwrap() @@ -947,7 +955,7 @@ impl Graph { lower_layer_modules.insert(descendant.clone()); } - let mut higher_layer_modules = HashSet::from([higher_layer_module.clone()]); + let mut higher_layer_modules = FxHashSet::from_iter([higher_layer_module.clone()]); for descendant in self .find_descendants(higher_layer_module) .unwrap() @@ -1050,7 +1058,7 @@ mod tests { fn modules_when_empty() { let graph = Graph::default(); - assert_eq!(graph.get_modules(), HashSet::new()); + assert_eq!(graph.get_modules(), FxHashSet::default()); } #[test] @@ -1069,7 +1077,7 @@ mod tests { let result = graph.get_modules(); - assert_eq!(result, HashSet::from([&mypackage])); + assert_eq!(result, FxHashSet::from_iter([&mypackage])); } #[test] @@ -1080,7 +1088,7 @@ mod tests { let result = graph.get_modules(); - assert_eq!(result, HashSet::from([&mypackage])); + assert_eq!(result, FxHashSet::from_iter([&mypackage])); } #[test] @@ -1093,7 +1101,7 @@ mod tests { let result = graph.get_modules(); - assert_eq!(result, HashSet::from([&mypackage, &mypackage_foo])); + assert_eq!(result, FxHashSet::from_iter([&mypackage, &mypackage_foo])); assert_eq!( graph.pretty_str(), " @@ -1117,7 +1125,7 @@ imports: graph.remove_module(&mypackage_foo); let result = graph.get_modules(); - assert_eq!(result, HashSet::from([&mypackage])); + assert_eq!(result, FxHashSet::from_iter([&mypackage])); } #[test] @@ -1136,7 +1144,7 @@ imports: let result = graph.get_modules(); assert_eq!( result, - HashSet::from([ + FxHashSet::from_iter([ &mypackage, &mypackage_foo_alpha, // To be consistent with previous versions of Grimp. ]) @@ -1162,7 +1170,7 @@ imports: let result = graph.get_modules(); assert_eq!( result, - HashSet::from([&mypackage, &mypackage_foo_alpha, &importer, &imported]) + FxHashSet::from_iter([&mypackage, &mypackage_foo_alpha, &importer, &imported]) ); assert_eq!( graph.direct_import_exists(&importer, &mypackage_foo, false), @@ -1190,7 +1198,7 @@ imports: assert_eq!( graph.get_import_details(&importer, &imported), - HashSet::new() + FxHashSet::default() ); } @@ -1210,7 +1218,7 @@ imports: assert_eq!( graph.get_import_details(&importer, &imported), - HashSet::new() + FxHashSet::default() ); } @@ -1229,7 +1237,10 @@ imports: false ); // ...but the modules are still there. - assert_eq!(graph.get_modules(), HashSet::from([&importer, &imported])); + assert_eq!( + graph.get_modules(), + FxHashSet::from_iter([&importer, &imported]) + ); } #[test] @@ -1243,7 +1254,10 @@ imports: graph.remove_import(&importer, &imported); // The modules are still there. - assert_eq!(graph.get_modules(), HashSet::from([&importer, &imported])); + assert_eq!( + graph.get_modules(), + FxHashSet::from_iter([&importer, &imported]) + ); } #[test] @@ -1336,7 +1350,7 @@ imports: graph.add_module(mypackage.clone()); graph.add_module(mypackage_foo.clone()); - assert_eq!(graph.find_children(&mypackage_foo), HashSet::new()); + assert_eq!(graph.find_children(&mypackage_foo), FxHashSet::default()); } #[test] @@ -1352,7 +1366,7 @@ imports: assert_eq!( graph.find_children(&mypackage), - HashSet::from([&mypackage_foo, &mypackage_bar]) + FxHashSet::from_iter([&mypackage_foo, &mypackage_bar]) ); } @@ -1369,7 +1383,7 @@ imports: assert_eq!( graph.find_children(&mypackage), - HashSet::from([&mypackage_foo, &mypackage_bar]) + FxHashSet::from_iter([&mypackage_foo, &mypackage_bar]) ); } @@ -1385,7 +1399,7 @@ imports: assert_eq!( graph.find_children(&Module::new("mypackage".to_string())), - HashSet::new() + FxHashSet::default() ); } @@ -1408,7 +1422,10 @@ imports: graph.add_module(mypackage_foo_alpha_green.clone()); graph.add_module(mypackage_foo_beta.clone()); - assert_eq!(graph.find_descendants(&mypackage_bar), Ok(HashSet::new())); + assert_eq!( + graph.find_descendants(&mypackage_bar), + Ok(FxHashSet::default()) + ); } #[test] @@ -1447,7 +1464,7 @@ imports: assert_eq!( graph.find_descendants(&mypackage_foo), - Ok(HashSet::from([ + Ok(FxHashSet::from_iter([ &mypackage_foo_alpha, &mypackage_foo_alpha_blue, &mypackage_foo_alpha_green, @@ -1479,7 +1496,7 @@ imports: assert_eq!( graph.find_descendants(&mypackage_foo), // mypackage.foo.blue is not included. - Ok(HashSet::from([ + Ok(FxHashSet::from_iter([ &mypackage_foo_blue_alpha, &mypackage_foo_blue_alpha_one, &mypackage_foo_blue_alpha_two, @@ -1512,7 +1529,7 @@ imports: assert_eq!( graph.find_descendants(&mypackage_foo), - Ok(HashSet::from([ + Ok(FxHashSet::from_iter([ &mypackage_foo_blue, // Should be included. &mypackage_foo_blue_alpha, &mypackage_foo_blue_alpha_one, @@ -1608,7 +1625,7 @@ imports: assert_eq!( graph.get_modules(), - HashSet::from([&mypackage_bar, &mypackage_foo]) + FxHashSet::from_iter([&mypackage_bar, &mypackage_foo]) ); assert!(graph.direct_import_exists(&mypackage_foo, &mypackage_bar, false)); assert_eq!( @@ -1635,7 +1652,7 @@ imports: assert_eq!( graph.get_modules(), - HashSet::from([&mypackage_bar, &mypackage_foo]) + FxHashSet::from_iter([&mypackage_bar, &mypackage_foo]) ); assert!(graph.direct_import_exists(&mypackage_foo, &mypackage_bar, false)); assert_eq!( @@ -1777,7 +1794,7 @@ imports: assert_eq!( result, - HashSet::from([&mypackage_foo_alpha, &anotherpackage]) + FxHashSet::from_iter([&mypackage_foo_alpha, &anotherpackage]) ) } @@ -1793,7 +1810,7 @@ imports: graph.remove_import(&green, &blue); let result = graph.find_modules_that_directly_import(&blue); - assert_eq!(result, HashSet::from([&yellow])) + assert_eq!(result, FxHashSet::from_iter([&yellow])) } #[test] @@ -1822,7 +1839,7 @@ imports: assert_eq!( result, - HashSet::from([&mypackage_foo_alpha, &anotherpackage]) + FxHashSet::from_iter([&mypackage_foo_alpha, &anotherpackage]) ) } @@ -1838,7 +1855,7 @@ imports: graph.remove_import(&blue, &green); let result = graph.find_modules_directly_imported_by(&blue); - assert_eq!(result, HashSet::from([&yellow])) + assert_eq!(result, FxHashSet::from_iter([&yellow])) } #[test] @@ -2059,7 +2076,10 @@ imports: let result = graph.find_upstream_modules(&blue, false); - assert_eq!(result, HashSet::from([&green, &red, &yellow, &purple])) + assert_eq!( + result, + FxHashSet::from_iter([&green, &red, &yellow, &purple]) + ) } #[test] @@ -2069,7 +2089,7 @@ imports: let result = graph.find_upstream_modules(&blue, false); - assert_eq!(result, HashSet::new()) + assert_eq!(result, FxHashSet::default()) } #[test] @@ -2106,7 +2126,10 @@ imports: let result = graph.find_upstream_modules(&blue, true); - assert_eq!(result, HashSet::from([&green, &yellow, &purple, &brown])) + assert_eq!( + result, + FxHashSet::from_iter([&green, &yellow, &purple, &brown]) + ) } #[test] @@ -2138,7 +2161,7 @@ imports: let result = graph.find_downstream_modules(&purple, false); - assert_eq!(result, HashSet::from([&yellow, &green, &blue])) + assert_eq!(result, FxHashSet::from_iter([&yellow, &green, &blue])) } #[test] @@ -2148,7 +2171,7 @@ imports: let result = graph.find_downstream_modules(&blue, false); - assert_eq!(result, HashSet::new()) + assert_eq!(result, FxHashSet::default()) } #[test] @@ -2185,7 +2208,10 @@ imports: let result = graph.find_downstream_modules(&blue, true); - assert_eq!(result, HashSet::from([&green, &yellow, &purple, &brown])) + assert_eq!( + result, + FxHashSet::from_iter([&green, &yellow, &purple, &brown]) + ) } // find_shortest_chain @@ -2336,7 +2362,7 @@ imports: let result = graph.find_shortest_chains(&blue, &green, true); - assert_eq!(result, Ok(HashSet::new())); + assert_eq!(result, Ok(FxHashSet::default())); } #[test] @@ -2361,7 +2387,7 @@ imports: let result = graph.find_shortest_chains(&blue, &green, true); - assert_eq!(result, Ok(HashSet::from([vec![blue, red, green],]))); + assert_eq!(result, Ok(FxHashSet::from_iter([vec![blue, red, green],]))); } #[test] @@ -2388,7 +2414,10 @@ imports: let result = graph.find_shortest_chains(&blue, &green, true); - assert_eq!(result, Ok(HashSet::from([vec![blue, red, green_alpha]]))); + assert_eq!( + result, + Ok(FxHashSet::from_iter([vec![blue, red, green_alpha]])) + ); } #[test] @@ -2419,7 +2448,7 @@ imports: assert_eq!( result, - Ok(HashSet::from([vec![blue, red, green_alpha_one],])) + Ok(FxHashSet::from_iter([vec![blue, red, green_alpha_one],])) ) } @@ -2447,7 +2476,10 @@ imports: let result = graph.find_shortest_chains(&blue, &green, true); - assert_eq!(result, Ok(HashSet::from([vec![blue_alpha, red, green],]))); + assert_eq!( + result, + Ok(FxHashSet::from_iter([vec![blue_alpha, red, green],])) + ); } #[test] @@ -2478,7 +2510,7 @@ imports: assert_eq!( result, - Ok(HashSet::from([vec![blue_alpha_one, red, green],])) + Ok(FxHashSet::from_iter([vec![blue_alpha_one, red, green],])) ) } @@ -2593,7 +2625,7 @@ imports: fn find_illegal_dependencies_for_layers_empty_everything() { let graph = Graph::default(); - let dependencies = graph.find_illegal_dependencies_for_layers(vec![], HashSet::new()); + let dependencies = graph.find_illegal_dependencies_for_layers(vec![], FxHashSet::default()); assert_eq!(dependencies, Ok(vec![])); } @@ -2603,8 +2635,10 @@ imports: let graph = Graph::default(); let container = "nonexistent_container".to_string(); - let dependencies = - graph.find_illegal_dependencies_for_layers(vec![], HashSet::from([container.clone()])); + let dependencies = graph.find_illegal_dependencies_for_layers( + vec![], + FxHashSet::from_iter([container.clone()]), + ); assert_eq!( dependencies, @@ -2622,7 +2656,8 @@ imports: independent: true, }; - let dependencies = graph.find_illegal_dependencies_for_layers(vec![level], HashSet::new()); + let dependencies = + graph.find_illegal_dependencies_for_layers(vec![level], FxHashSet::default()); assert_eq!(dependencies, Ok(vec![])); } @@ -2637,8 +2672,8 @@ imports: }; let container = "mypackage".to_string(); - let dependencies = - graph.find_illegal_dependencies_for_layers(vec![level], HashSet::from([container])); + let dependencies = graph + .find_illegal_dependencies_for_layers(vec![level], FxHashSet::from_iter([container])); assert_eq!(dependencies, Ok(vec![])); } @@ -2660,7 +2695,7 @@ imports: }, ]; - let dependencies = graph.find_illegal_dependencies_for_layers(levels, HashSet::new()); + let dependencies = graph.find_illegal_dependencies_for_layers(levels, FxHashSet::default()); assert_eq!( dependencies, @@ -2695,7 +2730,7 @@ imports: }, ]; - let dependencies = graph.find_illegal_dependencies_for_layers(levels, HashSet::new()); + let dependencies = graph.find_illegal_dependencies_for_layers(levels, FxHashSet::default()); assert_eq!( dependencies, @@ -2741,7 +2776,7 @@ imports: independent: true, }, ]; - let containers = HashSet::from(["blue".to_string(), "green".to_string()]); + let containers = FxHashSet::from_iter(["blue".to_string(), "green".to_string()]); let dependencies = graph.find_illegal_dependencies_for_layers(levels, containers); @@ -2786,7 +2821,7 @@ imports: independent: true, }]; - let dependencies = graph.find_illegal_dependencies_for_layers(levels, HashSet::new()); + let dependencies = graph.find_illegal_dependencies_for_layers(levels, FxHashSet::default()); assert_eq!( dependencies, @@ -2810,7 +2845,7 @@ imports: let result = graph.get_import_details(&importer, &imported); - assert_eq!(result, HashSet::new()); + assert_eq!(result, FxHashSet::default()); } #[test] @@ -2822,7 +2857,7 @@ imports: let result = graph.get_import_details(&importer, &imported); - assert_eq!(result, HashSet::new()); + assert_eq!(result, FxHashSet::default()); } #[test] @@ -2847,7 +2882,7 @@ imports: let result = graph.get_import_details(&importer, &imported); - assert_eq!(result, HashSet::from([import])); + assert_eq!(result, FxHashSet::from_iter([import])); } #[test] @@ -2872,7 +2907,10 @@ imports: let result = graph.get_import_details(&blue, &green); - assert_eq!(result, HashSet::from([blue_to_green_a, blue_to_green_b])); + assert_eq!( + result, + FxHashSet::from_iter([blue_to_green_a, blue_to_green_b]) + ); } #[test] @@ -2898,7 +2936,7 @@ imports: let result = graph.get_import_details(&importer, &imported); - assert_eq!(result, HashSet::new()); + assert_eq!(result, FxHashSet::default()); } #[test] @@ -2924,6 +2962,6 @@ imports: let result = graph.get_import_details(&importer, &imported); - assert_eq!(result, HashSet::from([import])); + assert_eq!(result, FxHashSet::from_iter([import])); } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 112dbb0e..10d52631 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,7 +6,7 @@ use pyo3::create_exception; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; use pyo3::types::{PyDict, PyFrozenSet, PyList, PySet, PyString, PyTuple}; -use std::collections::HashSet; +use rustc_hash::FxHashSet; #[pymodule] fn _rustgrimp(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> { @@ -34,7 +34,7 @@ impl GraphWrapper { } } - pub fn get_modules(&self) -> HashSet { + pub fn get_modules(&self) -> FxHashSet { self._graph .get_modules() .iter() @@ -125,7 +125,7 @@ impl GraphWrapper { self._graph.count_imports() } - pub fn find_children(&self, module: &str) -> HashSet { + pub fn find_children(&self, module: &str) -> FxHashSet { self._graph .find_children(&Module::new(module.to_string())) .iter() @@ -133,7 +133,7 @@ impl GraphWrapper { .collect() } - pub fn find_descendants(&self, module: &str) -> HashSet { + pub fn find_descendants(&self, module: &str) -> FxHashSet { self._graph .find_descendants(&Module::new(module.to_string())) .unwrap() @@ -169,7 +169,7 @@ impl GraphWrapper { )) } - pub fn find_modules_directly_imported_by(&self, module: &str) -> HashSet { + pub fn find_modules_directly_imported_by(&self, module: &str) -> FxHashSet { self._graph .find_modules_directly_imported_by(&Module::new(module.to_string())) .iter() @@ -177,7 +177,7 @@ impl GraphWrapper { .collect() } - pub fn find_modules_that_directly_import(&self, module: &str) -> HashSet { + pub fn find_modules_that_directly_import(&self, module: &str) -> FxHashSet { self._graph .find_modules_that_directly_import(&Module::new(module.to_string())) .iter() @@ -226,7 +226,7 @@ impl GraphWrapper { #[allow(unused_variables)] #[pyo3(signature = (module, as_package=false))] - pub fn find_downstream_modules(&self, module: &str, as_package: bool) -> HashSet { + pub fn find_downstream_modules(&self, module: &str, as_package: bool) -> FxHashSet { // Turn the Modules to Strings. self._graph .find_downstream_modules(&Module::new(module.to_string()), as_package) @@ -237,7 +237,7 @@ impl GraphWrapper { #[allow(unused_variables)] #[pyo3(signature = (module, as_package=false))] - pub fn find_upstream_modules(&self, module: &str, as_package: bool) -> HashSet { + pub fn find_upstream_modules(&self, module: &str, as_package: bool) -> FxHashSet { self._graph .find_upstream_modules(&Module::new(module.to_string()), as_package) .iter() @@ -262,7 +262,7 @@ impl GraphWrapper { imported: &str, as_packages: bool, ) -> PyResult> { - let rust_chains: HashSet> = self + let rust_chains: FxHashSet> = self ._graph .find_shortest_chains( &Module::new(importer.to_string()), @@ -308,18 +308,16 @@ impl GraphWrapper { )) } - #[allow(unused_variables)] #[pyo3(signature = (layers, containers))] pub fn find_illegal_dependencies_for_layers<'py>( &self, py: Python<'py>, layers: &Bound<'py, PyTuple>, - containers: HashSet, + containers: FxHashSet, ) -> PyResult> { info!("Using Rust to find illegal dependencies."); let levels = rustify_levels(layers); - println!("\nIncoming {:?}, {:?}", levels, containers); let dependencies = py.allow_threads(|| { self._graph .find_illegal_dependencies_for_layers(levels, containers) @@ -343,7 +341,7 @@ fn rustify_levels<'a>(levels_python: &Bound<'a, PyTuple>) -> Vec { let mut rust_levels: Vec = vec![]; for level_python in levels_python.into_iter() { let level_dict = level_python.downcast::().unwrap(); - let layers: HashSet = level_dict + let layers: FxHashSet = level_dict .get_item("layers") .unwrap() .unwrap() @@ -431,15 +429,15 @@ mod tests { let elements = vec![ pydict! (py, { "independent" => true, - "layers" => HashSet::from(["high"]), + "layers" => FxHashSet::from_iter(["high"]), }), pydict! (py, { "independent" => true, - "layers" => HashSet::from(["medium"]), + "layers" => FxHashSet::from_iter(["medium"]), }), pydict! (py, { "independent" => true, - "layers" => HashSet::from(["low"]), + "layers" => FxHashSet::from_iter(["low"]), }), ]; let python_levels = PyTuple::new(py, elements)?; @@ -476,19 +474,19 @@ mod tests { let elements = vec![ pydict! (py, { "independent" => true, - "layers" => HashSet::from(["high"]), + "layers" => FxHashSet::from_iter(["high"]), }), pydict! (py, { "independent" => true, - "layers" => HashSet::from(["blue", "green", "orange"]), + "layers" => FxHashSet::from_iter(["blue", "green", "orange"]), }), pydict! (py, { "independent" => false, - "layers" => HashSet::from(["red", "yellow"]), + "layers" => FxHashSet::from_iter(["red", "yellow"]), }), pydict! (py, { "independent" => true, - "layers" => HashSet::from(["low"]), + "layers" => FxHashSet::from_iter(["low"]), }), ]; let python_levels = PyTuple::new(py, elements)?; diff --git a/rust/tests/large.rs b/rust/tests/large.rs index 1cdaf9ab..5eaca91b 100644 --- a/rust/tests/large.rs +++ b/rust/tests/large.rs @@ -1,6 +1,6 @@ use _rustgrimp::graph::{Graph, Level, Module}; +use rustc_hash::FxHashSet; use serde_json::{Map, Value}; -use std::collections::HashSet; use std::fs; #[test] @@ -40,7 +40,7 @@ fn test_large_graph_deep_layers() { layers: vec![layer.to_string()], }) .collect(); - let containers = HashSet::new(); + let containers = FxHashSet::default(); let deps = graph .find_illegal_dependencies_for_layers(levels, containers)