Skip to content

Instantly share code, notes, and snippets.

@utkarshg6
Last active April 18, 2022 08:55
Show Gist options
  • Save utkarshg6/c8a5cb39ef89b8f16fcce3098754c001 to your computer and use it in GitHub Desktop.
Save utkarshg6/c8a5cb39ef89b8f16fcce3098754c001 to your computer and use it in GitHub Desktop.
A cacher that can store the computed values of a closure inside a HashMap and can return the pre-computed values without running the closure again.
use std::collections::HashMap;
use core::hash::Hash;
struct Cacher<T, V>
where
T: Fn(V) -> V,
V: Eq + Hash + Copy,
{
calculation: T,
value: HashMap<V, V>,
}
impl<T, V> Cacher<T, V>
where
T: Fn(V) -> V,
V: Eq + Hash + Copy,
{
fn new(calculation: T) -> Cacher<T, V> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: V) -> V {
if let Some(&v) = self.value.get(&arg) {
v
} else {
let v = (self.calculation)(arg);
self.value.insert(arg, v);
v
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn able_to_cache_numbers() {
let mut cacher = Cacher::new(|x| x);
assert_eq!(cacher.value(1), 1);
assert_eq!(cacher.value(2), 2);
assert_eq!(cacher.value(3), 3);
}
#[test]
fn able_to_cache_string_slices() {
let mut cacher = Cacher::new(|x| x);
let first_argument = "first_argument";
let second_argument = "second_argument";
assert_eq!(cacher.value(first_argument), first_argument);
assert_eq!(cacher.value(second_argument), second_argument);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment