1use std::hash::Hasher;
2use std::iter::Extend;
3
4use libc::size_t;
5
6extern "C" {
7 fn Hash64(s: *const u8, len: size_t) -> u64;
8 fn Hash64WithSeed(s: *const u8, len: size_t, seed: u64) -> u64;
9}
10
11fn hash_64(input: &[u8]) -> u64 {
13 unsafe { Hash64(input.as_ptr(), input.len() as size_t) }
14}
15
16fn hash_64_with_seed(input: &[u8], seed: u64) -> u64 {
18 unsafe { Hash64WithSeed(input.as_ptr(), input.len() as size_t, seed) }
19}
20
21#[derive(Debug, Default)]
23pub struct Hash64 {
24 buf: Vec<u8>,
25 seed: Option<u64>,
26}
27
28impl Hash64 {
29 pub fn with_seed(seed: u64) -> Hash64 {
31 Hash64 {
32 buf: Default::default(),
33 seed: Some(seed),
34 }
35 }
36}
37
38impl Hasher for Hash64 {
39 fn write(&mut self, bytes: &[u8]) {
40 self.buf.extend(bytes);
41 }
42
43 fn finish(&self) -> u64 {
44 if let Some(s) = self.seed {
45 hash_64_with_seed(&self.buf, s)
46 } else {
47 hash_64(&self.buf)
48 }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use std::hash::Hasher;
55
56 use super::Hash64;
57
58 #[test]
59 fn no_seed_64() {
60 const EXPECTED: u64 = 18084869015357591102;
61
62 let mut h = Hash64::default();
63 h.write(b"farmhash");
64
65 assert_eq!(EXPECTED, h.finish());
66 }
67
68 #[test]
69 fn seed_64() {
70 const EXPECTED: u64 = 15795874029479571151;
71
72 let mut h = Hash64::with_seed(7);
73 h.write(b"farmhash");
74
75 assert_eq!(EXPECTED, h.finish());
76 }
77}