things3_core/cache/config.rs
1use crate::models::ThingsId;
2use serde::{Deserialize, Serialize};
3use std::time::Duration;
4
5/// Cache invalidation strategy
6#[non_exhaustive]
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum InvalidationStrategy {
9 /// Time-based invalidation (TTL)
10 TimeBased,
11 /// Event-based invalidation (manual triggers)
12 EventBased,
13 /// Dependency-based invalidation (related data changes)
14 DependencyBased,
15 /// Hybrid approach combining multiple strategies
16 Hybrid,
17}
18
19/// Cache dependency tracking for intelligent invalidation
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct CacheDependency {
22 /// The entity type this cache entry depends on
23 pub entity_type: String,
24 /// The specific entity ID this cache entry depends on
25 pub entity_id: Option<ThingsId>,
26 /// The operation that would invalidate this cache entry
27 pub invalidating_operations: Vec<String>,
28}
29
30impl CacheDependency {
31 /// Test whether this dependency matches a mutation on `(entity_type, entity_id)`.
32 ///
33 /// `entity_id == None` on either side acts as a wildcard: a dependency with
34 /// no specific id matches any concrete mutation of the same type, and a
35 /// caller passing `None` matches every dependency of that type.
36 #[must_use]
37 pub fn matches(&self, entity_type: &str, entity_id: Option<&ThingsId>) -> bool {
38 if self.entity_type != entity_type {
39 return false;
40 }
41 match (&self.entity_id, entity_id) {
42 (Some(dep_id), Some(req_id)) => dep_id == req_id,
43 _ => true,
44 }
45 }
46
47 /// Test whether this dependency lists `operation` as one of its invalidators.
48 #[must_use]
49 pub fn matches_operation(&self, operation: &str) -> bool {
50 self.invalidating_operations
51 .iter()
52 .any(|op| op == operation)
53 }
54}
55
56/// Enhanced cache configuration with intelligent invalidation
57#[derive(Debug, Clone)]
58pub struct CacheConfig {
59 /// Maximum number of entries in the cache
60 pub max_capacity: u64,
61 /// Time to live for cache entries
62 pub ttl: Duration,
63 /// Time to idle for cache entries
64 pub tti: Duration,
65 /// Invalidation strategy to use
66 pub invalidation_strategy: InvalidationStrategy,
67 /// Enable cache warming for frequently accessed data
68 pub enable_cache_warming: bool,
69 /// Cache warming interval
70 pub warming_interval: Duration,
71 /// Maximum cache warming entries
72 pub max_warming_entries: usize,
73}
74
75impl Default for CacheConfig {
76 fn default() -> Self {
77 Self {
78 max_capacity: 1000,
79 ttl: Duration::from_secs(300), // 5 minutes
80 tti: Duration::from_secs(60), // 1 minute
81 invalidation_strategy: InvalidationStrategy::Hybrid,
82 enable_cache_warming: true,
83 warming_interval: Duration::from_secs(60), // 1 minute
84 max_warming_entries: 50,
85 }
86 }
87}