diff --git a/phf/src/lib.rs b/phf/src/lib.rs index 9eccddbb..b8edb76b 100644 --- a/phf/src/lib.rs +++ b/phf/src/lib.rs @@ -104,7 +104,7 @@ impl PhfMap where K: PhfHash+Eq { } impl PhfMap { - fn get_entry(&self, key: &T, check: |&K| -> bool) -> Option<&(K, V)> where T: PhfHash { + fn get_entry(&self, key: &T, check: |&K| -> bool) -> Option<&(K, V)> where T: PhfHash { let (g, f1, f2) = key.phf_hash(self.key); let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as uint]; let entry = &self.entries[(shared::displace(f1, f2, d1, d2) % (self.entries.len() as u32)) @@ -117,13 +117,13 @@ impl PhfMap { } /// Like `find`, but can operate on any type that is equivalent to a key. - pub fn find_equiv(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv { + pub fn find_equiv(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv { self.get_entry(key, |k| key.equiv(k)).map(|e| &e.1) } /// Like `find_key`, but can operate on any type that is equivalent to a /// key. - pub fn find_key_equiv(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv { + pub fn find_key_equiv(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv { self.get_entry(key, |k| key.equiv(k)).map(|e| &e.0) } } @@ -304,14 +304,14 @@ impl PhfSet { /// Like `contains`, but can operate on any type that is equivalent to a /// value #[inline] - pub fn contains_equiv(&self, key: &U) -> bool where U: PhfHash+Equiv { + pub fn contains_equiv(&self, key: &U) -> bool where U: PhfHash+Equiv { self.map.find_equiv(key).is_some() } /// Like `find_key`, but can operate on any type that is equivalent to a /// value #[inline] - pub fn find_key_equiv(&self, key: &U) -> Option<&T> where U: PhfHash+Equiv { + pub fn find_key_equiv(&self, key: &U) -> Option<&T> where U: PhfHash+Equiv { self.map.find_key_equiv(key) } } @@ -438,7 +438,7 @@ impl PhfOrderedMap where K: PhfHash+Eq { } impl PhfOrderedMap { - fn find_entry(&self, key: &T, check: |&K| -> bool) -> Option<(uint, &(K, V))> + fn find_entry(&self, key: &T, check: |&K| -> bool) -> Option<(uint, &(K, V))> where T: PhfHash { let (g, f1, f2) = key.phf_hash(self.key); let (d1, d2) = self.disps[(g % (self.disps.len() as u32)) as uint]; @@ -453,19 +453,19 @@ impl PhfOrderedMap { } /// Like `find`, but can operate on any type that is equivalent to a key. - pub fn find_equiv(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv { + pub fn find_equiv(&self, key: &T) -> Option<&V> where T: PhfHash+Equiv { self.find_entry(key, |k| key.equiv(k)).map(|(_, e)| &e.1) } /// Like `find_key`, but can operate on any type that is equivalent to a /// key. - pub fn find_key_equiv(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv { + pub fn find_key_equiv(&self, key: &T) -> Option<&K> where T: PhfHash+Equiv { self.find_entry(key, |k| key.equiv(k)).map(|(_, e)| &e.0) } /// Like `find_index`, but can operate on any type that is equivalent to a /// key. - pub fn find_index_equiv(&self, key: &T) -> Option where T: PhfHash+Equiv { + pub fn find_index_equiv(&self, key: &T) -> Option where T: PhfHash+Equiv { self.find_entry(key, |k| key.equiv(k)).map(|(i, _)| i) } @@ -683,20 +683,20 @@ impl PhfOrderedSet { /// Like `contains`, but can operate on any type that is equivalent to a /// value #[inline] - pub fn contains_equiv(&self, key: &U) -> bool where U: PhfHash+Equiv { + pub fn contains_equiv(&self, key: &U) -> bool where U: PhfHash+Equiv { self.map.find_equiv(key).is_some() } /// Like `find_key`, but can operate on any type that is equivalent to a /// value #[inline] - pub fn find_key_equiv(&self, key: &U) -> Option<&T> where U: PhfHash+Equiv { + pub fn find_key_equiv(&self, key: &U) -> Option<&T> where U: PhfHash+Equiv { self.map.find_key_equiv(key) } /// Like `find_index`, but can operate on any type that is equivalent to a /// key. - pub fn find_index_equiv(&self, key: &U) -> Option where U: PhfHash+Equiv { + pub fn find_index_equiv(&self, key: &U) -> Option where U: PhfHash+Equiv { self.map.find_index_equiv(key) } diff --git a/phf/tests/test.rs b/phf/tests/test.rs index 80805a5d..71204252 100644 --- a/phf/tests/test.rs +++ b/phf/tests/test.rs @@ -112,7 +112,7 @@ mod map { static MAP: PhfMap<&'static str, int> = phf_map!( "a" => 0, ); - assert_eq!(Some(&0), MAP.find_equiv(&"a".to_string()[])); + assert_eq!(Some(&0), MAP.find_equiv("a".to_string()[])); } #[test] @@ -248,7 +248,7 @@ mod set { "hello", "world", }; - assert!(SET.contains_equiv(&"hello".to_string()[])); + assert!(SET.contains_equiv("hello".to_string()[])); } } @@ -289,9 +289,9 @@ mod ordered_map { assert_eq!(None, MAP.find_index(&"xyz")); assert_eq!(&"baz", MAP.keys().idx(MAP.find_index(&"baz").unwrap()).unwrap()); - assert_eq!(Some(0), MAP.find_index_equiv(&"foo".to_string()[])); - assert_eq!(Some(2), MAP.find_index_equiv(&"baz".to_string()[])); - assert_eq!(None, MAP.find_index_equiv(&"xyz".to_string()[])); + assert_eq!(Some(0), MAP.find_index_equiv("foo".to_string()[])); + assert_eq!(Some(2), MAP.find_index_equiv("baz".to_string()[])); + assert_eq!(None, MAP.find_index_equiv("xyz".to_string()[])); } #[test] @@ -349,7 +349,7 @@ mod ordered_map { static MAP: PhfOrderedMap<&'static str, int> = phf_ordered_map!( "a" => 0, ); - assert_eq!(Some(&0), MAP.find_equiv(&"a".to_string()[])); + assert_eq!(Some(&0), MAP.find_equiv("a".to_string()[])); } } @@ -392,9 +392,9 @@ mod ordered_set { assert_eq!(None, SET.find_index(&"xyz")); assert_eq!(&"baz", SET.iter().idx(SET.find_index(&"baz").unwrap()).unwrap()); - assert_eq!(Some(0), SET.find_index_equiv(&"foo".to_string()[])); - assert_eq!(Some(2), SET.find_index_equiv(&"baz".to_string()[])); - assert_eq!(None, SET.find_index_equiv(&"xyz".to_string()[])); + assert_eq!(Some(0), SET.find_index_equiv("foo".to_string()[])); + assert_eq!(Some(2), SET.find_index_equiv("baz".to_string()[])); + assert_eq!(None, SET.find_index_equiv("xyz".to_string()[])); } #[test] @@ -414,6 +414,6 @@ mod ordered_set { "hello", "world", }; - assert!(SET.contains_equiv(&"hello".to_string()[])); + assert!(SET.contains_equiv("hello".to_string()[])); } } diff --git a/shared/mod.rs b/shared/mod.rs index 5e83c187..d17af213 100644 --- a/shared/mod.rs +++ b/shared/mod.rs @@ -1,4 +1,7 @@ extern crate xxhash; +extern crate core; + +use self::core::kinds::Sized; #[inline] pub fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 { @@ -16,7 +19,7 @@ fn split(hash: u64) -> (u32, u32, u32) { } /// A trait implemented by types which can be used in PHF data structures -pub trait PhfHash { +pub trait PhfHash for Sized? { /// Hashes the value of `self`, factoring in a seed fn phf_hash(&self, seed: u64) -> (u32, u32, u32); } @@ -35,6 +38,21 @@ impl<'a> PhfHash for &'a [u8] { } } +impl PhfHash for str { + #[inline] + fn phf_hash(&self, seed: u64) -> (u32, u32, u32) { + split(xxhash::hash_with_seed(seed, &self)) + } +} + +impl PhfHash for [u8] { + #[inline] + fn phf_hash(&self, seed: u64) -> (u32, u32, u32) { + split(xxhash::oneshot(self, seed)) + } +} + + macro_rules! sip_impl( ($t:ty) => ( impl PhfHash for $t {