diff --git a/phf/src/map.rs b/phf/src/map.rs index d74c9f72..edcd90ad 100644 --- a/phf/src/map.rs +++ b/phf/src/map.rs @@ -2,7 +2,6 @@ use debug_builders::DebugMap; use std::borrow::Borrow; use std::ops::Index; -use std::hash::{Hasher, SipHasher}; use std::slice; use std::fmt; use std::iter::IntoIterator; @@ -71,13 +70,9 @@ impl Map { /// Like `get`, but returns both the key and the value. pub fn get_entry(&self, key: &T) -> Option<(&K, &V)> where T: Eq + PhfHash, K: Borrow { - let mut hasher = SipHasher::new_with_keys(0, self.key); - key.phf_hash(&mut hasher); - let (g, f1, f2) = phf_shared::split(hasher.finish()); - - let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as usize]; - let entry = &self.entries[(phf_shared::displace(f1, f2, d1, d2) % (self.entries.len() as u32)) - as usize]; + let hash = phf_shared::hash(key, self.key); + let index = phf_shared::get_index(hash, self.disps, self.entries.len()); + let entry = &self.entries[index as usize]; let b: &T = entry.0.borrow(); if b == key { Some((&entry.0, &entry.1)) diff --git a/phf/src/ordered_map.rs b/phf/src/ordered_map.rs index e9044dec..be032e26 100644 --- a/phf/src/ordered_map.rs +++ b/phf/src/ordered_map.rs @@ -1,7 +1,6 @@ //! An order-preserving immutable map constructed at compile time. use debug_builders::DebugMap; use std::borrow::Borrow; -use std::hash::{Hasher, SipHasher}; use std::iter::IntoIterator; use std::ops::Index; use std::fmt; @@ -95,12 +94,9 @@ impl OrderedMap { fn get_internal(&self, key: &T) -> Option<(usize, (&K, &V))> where T: Eq + PhfHash, K: Borrow { - let mut hasher = SipHasher::new_with_keys(0, self.key); - key.phf_hash(&mut hasher); - let (g, f1, f2) = phf_shared::split(hasher.finish()); - - let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as usize]; - let idx = self.idxs[(phf_shared::displace(f1, f2, d1, d2) % (self.idxs.len() as u32)) as usize]; + let hash = phf_shared::hash(key, self.key); + let idx_index = phf_shared::get_index(hash, self.disps, self.idxs.len()); + let idx = self.idxs[idx_index as usize]; let entry = &self.entries[idx]; let b: &T = entry.0.borrow(); diff --git a/phf_generator/src/lib.rs b/phf_generator/src/lib.rs index c5b73383..09f7a88c 100644 --- a/phf_generator/src/lib.rs +++ b/phf_generator/src/lib.rs @@ -4,7 +4,6 @@ extern crate rand; use phf_shared::PhfHash; use rand::{SeedableRng, XorShiftRng, Rng}; -use std::hash::{Hasher, SipHasher}; const DEFAULT_LAMBDA: usize = 5; @@ -38,12 +37,10 @@ fn try_generate_hash(entries: &[H], rng: &mut XorShiftRng) -> Option } let key = rng.gen(); - let hasher = SipHasher::new_with_keys(0, key); let hashes: Vec<_> = entries.iter().map(|entry| { - let mut hasher = hasher.clone(); - entry.phf_hash(&mut hasher); - let (g, f1, f2) = phf_shared::split(hasher.finish()); + let hash = phf_shared::hash(entry, key); + let (g, f1, f2) = phf_shared::split(hash); Hashes { g: g, f1: f1, diff --git a/phf_shared/src/lib.rs b/phf_shared/src/lib.rs index 1a5a028a..31acb62b 100644 --- a/phf_shared/src/lib.rs +++ b/phf_shared/src/lib.rs @@ -1,6 +1,6 @@ #![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")] -use std::hash::{Hasher, Hash}; +use std::hash::{Hasher, Hash, SipHasher}; #[inline] pub fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 { @@ -17,6 +17,26 @@ pub fn split(hash: u64) -> (u32, u32, u32) { ((hash >> (2 * BITS)) & MASK) as u32) } +/// `key` is from `phf_generator::HashState::key`. +#[inline] +pub fn hash(x: &T, key: u64) -> u64 { + let mut hasher = SipHasher::new_with_keys(0, key); + x.phf_hash(&mut hasher); + hasher.finish() +} + +/// Return an index into `phf_generator::HashState::map`. +/// +/// * `hash` is from `hash()` in this crate. +/// * `disps` is from `phf_generator::HashState::disps`. +/// * `len` is the length of `phf_generator::HashState::map`. +#[inline] +pub fn get_index(hash: u64, disps: &[(u32, u32)], len: usize) -> u32 { + let (g, f1, f2) = split(hash); + let (d1, d2) = disps[(g % (disps.len() as u32)) as usize]; + displace(f1, f2, d1, d2) % (len as u32) +} + /// A trait implemented by types which can be used in PHF data structures. /// /// This differs from the standard library's `Hash` trait in that `PhfHash`'s