1*013ffb70SLoGin #![no_std] 2*013ffb70SLoGin #![feature(core_intrinsics)] 3*013ffb70SLoGin #![allow(internal_features)] 4*013ffb70SLoGin #![allow(clippy::needless_return)] 5*013ffb70SLoGin 6*013ffb70SLoGin #[cfg(test)] 7*013ffb70SLoGin #[macro_use] 8*013ffb70SLoGin extern crate std; 9*013ffb70SLoGin 10*013ffb70SLoGin use core::cmp::min; 11*013ffb70SLoGin use core::intrinsics::unlikely; 12*013ffb70SLoGin use core::marker::PhantomData; 13*013ffb70SLoGin use core::ops::Deref; 14*013ffb70SLoGin 15*013ffb70SLoGin struct EmptyIdaItemRef<'a> { 16*013ffb70SLoGin _marker: PhantomData<&'a EmptyIdaItem>, 17*013ffb70SLoGin } 18*013ffb70SLoGin 19*013ffb70SLoGin impl<'a> Deref for EmptyIdaItemRef<'a> { 20*013ffb70SLoGin type Target = EmptyIdaItem; 21*013ffb70SLoGin 22*013ffb70SLoGin fn deref(&self) -> &Self::Target { 23*013ffb70SLoGin &EmptyIdaItem 24*013ffb70SLoGin } 25*013ffb70SLoGin } 26*013ffb70SLoGin 27*013ffb70SLoGin struct EmptyIdaItem; 28*013ffb70SLoGin 29*013ffb70SLoGin unsafe impl kdepends::xarray::ItemEntry for EmptyIdaItem { 30*013ffb70SLoGin type Ref<'a> = EmptyIdaItemRef<'a> where Self: 'a; 31*013ffb70SLoGin 32*013ffb70SLoGin fn into_raw(self) -> *const () { 33*013ffb70SLoGin core::ptr::null() 34*013ffb70SLoGin } 35*013ffb70SLoGin 36*013ffb70SLoGin unsafe fn from_raw(_raw: *const ()) -> Self { 37*013ffb70SLoGin EmptyIdaItem 38*013ffb70SLoGin } 39*013ffb70SLoGin 40*013ffb70SLoGin unsafe fn raw_as_ref<'a>(_raw: *const ()) -> Self::Ref<'a> { 41*013ffb70SLoGin EmptyIdaItemRef { 42*013ffb70SLoGin _marker: PhantomData, 43*013ffb70SLoGin } 44*013ffb70SLoGin } 45*013ffb70SLoGin } 46*013ffb70SLoGin /// id分配器 47*013ffb70SLoGin pub struct IdAllocator { 48*013ffb70SLoGin current_id: usize, 49*013ffb70SLoGin min_id: usize, 50*013ffb70SLoGin max_id: usize, 51*013ffb70SLoGin used: usize, 52*013ffb70SLoGin xarray: kdepends::xarray::XArray<EmptyIdaItem>, 53*013ffb70SLoGin } 54*013ffb70SLoGin 55*013ffb70SLoGin impl IdAllocator { 56*013ffb70SLoGin /// 创建一个新的id分配器 57*013ffb70SLoGin pub const fn new(initial_id: usize, max_id: usize) -> Option<Self> { 58*013ffb70SLoGin if initial_id >= max_id { 59*013ffb70SLoGin return None; 60*013ffb70SLoGin } 61*013ffb70SLoGin Some(Self { 62*013ffb70SLoGin current_id: initial_id, 63*013ffb70SLoGin min_id: initial_id, 64*013ffb70SLoGin max_id, 65*013ffb70SLoGin used: 0, 66*013ffb70SLoGin xarray: kdepends::xarray::XArray::new(), 67*013ffb70SLoGin }) 68*013ffb70SLoGin } 69*013ffb70SLoGin 70*013ffb70SLoGin /// 可用的id数量 71*013ffb70SLoGin #[inline] 72*013ffb70SLoGin pub fn available(&self) -> usize { 73*013ffb70SLoGin self.max_id - self.min_id - self.used 74*013ffb70SLoGin } 75*013ffb70SLoGin 76*013ffb70SLoGin /// 分配一个新的id 77*013ffb70SLoGin /// 78*013ffb70SLoGin /// ## 返回 79*013ffb70SLoGin /// 80*013ffb70SLoGin /// 如果分配成功,返回Some(id),否则返回None 81*013ffb70SLoGin pub fn alloc(&mut self) -> Option<usize> { 82*013ffb70SLoGin if unlikely(self.available() == 0) { 83*013ffb70SLoGin return None; 84*013ffb70SLoGin } 85*013ffb70SLoGin 86*013ffb70SLoGin if let Some(try1) = self.do_find_first_free_index(self.current_id, self.max_id) { 87*013ffb70SLoGin self.current_id = try1; 88*013ffb70SLoGin self.xarray.store(try1 as u64, EmptyIdaItem); 89*013ffb70SLoGin self.used += 1; 90*013ffb70SLoGin return Some(try1); 91*013ffb70SLoGin } 92*013ffb70SLoGin 93*013ffb70SLoGin // 从头开始找 94*013ffb70SLoGin if let Some(try2) = 95*013ffb70SLoGin self.do_find_first_free_index(self.min_id, min(self.current_id, self.max_id)) 96*013ffb70SLoGin { 97*013ffb70SLoGin self.current_id = try2; 98*013ffb70SLoGin self.xarray.store(try2 as u64, EmptyIdaItem); 99*013ffb70SLoGin self.used += 1; 100*013ffb70SLoGin return Some(try2); 101*013ffb70SLoGin } 102*013ffb70SLoGin return None; 103*013ffb70SLoGin } 104*013ffb70SLoGin 105*013ffb70SLoGin /// 检查id是否存在 106*013ffb70SLoGin /// 107*013ffb70SLoGin /// ## 参数 108*013ffb70SLoGin /// 109*013ffb70SLoGin /// - `id`:要检查的id 110*013ffb70SLoGin /// 111*013ffb70SLoGin /// ## 返回 112*013ffb70SLoGin /// 113*013ffb70SLoGin /// 如果id存在,返回true,否则返回false 114*013ffb70SLoGin pub fn exists(&self, id: usize) -> bool { 115*013ffb70SLoGin if id < self.min_id || id >= self.max_id { 116*013ffb70SLoGin return false; 117*013ffb70SLoGin } 118*013ffb70SLoGin self.xarray.load(id as u64).is_some() 119*013ffb70SLoGin } 120*013ffb70SLoGin 121*013ffb70SLoGin fn do_find_first_free_index(&self, start_id: usize, end: usize) -> Option<usize> { 122*013ffb70SLoGin (start_id..end).find(|&i| !self.exists(i)) 123*013ffb70SLoGin } 124*013ffb70SLoGin 125*013ffb70SLoGin /// 释放一个id 126*013ffb70SLoGin /// 127*013ffb70SLoGin /// ## 参数 128*013ffb70SLoGin /// 129*013ffb70SLoGin /// - `id`:要释放的id 130*013ffb70SLoGin pub fn free(&mut self, id: usize) { 131*013ffb70SLoGin if id < self.min_id || id >= self.max_id { 132*013ffb70SLoGin return; 133*013ffb70SLoGin } 134*013ffb70SLoGin if self.xarray.remove(id as u64).is_some() { 135*013ffb70SLoGin self.used -= 1; 136*013ffb70SLoGin } 137*013ffb70SLoGin } 138*013ffb70SLoGin 139*013ffb70SLoGin /// 返回已经使用的id数量 140*013ffb70SLoGin pub fn used(&self) -> usize { 141*013ffb70SLoGin self.used 142*013ffb70SLoGin } 143*013ffb70SLoGin } 144*013ffb70SLoGin 145*013ffb70SLoGin impl core::fmt::Debug for IdAllocator { 146*013ffb70SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 147*013ffb70SLoGin f.debug_struct("IdAllocator") 148*013ffb70SLoGin .field("current_id", &self.current_id) 149*013ffb70SLoGin .field("min_id", &self.min_id) 150*013ffb70SLoGin .field("max_id", &self.max_id) 151*013ffb70SLoGin .field("used", &self.used) 152*013ffb70SLoGin .field("xarray", &"xarray<()>") 153*013ffb70SLoGin .finish() 154*013ffb70SLoGin } 155*013ffb70SLoGin } 156*013ffb70SLoGin 157*013ffb70SLoGin #[cfg(test)] 158*013ffb70SLoGin mod tests { 159*013ffb70SLoGin use super::*; 160*013ffb70SLoGin #[test] 161*013ffb70SLoGin fn test_new_fail() { 162*013ffb70SLoGin assert_eq!(IdAllocator::new(10, 10).is_none(), true); 163*013ffb70SLoGin assert_eq!(IdAllocator::new(11, 10).is_none(), true); 164*013ffb70SLoGin } 165*013ffb70SLoGin #[test] 166*013ffb70SLoGin fn test_new_success() { 167*013ffb70SLoGin assert_eq!(IdAllocator::new(9, 10).is_some(), true); 168*013ffb70SLoGin assert_eq!(IdAllocator::new(0, 10).is_some(), true); 169*013ffb70SLoGin } 170*013ffb70SLoGin 171*013ffb70SLoGin #[test] 172*013ffb70SLoGin fn test_id_allocator() { 173*013ffb70SLoGin let mut ida = IdAllocator::new(0, 10).unwrap(); 174*013ffb70SLoGin assert_eq!(ida.alloc(), Some(0)); 175*013ffb70SLoGin assert_eq!(ida.alloc(), Some(1)); 176*013ffb70SLoGin assert_eq!(ida.alloc(), Some(2)); 177*013ffb70SLoGin assert_eq!(ida.alloc(), Some(3)); 178*013ffb70SLoGin assert_eq!(ida.alloc(), Some(4)); 179*013ffb70SLoGin assert_eq!(ida.alloc(), Some(5)); 180*013ffb70SLoGin assert_eq!(ida.alloc(), Some(6)); 181*013ffb70SLoGin assert_eq!(ida.alloc(), Some(7)); 182*013ffb70SLoGin assert_eq!(ida.alloc(), Some(8)); 183*013ffb70SLoGin assert_eq!(ida.alloc(), Some(9)); 184*013ffb70SLoGin assert_eq!(ida.alloc(), None); 185*013ffb70SLoGin 186*013ffb70SLoGin for i in 0..10 { 187*013ffb70SLoGin assert_eq!(ida.exists(i), true); 188*013ffb70SLoGin } 189*013ffb70SLoGin 190*013ffb70SLoGin ida.free(5); 191*013ffb70SLoGin 192*013ffb70SLoGin for i in 0..10 { 193*013ffb70SLoGin if i == 5 { 194*013ffb70SLoGin assert_eq!(ida.exists(i), false); 195*013ffb70SLoGin } else { 196*013ffb70SLoGin assert_eq!(ida.exists(i), true); 197*013ffb70SLoGin } 198*013ffb70SLoGin } 199*013ffb70SLoGin assert_eq!(ida.used(), 9); 200*013ffb70SLoGin assert_eq!(ida.alloc(), Some(5)); 201*013ffb70SLoGin assert_eq!(ida.alloc(), None); 202*013ffb70SLoGin 203*013ffb70SLoGin assert_eq!(ida.used(), 10); 204*013ffb70SLoGin for i in 0..10 { 205*013ffb70SLoGin ida.free(i); 206*013ffb70SLoGin } 207*013ffb70SLoGin 208*013ffb70SLoGin assert_eq!(ida.used(), 0); 209*013ffb70SLoGin } 210*013ffb70SLoGin } 211