mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-04-29 11:35:24 -04:00
refactor(common): Remove TtlCache
It is now unused. Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
committed by
Ivan Enderlin
parent
53ffa347e4
commit
489d7195bb
@@ -48,6 +48,10 @@ All notable changes to this project will be documented in this file.
|
||||
([#6057](https://github.com/matrix-org/matrix-rust-sdk/pull/6057))
|
||||
- Fix `TimelineEvent::from_bundled_latest_event` sometimes removing the `session_id` of UTDs. This broken event could later be saved to the event cache and become an unresolvable UTD. ([#5970](https://github.com/matrix-org/matrix-rust-sdk/pull/5970)).
|
||||
|
||||
### Refactor
|
||||
|
||||
- [**breaking**] Remove `ttl_cache::TtlCache` because it is now unused.
|
||||
|
||||
## [0.16.0] - 2025-12-04
|
||||
|
||||
### Features
|
||||
|
||||
@@ -12,118 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! A TTL cache which can be used to time out repeated operations that might
|
||||
//! experience intermittent failures.
|
||||
//! Types to implement TTL caches which can be used to persist data for a fixed
|
||||
//! duration.
|
||||
|
||||
use std::{borrow::Borrow, collections::HashMap, hash::Hash, time::Duration};
|
||||
|
||||
use ruma::time::{Instant, SystemTime};
|
||||
use ruma::time::SystemTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// One day is the default lifetime.
|
||||
const DEFAULT_LIFETIME: Duration = Duration::from_secs(24 * 60 * 60);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct TtlItem<V: Clone> {
|
||||
value: V,
|
||||
insertion_time: Instant,
|
||||
lifetime: Duration,
|
||||
}
|
||||
|
||||
impl<V: Clone> TtlItem<V> {
|
||||
fn expired(&self) -> bool {
|
||||
self.insertion_time.elapsed() >= self.lifetime
|
||||
}
|
||||
}
|
||||
|
||||
/// A TTL cache where items get removed deterministically in the `get()` call.
|
||||
#[derive(Debug)]
|
||||
pub struct TtlCache<K: Eq + Hash, V: Clone> {
|
||||
lifetime: Duration,
|
||||
items: HashMap<K, TtlItem<V>>,
|
||||
}
|
||||
|
||||
impl<K, V> TtlCache<K, V>
|
||||
where
|
||||
K: Eq + Hash,
|
||||
V: Clone,
|
||||
{
|
||||
/// Create a new, empty, [`TtlCache`].
|
||||
pub fn new() -> Self {
|
||||
Self { items: Default::default(), lifetime: DEFAULT_LIFETIME }
|
||||
}
|
||||
|
||||
/// Does the cache contain an non-expired item with the matching key.
|
||||
pub fn contains<Q>(&self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let cache = &self.items;
|
||||
if let Some(item) = cache.get(key) { !item.expired() } else { false }
|
||||
}
|
||||
|
||||
/// Add a single item to the cache.
|
||||
pub fn insert(&mut self, key: K, value: V) {
|
||||
self.extend([(key, value)]);
|
||||
}
|
||||
|
||||
/// Extend the cache with the given iterator of items.
|
||||
pub fn extend(&mut self, iterator: impl IntoIterator<Item = (K, V)>) {
|
||||
let cache = &mut self.items;
|
||||
|
||||
let now = Instant::now();
|
||||
|
||||
for (key, value) in iterator {
|
||||
let item = TtlItem { value, insertion_time: now, lifetime: self.lifetime };
|
||||
|
||||
cache.insert(key, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the item that matches the given key.
|
||||
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
self.items.remove(key.borrow()).map(|item| item.value)
|
||||
}
|
||||
|
||||
/// Get the item that matches the given key, if the item has expired `None`
|
||||
/// will be returned and the item will be evicted from the cache.
|
||||
pub fn get<Q>(&mut self, key: &Q) -> Option<V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
// Remove all expired items.
|
||||
self.items.retain(|_, value| !value.expired());
|
||||
// Now get the wanted item.
|
||||
self.items.get(key.borrow()).map(|item| item.value.clone())
|
||||
}
|
||||
|
||||
/// Force the expiry of the given item, if it is present in the cache.
|
||||
///
|
||||
/// This doesn't remove the item, it just marks it as expired.
|
||||
#[doc(hidden)]
|
||||
pub fn expire<Q>(&mut self, key: &Q)
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
if let Some(item) = self.items.get_mut(key) {
|
||||
item.lifetime = Duration::from_secs(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash, V: Clone> Default for TtlCache<K, V> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// A value that expires after some time.
|
||||
///
|
||||
/// This value is (de)serializable so it can be persisted in a store.
|
||||
@@ -218,24 +112,7 @@ mod tests {
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
|
||||
use super::{TtlCache, TtlValue, now_timestamp_ms};
|
||||
|
||||
#[test]
|
||||
fn test_ttl_cache_insertion() {
|
||||
let mut cache = TtlCache::new();
|
||||
assert!(!cache.contains("A"));
|
||||
|
||||
cache.insert("A", 1);
|
||||
assert!(cache.contains("A"));
|
||||
|
||||
let value = cache.get("A").expect("The value should be in the cache");
|
||||
assert_eq!(value, 1);
|
||||
|
||||
cache.expire("A");
|
||||
|
||||
assert!(!cache.contains("A"));
|
||||
assert!(cache.get("A").is_none(), "The item should have been removed from the cache");
|
||||
}
|
||||
use super::{TtlValue, now_timestamp_ms};
|
||||
|
||||
#[test]
|
||||
fn test_ttl_value_expiry() {
|
||||
|
||||
Reference in New Issue
Block a user