use std::collections::HashMap;
use std::hash::Hash;
use std::time::{Duration, Instant};
pub struct TimedCache<K, V> {
cache: HashMap<K, (V, Instant)>,
}
impl<K, V> TimedCache<K, V>
where
K: Eq + Hash,
{
pub fn new() -> TimedCache<K, V> {
TimedCache {
cache: HashMap::new(),
}
}
pub fn get(&self, key: &K) -> Option<&V> {
if let Some((value, stored_at)) = self.cache.get(key) {
if stored_at > &Instant::now() {
return Some(value);
}
}
None
}
pub fn set(&mut self, key: K, value: V, ttl: Duration) {
self.cache.insert(key, (value, Instant::now() + ttl));
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::thread;
use std::sync::Arc;
#[test]
fn works_as_expected() {
let mut cache: TimedCache<Arc<&str>, usize> = TimedCache::new();
let key = Arc::new("hello");
assert!(cache.get(&key).is_none());
cache.set(Arc::clone(&key), 10, Duration::from_secs(1));
assert_eq!(Some(&10), cache.get(&key));
thread::sleep(Duration::from_secs(2));
assert!(cache.get(&key).is_none());
}
}