1013ffb70SLoGin #![no_std] 2013ffb70SLoGin #![feature(core_intrinsics)] 3013ffb70SLoGin #![allow(internal_features)] 4013ffb70SLoGin #![allow(clippy::needless_return)] 5013ffb70SLoGin 6013ffb70SLoGin #[cfg(test)] 7013ffb70SLoGin #[macro_use] 8013ffb70SLoGin extern crate std; 9013ffb70SLoGin 10013ffb70SLoGin use core::cmp::min; 11013ffb70SLoGin use core::intrinsics::unlikely; 12013ffb70SLoGin use core::marker::PhantomData; 13013ffb70SLoGin use core::ops::Deref; 14013ffb70SLoGin 15013ffb70SLoGin struct EmptyIdaItemRef<'a> { 16013ffb70SLoGin _marker: PhantomData<&'a EmptyIdaItem>, 17013ffb70SLoGin } 18013ffb70SLoGin 19013ffb70SLoGin impl<'a> Deref for EmptyIdaItemRef<'a> { 20013ffb70SLoGin type Target = EmptyIdaItem; 21013ffb70SLoGin 22013ffb70SLoGin fn deref(&self) -> &Self::Target { 23013ffb70SLoGin &EmptyIdaItem 24013ffb70SLoGin } 25013ffb70SLoGin } 26013ffb70SLoGin 27013ffb70SLoGin struct EmptyIdaItem; 28013ffb70SLoGin 29013ffb70SLoGin unsafe impl kdepends::xarray::ItemEntry for EmptyIdaItem { 30013ffb70SLoGin type Ref<'a> = EmptyIdaItemRef<'a> where Self: 'a; 31013ffb70SLoGin 32013ffb70SLoGin fn into_raw(self) -> *const () { 33013ffb70SLoGin core::ptr::null() 34013ffb70SLoGin } 35013ffb70SLoGin 36013ffb70SLoGin unsafe fn from_raw(_raw: *const ()) -> Self { 37013ffb70SLoGin EmptyIdaItem 38013ffb70SLoGin } 39013ffb70SLoGin 40013ffb70SLoGin unsafe fn raw_as_ref<'a>(_raw: *const ()) -> Self::Ref<'a> { 41013ffb70SLoGin EmptyIdaItemRef { 42013ffb70SLoGin _marker: PhantomData, 43013ffb70SLoGin } 44013ffb70SLoGin } 45013ffb70SLoGin } 46013ffb70SLoGin /// id分配器 47013ffb70SLoGin pub struct IdAllocator { 48013ffb70SLoGin current_id: usize, 49013ffb70SLoGin min_id: usize, 50013ffb70SLoGin max_id: usize, 51013ffb70SLoGin used: usize, 52013ffb70SLoGin xarray: kdepends::xarray::XArray<EmptyIdaItem>, 53013ffb70SLoGin } 54013ffb70SLoGin 55013ffb70SLoGin impl IdAllocator { 56013ffb70SLoGin /// 创建一个新的id分配器 57013ffb70SLoGin pub const fn new(initial_id: usize, max_id: usize) -> Option<Self> { 58013ffb70SLoGin if initial_id >= max_id { 59013ffb70SLoGin return None; 60013ffb70SLoGin } 61013ffb70SLoGin Some(Self { 62013ffb70SLoGin current_id: initial_id, 63013ffb70SLoGin min_id: initial_id, 64013ffb70SLoGin max_id, 65013ffb70SLoGin used: 0, 66013ffb70SLoGin xarray: kdepends::xarray::XArray::new(), 67013ffb70SLoGin }) 68013ffb70SLoGin } 69013ffb70SLoGin 70013ffb70SLoGin /// 可用的id数量 71013ffb70SLoGin #[inline] 72013ffb70SLoGin pub fn available(&self) -> usize { 73013ffb70SLoGin self.max_id - self.min_id - self.used 74013ffb70SLoGin } 75013ffb70SLoGin 76013ffb70SLoGin /// 分配一个新的id 77013ffb70SLoGin /// 78013ffb70SLoGin /// ## 返回 79013ffb70SLoGin /// 80013ffb70SLoGin /// 如果分配成功,返回Some(id),否则返回None 81013ffb70SLoGin pub fn alloc(&mut self) -> Option<usize> { 82013ffb70SLoGin if unlikely(self.available() == 0) { 83013ffb70SLoGin return None; 84013ffb70SLoGin } 85013ffb70SLoGin 86013ffb70SLoGin if let Some(try1) = self.do_find_first_free_index(self.current_id, self.max_id) { 87013ffb70SLoGin self.current_id = try1; 88013ffb70SLoGin self.xarray.store(try1 as u64, EmptyIdaItem); 89013ffb70SLoGin self.used += 1; 90013ffb70SLoGin return Some(try1); 91013ffb70SLoGin } 92013ffb70SLoGin 93013ffb70SLoGin // 从头开始找 94013ffb70SLoGin if let Some(try2) = 95013ffb70SLoGin self.do_find_first_free_index(self.min_id, min(self.current_id, self.max_id)) 96013ffb70SLoGin { 97013ffb70SLoGin self.current_id = try2; 98013ffb70SLoGin self.xarray.store(try2 as u64, EmptyIdaItem); 99013ffb70SLoGin self.used += 1; 100013ffb70SLoGin return Some(try2); 101013ffb70SLoGin } 102013ffb70SLoGin return None; 103013ffb70SLoGin } 104013ffb70SLoGin 105013ffb70SLoGin /// 检查id是否存在 106013ffb70SLoGin /// 107013ffb70SLoGin /// ## 参数 108013ffb70SLoGin /// 109013ffb70SLoGin /// - `id`:要检查的id 110013ffb70SLoGin /// 111013ffb70SLoGin /// ## 返回 112013ffb70SLoGin /// 113013ffb70SLoGin /// 如果id存在,返回true,否则返回false 114013ffb70SLoGin pub fn exists(&self, id: usize) -> bool { 115013ffb70SLoGin if id < self.min_id || id >= self.max_id { 116013ffb70SLoGin return false; 117013ffb70SLoGin } 118013ffb70SLoGin self.xarray.load(id as u64).is_some() 119013ffb70SLoGin } 120013ffb70SLoGin 121013ffb70SLoGin fn do_find_first_free_index(&self, start_id: usize, end: usize) -> Option<usize> { 122013ffb70SLoGin (start_id..end).find(|&i| !self.exists(i)) 123013ffb70SLoGin } 124013ffb70SLoGin 125013ffb70SLoGin /// 释放一个id 126013ffb70SLoGin /// 127013ffb70SLoGin /// ## 参数 128013ffb70SLoGin /// 129013ffb70SLoGin /// - `id`:要释放的id 130013ffb70SLoGin pub fn free(&mut self, id: usize) { 131013ffb70SLoGin if id < self.min_id || id >= self.max_id { 132013ffb70SLoGin return; 133013ffb70SLoGin } 134013ffb70SLoGin if self.xarray.remove(id as u64).is_some() { 135013ffb70SLoGin self.used -= 1; 136013ffb70SLoGin } 137013ffb70SLoGin } 138013ffb70SLoGin 139013ffb70SLoGin /// 返回已经使用的id数量 140013ffb70SLoGin pub fn used(&self) -> usize { 141013ffb70SLoGin self.used 142013ffb70SLoGin } 143*f5b20388Scodeironman 144*f5b20388Scodeironman /// 返回最大id数 145*f5b20388Scodeironman pub fn get_max_id(&self) -> usize { 146*f5b20388Scodeironman self.max_id 147*f5b20388Scodeironman } 148013ffb70SLoGin } 149013ffb70SLoGin 150013ffb70SLoGin impl core::fmt::Debug for IdAllocator { 151013ffb70SLoGin fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 152013ffb70SLoGin f.debug_struct("IdAllocator") 153013ffb70SLoGin .field("current_id", &self.current_id) 154013ffb70SLoGin .field("min_id", &self.min_id) 155013ffb70SLoGin .field("max_id", &self.max_id) 156013ffb70SLoGin .field("used", &self.used) 157013ffb70SLoGin .field("xarray", &"xarray<()>") 158013ffb70SLoGin .finish() 159013ffb70SLoGin } 160013ffb70SLoGin } 161013ffb70SLoGin 162013ffb70SLoGin #[cfg(test)] 163013ffb70SLoGin mod tests { 164013ffb70SLoGin use super::*; 165013ffb70SLoGin #[test] 166013ffb70SLoGin fn test_new_fail() { 167013ffb70SLoGin assert_eq!(IdAllocator::new(10, 10).is_none(), true); 168013ffb70SLoGin assert_eq!(IdAllocator::new(11, 10).is_none(), true); 169013ffb70SLoGin } 170013ffb70SLoGin #[test] 171013ffb70SLoGin fn test_new_success() { 172013ffb70SLoGin assert_eq!(IdAllocator::new(9, 10).is_some(), true); 173013ffb70SLoGin assert_eq!(IdAllocator::new(0, 10).is_some(), true); 174013ffb70SLoGin } 175013ffb70SLoGin 176013ffb70SLoGin #[test] 177013ffb70SLoGin fn test_id_allocator() { 178013ffb70SLoGin let mut ida = IdAllocator::new(0, 10).unwrap(); 179013ffb70SLoGin assert_eq!(ida.alloc(), Some(0)); 180013ffb70SLoGin assert_eq!(ida.alloc(), Some(1)); 181013ffb70SLoGin assert_eq!(ida.alloc(), Some(2)); 182013ffb70SLoGin assert_eq!(ida.alloc(), Some(3)); 183013ffb70SLoGin assert_eq!(ida.alloc(), Some(4)); 184013ffb70SLoGin assert_eq!(ida.alloc(), Some(5)); 185013ffb70SLoGin assert_eq!(ida.alloc(), Some(6)); 186013ffb70SLoGin assert_eq!(ida.alloc(), Some(7)); 187013ffb70SLoGin assert_eq!(ida.alloc(), Some(8)); 188013ffb70SLoGin assert_eq!(ida.alloc(), Some(9)); 189013ffb70SLoGin assert_eq!(ida.alloc(), None); 190013ffb70SLoGin 191013ffb70SLoGin for i in 0..10 { 192013ffb70SLoGin assert_eq!(ida.exists(i), true); 193013ffb70SLoGin } 194013ffb70SLoGin 195013ffb70SLoGin ida.free(5); 196013ffb70SLoGin 197013ffb70SLoGin for i in 0..10 { 198013ffb70SLoGin if i == 5 { 199013ffb70SLoGin assert_eq!(ida.exists(i), false); 200013ffb70SLoGin } else { 201013ffb70SLoGin assert_eq!(ida.exists(i), true); 202013ffb70SLoGin } 203013ffb70SLoGin } 204013ffb70SLoGin assert_eq!(ida.used(), 9); 205013ffb70SLoGin assert_eq!(ida.alloc(), Some(5)); 206013ffb70SLoGin assert_eq!(ida.alloc(), None); 207013ffb70SLoGin 208013ffb70SLoGin assert_eq!(ida.used(), 10); 209013ffb70SLoGin for i in 0..10 { 210013ffb70SLoGin ida.free(i); 211013ffb70SLoGin } 212013ffb70SLoGin 213013ffb70SLoGin assert_eq!(ida.used(), 0); 214013ffb70SLoGin } 215013ffb70SLoGin } 216