| use std::borrow::Borrow; |
| use std::collections::HashMap; |
| use std::hash::Hash; |
| use std::sync::RwLock; |
|
|
| |
| pub static DEFAULT_CACHE_CAPACITY: usize = 10_000; |
|
|
| |
| |
| |
| |
| #[derive(Debug)] |
| pub(crate) struct Cache<K, V> |
| where |
| K: Eq + Hash + Clone, |
| V: Clone, |
| { |
| map: RwLock<HashMap<K, V>>, |
| pub capacity: usize, |
| } |
|
|
| |
| impl<K, V> PartialEq for Cache<K, V> |
| where |
| K: Eq + Hash + Clone, |
| V: Clone, |
| { |
| fn eq(&self, _other: &Cache<K, V>) -> bool { |
| true |
| } |
| } |
|
|
| impl<K, V> Default for Cache<K, V> |
| where |
| K: Eq + Hash + Clone, |
| V: Clone, |
| { |
| fn default() -> Self { |
| Self::new(DEFAULT_CACHE_CAPACITY) |
| } |
| } |
|
|
| impl<K, V> Cache<K, V> |
| where |
| K: Eq + Hash + Clone, |
| V: Clone, |
| { |
| |
| pub(crate) fn new(capacity: usize) -> Self { |
| let map = RwLock::new(HashMap::with_capacity(capacity)); |
| Cache { map, capacity } |
| } |
|
|
| |
| pub(crate) fn fresh(&self) -> Self { |
| Self::new(self.capacity) |
| } |
|
|
| |
| pub(crate) fn clear(&self) { |
| self.map.write().unwrap().clear(); |
| } |
|
|
| #[allow(dead_code)] |
| pub(crate) fn get_values<'a, I, Q>(&self, keys_iter: I) -> Option<Vec<Option<V>>> |
| where |
| I: Iterator<Item = &'a Q>, |
| K: Borrow<Q>, |
| Q: Hash + Eq + ?Sized + 'a, |
| { |
| if let Ok(ref mut cache) = self.map.try_read() { |
| Some(keys_iter.map(|k| cache.get(k).cloned()).collect()) |
| } else { |
| None |
| } |
| } |
|
|
| pub(crate) fn get<Q>(&self, key: &Q) -> Option<V> |
| where |
| K: Borrow<Q>, |
| Q: Hash + Eq + ?Sized, |
| { |
| if let Ok(ref mut cache) = self.map.try_read() { |
| cache.get(key).cloned() |
| } else { |
| None |
| } |
| } |
|
|
| pub(crate) fn set_values<I>(&self, entries: I) |
| where |
| I: IntoIterator<Item = (K, V)>, |
| { |
| |
| |
| if let Ok(cache) = self.map.try_read() { |
| if cache.len() >= self.capacity { |
| |
| return; |
| } |
| } else { |
| |
| |
| return; |
| } |
|
|
| |
| if let Ok(mut cache) = self.map.try_write() { |
| let free = self.capacity - cache.len(); |
| cache.extend(entries.into_iter().take(free)); |
| } |
| } |
|
|
| pub(crate) fn set(&self, key: K, value: V) { |
| self.set_values(std::iter::once((key, value))) |
| } |
| } |
|
|