1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
6
7use std::os::raw::c_char;
8
9pub fn farm_hash_32(bytes: &[u8]) -> u32 {
11 unsafe { farmhash_hash32(bytes.as_ptr() as *const c_char, bytes.len()) }
12}
13
14pub fn farm_hash_32_with_seed(bytes: &[u8], seed: u32) -> u32 {
16 unsafe { farmhash_hash32_with_seed(bytes.as_ptr() as *const c_char, bytes.len(), seed) }
17}
18
19pub fn farm_hash_64(bytes: &[u8]) -> u64 {
21 unsafe { farmhash_hash64(bytes.as_ptr() as *const c_char, bytes.len()) }
22}
23
24pub fn farm_hash_64_with_seed(bytes: &[u8], seed: u64) -> u64 {
26 unsafe { farmhash_hash64_with_seed(bytes.as_ptr() as *const c_char, bytes.len(), seed) }
27}
28
29pub fn farm_hash_64_with_seeds(bytes: &[u8], seed0: u64, seed1: u64) -> u64 {
31 unsafe {
32 farmhash_hash64_with_seeds(bytes.as_ptr() as *const c_char, bytes.len(), seed0, seed1)
33 }
34}
35
36pub fn farm_hash_128(bytes: &[u8]) -> (u64, u64) {
38 unsafe {
39 let result = farmhash_fingerprint128(bytes.as_ptr() as *const c_char, bytes.len());
40 (result.low, result.high)
41 }
42}
43
44pub fn farm_hash_128_with_seed(bytes: &[u8], seed: u64) -> (u64, u64) {
46 let low = farm_hash_64_with_seed(bytes, seed);
48 let high = farm_hash_64_with_seed(bytes, seed.wrapping_add(1));
49 (low, high)
50}
51
52use std::hash::Hasher;
53
54pub struct FarmHashHasher {
56 buffer: Vec<u8>,
57 seed: Option<u64>,
58}
59
60impl FarmHashHasher {
61 pub fn new() -> Self {
63 Self {
64 buffer: Vec::new(),
65 seed: None,
66 }
67 }
68
69 pub fn with_seed(seed: u64) -> Self {
71 Self {
72 buffer: Vec::new(),
73 seed: Some(seed),
74 }
75 }
76}
77
78impl Default for FarmHashHasher {
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84impl Hasher for FarmHashHasher {
85 fn finish(&self) -> u64 {
86 if self.seed.is_some() {
87 farm_hash_64_with_seed(&self.buffer, self.seed.unwrap())
88 } else {
89 farm_hash_64(&self.buffer)
90 }
91 }
92
93 fn write(&mut self, bytes: &[u8]) {
94 self.buffer.extend_from_slice(bytes);
97 }
98}
99
100#[allow(dead_code)]
101type FarmHashHasherDefault = std::hash::BuildHasherDefault<FarmHashHasher>;
103
104pub mod farmhash {
106 use super::*;
107
108 pub fn hash32(bytes: &[u8]) -> u32 {
110 farm_hash_32(bytes)
111 }
112
113 pub fn hash32_with_seed(bytes: &[u8], seed: u32) -> u32 {
115 farm_hash_32_with_seed(bytes, seed)
116 }
117
118 pub fn hash64(bytes: &[u8]) -> u64 {
120 farm_hash_64(bytes)
121 }
122
123 pub fn hash64_with_seed(bytes: &[u8], seed: u64) -> u64 {
125 farm_hash_64_with_seed(bytes, seed)
126 }
127
128 pub fn hash64_with_seeds(bytes: &[u8], seed0: u64, seed1: u64) -> u64 {
130 farm_hash_64_with_seeds(bytes, seed0, seed1)
131 }
132
133 pub fn fingerprint128(bytes: &[u8]) -> (u64, u64) {
135 farm_hash_128(bytes)
136 }
137
138 pub fn fingerprint128_with_seed(bytes: &[u8], seed: u64) -> (u64, u64) {
140 farm_hash_128_with_seed(bytes, seed)
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_farm_hash_32() {
150 let data = b"hello world";
151 let hash = farm_hash_32(data);
152 assert_eq!(hash, farm_hash_32(data));
154 assert_ne!(hash, 0);
155 }
156
157 #[test]
158 fn test_farm_hash_32_with_seed() {
159 let data = b"hello world";
160 let seed = 123456789;
161 let hash = farm_hash_32_with_seed(data, seed);
162 assert_eq!(hash, farm_hash_32_with_seed(data, seed));
164 assert_ne!(hash, farm_hash_32_with_seed(data, seed + 1));
166 }
167
168 #[test]
169 fn test_farm_hash_64() {
170 let data = b"hello world";
171 let hash = farm_hash_64(data);
172 assert_eq!(hash, farm_hash_64(data));
174 assert_ne!(hash, 0);
175 }
176
177 #[test]
178 fn test_farm_hash_64_with_seed() {
179 let data = b"hello world";
180 let seed = 123456789;
181 let hash = farm_hash_64_with_seed(data, seed);
182 assert_eq!(hash, farm_hash_64_with_seed(data, seed));
184 assert_ne!(hash, farm_hash_64_with_seed(data, seed + 1));
186 }
187
188 #[test]
189 fn test_farm_hash_64_with_seeds() {
190 let data = b"hello world";
191 let seed0 = 123456789;
192 let seed1 = 987654321;
193 let hash = farm_hash_64_with_seeds(data, seed0, seed1);
194 assert_eq!(hash, farm_hash_64_with_seeds(data, seed0, seed1));
196 assert_ne!(hash, farm_hash_64_with_seeds(data, seed0 + 1, seed1));
198 }
199
200 #[test]
201 fn test_farm_hash_128() {
202 let data = b"hello world";
203 let (low, high) = farm_hash_128(data);
204 let (low2, high2) = farm_hash_128(data);
206 assert_eq!((low, high), (low2, high2));
207 assert!(low != 0 || high != 0);
209 }
210
211 #[test]
212 fn test_farm_hash_128_with_seed() {
213 let data = b"hello world";
214 let seed = 123456789;
215 let (low1, high1) = farm_hash_128_with_seed(data, seed);
216 assert_eq!(farm_hash_128_with_seed(data, seed), (low1, high1));
218 let (low2, high2) = farm_hash_128_with_seed(data, seed + 1);
220 assert!(low1 != low2 || high1 != high2);
221 }
222
223 #[test]
224 fn test_farmhash_module_compatibility() {
225 let data = b"hello world";
226 assert_eq!(farmhash::hash32(data), farm_hash_32(data));
228 assert_eq!(farmhash::hash64(data), farm_hash_64(data));
229 assert_eq!(farmhash::fingerprint128(data), farm_hash_128(data));
230 }
231
232 #[test]
233 fn test_farm_hash_hasher() {
234 let data = b"hello world";
235 let mut hasher = FarmHashHasher::new();
236 hasher.write(data);
237 let hash = hasher.finish();
238 assert_eq!(hash, farm_hash_64(data));
240 }
241
242 #[test]
243 fn test_farm_hash_hasher_with_seed() {
244 let data = b"hello world";
245 let seed = 123456789;
246 let mut hasher = FarmHashHasher::with_seed(seed);
247 hasher.write(data);
248 let hash = hasher.finish();
249 assert_eq!(hash, farm_hash_64_with_seed(data, seed));
251 }
252}