safecoin_client/
rpc_cache.rs

1use {
2    crate::{rpc_config::RpcLargestAccountsFilter, rpc_response::RpcAccountBalance},
3    std::{
4        collections::HashMap,
5        time::{Duration, SystemTime},
6    },
7};
8
9#[derive(Debug, Clone)]
10pub struct LargestAccountsCache {
11    duration: u64,
12    cache: HashMap<Option<RpcLargestAccountsFilter>, LargestAccountsCacheValue>,
13}
14
15#[derive(Debug, Clone)]
16struct LargestAccountsCacheValue {
17    accounts: Vec<RpcAccountBalance>,
18    slot: u64,
19    cached_time: SystemTime,
20}
21
22impl LargestAccountsCache {
23    pub fn new(duration: u64) -> Self {
24        Self {
25            duration,
26            cache: HashMap::new(),
27        }
28    }
29
30    pub fn get_largest_accounts(
31        &self,
32        filter: &Option<RpcLargestAccountsFilter>,
33    ) -> Option<(u64, Vec<RpcAccountBalance>)> {
34        self.cache.get(filter).and_then(|value| {
35            if let Ok(elapsed) = value.cached_time.elapsed() {
36                if elapsed < Duration::from_secs(self.duration) {
37                    return Some((value.slot, value.accounts.clone()));
38                }
39            }
40            None
41        })
42    }
43
44    pub fn set_largest_accounts(
45        &mut self,
46        filter: &Option<RpcLargestAccountsFilter>,
47        slot: u64,
48        accounts: &[RpcAccountBalance],
49    ) {
50        self.cache.insert(
51            filter.clone(),
52            LargestAccountsCacheValue {
53                accounts: accounts.to_owned(),
54                slot,
55                cached_time: SystemTime::now(),
56            },
57        );
58    }
59}
60
61#[cfg(test)]
62pub mod test {
63    use super::*;
64
65    #[test]
66    fn test_old_entries_expire() {
67        let mut cache = LargestAccountsCache::new(1);
68
69        let filter = Some(RpcLargestAccountsFilter::Circulating);
70
71        let accounts: Vec<RpcAccountBalance> = Vec::new();
72
73        cache.set_largest_accounts(&filter, 1000, &accounts);
74        std::thread::sleep(Duration::from_secs(1));
75        assert_eq!(cache.get_largest_accounts(&filter), None);
76    }
77}