0
0
Fork 0

cache: Add method to update or initialize items

This commit is contained in:
Jannik Beyerstedt 2026-06-20 22:38:39 +02:00
commit 3ae65edcbe

View file

@ -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.