use std::hash::Hasher;
use std::os::raw::c_void;
use ffi;
use hasher::{FastHash, FastHasher, StreamHasher};
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,
)
}
}
}
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(*mut 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);
}
}
}
impl Hasher for Hasher32 {
#[inline(always)]
fn finish(&self) -> u64 {
unsafe { u64::from(ffi::XXH32_digest(self.0)) }
}
#[inline(always)]
fn write(&mut self, bytes: &[u8]) {
unsafe {
ffi::XXH32_update(self.0, bytes.as_ptr() as *const c_void, bytes.len());
}
}
}
impl FastHasher for Hasher32 {
type Seed = u32;
#[inline(always)]
fn with_seed(seed: u32) -> Self {
let h = unsafe { ffi::XXH32_createState() };
unsafe {
ffi::XXH32_reset(h, seed);
}
Hasher32(h)
}
}
impl StreamHasher for Hasher32 {}
impl_fasthash!(Hasher32, Hash32);
pub struct Hasher64(*mut 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);
}
}
}
impl Hasher for Hasher64 {
#[inline(always)]
fn finish(&self) -> u64 {
unsafe { ffi::XXH64_digest(self.0) }
}
#[inline(always)]
fn write(&mut self, bytes: &[u8]) {
unsafe {
ffi::XXH64_update(self.0, bytes.as_ptr() as *const c_void, bytes.len());
}
}
}
impl FastHasher for Hasher64 {
type Seed = u64;
#[inline(always)]
fn with_seed(seed: u64) -> Self {
let h = unsafe { ffi::XXH64_createState() };
unsafe {
ffi::XXH64_reset(h, seed);
}
Hasher64(h)
}
}
impl StreamHasher for Hasher64 {}
impl_fasthash!(Hasher64, Hash64);