From 566f4c0e010785a350955f97a39152da3aeb12f5 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Wed, 7 Aug 2019 18:50:28 +0200 Subject: [PATCH] Add cache struct and implementation --- backend/src/cache.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 backend/src/cache.rs diff --git a/backend/src/cache.rs b/backend/src/cache.rs new file mode 100644 index 0000000..9ca559d --- /dev/null +++ b/backend/src/cache.rs @@ -0,0 +1,83 @@ +use std::{ + collections::HashMap, + hash::Hash, + time::{Duration, Instant}, +}; + +pub(crate) struct Cache { + cache: HashMap>, + duration: Duration, +} + +impl Cache +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 { + 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) -> bool { + entry.0 >= when + } +} + +pub(crate) enum CacheResult { + Cached(T), + Invalid, + Empty, +} + +struct CacheEntry(Instant, T); + +impl CacheEntry { + 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) + } +}