Add cache struct and implementation
This commit is contained in:
parent
0c22e5662a
commit
566f4c0e01
83
backend/src/cache.rs
Normal file
83
backend/src/cache.rs
Normal 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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user