#![allow(non_camel_case_types)]
use crate::ffi;
use crate::hasher::FastHash;
#[derive(Clone, Default)]
pub struct Hash64_1;
impl FastHash for Hash64_1 {
type Hash = u64;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u64 {
let mut hash = 0_u64;
unsafe {
ffi::metrohash64_1(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u64 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher64_1(Hash64_1) -> u64
}
#[derive(Clone, Default)]
pub struct Hash64_2;
impl FastHash for Hash64_2 {
type Hash = u64;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u64 {
let mut hash = 0_u64;
unsafe {
ffi::metrohash64_2(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u64 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher64_2(Hash64_2) -> u64
}
#[derive(Clone, Default)]
pub struct Hash128_1;
impl FastHash for Hash128_1 {
type Hash = u128;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u128 {
let mut hash = 0;
unsafe {
ffi::metrohash128_1(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u128 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher128_1(Hash128_1) -> u128
}
#[derive(Clone, Default)]
pub struct Hash128_2;
impl FastHash for Hash128_2 {
type Hash = u128;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u128 {
let mut hash = 0;
unsafe {
ffi::metrohash128_2(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u128 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher128_2(Hash128_2) -> u128
}
#[cfg(any(feature = "sse42", target_feature = "sse4.2"))]
pub mod crc {
use crate::FastHash;
#[derive(Clone, Default)]
pub struct Hash64_1;
impl FastHash for Hash64_1 {
type Hash = u64;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u64 {
let mut hash = 0_u64;
unsafe {
ffi::metrohash64crc_1(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u64 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher64_1(Hash64_1) -> u64
}
#[derive(Clone, Default)]
pub struct Hash64_2;
impl FastHash for Hash64_2 {
type Hash = u64;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u64 {
let mut hash = 0_u64;
unsafe {
ffi::metrohash64crc_2(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u64 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher64_2(Hash64_2) -> u64
}
#[derive(Clone, Default)]
pub struct Hash128_1;
impl FastHash for Hash128_1 {
type Hash = u128;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u128 {
let mut hash = 0;
unsafe {
ffi::metrohash128crc_1(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u128 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher128_1(Hash128_1) -> u128
}
#[derive(Clone, Default)]
pub struct Hash128_2;
impl FastHash for Hash128_2 {
type Hash = u128;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u128 {
let mut hash = 0;
unsafe {
ffi::metrohash128crc_2(
bytes.as_ref().as_ptr() as *const u8,
bytes.as_ref().len() as u64,
seed,
&mut hash as *mut u128 as *mut u8,
);
}
hash
}
}
trivial_hasher! {
Hasher128_2(Hash128_2) -> u128
}
}
cfg_if! {
if #[cfg(any(feature = "sse42", target_feature = "sse4.2"))] {
#[inline(always)]
pub fn hash64<T: AsRef<[u8]>>(v: T) -> u64 {
crc::Hash64_1::hash(v)
}
#[inline(always)]
pub fn hash64_with_seed<T: AsRef<[u8]>>(v: T, seed: u32) -> u64 {
crc::Hash64_1::hash_with_seed(v, seed)
}
#[inline(always)]
pub fn hash128<T: AsRef<[u8]>>(v: T) -> u128 {
crc::Hash128_1::hash(v)
}
#[inline(always)]
pub fn hash128_with_seed<T: AsRef<[u8]>>(v: T, seed: u32) -> u128 {
crc::Hash128_1::hash_with_seed(v, seed)
}
} else {
#[inline(always)]
pub fn hash64<T: AsRef<[u8]>>(v: T) -> u64 {
Hash64_1::hash(v)
}
#[inline(always)]
pub fn hash64_with_seed<T: AsRef<[u8]>>(v: T, seed: u32) -> u64 {
Hash64_1::hash_with_seed(v, seed)
}
#[inline(always)]
pub fn hash128<T: AsRef<[u8]>>(v: T) -> u128 {
Hash128_1::hash(v)
}
#[inline(always)]
pub fn hash128_with_seed<T: AsRef<[u8]>>(v: T, seed: u32) -> u128 {
Hash128_1::hash_with_seed(v, seed)
}
}
}