#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
use std::os::raw::c_char;
pub fn farm_hash_32(bytes: &[u8]) -> u32 {
unsafe { farmhash_hash32(bytes.as_ptr() as *const c_char, bytes.len()) }
}
pub fn farm_hash_32_with_seed(bytes: &[u8], seed: u32) -> u32 {
unsafe { farmhash_hash32_with_seed(bytes.as_ptr() as *const c_char, bytes.len(), seed) }
}
pub fn farm_hash_64(bytes: &[u8]) -> u64 {
unsafe { farmhash_hash64(bytes.as_ptr() as *const c_char, bytes.len()) }
}
pub fn farm_hash_64_with_seed(bytes: &[u8], seed: u64) -> u64 {
unsafe { farmhash_hash64_with_seed(bytes.as_ptr() as *const c_char, bytes.len(), seed) }
}
pub fn farm_hash_64_with_seeds(bytes: &[u8], seed0: u64, seed1: u64) -> u64 {
unsafe {
farmhash_hash64_with_seeds(bytes.as_ptr() as *const c_char, bytes.len(), seed0, seed1)
}
}
pub fn farm_hash_128(bytes: &[u8]) -> (u64, u64) {
unsafe {
let result = farmhash_fingerprint128(bytes.as_ptr() as *const c_char, bytes.len());
(result.low, result.high)
}
}
pub fn farm_hash_128_with_seed(bytes: &[u8], seed: u64) -> (u64, u64) {
let low = farm_hash_64_with_seed(bytes, seed);
let high = farm_hash_64_with_seed(bytes, seed.wrapping_add(1));
(low, high)
}
use std::hash::Hasher;
pub struct FarmHashHasher {
buffer: Vec<u8>,
seed: Option<u64>,
}
impl FarmHashHasher {
pub fn new() -> Self {
Self {
buffer: Vec::new(),
seed: None,
}
}
pub fn with_seed(seed: u64) -> Self {
Self {
buffer: Vec::new(),
seed: Some(seed),
}
}
}
impl Default for FarmHashHasher {
fn default() -> Self {
Self::new()
}
}
impl Hasher for FarmHashHasher {
fn finish(&self) -> u64 {
if self.seed.is_some() {
farm_hash_64_with_seed(&self.buffer, self.seed.unwrap())
} else {
farm_hash_64(&self.buffer)
}
}
fn write(&mut self, bytes: &[u8]) {
self.buffer.extend_from_slice(bytes);
}
}
#[allow(dead_code)]
type FarmHashHasherDefault = std::hash::BuildHasherDefault<FarmHashHasher>;
pub mod farmhash {
use super::*;
pub fn hash32(bytes: &[u8]) -> u32 {
farm_hash_32(bytes)
}
pub fn hash32_with_seed(bytes: &[u8], seed: u32) -> u32 {
farm_hash_32_with_seed(bytes, seed)
}
pub fn hash64(bytes: &[u8]) -> u64 {
farm_hash_64(bytes)
}
pub fn hash64_with_seed(bytes: &[u8], seed: u64) -> u64 {
farm_hash_64_with_seed(bytes, seed)
}
pub fn hash64_with_seeds(bytes: &[u8], seed0: u64, seed1: u64) -> u64 {
farm_hash_64_with_seeds(bytes, seed0, seed1)
}
pub fn fingerprint128(bytes: &[u8]) -> (u64, u64) {
farm_hash_128(bytes)
}
pub fn fingerprint128_with_seed(bytes: &[u8], seed: u64) -> (u64, u64) {
farm_hash_128_with_seed(bytes, seed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_farm_hash_32() {
let data = b"hello world";
let hash = farm_hash_32(data);
assert_eq!(hash, farm_hash_32(data));
assert_ne!(hash, 0);
}
#[test]
fn test_farm_hash_32_with_seed() {
let data = b"hello world";
let seed = 123456789;
let hash = farm_hash_32_with_seed(data, seed);
assert_eq!(hash, farm_hash_32_with_seed(data, seed));
assert_ne!(hash, farm_hash_32_with_seed(data, seed + 1));
}
#[test]
fn test_farm_hash_64() {
let data = b"hello world";
let hash = farm_hash_64(data);
assert_eq!(hash, farm_hash_64(data));
assert_ne!(hash, 0);
}
#[test]
fn test_farm_hash_64_with_seed() {
let data = b"hello world";
let seed = 123456789;
let hash = farm_hash_64_with_seed(data, seed);
assert_eq!(hash, farm_hash_64_with_seed(data, seed));
assert_ne!(hash, farm_hash_64_with_seed(data, seed + 1));
}
#[test]
fn test_farm_hash_64_with_seeds() {
let data = b"hello world";
let seed0 = 123456789;
let seed1 = 987654321;
let hash = farm_hash_64_with_seeds(data, seed0, seed1);
assert_eq!(hash, farm_hash_64_with_seeds(data, seed0, seed1));
assert_ne!(hash, farm_hash_64_with_seeds(data, seed0 + 1, seed1));
}
#[test]
fn test_farm_hash_128() {
let data = b"hello world";
let (low, high) = farm_hash_128(data);
let (low2, high2) = farm_hash_128(data);
assert_eq!((low, high), (low2, high2));
assert!(low != 0 || high != 0);
}
#[test]
fn test_farm_hash_128_with_seed() {
let data = b"hello world";
let seed = 123456789;
let (low1, high1) = farm_hash_128_with_seed(data, seed);
assert_eq!(farm_hash_128_with_seed(data, seed), (low1, high1));
let (low2, high2) = farm_hash_128_with_seed(data, seed + 1);
assert!(low1 != low2 || high1 != high2);
}
#[test]
fn test_farmhash_module_compatibility() {
let data = b"hello world";
assert_eq!(farmhash::hash32(data), farm_hash_32(data));
assert_eq!(farmhash::hash64(data), farm_hash_64(data));
assert_eq!(farmhash::fingerprint128(data), farm_hash_128(data));
}
#[test]
fn test_farm_hash_hasher() {
let data = b"hello world";
let mut hasher = FarmHashHasher::new();
hasher.write(data);
let hash = hasher.finish();
assert_eq!(hash, farm_hash_64(data));
}
#[test]
fn test_farm_hash_hasher_with_seed() {
let data = b"hello world";
let seed = 123456789;
let mut hasher = FarmHashHasher::with_seed(seed);
hasher.write(data);
let hash = hasher.finish();
assert_eq!(hash, farm_hash_64_with_seed(data, seed));
}
}