Add cache struct and implementation

This commit is contained in:
Valentin Brandl 2019-08-07 18:50:28 +02:00
parent 0c22e5662a
commit 566f4c0e01
No known key found for this signature in database
GPG Key ID: 30D341DD34118D7D

83
backend/src/cache.rs Normal file
View File

@ -0,0 +1,83 @@
use std::{
collections::HashMap,
hash::Hash,
time::{Duration, Instant},
};
pub(crate) struct Cache<K, V> {
cache: HashMap<K, CacheEntry<V>>,
duration: Duration,
}
impl<K, V> Cache<K, V>
where
K: Eq + Hash,
{
pub(crate) fn new() -> Self {
Self {
cache: HashMap::new(),
duration: Duration::from_secs(5 * 60),
}
}
pub(crate) 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(crate) fn invalidate(&mut self, key: &K) -> bool {
self.cache.remove(key).is_some()
}
pub(crate) fn store(&mut self, key: K, value: V) -> Option<V> {
self.cache
.insert(key, CacheEntry::new(value, self.duration))
.map(|old| old.1)
}
pub(crate) 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(crate) 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)
}
}
#[derive(Eq, PartialEq, Hash, Debug)]
pub(crate) struct Key(Service, String, String, String);
#[derive(Eq, PartialEq, Hash, Debug)]
pub(crate) enum Service {
GitHub,
GitLab,
Bitbucket,
}
impl Key {
pub(crate) fn new(service: Service, user: String, repo: String, branch: String) -> Self {
Key(service, user, repo, branch)
}
}