Created
May 17, 2018 17:36
-
-
Save Gankra/fb0bfe6f6770aba09b9a1cdf0ecf47e0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::hash_map::DefaultHasher; | |
use std::hash::{BuildHasherDefault, Hasher}; | |
use std::cell::Cell; | |
// Use `BuildHasherDefault` to get deterministic hashing between map instances | |
type SimpleMap<K, V> = HashMap<K, V, BuilderHasherDefault<DefaultHasher>>; | |
/// A very naively memoized string | |
pub struct MemoizedString { | |
string: String, | |
hash: Cell<u64>, | |
} | |
impl MemoizedString { | |
/// Create a new string with no memoized hash | |
pub fn new(string: String) -> Self { | |
MemoizedString { string, hash: Cell::new(0) } | |
} | |
/// Either get the memoized hash, or compute a new one | |
pub fn hash_memoized<H: Hasher>(&self, mut hasher: H) -> u64 { | |
let hash = self.hash.get(); | |
if hash != 0 { | |
hash | |
} else { | |
self.string.hash(&mut hasher); | |
// mask on the high bit so it's never 0 | |
let new_hash = hasher.finish() | 0x8000_0000; | |
self.hash.set(new_hash); | |
new_hash | |
} | |
} | |
} | |
fn main() { | |
let key = MemoizedString::new(String::from("gotta go fast!")); | |
let mut map = SimpleMap::default(); | |
*map.raw_entry() | |
.hash_with(|hasher| key.hash_memoized(hasher)) | |
.search_by(&key.string) | |
.or_insert(|| (key.string.clone(), 0)) | |
.1 += 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment