Skip to content

Instantly share code, notes, and snippets.

@alexkuang0
Created November 9, 2021 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexkuang0/8e3507a7b2d1a0edd3b3fd295afaec16 to your computer and use it in GitHub Desktop.
Save alexkuang0/8e3507a7b2d1a0edd3b3fd295afaec16 to your computer and use it in GitHub Desktop.
// Solution from:
// https://users.rust-lang.org/t/30856/5
use std::collections::{HashMap, hash_map::Entry};
use std::cmp::Eq;
use std::hash::Hash;
use std::thread::sleep;
use std::time::Duration;
struct Cacher<T, U, V>
where T: Fn(&U) -> V, U: Eq + Hash {
func: T,
cache: HashMap<U, V>,
}
impl<T, U, V> Cacher<T, U, V>
where T: Fn(&U) -> V, U: Eq + Hash {
fn new(func: T) -> Cacher<T, U, V> {
Cacher {
func,
cache: HashMap::new()
}
}
fn get(&mut self, value: U) -> &V {
match self.cache.entry(value) {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let v = (self.func)(entry.key());
entry.insert(v)
}
}
}
}
fn main() {
let mut cache = Cacher::new(|x| {
sleep(Duration::from_secs(2));
x + 1
});
println!("Start!");
println!("First: {}", cache.get(1));
println!("Second: {}", cache.get(1));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment