cache: Add method to update or initialize items
This commit is contained in:
parent
044a735778
commit
3ae65edcbe
1 changed files with 39 additions and 2 deletions
41
src/cache.rs
41
src/cache.rs
|
|
@ -13,6 +13,14 @@ where
|
||||||
fn key(&self) -> K;
|
fn key(&self) -> K;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Initable<T, K>
|
||||||
|
where
|
||||||
|
T: Cachable<K>,
|
||||||
|
K: core::cmp::PartialEq,
|
||||||
|
{
|
||||||
|
fn init(key: K) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
struct CacheItem<K, T>
|
struct CacheItem<K, T>
|
||||||
where
|
where
|
||||||
T: Cachable<K>,
|
T: Cachable<K>,
|
||||||
|
|
@ -105,7 +113,7 @@ where
|
||||||
K: core::cmp::PartialEq + core::fmt::Display,
|
K: core::cmp::PartialEq + core::fmt::Display,
|
||||||
{
|
{
|
||||||
/// Creates a new cache with a certain item lifetime
|
/// Creates a new cache with a certain item lifetime
|
||||||
pub fn new(lifetime: chrono::Duration) -> Self {
|
pub const fn new(lifetime: chrono::Duration) -> Self {
|
||||||
Self {
|
Self {
|
||||||
lifetime,
|
lifetime,
|
||||||
items: alloc::vec![],
|
items: alloc::vec![],
|
||||||
|
|
@ -120,6 +128,13 @@ where
|
||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determines the index of a certain key
|
||||||
|
fn find(&mut self, key: &K) -> Option<usize> {
|
||||||
|
self.items
|
||||||
|
.iter()
|
||||||
|
.position(|i| i.data.borrow().key() == *key)
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieves all known keys
|
/// Retrieves all known keys
|
||||||
pub fn keys(&self) -> Vec<K> {
|
pub fn keys(&self) -> Vec<K> {
|
||||||
self.items.iter().map(|i| i.data.borrow().key()).collect()
|
self.items.iter().map(|i| i.data.borrow().key()).collect()
|
||||||
|
|
@ -194,7 +209,7 @@ where
|
||||||
K: core::fmt::Display,
|
K: core::fmt::Display,
|
||||||
{
|
{
|
||||||
// find item
|
// find item
|
||||||
let Some(pos) = self.items.iter().position(|i| i.data.borrow().key() == key) else {
|
let Some(pos) = self.find(&key) else {
|
||||||
return Err(CacheError::KeyNotFound(key));
|
return Err(CacheError::KeyNotFound(key));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -209,6 +224,28 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates an item in the cache using the provided function or create a new item with default values
|
||||||
|
pub fn update_or_init<F>(&mut self, time_now: chrono::NaiveDateTime, key: K, mut func: F)
|
||||||
|
where
|
||||||
|
F: FnMut(&mut T),
|
||||||
|
K: core::fmt::Display,
|
||||||
|
T: Initable<T, K>,
|
||||||
|
{
|
||||||
|
if let Some(pos) = self.find(&key) {
|
||||||
|
// update existsting item
|
||||||
|
// unwrap is fine since we fetched the position before
|
||||||
|
let item = self.items.get_mut(pos).unwrap();
|
||||||
|
|
||||||
|
let mut data = item.data.borrow_mut();
|
||||||
|
func(&mut data);
|
||||||
|
|
||||||
|
item.timestamp = time_now;
|
||||||
|
} else {
|
||||||
|
// insert new item
|
||||||
|
self.items.push(CacheItem::new(time_now, T::init(key)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Cleans items which timed out from the cache
|
/// Cleans items which timed out from the cache
|
||||||
///
|
///
|
||||||
/// Call this regularly to prune old items.
|
/// Call this regularly to prune old items.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue