lib.rs 5.3 KB

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