safecoin_client/
rpc_cache.rs1use {
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}