#[cfg(test)] mod tests; use { crate::ptr_ext::MutPtrExt, std::{ array, cell::UnsafeCell, fmt::{Debug, Formatter}, marker::PhantomData, }, }; type Seg = usize; const SEG_SIZE: usize = size_of::() * 8; pub struct FreeList { levels: UnsafeCell<[Vec; N]>, _phantom: PhantomData, } impl Default for FreeList { fn default() -> Self { Self { levels: UnsafeCell::new(array::from_fn(|_| Vec::new())), _phantom: Default::default(), } } } impl Debug for FreeList { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("FreeList") .field("levels", self.get()) .finish() } } impl FreeList { fn get(&self) -> &mut [Vec; N] { unsafe { self.levels.get().deref_mut() } } pub fn release(&self, n: T) where T: Into, { let mut ext = n.into() as usize; let mut int; let levels = self.get(); assert!(ext / SEG_SIZE < levels[0].len()); for level in self.get() { int = ext % SEG_SIZE; ext /= SEG_SIZE; unsafe { *level.get_unchecked_mut(ext) |= 1 << int; } } } pub fn acquire(&self) -> T where u32: Into, { let mut ext = 'last: { let level = &mut self.get()[N - 1]; for (idx, &seg) in level.iter().enumerate() { if seg != 0 { break 'last idx; } } level.len() }; for level in self.get().iter_mut().rev() { if ext == level.len() { level.push(!0); } let seg = unsafe { level.get_unchecked(ext) }; ext = SEG_SIZE * ext + seg.trailing_zeros() as usize; } let id = ext as u32; for level in self.get().iter_mut() { let int = ext % SEG_SIZE; ext /= SEG_SIZE; let seg = unsafe { level.get_unchecked_mut(ext) }; *seg &= !(1 << int); if *seg != 0 { break; } } id.into() } }