1pub struct BitmapReader<'a> {
13 data: &'a [u8],
14 bit_count: u64,
15}
16
17impl<'a> BitmapReader<'a> {
18 pub fn new(data: &'a [u8], bit_count: u64) -> Self {
23 Self { data, bit_count }
24 }
25
26 pub fn bit_count(&self) -> u64 {
28 self.bit_count
29 }
30
31 #[inline]
35 pub fn is_bit_set(&self, index: u64) -> bool {
36 if index >= self.bit_count {
37 return false;
38 }
39 let byte_idx = (index / 8) as usize;
40 let bit_idx = (index % 8) as u32;
41 if byte_idx >= self.data.len() {
42 return false;
43 }
44 self.data[byte_idx] & (1u8 << bit_idx) != 0
45 }
46
47 pub fn count_set_bits(&self) -> u64 {
49 if self.bit_count == 0 {
50 return 0;
51 }
52
53 let full_bytes = (self.bit_count / 8) as usize;
54 let remaining_bits = (self.bit_count % 8) as u32;
55
56 let mut count: u64 = 0;
57
58 for &byte in &self.data[..full_bytes] {
60 count += byte.count_ones() as u64;
61 }
62
63 if remaining_bits > 0 && full_bytes < self.data.len() {
65 let mask = (1u8 << remaining_bits) - 1;
66 count += (self.data[full_bytes] & mask).count_ones() as u64;
67 }
68
69 count
70 }
71
72 pub fn count_clear_bits(&self) -> u64 {
74 self.bit_count - self.count_set_bits()
75 }
76
77 #[inline]
94 fn top_set_bit(byte: u8) -> u32 {
95 debug_assert!(byte != 0, "top_set_bit requires a non-zero byte");
96 31 - (byte as u32).leading_zeros()
97 }
98
99 pub fn highest_set_bit(&self) -> Option<u64> {
103 if self.bit_count == 0 {
104 return None;
105 }
106
107 let full_bytes = (self.bit_count / 8) as usize;
108 let remaining_bits = (self.bit_count % 8) as u32;
109
110 if remaining_bits > 0 && full_bytes < self.data.len() {
112 let mask = (1u8 << remaining_bits) - 1;
113 let masked = self.data[full_bytes] & mask;
114 if masked != 0 {
115 let top_bit = Self::top_set_bit(masked);
116 return Some(full_bytes as u64 * 8 + top_bit as u64);
117 }
118 }
119
120 for i in (0..full_bytes).rev() {
122 if self.data[i] != 0 {
123 let top_bit = Self::top_set_bit(self.data[i]);
124 return Some(i as u64 * 8 + top_bit as u64);
125 }
126 }
127
128 None
129 }
130
131 pub fn highest_clear_bit(&self) -> Option<u64> {
137 if self.bit_count == 0 {
138 return None;
139 }
140
141 let full_bytes = (self.bit_count / 8) as usize;
142 let remaining_bits = (self.bit_count % 8) as u32;
143
144 if remaining_bits > 0 && full_bytes < self.data.len() {
147 let mask = (1u8 << remaining_bits) - 1;
148 let inv = (!self.data[full_bytes]) & mask;
149 if inv != 0 {
150 let top_bit = Self::top_set_bit(inv);
151 return Some(full_bytes as u64 * 8 + top_bit as u64);
154 }
155 }
156
157 for i in (0..full_bytes).rev() {
158 let inv = !self.data[i];
159 if inv != 0 {
160 let top_bit = Self::top_set_bit(inv);
161 return Some(i as u64 * 8 + top_bit as u64);
162 }
163 }
164
165 None
166 }
167
168 pub fn lowest_clear_bit(&self) -> Option<u64> {
172 if self.bit_count == 0 {
173 return None;
174 }
175
176 let full_bytes = (self.bit_count / 8) as usize;
177 let remaining_bits = (self.bit_count % 8) as u32;
178
179 for i in 0..full_bytes {
181 if self.data[i] != 0xFF {
182 let bit = self.data[i].trailing_ones();
183 return Some(i as u64 * 8 + bit as u64);
184 }
185 }
186
187 if remaining_bits > 0 && full_bytes < self.data.len() {
189 let mask = (1u8 << remaining_bits) - 1;
190 let masked = self.data[full_bytes] & mask;
191 if masked != mask {
192 let bit = masked.trailing_ones();
194 if bit < remaining_bits {
195 return Some(full_bytes as u64 * 8 + bit as u64);
196 }
197 }
198 }
199
200 None
201 }
202
203 pub fn iter_set_bits(&self) -> SetBitsIter<'_> {
205 SetBitsIter {
206 bitmap: self,
207 index: 0,
208 }
209 }
210
211 pub fn iter_clear_bits(&self) -> ClearBitsIter<'_> {
213 ClearBitsIter {
214 bitmap: self,
215 index: 0,
216 }
217 }
218}
219
220pub struct SetBitsIter<'a> {
222 bitmap: &'a BitmapReader<'a>,
223 index: u64,
224}
225
226impl Iterator for SetBitsIter<'_> {
227 type Item = u64;
228
229 fn next(&mut self) -> Option<u64> {
230 while self.index < self.bitmap.bit_count {
231 let i = self.index;
232 self.index += 1;
233 if self.bitmap.is_bit_set(i) {
234 return Some(i);
235 }
236 }
237 None
238 }
239}
240
241pub struct ClearBitsIter<'a> {
243 bitmap: &'a BitmapReader<'a>,
244 index: u64,
245}
246
247impl Iterator for ClearBitsIter<'_> {
248 type Item = u64;
249
250 fn next(&mut self) -> Option<u64> {
251 while self.index < self.bitmap.bit_count {
252 let i = self.index;
253 self.index += 1;
254 if !self.bitmap.is_bit_set(i) {
255 return Some(i);
256 }
257 }
258 None
259 }
260}
261
262#[inline]
268pub fn bitmap_set_bit(data: &mut [u8], index: u64) {
269 let byte_idx = (index / 8) as usize;
270 let bit_idx = (index % 8) as u32;
271 data[byte_idx] |= 1u8 << bit_idx;
272}
273
274#[inline]
278pub fn bitmap_clear_bit(data: &mut [u8], index: u64) {
279 let byte_idx = (index / 8) as usize;
280 let bit_idx = (index % 8) as u32;
281 data[byte_idx] &= !(1u8 << bit_idx);
282}
283
284pub fn bitmap_find_clear_bit(data: &[u8], bit_count: u64) -> Option<u64> {
288 let full_bytes = (bit_count / 8) as usize;
289 let remaining_bits = (bit_count % 8) as u32;
290
291 for (i, &byte) in data[..full_bytes].iter().enumerate() {
292 if byte != 0xFF {
293 let bit = byte.trailing_ones();
294 return Some(i as u64 * 8 + bit as u64);
295 }
296 }
297
298 if remaining_bits > 0 && full_bytes < data.len() {
299 let mask = (1u8 << remaining_bits) - 1;
300 let masked = data[full_bytes] & mask;
301 if masked != mask {
302 let bit = masked.trailing_ones();
303 if bit < remaining_bits {
304 return Some(full_bytes as u64 * 8 + bit as u64);
305 }
306 }
307 }
308
309 None
310}
311
312#[cfg(test)]
313mod tests {
314 use super::*;
315
316 #[test]
328 fn top_set_bit_matches_a_plain_scan_for_every_byte() {
329 for byte in 1u8..=255 {
330 let expected = (0..8u32).filter(|b| byte & (1 << b) != 0).max().unwrap();
331 assert_eq!(
332 BitmapReader::top_set_bit(byte),
333 expected,
334 "top_set_bit({byte:#04x})"
335 );
336 }
337 }
338
339 #[test]
342 fn highest_set_and_clear_bits_are_positionally_correct() {
343 for bit in 0..8u64 {
344 let data = [1u8 << bit];
345 let bm = BitmapReader::new(&data, 8);
346 assert_eq!(bm.highest_set_bit(), Some(bit), "highest_set_bit for {bit}");
347
348 let inv = [!(1u8 << bit)];
350 let bmi = BitmapReader::new(&inv, 8);
351 assert_eq!(
352 bmi.highest_clear_bit(),
353 Some(bit),
354 "highest_clear_bit for {bit}"
355 );
356 }
357
358 let data = [0x00u8, 0b0001_0000, 0x00];
360 assert_eq!(
361 BitmapReader::new(&data, 24).highest_set_bit(),
362 Some(8 + 4),
363 "highest set bit should be byte 1, bit 4"
364 );
365 }
366
367 #[test]
368 fn test_single_byte_set_bits() {
369 let data = [0b10100101u8]; let bm = BitmapReader::new(&data, 8);
371 assert!(bm.is_bit_set(0));
372 assert!(!bm.is_bit_set(1));
373 assert!(bm.is_bit_set(2));
374 assert!(!bm.is_bit_set(3));
375 assert!(!bm.is_bit_set(4));
376 assert!(bm.is_bit_set(5));
377 assert!(!bm.is_bit_set(6));
378 assert!(bm.is_bit_set(7));
379 assert_eq!(bm.count_set_bits(), 4);
380 assert_eq!(bm.count_clear_bits(), 4);
381 assert_eq!(bm.highest_set_bit(), Some(7));
382 }
383
384 #[test]
385 fn test_partial_byte() {
386 let data = [0xFF];
387 let bm = BitmapReader::new(&data, 5); assert_eq!(bm.count_set_bits(), 5); assert_eq!(bm.count_clear_bits(), 0);
390 assert_eq!(bm.highest_set_bit(), Some(4));
391 }
392
393 #[test]
394 fn test_partial_byte_with_clear_bits() {
395 let data = [0b11110011u8];
397 let bm = BitmapReader::new(&data, 6); assert_eq!(bm.count_set_bits(), 4);
400 assert_eq!(bm.count_clear_bits(), 2);
401 assert_eq!(bm.highest_set_bit(), Some(5));
402 }
403
404 #[test]
405 fn test_iter_set_bits() {
406 let data = [0b00000101u8]; let bm = BitmapReader::new(&data, 8);
408 let bits: Vec<u64> = bm.iter_set_bits().collect();
409 assert_eq!(bits, vec![0, 2]);
410 }
411
412 #[test]
413 fn test_iter_clear_bits() {
414 let data = [0b11111010u8]; let bm = BitmapReader::new(&data, 8);
416 let bits: Vec<u64> = bm.iter_clear_bits().collect();
417 assert_eq!(bits, vec![0, 2]);
418 }
419
420 #[test]
421 fn test_iter_set_bits_partial() {
422 let data = [0b11111111u8];
423 let bm = BitmapReader::new(&data, 3); let bits: Vec<u64> = bm.iter_set_bits().collect();
425 assert_eq!(bits, vec![0, 1, 2]);
426 }
427
428 #[test]
429 fn test_multi_byte() {
430 let data = [0xFF, 0x00, 0b00000011]; let bm = BitmapReader::new(&data, 24);
432 assert_eq!(bm.count_set_bits(), 10); assert_eq!(bm.count_clear_bits(), 14);
434 assert_eq!(bm.highest_set_bit(), Some(17)); }
436
437 #[test]
438 fn test_multi_byte_partial() {
439 let data = [0xFF, 0xFF, 0b00001111];
440 let bm = BitmapReader::new(&data, 20); assert_eq!(bm.count_set_bits(), 20); assert_eq!(bm.highest_set_bit(), Some(19));
443 }
444
445 #[test]
446 fn test_highest_set_bit_middle() {
447 let data = [0x00, 0b10000000, 0x00]; let bm = BitmapReader::new(&data, 24);
449 assert_eq!(bm.highest_set_bit(), Some(15));
450 }
451
452 #[test]
453 fn test_highest_set_bit_none() {
454 let data = [0x00, 0x00];
455 let bm = BitmapReader::new(&data, 16);
456 assert_eq!(bm.highest_set_bit(), None);
457 }
458
459 #[test]
460 fn test_highest_clear_bit_basic() {
461 let data = [0b10110101u8];
463 let bm = BitmapReader::new(&data, 8);
464 assert_eq!(bm.highest_clear_bit(), Some(6));
465 }
466
467 #[test]
468 fn test_highest_clear_bit_all_set() {
469 let data = [0xFF, 0xFF];
470 let bm = BitmapReader::new(&data, 16);
471 assert_eq!(bm.highest_clear_bit(), None);
472 }
473
474 #[test]
475 fn test_highest_clear_bit_partial() {
476 let data = [0xFE, 0xFF];
478 let bm = BitmapReader::new(&data, 11);
479 assert_eq!(bm.highest_clear_bit(), Some(0));
481 }
482
483 #[test]
484 fn test_highest_clear_bit_partial_with_clear() {
485 let data = [0xFF, 0b00000101]; let bm = BitmapReader::new(&data, 11);
488 assert_eq!(bm.highest_clear_bit(), Some(9));
490 }
491
492 #[test]
493 fn test_highest_clear_bit_middle_byte() {
494 let data = [0xFF, 0b01111111, 0xFF];
497 let bm = BitmapReader::new(&data, 24);
498 assert_eq!(bm.highest_clear_bit(), Some(15));
500 }
501
502 #[test]
503 fn test_highest_clear_bit_empty() {
504 let data: [u8; 0] = [];
505 let bm = BitmapReader::new(&data, 0);
506 assert_eq!(bm.highest_clear_bit(), None);
507 }
508
509 #[test]
510 fn test_lowest_clear_bit() {
511 let data = [0xFF, 0b11111110]; let bm = BitmapReader::new(&data, 16);
513 assert_eq!(bm.lowest_clear_bit(), Some(8)); }
515
516 #[test]
517 fn test_lowest_clear_bit_first() {
518 let data = [0b11111110]; let bm = BitmapReader::new(&data, 8);
520 assert_eq!(bm.lowest_clear_bit(), Some(0));
521 }
522
523 #[test]
524 fn test_lowest_clear_bit_none() {
525 let data = [0xFF, 0xFF];
526 let bm = BitmapReader::new(&data, 16);
527 assert_eq!(bm.lowest_clear_bit(), None);
528 }
529
530 #[test]
531 fn test_lowest_clear_bit_partial() {
532 let data = [0xFF, 0b11111011]; let bm = BitmapReader::new(&data, 12); assert_eq!(bm.lowest_clear_bit(), Some(10));
537 }
538
539 #[test]
540 fn test_empty_bitmap() {
541 let data = [];
542 let bm = BitmapReader::new(&data, 0);
543 assert_eq!(bm.count_set_bits(), 0);
544 assert_eq!(bm.count_clear_bits(), 0);
545 assert_eq!(bm.highest_set_bit(), None);
546 assert_eq!(bm.lowest_clear_bit(), None);
547 assert!(!bm.is_bit_set(0));
548 assert_eq!(bm.iter_set_bits().count(), 0);
549 assert_eq!(bm.iter_clear_bits().count(), 0);
550 }
551
552 #[test]
553 fn test_out_of_range() {
554 let data = [0xFF];
555 let bm = BitmapReader::new(&data, 8);
556 assert!(!bm.is_bit_set(8));
557 assert!(!bm.is_bit_set(100));
558 }
559
560 #[test]
561 fn test_bit_count() {
562 let data = [0xFF; 4];
563 let bm = BitmapReader::new(&data, 30);
564 assert_eq!(bm.bit_count(), 30);
565 }
566
567 #[test]
568 fn test_large_bitmap() {
569 let data = vec![0xFF; 128];
571 let bm = BitmapReader::new(&data, 1024);
572 assert_eq!(bm.count_set_bits(), 1024);
573 assert_eq!(bm.count_clear_bits(), 0);
574 assert_eq!(bm.highest_set_bit(), Some(1023));
575 assert_eq!(bm.lowest_clear_bit(), None);
576 }
577
578 #[test]
579 fn test_large_bitmap_sparse() {
580 let data = vec![0x01; 128];
582 let bm = BitmapReader::new(&data, 1024);
583 assert_eq!(bm.count_set_bits(), 128);
584 assert_eq!(bm.count_clear_bits(), 896);
585 assert_eq!(bm.highest_set_bit(), Some(1016)); assert_eq!(bm.lowest_clear_bit(), Some(1)); }
588
589 #[test]
590 fn test_iter_set_bits_multi_byte() {
591 let data = [0b00000001, 0b10000000]; let bm = BitmapReader::new(&data, 16);
593 let bits: Vec<u64> = bm.iter_set_bits().collect();
594 assert_eq!(bits, vec![0, 15]);
595 }
596
597 #[test]
598 fn test_iter_clear_bits_all_set() {
599 let data = [0xFF];
600 let bm = BitmapReader::new(&data, 8);
601 let bits: Vec<u64> = bm.iter_clear_bits().collect();
602 assert!(bits.is_empty());
603 }
604
605 #[test]
606 fn test_iter_set_bits_all_clear() {
607 let data = [0x00];
608 let bm = BitmapReader::new(&data, 8);
609 let bits: Vec<u64> = bm.iter_set_bits().collect();
610 assert!(bits.is_empty());
611 }
612
613 #[test]
616 fn test_bitmap_set_bit() {
617 let mut data = [0u8; 2];
618 bitmap_set_bit(&mut data, 0);
619 assert_eq!(data[0], 0b00000001);
620 bitmap_set_bit(&mut data, 7);
621 assert_eq!(data[0], 0b10000001);
622 bitmap_set_bit(&mut data, 8);
623 assert_eq!(data[1], 0b00000001);
624 bitmap_set_bit(&mut data, 15);
625 assert_eq!(data[1], 0b10000001);
626 }
627
628 #[test]
629 fn test_bitmap_clear_bit() {
630 let mut data = [0xFF, 0xFF];
631 bitmap_clear_bit(&mut data, 0);
632 assert_eq!(data[0], 0b11111110);
633 bitmap_clear_bit(&mut data, 7);
634 assert_eq!(data[0], 0b01111110);
635 bitmap_clear_bit(&mut data, 8);
636 assert_eq!(data[1], 0b11111110);
637 }
638
639 #[test]
640 fn test_bitmap_set_clear_roundtrip() {
641 let mut data = [0u8; 4];
642 for i in 0..32u64 {
643 bitmap_set_bit(&mut data, i);
644 }
645 assert_eq!(data, [0xFF; 4]);
646 for i in 0..32u64 {
647 bitmap_clear_bit(&mut data, i);
648 }
649 assert_eq!(data, [0x00; 4]);
650 }
651
652 #[test]
653 fn test_bitmap_find_clear_bit_basic() {
654 let data = [0xFF, 0b11111110]; assert_eq!(bitmap_find_clear_bit(&data, 16), Some(8));
656 }
657
658 #[test]
659 fn test_bitmap_find_clear_bit_first() {
660 let data = [0b11111110]; assert_eq!(bitmap_find_clear_bit(&data, 8), Some(0));
662 }
663
664 #[test]
665 fn test_bitmap_find_clear_bit_none() {
666 let data = [0xFF, 0xFF];
667 assert_eq!(bitmap_find_clear_bit(&data, 16), None);
668 }
669
670 #[test]
671 fn test_bitmap_find_clear_bit_partial() {
672 let data = [0xFF, 0b00001111]; assert_eq!(bitmap_find_clear_bit(&data, 12), None); }
675
676 #[test]
677 fn test_bitmap_find_clear_bit_in_partial() {
678 let data = [0xFF, 0b11111011]; assert_eq!(bitmap_find_clear_bit(&data, 12), Some(10));
680 }
681}