use std::{collections::{HashMap, HashSet}, sync::{OnceLock}, time::{SystemTime, UNIX_EPOCH}}; use dashmap::{DashMap}; use tracing::debug; type IdentityID = u32; type Port = u16; type Proto = u8; #[derive(Debug)] pub struct RuleInfo { pub proto: Proto, pub port: Port, } static RULE_CACHE: OnceLock>)>> = OnceLock::new(); // static RULE_CACHE: OnceLock>>> = OnceLock::new(); pub fn set_identity_cache(identity: IdentityID, infos: Vec) { debug!("setting identity cache for identity={}, infos: {:?}", identity, infos); let cache = RULE_CACHE.get().expect("should set first"); let mut temp = HashMap::new(); let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); for info in &infos { let mut protomap = HashSet::new(); protomap.insert(info.proto); temp.insert(info.port, protomap); } cache.remove(&identity); cache.insert(identity, (now, temp)); } // result.1 is should renew pub fn is_identity_ok(identity: IdentityID, proto: Proto, port: Port) -> (Option, bool) { let cache = RULE_CACHE.get().expect("should set first"); let mut should_renew = false; let result: Option; match cache.get(&identity) { Some(data) => { let tm = data.0; let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); if tm + 10 < now { should_renew = true; } if let Some(proto_info) = data.1.get(&port) { if let Some(_has) = proto_info.get(&proto) { result = Some(true); // return Some(true); } else { result = Some(false); } } else { result = Some(false); } } None => { result = None; } } return (result, should_renew); }