1 // Copyright © 2022 Collabora, Ltd. 2 // SPDX-License-Identifier: MIT 3 4 use std::ops::{ 5 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Range, 6 }; 7 8 #[derive(Clone)] 9 pub struct BitSet { 10 words: Vec<u32>, 11 } 12 13 impl BitSet { new() -> BitSet14 pub fn new() -> BitSet { 15 BitSet { words: Vec::new() } 16 } 17 reserve_words(&mut self, words: usize)18 fn reserve_words(&mut self, words: usize) { 19 if self.words.len() < words { 20 self.words.resize(words, 0); 21 } 22 } 23 reserve(&mut self, bits: usize)24 pub fn reserve(&mut self, bits: usize) { 25 self.reserve_words(bits.div_ceil(32)); 26 } 27 clear(&mut self)28 pub fn clear(&mut self) { 29 for w in self.words.iter_mut() { 30 *w = 0; 31 } 32 } 33 get(&self, idx: usize) -> bool34 pub fn get(&self, idx: usize) -> bool { 35 let w = idx / 32; 36 let b = idx % 32; 37 if w < self.words.len() { 38 self.words[w] & (1_u32 << b) != 0 39 } else { 40 false 41 } 42 } 43 is_empty(&self) -> bool44 pub fn is_empty(&self) -> bool { 45 for w in self.words.iter() { 46 if *w != 0 { 47 return false; 48 } 49 } 50 true 51 } 52 iter(&self) -> BitSetIter<'_>53 pub fn iter(&self) -> BitSetIter<'_> { 54 BitSetIter::new(self, 0) 55 } 56 get_word(&self, word: usize) -> u3257 pub fn get_word(&self, word: usize) -> u32 { 58 self.words.get(word).cloned().unwrap_or(0) 59 } 60 next_unset(&self, start: usize) -> usize61 pub fn next_unset(&self, start: usize) -> usize { 62 if start >= self.words.len() * 32 { 63 return start; 64 } 65 66 let mut w = start / 32; 67 let mut mask = !(u32::MAX << (start % 32)); 68 while w < self.words.len() { 69 let b = (self.words[w] | mask).trailing_ones(); 70 if b < 32 { 71 return w * 32 + usize::try_from(b).unwrap(); 72 } 73 mask = 0; 74 w += 1; 75 } 76 self.words.len() * 32 77 } 78 insert(&mut self, idx: usize) -> bool79 pub fn insert(&mut self, idx: usize) -> bool { 80 let w = idx / 32; 81 let b = idx % 32; 82 self.reserve_words(w + 1); 83 let exists = self.words[w] & (1_u32 << b) != 0; 84 self.words[w] |= 1_u32 << b; 85 !exists 86 } 87 remove(&mut self, idx: usize) -> bool88 pub fn remove(&mut self, idx: usize) -> bool { 89 let w = idx / 32; 90 let b = idx % 32; 91 self.reserve_words(w + 1); 92 let exists = self.words[w] & (1_u32 << b) != 0; 93 self.words[w] &= !(1_u32 << b); 94 exists 95 } 96 97 #[inline] set_word( &mut self, w: usize, mask: u32, f: &mut impl FnMut(usize) -> u32, )98 fn set_word( 99 &mut self, 100 w: usize, 101 mask: u32, 102 f: &mut impl FnMut(usize) -> u32, 103 ) { 104 self.words[w] = (self.words[w] & !mask) | (f(w) & mask); 105 } 106 set_words( &mut self, bits: Range<usize>, mut f: impl FnMut(usize) -> u32, )107 pub fn set_words( 108 &mut self, 109 bits: Range<usize>, 110 mut f: impl FnMut(usize) -> u32, 111 ) { 112 if bits.is_empty() { 113 return; 114 } 115 116 let first_word = bits.start / 32; 117 let last_word = (bits.end - 1) / 32; 118 let start_mask = !0_u32 << (bits.start % 32); 119 let end_mask = !0_u32 >> (31 - ((bits.end - 1) % 32)); 120 121 self.reserve(last_word + 1); 122 123 if first_word == last_word { 124 self.set_word(first_word, start_mask & end_mask, &mut f); 125 } else { 126 self.set_word(first_word, start_mask, &mut f); 127 for w in (first_word + 1)..last_word { 128 self.set_word(w, !0, &mut f); 129 } 130 self.set_word(last_word, end_mask, &mut f); 131 } 132 } 133 union_with(&mut self, other: &BitSet) -> bool134 pub fn union_with(&mut self, other: &BitSet) -> bool { 135 let mut added_bits = false; 136 self.reserve_words(other.words.len()); 137 for w in 0..other.words.len() { 138 let uw = self.words[w] | other.words[w]; 139 if uw != self.words[w] { 140 added_bits = true; 141 self.words[w] = uw; 142 } 143 } 144 added_bits 145 } 146 } 147 148 impl Default for BitSet { default() -> BitSet149 fn default() -> BitSet { 150 BitSet::new() 151 } 152 } 153 154 impl BitAndAssign for BitSet { bitand_assign(&mut self, rhs: BitSet)155 fn bitand_assign(&mut self, rhs: BitSet) { 156 self.reserve_words(rhs.words.len()); 157 for w in 0..rhs.words.len() { 158 self.words[w] &= rhs.words[w]; 159 } 160 } 161 } 162 163 impl BitAnd<BitSet> for BitSet { 164 type Output = BitSet; 165 bitand(self, rhs: BitSet) -> BitSet166 fn bitand(self, rhs: BitSet) -> BitSet { 167 let mut res = self; 168 res.bitand_assign(rhs); 169 res 170 } 171 } 172 173 impl BitOrAssign for BitSet { bitor_assign(&mut self, rhs: BitSet)174 fn bitor_assign(&mut self, rhs: BitSet) { 175 self.reserve_words(rhs.words.len()); 176 for w in 0..rhs.words.len() { 177 self.words[w] |= rhs.words[w]; 178 } 179 } 180 } 181 182 impl BitOr<BitSet> for BitSet { 183 type Output = BitSet; 184 bitor(self, rhs: BitSet) -> BitSet185 fn bitor(self, rhs: BitSet) -> BitSet { 186 let mut res = self; 187 res.bitor_assign(rhs); 188 res 189 } 190 } 191 192 impl BitXorAssign for BitSet { bitxor_assign(&mut self, rhs: BitSet)193 fn bitxor_assign(&mut self, rhs: BitSet) { 194 self.reserve_words(rhs.words.len()); 195 for w in 0..rhs.words.len() { 196 self.words[w] ^= rhs.words[w]; 197 } 198 } 199 } 200 201 impl BitXor<BitSet> for BitSet { 202 type Output = BitSet; 203 bitxor(self, rhs: BitSet) -> BitSet204 fn bitxor(self, rhs: BitSet) -> BitSet { 205 let mut res = self; 206 res.bitxor_assign(rhs); 207 res 208 } 209 } 210 211 impl Not for BitSet { 212 type Output = BitSet; 213 not(self) -> BitSet214 fn not(self) -> BitSet { 215 let mut res = self; 216 for w in 0..res.words.len() { 217 res.words[w] = !res.words[w]; 218 } 219 res 220 } 221 } 222 223 pub struct BitSetIter<'a> { 224 set: &'a BitSet, 225 w: usize, 226 mask: u32, 227 } 228 229 impl<'a> BitSetIter<'a> { new(set: &'a BitSet, start: usize) -> Self230 fn new(set: &'a BitSet, start: usize) -> Self { 231 Self { 232 set, 233 w: start / 32, 234 mask: u32::MAX << (start % 32), 235 } 236 } 237 } 238 239 impl<'a> Iterator for BitSetIter<'a> { 240 type Item = usize; 241 next(&mut self) -> Option<usize>242 fn next(&mut self) -> Option<usize> { 243 while self.w < self.set.words.len() { 244 let b = (self.set.words[self.w] & self.mask).trailing_zeros(); 245 if b < 32 { 246 return Some(self.w * 32 + usize::try_from(b).unwrap()); 247 } 248 self.mask = u32::MAX; 249 self.w += 1; 250 } 251 None 252 } 253 } 254