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;
}
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.