diff --git a/concrete-optimizer/Cargo.toml b/concrete-optimizer/Cargo.toml index 158804534..45097ce4f 100644 --- a/concrete-optimizer/Cargo.toml +++ b/concrete-optimizer/Cargo.toml @@ -11,6 +11,8 @@ file-lock = "2.1.6" serde = { version = "1.0", features = ["derive"] } bincode = "1.3" puruspe = "0.2.0" +rustc-hash = "1.1" +rand = "0.8" [dev-dependencies] approx = "0.5" diff --git a/concrete-optimizer/src/utils/cache/read_only.rs b/concrete-optimizer/src/utils/cache/read_only.rs index 89037eb4e..8bd54b3ee 100644 --- a/concrete-optimizer/src/utils/cache/read_only.rs +++ b/concrete-optimizer/src/utils/cache/read_only.rs @@ -1,12 +1,10 @@ -use std::cmp::Eq; -use std::collections::hash_map::RandomState; +use crate::utils::hasher_builder::FxRandomState; +use serde::de::DeserializeOwned; +use serde::Serialize; use std::collections::HashMap; use std::hash::Hash; -use serde::de::DeserializeOwned; -use serde::Serialize; - -pub type Map = HashMap; +pub type Map = HashMap; #[allow(clippy::len_without_is_empty)] pub trait ReadOnlyCache: Clone + Serialize + DeserializeOwned + Default { diff --git a/concrete-optimizer/src/utils/hasher_builder.rs b/concrete-optimizer/src/utils/hasher_builder.rs new file mode 100644 index 000000000..15188f72b --- /dev/null +++ b/concrete-optimizer/src/utils/hasher_builder.rs @@ -0,0 +1,33 @@ +use rand::Rng; +use rustc_hash::FxHasher; +use std::cell::Cell; +use std::hash::{BuildHasher, Hasher}; + +// Randomized hasher builder to avoid the stable hashmap trap +// see https://morestina.net/blog/1843/the-stable-hashmap-trap +#[derive(Copy, Clone, Debug)] +pub struct FxRandomState(usize); + +impl BuildHasher for FxRandomState { + type Hasher = FxHasher; + + fn build_hasher(&self) -> FxHasher { + let mut hasher = FxHasher::default(); + hasher.write_usize(self.0); + hasher + } +} + +impl Default for FxRandomState { + fn default() -> Self { + thread_local! { + static SEED: Cell = Cell::new(rand::thread_rng().gen()) + } + let seed = SEED.with(|seed| { + let n = seed.get(); + seed.set(n.wrapping_add(1)); + n + }); + Self(seed) + } +} diff --git a/concrete-optimizer/src/utils/mod.rs b/concrete-optimizer/src/utils/mod.rs index 6860fdca1..5f8e5bfa9 100644 --- a/concrete-optimizer/src/utils/mod.rs +++ b/concrete-optimizer/src/utils/mod.rs @@ -1,4 +1,5 @@ pub mod cache; +pub mod hasher_builder; pub fn square(v: V) -> V where