use std::hash::Hasher;
use std::mem;
use std::ptr::NonNull;
use crate::{FastHash, FastHasher, HasherExt, StreamHasher};
#[inline(always)]
pub fn hash64<T: AsRef<[u8]>>(v: T) -> u64 {
Hash64::hash(v)
}
#[inline(always)]
pub fn hash64_with_seed<T: AsRef<[u8]>>(v: T, seed: u64) -> u64 {
Hash64::hash_with_seed(v, seed)
}
#[inline(always)]
pub fn hash128<T: AsRef<[u8]>>(v: T) -> u128 {
Hash128::hash(v)
}
#[inline(always)]
pub fn hash128_with_seed<T: AsRef<[u8]>>(v: T, seed: u64) -> u128 {
Hash128::hash_with_seed(v, seed)
}
#[derive(Clone, Default)]
pub struct Hash64;
impl FastHash for Hash64 {
type Hash = u64;
type Seed = u64;
#[inline(always)]
fn hash<T: AsRef<[u8]>>(bytes: T) -> Self::Hash {
let bytes = bytes.as_ref();
unsafe { ffi::XXH3_64bits(bytes.as_ptr() as *const _, bytes.len()) }
}
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: Self::Seed) -> Self::Hash {
let bytes = bytes.as_ref();
unsafe { ffi::XXH3_64bits_withSeed(bytes.as_ptr() as *const _, bytes.len(), seed) }
}
}
pub struct Hasher64(NonNull<ffi::XXH3_state_t>);
impl Default for Hasher64 {
fn default() -> Self {
Hasher64(unsafe { NonNull::new_unchecked(ffi::XXH3_createState()) })
}
}
impl Clone for Hasher64 {
fn clone(&self) -> Self {
unsafe {
let state = ffi::XXH3_createState();
ffi::XXH3_copyState(state, self.0.as_ptr());
Hasher64(NonNull::new_unchecked(state))
}
}
}
impl Drop for Hasher64 {
fn drop(&mut self) {
unsafe {
ffi::XXH3_freeState(self.0.as_ptr());
}
}
}
impl Hasher for Hasher64 {
#[inline(always)]
fn finish(&self) -> u64 {
unsafe { ffi::XXH3_64bits_digest(self.0.as_ptr()) }
}
#[inline(always)]
fn write(&mut self, bytes: &[u8]) {
unsafe {
ffi::XXH3_64bits_update(self.0.as_ptr(), bytes.as_ptr() as *const _, bytes.len());
}
}
}
impl FastHasher for Hasher64 {
type Seed = u64;
type Output = u64;
#[inline(always)]
fn with_seed(seed: u64) -> Self {
unsafe {
let state = ffi::XXH3_createState();
ffi::XXH3_64bits_reset_withSeed(state, seed);
Hasher64(NonNull::new_unchecked(state))
}
}
}
impl StreamHasher for Hasher64 {}
impl_build_hasher!(Hasher64, Hash64);
#[derive(Clone, Default)]
pub struct Hash128;
impl FastHash for Hash128 {
type Hash = u128;
type Seed = u64;
#[inline(always)]
fn hash<T: AsRef<[u8]>>(bytes: T) -> Self::Hash {
let bytes = bytes.as_ref();
unsafe { mem::transmute(ffi::XXH3_128bits(bytes.as_ptr() as *const _, bytes.len())) }
}
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: Self::Seed) -> Self::Hash {
let bytes = bytes.as_ref();
unsafe {
mem::transmute(ffi::XXH3_128bits_withSeed(
bytes.as_ptr() as *const _,
bytes.len(),
seed,
))
}
}
}
pub struct Hasher128(NonNull<ffi::XXH3_state_t>);
impl Default for Hasher128 {
fn default() -> Self {
Hasher128(unsafe { NonNull::new_unchecked(ffi::XXH3_createState()) })
}
}
impl Clone for Hasher128 {
fn clone(&self) -> Self {
unsafe {
let state = ffi::XXH3_createState();
ffi::XXH3_copyState(state, self.0.as_ptr());
Hasher128(NonNull::new_unchecked(state))
}
}
}
impl Drop for Hasher128 {
fn drop(&mut self) {
unsafe {
ffi::XXH3_freeState(self.0.as_ptr());
}
}
}
impl Hasher for Hasher128 {
#[inline(always)]
fn finish(&self) -> u64 {
unsafe { ffi::XXH3_128bits_digest(self.0.as_ptr()).low64 }
}
#[inline(always)]
fn write(&mut self, bytes: &[u8]) {
unsafe {
ffi::XXH3_128bits_update(self.0.as_ptr(), bytes.as_ptr() as *const _, bytes.len());
}
}
}
impl HasherExt for Hasher128 {
#[inline(always)]
fn finish_ext(&self) -> u128 {
let h = unsafe { ffi::XXH3_128bits_digest(self.0.as_ptr()) };
u128::from(h.low64) + (u128::from(h.high64) << 64)
}
}
impl FastHasher for Hasher128 {
type Seed = u64;
type Output = u128;
#[inline(always)]
fn with_seed(seed: u64) -> Self {
unsafe {
let state = ffi::XXH3_createState();
ffi::XXH3_128bits_reset_withSeed(state, seed);
Hasher128(NonNull::new_unchecked(state))
}
}
}
impl StreamHasher for Hasher128 {}
impl_build_hasher!(Hasher128, Hash128);