vtcode_core/code/code_completion/cache/
mod.rs1use super::engine::CompletionSuggestion;
2use std::collections::HashMap;
3use std::time::{Duration, Instant};
4
5pub struct CompletionCache {
7 cache: HashMap<String, CacheEntry>,
8 max_entries: usize,
9 ttl: Duration,
10}
11
12#[derive(Debug, Clone)]
13struct CacheEntry {
14 suggestions: Vec<CompletionSuggestion>,
15 created_at: Instant,
16 access_count: usize,
17}
18
19impl CompletionCache {
20 pub fn new() -> Self {
21 Self {
22 cache: HashMap::new(),
23 max_entries: 1000,
24 ttl: Duration::from_secs(300), }
26 }
27
28 pub fn get(&mut self, context_key: &str) -> Option<Vec<CompletionSuggestion>> {
30 if let Some(entry) = self.cache.get_mut(context_key) {
31 if entry.created_at.elapsed() < self.ttl {
32 entry.access_count += 1;
33 return Some(entry.suggestions.clone());
34 } else {
35 self.cache.remove(context_key);
36 }
37 }
38 None
39 }
40
41 pub fn put(&mut self, context_key: String, suggestions: Vec<CompletionSuggestion>) {
43 self.cleanup_expired();
45
46 if self.cache.len() >= self.max_entries {
48 self.evict_lru();
49 }
50
51 let entry = CacheEntry {
52 suggestions,
53 created_at: Instant::now(),
54 access_count: 1,
55 };
56
57 self.cache.insert(context_key, entry);
58 }
59
60 fn cleanup_expired(&mut self) {
61 let now = Instant::now();
62 self.cache
63 .retain(|_, entry| now.duration_since(entry.created_at) < self.ttl);
64 }
65
66 fn evict_lru(&mut self) {
67 if let Some(lru_key) = self
68 .cache
69 .iter()
70 .min_by_key(|(_, entry)| entry.access_count)
71 .map(|(key, _)| key.clone())
72 {
73 self.cache.remove(&lru_key);
74 }
75 }
76}
77
78impl Default for CompletionCache {
79 fn default() -> Self {
80 Self::new()
81 }
82}