Created
January 21, 2025 22:23
-
-
Save sstadick/8c0631cbd8049480bddb7fc8b0436ec7 to your computer and use it in GitHub Desktop.
SplitMix64 Hasher for Rust u64
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::hash::{BuildHasher, Hasher}; | |
| #[derive(Clone, Copy, Default)] | |
| pub struct SplitMix64Hasher(u64); | |
| impl Hasher for SplitMix64Hasher { | |
| #[inline] | |
| fn finish(&self) -> u64 { | |
| self.0 | |
| } | |
| fn write(&mut self, _bytes: &[u8]) { | |
| panic!("This hasher only takes u64"); | |
| } | |
| #[inline] | |
| fn write_u64(&mut self, x: u64) { | |
| // Mix the seed (stored in self.0) with input | |
| let mut h = x; | |
| h ^= h >> 30; | |
| h = h.wrapping_mul(0xbf58476d1ce4e5b9); | |
| h ^= h >> 27; | |
| h = h.wrapping_mul(0x94d049bb133111eb); | |
| h ^= h >> 31; | |
| self.0 = h; | |
| } | |
| } | |
| #[derive(Default)] | |
| pub struct SplitMix64Builder; | |
| impl BuildHasher for SplitMix64Builder { | |
| type Hasher = SplitMix64Hasher; | |
| fn build_hasher(&self) -> Self::Hasher { | |
| Self::Hasher::default() | |
| } | |
| } | |
| #[cfg(test)] | |
| mod test { | |
| use std::collections::HashMap; | |
| use super::*; | |
| use rstest::rstest; | |
| #[rstest] | |
| fn test_simple() { | |
| let mut map: HashMap<u64, u32, SplitMix64Builder> = HashMap::with_hasher(SplitMix64Builder); | |
| for i in 0..10000 { | |
| map.insert(i, i as u32); | |
| } | |
| for i in 0..10000 { | |
| assert_eq!(map.get(&(i as u64)), Some(&(i as u32))); | |
| } | |
| } | |
| #[rstest] | |
| #[should_panic] | |
| fn test_non_u64() { | |
| let mut map: HashMap<u32, u32, SplitMix64Builder> = HashMap::with_hasher(SplitMix64Builder); | |
| for i in 0..10000 { | |
| map.insert(i, i as u32); | |
| } | |
| for i in 0..10000 { | |
| assert_eq!(map.get(&(i as u32)), Some(&(i as u32))); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment