use crate::{scanner_mode::ScannerMode, Result};
use rustc_hash::FxHashMap;
use std::sync::Arc;
use super::ScannerImpl;
pub(crate) struct ScannerCache {
cache: FxHashMap<Vec<ScannerMode>, Arc<ScannerImpl>>,
}
impl ScannerCache {
pub(crate) fn new() -> Self {
Self {
cache: FxHashMap::default(),
}
}
pub(crate) fn get(&mut self, modes: &[ScannerMode]) -> Result<ScannerImpl> {
if let Some(scanner) = self.cache.get(modes) {
let cloned_scanner =
unsafe { (*std::sync::Arc::<ScannerImpl>::as_ptr(scanner)).clone() };
Ok(cloned_scanner)
} else {
self.cache
.insert(modes.to_vec(), Arc::new(modes.try_into()?));
Ok(self.get(modes).unwrap())
}
}
}
pub(crate) static SCANNER_CACHE: std::sync::LazyLock<std::sync::RwLock<ScannerCache>> =
std::sync::LazyLock::new(|| std::sync::RwLock::new(ScannerCache::new()));