1use crate::core::pop_count64;
14
15#[derive(Debug, Clone, Default)]
17pub struct BitSet {
18 pub(crate) blocks: Vec<u64>,
20 pub(crate) block_count: u32,
22}
23
24impl BitSet {
25 pub fn new(bit_capacity: u32) -> BitSet {
27 let block_capacity = bit_capacity.div_ceil(u64::BITS);
28 BitSet {
29 blocks: vec![0; block_capacity as usize],
30 block_count: 0,
31 }
32 }
33
34 pub fn destroy(&mut self) {
39 self.blocks = Vec::new();
40 self.block_count = 0;
41 }
42
43 fn block_capacity(&self) -> u32 {
45 self.blocks.len() as u32
46 }
47
48 pub fn set_bit_count_and_clear(&mut self, bit_count: u32) {
50 let block_count = bit_count.div_ceil(u64::BITS);
51 if self.block_capacity() < block_count {
52 self.destroy();
53 let new_bit_capacity = bit_count + (bit_count >> 1);
54 *self = BitSet::new(new_bit_capacity);
55 }
56
57 self.block_count = block_count;
58 for block in &mut self.blocks[..block_count as usize] {
59 *block = 0;
60 }
61 }
62
63 pub fn grow(&mut self, block_count: u32) {
65 debug_assert!(block_count > self.block_count);
66 if block_count > self.block_capacity() {
67 let new_capacity = block_count + block_count / 2;
72 self.blocks.resize(new_capacity as usize, 0);
73 }
74
75 self.block_count = block_count;
76 }
77
78 pub fn in_place_union(&mut self, other: &BitSet) {
80 debug_assert!(self.block_count == other.block_count);
81 let block_count = self.block_count as usize;
82 for i in 0..block_count {
83 self.blocks[i] |= other.blocks[i];
84 }
85 }
86
87 pub fn count_set_bits(&self) -> i32 {
89 let mut pop_count = 0;
90 for i in 0..self.block_count as usize {
91 pop_count += pop_count64(self.blocks[i]);
92 }
93 pop_count
94 }
95
96 pub fn set_bit(&mut self, bit_index: u32) {
98 let block_index = bit_index / 64;
99 debug_assert!(block_index < self.block_count);
100 self.blocks[block_index as usize] |= 1u64 << (bit_index % 64);
101 }
102
103 pub fn set_bit_grow(&mut self, bit_index: u32) {
105 let block_index = bit_index / 64;
106 if block_index >= self.block_count {
107 self.grow(block_index + 1);
108 }
109 self.blocks[block_index as usize] |= 1u64 << (bit_index % 64);
110 }
111
112 pub fn clear_bit(&mut self, bit_index: u32) {
114 let block_index = bit_index / 64;
115 if block_index >= self.block_count {
116 return;
117 }
118 self.blocks[block_index as usize] &= !(1u64 << (bit_index % 64));
119 }
120
121 pub fn get_bit(&self, bit_index: u32) -> bool {
123 let block_index = bit_index / 64;
124 if block_index >= self.block_count {
125 return false;
126 }
127 (self.blocks[block_index as usize] & (1u64 << (bit_index % 64))) != 0
128 }
129
130 pub fn bytes(&self) -> i32 {
132 self.block_capacity() as i32 * core::mem::size_of::<u64>() as i32
133 }
134
135 pub fn block_count(&self) -> u32 {
138 self.block_count
139 }
140
141 pub fn block(&self, block_index: u32) -> u64 {
143 debug_assert!(block_index < self.block_count);
144 self.blocks[block_index as usize]
145 }
146}