use std::{collections::{VecDeque, HashMap}, hash::Hash};
pub trait ApiCache<K, V>
where K: Hash + Eq
{
fn get(&self, request: &K) -> Option<&V>;
fn put(&mut self, request: K, response: V);
fn capacity(&self) -> usize;
fn clear(&mut self);
fn new(capacity: usize) -> Self;
}
pub struct FifoCache<K, V> {
queue: VecDeque<K>,
index: HashMap<K, V>,
capacity: usize
}
impl<K, V> ApiCache<K, V> for FifoCache<K, V>
where K: Hash + Eq + Clone
{
fn get(&self, request: &K) -> Option<&V> {
self.index.get(request)
}
fn put(&mut self, request: K, response: V) {
if self.queue.len() == self.capacity {
if let Some(_) = self.queue.pop_front() {
self.index.remove(&request);
};
}
self.queue.push_back(request.clone());
self.index.insert(request, response);
}
fn capacity(&self) -> usize {
self.capacity
}
fn clear(&mut self) {
self.queue.clear();
self.index.clear();
}
fn new(capacity: usize) -> Self {
Self {
queue: VecDeque::with_capacity(capacity),
index: HashMap::with_capacity(capacity),
capacity,
}
}
}