customizable_buddy/
bitmap.rs1use crate::{BuddyCollection, BuddyLine, OligarchyCollection};
2use core::fmt;
3
4pub struct UsizeBuddy {
9 bits: usize,
10 base: usize,
11}
12
13impl UsizeBuddy {
14 const SIZE: usize = usize::BITS as usize;
15
16 #[inline]
17 fn take(&mut self, idx: usize) -> bool {
18 let bit = 1usize << idx;
19 let bits = self.bits;
20 self.bits &= !bit;
21 bits & bit == bit
22 }
23}
24
25impl BuddyLine for UsizeBuddy {
26 const EMPTY: Self = Self { bits: 0, base: 0 };
27
28 #[inline]
29 fn init(&mut self, _order: usize, base: usize) {
30 self.base = base;
31 }
32
33 #[inline]
34 fn take(&mut self, idx: usize) -> bool {
35 self.take(idx - self.base)
36 }
37}
38
39impl OligarchyCollection for UsizeBuddy {
40 #[inline]
41 fn take_any(&mut self, align_order: usize, count: usize) -> Option<usize> {
42 let count = (1 << count) - 1;
43 let align = 1usize << align_order;
44 let mut i = 0;
45 loop {
46 let mask = count << i;
47 if self.bits & mask == mask {
48 self.bits &= !mask;
49 return Some(self.base + i);
50 }
51 i += align;
52 if i >= usize::BITS as usize {
53 return None;
54 }
55 }
56 }
57
58 #[inline]
59 fn put(&mut self, idx: usize) {
60 self.bits |= 1 << (idx - self.base);
61 }
62}
63
64impl BuddyCollection for UsizeBuddy {
65 #[inline]
66 fn take_any(&mut self, align_order: usize) -> Option<usize> {
67 let align = 1usize << align_order;
68 let mut i = 0;
69 loop {
70 let mask = 1 << i;
71 if self.bits & mask == mask {
72 self.bits &= !mask;
73 return Some(self.base + i);
74 }
75 i += align;
76 if i >= usize::BITS as usize {
77 return None;
78 }
79 }
80 }
81
82 #[inline]
83 fn put(&mut self, idx: usize) -> Option<usize> {
84 let idx = idx - self.base;
85 debug_assert!(idx < Self::SIZE, "index out of bound");
86 let buddy = idx ^ 1;
87 if self.take(buddy) {
88 Some(idx << 1)
89 } else {
90 self.bits |= 1 << idx;
91 None
92 }
93 }
94}
95
96impl fmt::Debug for UsizeBuddy {
97 #[inline]
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(f, "{:b}", self.bits)
100 }
101}