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;
|
||||
}
|
||||
|
||||
pub trait Initable<T, K>
|
||||
where
|
||||
T: Cachable<K>,
|
||||
K: core::cmp::PartialEq,
|
||||
{
|
||||
fn init(key: K) -> T;
|
||||
}
|
||||
|
||||
struct CacheItem<K, T>
|
||||
where
|
||||
T: Cachable<K>,
|
||||
|
|
@ -105,7 +113,7 @@ where
|
|||
K: core::cmp::PartialEq + core::fmt::Display,
|
||||
{
|
||||
/// 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 {
|
||||
lifetime,
|
||||
items: alloc::vec![],
|
||||
|
|
@ -120,6 +128,13 @@ where
|
|||
.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
|
||||
pub fn keys(&self) -> Vec<K> {
|
||||
self.items.iter().map(|i| i.data.borrow().key()).collect()
|
||||
|
|
@ -194,7 +209,7 @@ where
|
|||
K: core::fmt::Display,
|
||||
{
|
||||
// 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));
|
||||
};
|
||||
|
||||
|
|
@ -209,6 +224,28 @@ where
|
|||
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
|
||||
///
|
||||
/// Call this regularly to prune old items.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue