1use core::gca;
2use std::{
3 io::{self, Cursor, Write},
4 ops::Range,
5};
6
7use azalea_buf::{AzBuf, BufReadError};
8
9#[derive(AzBuf, Clone, Debug, Default, Eq, Hash, PartialEq)]
11pub struct BitSet {
12 data: Box<[u64]>,
13}
14
15const LOG2_BITS_PER_WORD: usize = 6;
17
18impl BitSet {
20 #[inline]
21 pub fn new(num_bits: usize) -> Self {
22 BitSet {
23 data: vec![0; num_bits.div_ceil(64)].into(),
24 }
25 }
26
27 #[inline]
34 pub fn index(&self, index: usize) -> bool {
35 self.get(index).unwrap_or_else(|| {
36 let len = self.len();
37 panic!("index out of bounds: the len is {len} but the index is {index}")
38 })
39 }
40
41 #[inline]
42 pub fn get(&self, index: usize) -> Option<bool> {
43 self.data
44 .get(index / 64)
45 .map(|word| (word & (1u64 << (index % 64))) != 0)
46 }
47
48 pub fn clear(&mut self, range: Range<usize>) {
54 assert!(
55 range.start <= range.end,
56 "Range ends before it starts; {} must be less than or equal to {}",
57 range.start,
58 range.end
59 );
60
61 let from_idx = range.start;
62 let mut to_idx = range.end;
63
64 if from_idx == to_idx {
65 return;
66 }
67
68 let start_word_idx = self.word_index(from_idx);
69 if start_word_idx >= self.data.len() {
70 return;
71 }
72
73 let mut end_word_idx = self.word_index(to_idx - 1);
74 if end_word_idx >= self.data.len() {
75 to_idx = self.len();
76 end_word_idx = self.data.len() - 1;
77 }
78
79 let first_word_mask = u64::MAX.wrapping_shl(
80 from_idx
81 .try_into()
82 .expect("from_index shouldn't be larger than u32"),
83 );
84 let last_word_mask = u64::MAX.wrapping_shr((64 - (to_idx % 64)) as u32);
85 if start_word_idx == end_word_idx {
86 self.data[start_word_idx] &= !(first_word_mask & last_word_mask);
88 } else {
89 self.data[start_word_idx] &= !first_word_mask;
91 for i in (start_word_idx + 1)..end_word_idx {
92 self.data[i] = 0;
93 }
94 self.data[end_word_idx] &= !last_word_mask;
95 }
96 }
97
98 pub fn next_clear_bit(&self, from_index: usize) -> usize {
101 let mut u = self.word_index(from_index);
102 if u >= self.data.len() {
103 return from_index;
104 }
105
106 let mut word = !self.data[u] & (u64::MAX.wrapping_shl(from_index.try_into().unwrap()));
107
108 loop {
109 if word != 0 {
110 return (u * 64) + word.trailing_zeros() as usize;
111 }
112 u += 1;
113 if u == self.data.len() {
114 return self.data.len() * 64;
115 }
116 word = !self.data[u];
117 }
118 }
119
120 #[inline]
121 fn word_index(&self, bit_index: usize) -> usize {
122 bit_index >> LOG2_BITS_PER_WORD
123 }
124
125 #[inline]
132 pub fn set(&mut self, bit_index: usize) {
133 self.data[bit_index / 64] |= 1u64 << (bit_index % 64);
134 }
135
136 pub fn iter_ones(&self) -> impl Iterator<Item = usize> {
138 (0..self.len()).filter(|i| self.index(*i))
139 }
140
141 #[inline]
145 pub fn len(&self) -> usize {
146 self.data.len() * 64
147 }
148
149 pub fn is_empty(&self) -> bool {
153 self.len() == 0
154 }
155}
156
157impl From<Vec<u64>> for BitSet {
158 fn from(data: Vec<u64>) -> Self {
159 BitSet { data: data.into() }
160 }
161}
162
163impl From<Vec<u8>> for BitSet {
164 fn from(data: Vec<u8>) -> Self {
165 let mut words = vec![0; data.len().div_ceil(8)];
166 for (i, byte) in data.iter().enumerate() {
167 words[i / 8] |= (*byte as u64) << ((i % 8) * 8);
168 }
169 BitSet { data: words.into() }
170 }
171}
172
173#[derive(Clone, Debug, Eq, Hash, PartialEq)]
183pub struct FixedBitSet<const N: usize> {
184 data: BYTEARRAY<N>,
185}
186
187type BYTEARRAY<const N: usize> = [u8; gca!(BYTESIZE::<N>)];
188const BYTESIZE<const N: usize>: usize = const { N.div_ceil(8) };
189
190impl<const N: usize> FixedBitSet<N> {
191 #[must_use]
193 pub const fn new() -> Self {
194 FixedBitSet { data: [0; _] }
195 }
196
197 #[must_use]
199 pub const fn new_with_data(data: BYTEARRAY<N>) -> Self {
200 FixedBitSet { data }
201 }
202
203 #[inline]
205 #[must_use]
206 pub const fn bit_len(&self) -> usize {
207 N
208 }
209
210 #[inline]
212 #[must_use]
213 pub const fn byte_len(&self) -> usize {
214 BYTESIZE::<N>
215 }
216
217 #[inline]
219 #[must_use]
220 pub fn index(&self, index: usize) -> bool {
221 (self.data[index / 8] & (1u8 << (index % 8))) != 0
222 }
223
224 #[inline]
230 pub fn set(&mut self, bit_index: usize) {
231 assert!(bit_index < N, "Out of bounds write to FixedBitSet!");
232
233 self.data[bit_index / 8] |= 1u8 << (bit_index % 8);
234 }
235}
236
237impl<const N: usize> AzBuf for FixedBitSet<N> {
238 fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
239 let mut data = [0; _];
240 for item in data.iter_mut() {
241 *item = u8::azalea_read(buf)?;
242 }
243 Ok(FixedBitSet { data })
244 }
245 fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
246 for item in self.data {
247 item.azalea_write(buf)?;
248 }
249 Ok(())
250 }
251}
252impl<const N: usize> Default for FixedBitSet<N> {
253 #[inline]
254 fn default() -> Self {
255 Self::new()
256 }
257}
258
259#[derive(Clone, Debug, Eq, Hash, PartialEq)]
267pub struct FastFixedBitSet<const N: usize> {
268 data: LONGARRAY<N>,
269}
270
271type LONGARRAY<const N: usize> = [u64; gca!(LONGSIZE::<N>)];
272const LONGSIZE<const N: usize>: usize = const { N.div_ceil(64) };
273
274impl<const N: usize> FastFixedBitSet<N> {
275 #[must_use]
277 pub const fn new() -> Self {
278 FastFixedBitSet { data: [0; _] }
279 }
280
281 #[inline]
283 #[must_use]
284 pub const fn bit_len(&self) -> usize {
285 N
286 }
287
288 #[inline]
290 #[must_use]
291 pub const fn long_len(&self) -> usize {
292 LONGSIZE::<N>
293 }
294
295 #[inline]
297 #[must_use]
298 pub fn index(&self, index: usize) -> bool {
299 (self.data[index / 64] & (1u64 << (index % 64))) != 0
300 }
301
302 #[inline]
308 pub fn set(&mut self, bit_index: usize) {
309 assert!(bit_index < N, "Out of bounds write to FastFixedBitSet!");
310
311 self.data[bit_index / 64] |= 1u64 << (bit_index % 64);
312 }
313}
314impl<const N: usize> Default for FastFixedBitSet<N> {
315 #[inline]
316 fn default() -> Self {
317 Self::new()
318 }
319}
320
321#[cfg(test)]
322mod tests {
323 use super::*;
324
325 #[test]
326 fn test_bitset() {
327 let mut bitset = BitSet::new(64);
328 assert!(!bitset.index(0));
329 assert!(!bitset.index(1));
330 assert!(!bitset.index(2));
331 bitset.set(1);
332 assert!(!bitset.index(0));
333 assert!(bitset.index(1));
334 assert!(!bitset.index(2));
335 }
336
337 #[test]
338 fn test_clear() {
339 let mut bitset = BitSet::new(128);
340 bitset.set(62);
341 bitset.set(63);
342 bitset.set(64);
343 bitset.set(65);
344 bitset.set(66);
345
346 bitset.clear(63..65);
347
348 assert!(bitset.index(62));
349 assert!(!bitset.index(63));
350 assert!(!bitset.index(64));
351 assert!(bitset.index(65));
352 assert!(bitset.index(66));
353 }
354
355 #[test]
356 fn test_clear_2() {
357 let mut bitset = BitSet::new(128);
358 bitset.set(64);
359 bitset.set(65);
360 bitset.set(66);
361 bitset.set(67);
362 bitset.set(68);
363
364 bitset.clear(65..67);
365
366 assert!(bitset.index(64));
367 assert!(!bitset.index(65));
368 assert!(!bitset.index(66));
369 assert!(bitset.index(67));
370 assert!(bitset.index(68));
371 }
372}