use std::sync::atomic::{AtomicUsize, Ordering};
use rustc_hash::FxHashMap;
use parking_lot::{MappedRwLockReadGuard, Mutex, RwLock, RwLockReadGuard};
static ACCELERATORS: RwLock<(usize, Vec<Accelerator>)> = RwLock::new((0, Vec::new()));
static ID: AtomicUsize = AtomicUsize::new(0);
type Accelerator = Mutex<FxHashMap<u128, u128>>;
pub fn id() -> usize {
ID.fetch_add(1, Ordering::SeqCst)
}
pub fn evict() {
let mut accelerators = ACCELERATORS.write();
let (offset, vec) = &mut *accelerators;
*offset = ID.load(Ordering::SeqCst);
vec.iter_mut().for_each(|accelerator| accelerator.lock().clear())
}
pub fn get(id: usize) -> Option<MappedRwLockReadGuard<'static, Accelerator>> {
let mut accelerators = ACCELERATORS.read();
let mut i = id.checked_sub(accelerators.0)?;
if i >= accelerators.1.len() {
drop(accelerators);
resize(i + 1);
accelerators = ACCELERATORS.read();
i = id.checked_sub(accelerators.0)?;
}
Some(RwLockReadGuard::map(accelerators, move |(_, vec)| &vec[i]))
}
#[cold]
fn resize(len: usize) {
let mut pair = ACCELERATORS.write();
if len > pair.1.len() {
pair.1.resize_with(len, || Mutex::new(FxHashMap::default()));
}
}