Extract cache into own crate

This commit is contained in:
Valentin Brandl
2019-08-07 21:44:20 +02:00
parent 2ef81fb75b
commit 4985c497df
10 changed files with 132 additions and 106 deletions

3
time-cache/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock

6
time-cache/Cargo.lock generated Normal file
View File

@ -0,0 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "time-cache"
version = "0.1.0"

9
time-cache/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "time-cache"
version = "0.1.0"
authors = ["Valentin Brandl <vbrandl@riseup.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

74
time-cache/src/lib.rs Normal file
View File

@ -0,0 +1,74 @@
use std::{
collections::HashMap,
hash::Hash,
time::{Duration, Instant},
};
pub struct Cache<K, V> {
cache: HashMap<K, CacheEntry<V>>,
duration: Duration,
}
impl<K, V> Cache<K, V>
where
K: Eq + Hash,
{
pub fn new(duration: Duration) -> Self {
Self {
cache: HashMap::new(),
duration,
}
}
pub fn get(&self, key: &K) -> CacheResult<&V> {
if let Some(entry) = self.cache.get(key) {
if Self::is_valid(Instant::now(), entry) {
CacheResult::Cached(&entry.1)
} else {
CacheResult::Invalid
}
} else {
CacheResult::Empty
}
}
pub fn invalidate(&mut self, key: &K) -> bool {
self.cache.remove(key).is_some()
}
pub fn store(&mut self, key: K, value: V) -> Option<V> {
self.cache
.insert(key, CacheEntry::new(value, self.duration))
.map(|old| old.1)
}
pub fn clear(&mut self) {
let now = Instant::now();
self.cache.retain(|_, v| !Self::is_valid(now, v));
}
fn is_valid(when: Instant, entry: &CacheEntry<V>) -> bool {
entry.0 >= when
}
}
pub enum CacheResult<T> {
Cached(T),
Invalid,
Empty,
}
struct CacheEntry<T>(Instant, T);
impl<T> CacheEntry<T> {
fn new(value: T, duration: Duration) -> Self {
CacheEntry(Instant::now() + duration, value)
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}