From 1eb998c7faa3f9a0ebca87d32b9195a555db55ae Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 24 Apr 2025 18:01:19 -0700 Subject: [PATCH 1/3] Make CallHasher specific to ahash::RandomState --- src/specialize.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/specialize.rs b/src/specialize.rs index acdf7d1..311ba9e 100644 --- a/src/specialize.rs +++ b/src/specialize.rs @@ -1,3 +1,4 @@ +use crate::RandomState; use core::hash::BuildHasher; use core::hash::Hash; use core::hash::Hasher; @@ -18,7 +19,7 @@ use alloc::vec::Vec; /// Rather than using a Hasher generically which can hash any value, this provides a way to get a specialized hash /// for a specific type. So this may be faster for primitive types. pub(crate) trait CallHasher { - fn get_hash(value: &H, build_hasher: &B) -> u64; + fn get_hash(value: &H, build_hasher: &RandomState) -> u64; } #[cfg(not(feature = "specialize"))] @@ -27,7 +28,7 @@ where T: Hash + ?Sized, { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { let mut hasher = build_hasher.build_hasher(); value.hash(&mut hasher); hasher.finish() @@ -40,7 +41,7 @@ where T: Hash + ?Sized, { #[inline] - default fn get_hash(value: &H, build_hasher: &B) -> u64 { + default fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { let mut hasher = build_hasher.build_hasher(); value.hash(&mut hasher); hasher.finish() @@ -52,7 +53,7 @@ macro_rules! call_hasher_impl_u64 { #[cfg(feature = "specialize")] impl CallHasher for $typ { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { build_hasher.hash_as_u64(value) } } @@ -80,7 +81,7 @@ macro_rules! call_hasher_impl_fixed_length{ #[cfg(feature = "specialize")] impl CallHasher for $typ { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { build_hasher.hash_as_fixed_length(value) } } @@ -99,7 +100,7 @@ call_hasher_impl_fixed_length!(&isize); #[cfg(feature = "specialize")] impl CallHasher for [u8] { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { build_hasher.hash_as_str(value) } } @@ -107,7 +108,7 @@ impl CallHasher for [u8] { #[cfg(feature = "specialize")] impl CallHasher for Vec { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { build_hasher.hash_as_str(value) } } @@ -115,7 +116,7 @@ impl CallHasher for Vec { #[cfg(feature = "specialize")] impl CallHasher for str { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { build_hasher.hash_as_str(value) } } @@ -123,7 +124,7 @@ impl CallHasher for str { #[cfg(all(feature = "specialize"))] impl CallHasher for String { #[inline] - fn get_hash(value: &H, build_hasher: &B) -> u64 { + fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { build_hasher.hash_as_str(value) } } From e7b3ba1a199550171ede49743101761ebec58c29 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 24 Apr 2025 18:05:48 -0700 Subject: [PATCH 2/3] Eliminate BuildHasherExt trait --- src/lib.rs | 61 ++------------------------------------------- src/random_state.rs | 13 +++------- src/specialize.rs | 2 -- 3 files changed, 6 insertions(+), 70 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 96ce9a4..d937dca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,8 +146,6 @@ mod specialize; pub use crate::random_state::RandomState; use core::hash::BuildHasher; -use core::hash::Hash; -use core::hash::Hasher; #[cfg(feature = "std")] /// A convenience trait that can be used together with the type aliases defined to @@ -248,63 +246,6 @@ impl Default for AHasher { } } -/// Used for specialization. (Sealed) -pub(crate) trait BuildHasherExt: BuildHasher { - #[doc(hidden)] - fn hash_as_u64(&self, value: &T) -> u64; - - #[doc(hidden)] - fn hash_as_fixed_length(&self, value: &T) -> u64; - - #[doc(hidden)] - fn hash_as_str(&self, value: &T) -> u64; -} - -impl BuildHasherExt for B { - #[inline] - #[cfg(feature = "specialize")] - default fn hash_as_u64(&self, value: &T) -> u64 { - let mut hasher = self.build_hasher(); - value.hash(&mut hasher); - hasher.finish() - } - #[inline] - #[cfg(not(feature = "specialize"))] - fn hash_as_u64(&self, value: &T) -> u64 { - let mut hasher = self.build_hasher(); - value.hash(&mut hasher); - hasher.finish() - } - #[inline] - #[cfg(feature = "specialize")] - default fn hash_as_fixed_length(&self, value: &T) -> u64 { - let mut hasher = self.build_hasher(); - value.hash(&mut hasher); - hasher.finish() - } - #[inline] - #[cfg(not(feature = "specialize"))] - fn hash_as_fixed_length(&self, value: &T) -> u64 { - let mut hasher = self.build_hasher(); - value.hash(&mut hasher); - hasher.finish() - } - #[inline] - #[cfg(feature = "specialize")] - default fn hash_as_str(&self, value: &T) -> u64 { - let mut hasher = self.build_hasher(); - value.hash(&mut hasher); - hasher.finish() - } - #[inline] - #[cfg(not(feature = "specialize"))] - fn hash_as_str(&self, value: &T) -> u64 { - let mut hasher = self.build_hasher(); - value.hash(&mut hasher); - hasher.finish() - } -} - // #[inline(never)] // #[doc(hidden)] // pub fn hash_test(input: &[u8]) -> u64 { @@ -318,6 +259,8 @@ mod test { use crate::convert::Convert; use crate::specialize::CallHasher; use crate::*; + use core::hash::Hash; + use core::hash::Hasher; use std::collections::HashMap; #[test] diff --git a/src/random_state.rs b/src/random_state.rs index 878315e..114f6f9 100644 --- a/src/random_state.rs +++ b/src/random_state.rs @@ -10,11 +10,6 @@ cfg_if::cfg_if! { use crate::fallback_hash::*; } } -cfg_if::cfg_if! { - if #[cfg(feature = "specialize")]{ - use crate::BuildHasherExt; - } -} cfg_if::cfg_if! { if #[cfg(feature = "std")] { extern crate std as alloc; @@ -466,9 +461,9 @@ impl BuildHasher for RandomState { } #[cfg(feature = "specialize")] -impl BuildHasherExt for RandomState { +impl RandomState { #[inline] - fn hash_as_u64(&self, value: &T) -> u64 { + pub(crate) fn hash_as_u64(&self, value: &T) -> u64 { let mut hasher = AHasherU64 { buffer: self.k1, pad: self.k0, @@ -478,14 +473,14 @@ impl BuildHasherExt for RandomState { } #[inline] - fn hash_as_fixed_length(&self, value: &T) -> u64 { + pub(crate) fn hash_as_fixed_length(&self, value: &T) -> u64 { let mut hasher = AHasherFixed(self.build_hasher()); value.hash(&mut hasher); hasher.finish() } #[inline] - fn hash_as_str(&self, value: &T) -> u64 { + pub(crate) fn hash_as_str(&self, value: &T) -> u64 { let mut hasher = AHasherStr(self.build_hasher()); value.hash(&mut hasher); hasher.finish() diff --git a/src/specialize.rs b/src/specialize.rs index 311ba9e..1093bc0 100644 --- a/src/specialize.rs +++ b/src/specialize.rs @@ -8,8 +8,6 @@ extern crate alloc; #[cfg(feature = "std")] extern crate std as alloc; -#[cfg(feature = "specialize")] -use crate::BuildHasherExt; #[cfg(feature = "specialize")] use alloc::string::String; #[cfg(feature = "specialize")] From 8ac8706ac128011c3508c9ad78fc26842a1cffc8 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 24 Apr 2025 18:11:48 -0700 Subject: [PATCH 3/3] Rename argument of CallHasher to random_state --- src/specialize.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/specialize.rs b/src/specialize.rs index 1093bc0..09ed89d 100644 --- a/src/specialize.rs +++ b/src/specialize.rs @@ -17,7 +17,7 @@ use alloc::vec::Vec; /// Rather than using a Hasher generically which can hash any value, this provides a way to get a specialized hash /// for a specific type. So this may be faster for primitive types. pub(crate) trait CallHasher { - fn get_hash(value: &H, build_hasher: &RandomState) -> u64; + fn get_hash(value: &H, random_state: &RandomState) -> u64; } #[cfg(not(feature = "specialize"))] @@ -26,8 +26,8 @@ where T: Hash + ?Sized, { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - let mut hasher = build_hasher.build_hasher(); + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + let mut hasher = random_state.build_hasher(); value.hash(&mut hasher); hasher.finish() } @@ -39,8 +39,8 @@ where T: Hash + ?Sized, { #[inline] - default fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - let mut hasher = build_hasher.build_hasher(); + default fn get_hash(value: &H, random_state: &RandomState) -> u64 { + let mut hasher = random_state.build_hasher(); value.hash(&mut hasher); hasher.finish() } @@ -51,8 +51,8 @@ macro_rules! call_hasher_impl_u64 { #[cfg(feature = "specialize")] impl CallHasher for $typ { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - build_hasher.hash_as_u64(value) + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + random_state.hash_as_u64(value) } } }; @@ -79,8 +79,8 @@ macro_rules! call_hasher_impl_fixed_length{ #[cfg(feature = "specialize")] impl CallHasher for $typ { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - build_hasher.hash_as_fixed_length(value) + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + random_state.hash_as_fixed_length(value) } } }; @@ -98,32 +98,32 @@ call_hasher_impl_fixed_length!(&isize); #[cfg(feature = "specialize")] impl CallHasher for [u8] { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - build_hasher.hash_as_str(value) + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + random_state.hash_as_str(value) } } #[cfg(feature = "specialize")] impl CallHasher for Vec { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - build_hasher.hash_as_str(value) + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + random_state.hash_as_str(value) } } #[cfg(feature = "specialize")] impl CallHasher for str { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - build_hasher.hash_as_str(value) + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + random_state.hash_as_str(value) } } #[cfg(all(feature = "specialize"))] impl CallHasher for String { #[inline] - fn get_hash(value: &H, build_hasher: &RandomState) -> u64 { - build_hasher.hash_as_str(value) + fn get_hash(value: &H, random_state: &RandomState) -> u64 { + random_state.hash_as_str(value) } }