use { crate::{rpc_config::RpcLargestAccountsFilter, rpc_response::RpcAccountBalance}, std::{ collections::HashMap, time::{Duration, SystemTime}, }, }; #[derive(Debug, Clone)] pub struct LargestAccountsCache { duration: u64, cache: HashMap, LargestAccountsCacheValue>, } #[derive(Debug, Clone)] struct LargestAccountsCacheValue { accounts: Vec, 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, ) -> Option<(u64, Vec)> { 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, 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 = Vec::new(); cache.set_largest_accounts(&filter, 1000, &accounts); std::thread::sleep(Duration::from_secs(1)); assert_eq!(cache.get_largest_accounts(&filter), None); } }