lean_ctx/server/
reference_store.rs1use std::collections::HashMap;
2use std::sync::{Mutex, OnceLock};
3use std::time::{Duration, Instant, SystemTime};
4
5struct RefEntry {
6 content: String,
7 created_at: Instant,
8 access_count: u32,
9}
10
11const MAX_ENTRIES: usize = 200;
12const TTL: Duration = Duration::from_mins(5);
13
14fn store_lock() -> &'static Mutex<HashMap<String, RefEntry>> {
15 static STORE: OnceLock<Mutex<HashMap<String, RefEntry>>> = OnceLock::new();
16 STORE.get_or_init(|| Mutex::new(HashMap::new()))
17}
18
19pub fn store(content: String) -> String {
20 let id = format!("ref_{}", generate_id());
21 let mut map = store_lock()
22 .lock()
23 .unwrap_or_else(std::sync::PoisonError::into_inner);
24
25 map.retain(|_, v| v.created_at.elapsed() < TTL);
26
27 while map.len() >= MAX_ENTRIES {
28 if let Some(oldest_key) = map
29 .iter()
30 .min_by_key(|(_, v)| v.created_at)
31 .map(|(k, _)| k.clone())
32 {
33 map.remove(&oldest_key);
34 } else {
35 break;
36 }
37 }
38
39 map.insert(
40 id.clone(),
41 RefEntry {
42 content,
43 created_at: Instant::now(),
44 access_count: 0,
45 },
46 );
47
48 id
49}
50
51pub fn resolve(id: &str) -> Option<String> {
52 let mut map = store_lock()
53 .lock()
54 .unwrap_or_else(std::sync::PoisonError::into_inner);
55 if let Some(entry) = map.get_mut(id) {
56 if entry.created_at.elapsed() < TTL {
57 entry.access_count += 1;
58 return Some(entry.content.clone());
59 }
60 map.remove(id);
61 }
62 None
63}
64
65pub fn stats() -> (usize, usize) {
66 let map = store_lock()
67 .lock()
68 .unwrap_or_else(std::sync::PoisonError::into_inner);
69 let total = map.len();
70 let total_bytes: usize = map.values().map(|v| v.content.len()).sum();
71 (total, total_bytes)
72}
73
74fn generate_id() -> String {
75 let ts = SystemTime::now()
76 .duration_since(SystemTime::UNIX_EPOCH)
77 .unwrap_or_default()
78 .as_nanos();
79 format!("{ts:x}")
80}