use moka::sync::Cache;
use std::net::IpAddr;
use std::time::Duration;
use super::config::CrawlerConfig;
use super::detector::CrawlerVerificationResult;
#[derive(Debug)]
pub struct VerificationCache {
verification_cache: Cache<String, CrawlerVerificationResult>,
dns_cache: Cache<IpAddr, Option<String>>,
}
impl VerificationCache {
pub fn new(config: &CrawlerConfig) -> Self {
let verification_cache = Cache::builder()
.max_capacity(config.max_cache_entries)
.time_to_live(Duration::from_secs(config.verification_cache_ttl_secs))
.build();
let dns_cache = Cache::builder()
.max_capacity(config.max_cache_entries)
.time_to_live(Duration::from_secs(config.dns_cache_ttl_secs))
.build();
Self {
verification_cache,
dns_cache,
}
}
pub fn cache_key(user_agent: &str, ip: IpAddr) -> String {
use std::hash::{Hash, Hasher};
let mut hasher = std::collections::hash_map::DefaultHasher::new();
user_agent.hash(&mut hasher);
ip.hash(&mut hasher);
format!("{:x}", hasher.finish())
}
pub fn get_verification(&self, key: &str) -> Option<CrawlerVerificationResult> {
self.verification_cache.get(key)
}
pub fn put_verification(&self, key: String, result: CrawlerVerificationResult) {
self.verification_cache.insert(key, result);
}
pub fn get_dns(&self, ip: IpAddr) -> Option<Option<String>> {
self.dns_cache.get(&ip)
}
pub fn put_dns(&self, ip: IpAddr, hostname: Option<String>) {
self.dns_cache.insert(ip, hostname);
}
pub fn stats(&self) -> CacheStats {
CacheStats {
verification_entries: self.verification_cache.entry_count() as usize,
dns_entries: self.dns_cache.entry_count() as usize,
}
}
}
#[derive(Debug, Clone)]
pub struct CacheStats {
pub verification_entries: usize,
pub dns_entries: usize,
}