forge_lint/sol/analysis/
helper_cache.rs1use std::{
2 collections::{HashMap, HashSet, VecDeque},
3 hash::Hash,
4};
5
6pub const DEFAULT_HELPER_ANALYSIS_CACHE_LIMIT: usize = 65_536;
7
8#[derive(Debug)]
10pub struct HelperAnalysisCache<K, V> {
11 entries: HashMap<K, V>,
12 in_progress: HashSet<K>,
13 order: VecDeque<K>,
14 max_entries: usize,
15}
16
17impl<K, V> HelperAnalysisCache<K, V>
18where
19 K: Clone + Eq + Hash,
20{
21 pub fn new(max_entries: usize) -> Self {
22 Self {
23 entries: HashMap::new(),
24 in_progress: HashSet::new(),
25 order: VecDeque::new(),
26 max_entries,
27 }
28 }
29
30 pub fn is_in_progress(&self, key: &K) -> bool {
31 self.in_progress.contains(key)
32 }
33
34 pub fn get(&self, key: &K) -> Option<&V> {
35 self.entries.get(key)
36 }
37
38 pub fn start(&mut self, key: K) {
39 self.in_progress.insert(key);
40 }
41
42 pub fn finish(&mut self, key: K, value: V) {
43 self.in_progress.remove(&key);
44 if self.max_entries == 0 {
45 return;
46 }
47
48 if !self.entries.contains_key(&key) {
49 self.order.push_back(key.clone());
50 }
51 self.entries.insert(key, value);
52
53 while self.entries.len() > self.max_entries {
54 if let Some(oldest) = self.order.pop_front() {
55 self.entries.remove(&oldest);
56 self.in_progress.remove(&oldest);
57 } else {
58 break;
59 }
60 }
61 }
62}