Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
218
third-party/vendor/ahash/src/specialize.rs
vendored
Normal file
218
third-party/vendor/ahash/src/specialize.rs
vendored
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
use core::hash::BuildHasher;
|
||||
use core::hash::Hash;
|
||||
use core::hash::Hasher;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
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")]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// Provides a way to get an optimized hasher for a given data type.
|
||||
/// 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<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "specialize"))]
|
||||
impl<T> CallHasher for T
|
||||
where
|
||||
T: Hash + ?Sized,
|
||||
{
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
let mut hasher = build_hasher.build_hasher();
|
||||
value.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl<T> CallHasher for T
|
||||
where
|
||||
T: Hash + ?Sized,
|
||||
{
|
||||
#[inline]
|
||||
default fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
let mut hasher = build_hasher.build_hasher();
|
||||
value.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! call_hasher_impl {
|
||||
($typ:ty) => {
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for $typ {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_u64(value)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
call_hasher_impl!(u8);
|
||||
call_hasher_impl!(u16);
|
||||
call_hasher_impl!(u32);
|
||||
call_hasher_impl!(u64);
|
||||
call_hasher_impl!(i8);
|
||||
call_hasher_impl!(i16);
|
||||
call_hasher_impl!(i32);
|
||||
call_hasher_impl!(i64);
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for u128 {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_fixed_length(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for i128 {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_fixed_length(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for usize {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_fixed_length(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for isize {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_fixed_length(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for [u8] {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_str(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for Vec<u8> {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_str(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "specialize")]
|
||||
impl CallHasher for str {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_str(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "specialize"))]
|
||||
impl CallHasher for String {
|
||||
#[inline]
|
||||
fn get_hash<H: Hash + ?Sized, B: BuildHasher>(value: &H, build_hasher: &B) -> u64 {
|
||||
build_hasher.hash_as_str(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::*;
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "specialize")]
|
||||
pub fn test_specialized_invoked() {
|
||||
let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
|
||||
let shortened = u64::get_hash(&0, &build_hasher);
|
||||
let mut hasher = AHasher::new_with_keys(1, 2);
|
||||
0_u64.hash(&mut hasher);
|
||||
assert_ne!(hasher.finish(), shortened);
|
||||
}
|
||||
|
||||
/// Tests that some non-trivial transformation takes place.
|
||||
#[test]
|
||||
pub fn test_input_processed() {
|
||||
let build_hasher = RandomState::with_seeds(2, 2, 2, 2);
|
||||
assert_ne!(0, u64::get_hash(&0, &build_hasher));
|
||||
assert_ne!(1, u64::get_hash(&0, &build_hasher));
|
||||
assert_ne!(2, u64::get_hash(&0, &build_hasher));
|
||||
assert_ne!(3, u64::get_hash(&0, &build_hasher));
|
||||
assert_ne!(4, u64::get_hash(&0, &build_hasher));
|
||||
assert_ne!(5, u64::get_hash(&0, &build_hasher));
|
||||
|
||||
assert_ne!(0, u64::get_hash(&1, &build_hasher));
|
||||
assert_ne!(1, u64::get_hash(&1, &build_hasher));
|
||||
assert_ne!(2, u64::get_hash(&1, &build_hasher));
|
||||
assert_ne!(3, u64::get_hash(&1, &build_hasher));
|
||||
assert_ne!(4, u64::get_hash(&1, &build_hasher));
|
||||
assert_ne!(5, u64::get_hash(&1, &build_hasher));
|
||||
|
||||
let xored = u64::get_hash(&0, &build_hasher) ^ u64::get_hash(&1, &build_hasher);
|
||||
assert_ne!(0, xored);
|
||||
assert_ne!(1, xored);
|
||||
assert_ne!(2, xored);
|
||||
assert_ne!(3, xored);
|
||||
assert_ne!(4, xored);
|
||||
assert_ne!(5, xored);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_ref_independent() {
|
||||
let build_hasher = RandomState::with_seeds(1, 2, 3, 4);
|
||||
assert_eq!(u8::get_hash(&&1, &build_hasher), u8::get_hash(&1, &build_hasher));
|
||||
assert_eq!(u16::get_hash(&&2, &build_hasher), u16::get_hash(&2, &build_hasher));
|
||||
assert_eq!(u32::get_hash(&&3, &build_hasher), u32::get_hash(&3, &build_hasher));
|
||||
assert_eq!(u64::get_hash(&&4, &build_hasher), u64::get_hash(&4, &build_hasher));
|
||||
assert_eq!(u128::get_hash(&&5, &build_hasher), u128::get_hash(&5, &build_hasher));
|
||||
assert_eq!(
|
||||
str::get_hash(&"test", &build_hasher),
|
||||
str::get_hash("test", &build_hasher)
|
||||
);
|
||||
assert_eq!(
|
||||
str::get_hash(&"test", &build_hasher),
|
||||
String::get_hash(&"test".to_string(), &build_hasher)
|
||||
);
|
||||
#[cfg(feature = "specialize")]
|
||||
assert_eq!(
|
||||
str::get_hash(&"test", &build_hasher),
|
||||
<[u8]>::get_hash("test".as_bytes(), &build_hasher)
|
||||
);
|
||||
|
||||
let build_hasher = RandomState::with_seeds(10, 20, 30, 40);
|
||||
assert_eq!(u8::get_hash(&&&1, &build_hasher), u8::get_hash(&1, &build_hasher));
|
||||
assert_eq!(u16::get_hash(&&&2, &build_hasher), u16::get_hash(&2, &build_hasher));
|
||||
assert_eq!(u32::get_hash(&&&3, &build_hasher), u32::get_hash(&3, &build_hasher));
|
||||
assert_eq!(u64::get_hash(&&&4, &build_hasher), u64::get_hash(&4, &build_hasher));
|
||||
assert_eq!(u128::get_hash(&&&5, &build_hasher), u128::get_hash(&5, &build_hasher));
|
||||
assert_eq!(
|
||||
str::get_hash(&&"test", &build_hasher),
|
||||
str::get_hash("test", &build_hasher)
|
||||
);
|
||||
assert_eq!(
|
||||
str::get_hash(&&"test", &build_hasher),
|
||||
String::get_hash(&"test".to_string(), &build_hasher)
|
||||
);
|
||||
#[cfg(feature = "specialize")]
|
||||
assert_eq!(
|
||||
str::get_hash(&&"test", &build_hasher),
|
||||
<[u8]>::get_hash(&"test".to_string().into_bytes(), &build_hasher)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue