1use std::collections::HashMap;
2use std::path::PathBuf;
3use std::sync::Arc;
4use std::time::{Duration, SystemTime};
5use tokio::sync::RwLock;
6
7pub use ck_index::IndexStats;
15
16#[derive(Clone)]
17pub struct StatsCache {
18 stats: Arc<RwLock<HashMap<PathBuf, (IndexStats, SystemTime)>>>,
19 ttl: Duration,
20}
21
22impl StatsCache {
23 pub fn new(ttl: Duration) -> Self {
24 Self {
25 stats: Arc::new(RwLock::new(HashMap::new())),
26 ttl,
27 }
28 }
29
30 pub async fn get(&self, path: &PathBuf) -> Option<IndexStats> {
31 let stats = self.stats.read().await;
32 if let Some((stats, cached_at)) = stats.get(path)
33 && cached_at.elapsed().unwrap_or_default() < self.ttl
34 {
35 return Some(stats.clone());
36 }
37 None
38 }
39
40 pub async fn update(&self, path: PathBuf, stats: IndexStats) {
41 let mut cache = self.stats.write().await;
42 cache.insert(path, (stats, SystemTime::now()));
43 }
44
45 pub async fn invalidate(&self, path: &PathBuf) {
46 let mut cache = self.stats.write().await;
47 cache.remove(path);
48 }
49}
50
51impl Default for StatsCache {
52 fn default() -> Self {
54 Self::new(Duration::from_secs(30))
55 }
56}