use std::hash::Hasher;
use std::os::raw::c_void;
use std::ptr::NonNull;
use crate::ffi;
use crate::hasher::{FastHash, FastHasher, StreamHasher};
#[derive(Clone, Default)]
pub struct Hash32;
impl FastHash for Hash32 {
type Hash = u32;
type Seed = u32;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u32) -> u32 {
unsafe {
ffi::XXH32(
bytes.as_ref().as_ptr() as *const c_void,
bytes.as_ref().len(),
seed,
)
}
}
}
#[derive(Clone, Default)]
pub struct Hash64;
impl FastHash for Hash64 {
type Hash = u64;
type Seed = u64;
#[inline(always)]
fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: u64) -> u64 {
unsafe {
ffi::XXH64(
bytes.as_ref().as_ptr() as *const c_void,
bytes.as_ref().len(),
seed,
)
}
}
}
#[inline(always)]
pub fn hash32<T: AsRef<[u8]>>(v: T) -> u32 {
Hash32::hash(v)
}
#[inline(always)]
pub fn hash32_with_seed<T: AsRef<[u8]>>(v: T, seed: u32) -> u32 {
Hash32::hash_with_seed(v, seed)
}
#[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)
}
pub struct Hasher32(NonNull<ffi::XXH32_state_t>);
impl Default for Hasher32 {
fn default() -> Self {
Self::new()
}
}
impl Drop for Hasher32 {
#[inline(always)]
fn drop(&mut self) {
unsafe {
ffi::XXH32_freeState(self.0.as_ptr());
}
}
}
impl Clone for Hasher32 {
fn clone(&self) -> Self {
unsafe {
let state = ffi::XXH32_createState();
ffi::XXH32_copyState(state, self.0.as_ptr());
Hasher32(NonNull::new_unchecked(state))
}
}
}
impl Hasher for Hasher32 {
#[inline(always)]
fn finish(&self) -> u64 {
unsafe { u64::from(ffi::XXH32_digest(self.0.as_ptr())) }
}
#[inline(always)]
fn write(&mut self, bytes: &[u8]) {
unsafe {
ffi::XXH32_update(
self.0.as_ptr(),
bytes.as_ptr() as *const c_void,
bytes.len(),
);
}
}
}
impl FastHasher for Hasher32 {
type Seed = u32;
type Output = u32;
#[inline(always)]
fn with_seed(seed: u32) -> Self {
unsafe {
let h = ffi::XXH32_createState();
ffi::XXH32_reset(h, seed);
Hasher32(NonNull::new_unchecked(h))
}
}
}
impl StreamHasher for Hasher32 {}
impl_build_hasher!(Hasher32, Hash32);
pub struct Hasher64(NonNull<ffi::XXH64_state_t>);
impl Default for Hasher64 {
fn default() -> Self {
Self::new()
}
}
impl Drop for Hasher64 {
fn drop(&mut self) {
unsafe {
ffi::XXH64_freeState(self.0.as_ptr());
}
}
}
impl Clone for Hasher64 {
fn clone(&self) -> Self {
unsafe {
let state = ffi::XXH64_createState();
ffi::XXH64_copyState(state, self.0.as_ptr());
Hasher64(NonNull::new_unchecked(state))
}
}
}
impl Hasher for Hasher64 {
#[inline(always)]
fn finish(&self) -> u64 {
unsafe { ffi::XXH64_digest(self.0.as_ptr()) }
}
#[inline(always)]
fn write(&mut self, bytes: &[u8]) {
unsafe {
ffi::XXH64_update(
self.0.as_ptr(),
bytes.as_ptr() as *const c_void,
bytes.len(),
);
}
}
}
impl FastHasher for Hasher64 {
type Seed = u64;
type Output = u64;
#[inline(always)]
fn with_seed(seed: u64) -> Self {
unsafe {
let h = ffi::XXH64_createState();
ffi::XXH64_reset(h, seed);
Hasher64(NonNull::new_unchecked(h))
}
}
}
impl StreamHasher for Hasher64 {}
impl_build_hasher!(Hasher64, Hash64);