Skip to content

Instantly share code, notes, and snippets.

@Gankra
Created May 17, 2018 17:36
Show Gist options
  • Save Gankra/fb0bfe6f6770aba09b9a1cdf0ecf47e0 to your computer and use it in GitHub Desktop.
Save Gankra/fb0bfe6f6770aba09b9a1cdf0ecf47e0 to your computer and use it in GitHub Desktop.
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