rapidhash/
random_state.rs1use std::cell::Cell;
2use std::hash::BuildHasher;
3use crate::{rapidrng_fast, RapidHasher};
4
5#[derive(Copy, Clone, Eq, PartialEq)]
21pub struct RapidRandomState {
22 seed: u64,
23}
24
25impl RapidRandomState {
26 pub fn new() -> Self {
33 #[cfg(feature = "rand")]
34 thread_local! {
35 static RANDOM_SEED: Cell<u64> = {
36 Cell::new(rand::random())
37 }
38 }
39
40 #[cfg(all(feature = "std", not(feature = "rand")))]
41 thread_local! {
42 static RANDOM_SEED: Cell<u64> = {
43 let mut seed = crate::RAPID_SEED;
44 Cell::new(crate::rapidrng_time(&mut seed))
45 }
46 }
47
48 let mut seed = RANDOM_SEED.with(|cell| {
49 let seed = cell.get();
50 cell.set(seed.wrapping_add(1));
51 seed
52 });
53
54 Self {
55 seed: rapidrng_fast(&mut seed),
56 }
57 }
58}
59
60impl Default for RapidRandomState {
61 fn default() -> Self {
62 Self::new()
63 }
64}
65
66impl BuildHasher for RapidRandomState {
67 type Hasher = RapidHasher;
68
69 fn build_hasher(&self) -> Self::Hasher {
70 RapidHasher::new(self.seed)
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use std::hash::{BuildHasher, Hasher, RandomState};
77
78 #[test]
79 fn test_random_state() {
80 let state1 = RandomState::new();
82 let mut hash1a = state1.build_hasher();
83 let mut hash1b = state1.build_hasher();
84
85 let state2 = RandomState::new();
87 let mut hash2a = state2.build_hasher();
88
89 hash1a.write(b"hello");
90 hash1b.write(b"hello");
91 hash2a.write(b"hello");
92
93 let finish1a = hash1a.finish();
94 let finish1b = hash1b.finish();
95 let finish2a = hash2a.finish();
96
97 assert_eq!(finish1a, finish1b);
98 assert_ne!(finish1a, finish2a);
99 }
100}