Skip to content

Commit

Permalink
Add FxSeededState & co
Browse files Browse the repository at this point in the history
  • Loading branch information
WaffleLapkin committed Jan 17, 2024
1 parent 9ff57de commit 3a5e0c4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ extern crate rand;
#[cfg(feature = "rand")]
mod random_state;

mod seeded_state;

use core::convert::TryInto;
use core::default::Default;
#[cfg(feature = "std")]
Expand All @@ -55,6 +57,8 @@ pub type FxHashSet<V> = HashSet<V, BuildHasherDefault<FxHasher>>;
#[cfg(feature = "rand")]
pub use random_state::{FxHashMapRand, FxHashSetRand, FxRandomState};

pub use seeded_state::{FxHashMapSeed, FxHashSetSeed, FxSeededState};

/// A speedy hash algorithm for use within rustc. The hashmap in liballoc
/// by default uses SipHash which isn't quite as speedy as we want. In the
/// compiler we're not really worried about DOS attempts, so we use a fast
Expand Down
56 changes: 56 additions & 0 deletions src/seeded_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::collections::{HashMap, HashSet};

use crate::FxHasher;

/// Type alias for a hashmap using the `fx` hash algorithm with [`FxSeededState`].
pub type FxHashMapSeed<K, V> = HashMap<K, V, FxSeededState>;

/// Type alias for a hashmap using the `fx` hash algorithm with [`FxSeededState`].
pub type FxHashSetSeed<V> = HashSet<V, FxSeededState>;

/// [`FxSetState`] is an alternative state for `HashMap` types, allowing to use [`FxHasher`] with a set seed.
///
/// ```
/// # use std::collections::HashMap;
/// use rustc_hash::FxSeededState;
///
/// let mut map = HashMap::with_hasher(FxSeededState::with_seed(12));
/// map.insert(15, 610);
/// assert_eq!(map[&15], 610);
/// ```
pub struct FxSeededState {
seed: usize,
}

impl FxSeededState {
/// Constructs a new `FxSeededState` that is initialized with a `seed`.
pub fn with_seed(seed: usize) -> FxSeededState {
Self { seed }
}
}

impl core::hash::BuildHasher for FxSeededState {
type Hasher = FxHasher;

fn build_hasher(&self) -> Self::Hasher {
FxHasher::with_seed(self.seed)
}
}

#[cfg(test)]
mod tests {
use core::hash::BuildHasher;

use crate::{FxHashMapSeed, FxSeededState};

#[test]
fn different_states_are_different() {
let a = FxHashMapSeed::<&str, u32>::with_hasher(FxSeededState::with_seed(1));
let b = FxHashMapSeed::<&str, u32>::with_hasher(FxSeededState::with_seed(2));

assert_ne!(
a.hasher().build_hasher().hash,
b.hasher().build_hasher().hash
);
}
}

0 comments on commit 3a5e0c4

Please sign in to comment.