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