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 24 #[allow(dead_code)] reserve(&mut self, bits: usize)25 pub fn reserve(&mut self, bits: usize) { 26 self.reserve_words(bits.div_ceil(32)); 27 } 28 clear(&mut self)29 pub fn clear(&mut self) { 30 for w in self.words.iter_mut() { 31 *w = 0; 32 } 33 } 34 get(&self, idx: usize) -> bool35 pub fn get(&self, idx: usize) -> bool { 36 let w = idx / 32; 37 let b = idx % 32; 38 if w < self.words.len() { 39 self.words[w] & (1_u32 << b) != 0 40 } else { 41 false 42 } 43 } 44 45 #[allow(dead_code)] is_empty(&self) -> bool46 pub fn is_empty(&self) -> bool { 47 for w in self.words.iter() { 48 if *w != 0 { 49 return false; 50 } 51 } 52 true 53 } 54 get_word(&self, word: usize) -> u3255 pub fn get_word(&self, word: usize) -> u32 { 56 self.words.get(word).cloned().unwrap_or(0) 57 } 58 59 #[allow(dead_code)] next_set(&self, start: usize) -> Option<usize>60 pub fn next_set(&self, start: usize) -> Option<usize> { 61 if start >= self.words.len() * 32 { 62 return None; 63 } 64 65 let mut w = start / 32; 66 let mut mask = u32::MAX << (start % 32); 67 while w < self.words.len() { 68 let b = (self.words[w] & mask).trailing_zeros(); 69 if b < 32 { 70 return Some(w * 32 + usize::try_from(b).unwrap()); 71 } 72 mask = u32::MAX; 73 w += 1; 74 } 75 None 76 } 77 78 #[allow(dead_code)] next_unset(&self, start: usize) -> usize79 pub fn next_unset(&self, start: usize) -> usize { 80 if start >= self.words.len() * 32 { 81 return start; 82 } 83 84 let mut w = start / 32; 85 let mut mask = !(u32::MAX << (start % 32)); 86 while w < self.words.len() { 87 let b = (self.words[w] | mask).trailing_ones(); 88 if b < 32 { 89 return w * 32 + usize::try_from(b).unwrap(); 90 } 91 mask = 0; 92 w += 1; 93 } 94 self.words.len() * 32 95 } 96 insert(&mut self, idx: usize) -> bool97 pub fn insert(&mut self, idx: usize) -> bool { 98 let w = idx / 32; 99 let b = idx % 32; 100 self.reserve_words(w + 1); 101 let exists = self.words[w] & (1_u32 << b) != 0; 102 self.words[w] |= 1_u32 << b; 103 !exists 104 } 105 remove(&mut self, idx: usize) -> bool106 pub fn remove(&mut self, idx: usize) -> bool { 107 let w = idx / 32; 108 let b = idx % 32; 109 self.reserve_words(w + 1); 110 let exists = self.words[w] & (1_u32 << b) != 0; 111 self.words[w] &= !(1_u32 << b); 112 exists 113 } 114 115 #[inline] set_word( &mut self, w: usize, mask: u32, f: &mut impl FnMut(usize) -> u32, )116 fn set_word( 117 &mut self, 118 w: usize, 119 mask: u32, 120 f: &mut impl FnMut(usize) -> u32, 121 ) { 122 self.words[w] = (self.words[w] & !mask) | (f(w) & mask); 123 } 124 set_words( &mut self, bits: Range<usize>, mut f: impl FnMut(usize) -> u32, )125 pub fn set_words( 126 &mut self, 127 bits: Range<usize>, 128 mut f: impl FnMut(usize) -> u32, 129 ) { 130 if bits.is_empty() { 131 return; 132 } 133 134 let first_word = bits.start / 32; 135 let last_word = (bits.end - 1) / 32; 136 let start_mask = !0_u32 << (bits.start % 32); 137 let end_mask = !0_u32 >> (31 - ((bits.end - 1) % 32)); 138 139 self.reserve(last_word + 1); 140 141 if first_word == last_word { 142 self.set_word(first_word, start_mask & end_mask, &mut f); 143 } else { 144 self.set_word(first_word, start_mask, &mut f); 145 for w in (first_word + 1)..last_word { 146 self.set_word(w, !0, &mut f); 147 } 148 self.set_word(last_word, end_mask, &mut f); 149 } 150 } 151 union_with(&mut self, other: &BitSet) -> bool152 pub fn union_with(&mut self, other: &BitSet) -> bool { 153 let mut added_bits = false; 154 self.reserve_words(other.words.len()); 155 for w in 0..other.words.len() { 156 let uw = self.words[w] | other.words[w]; 157 if uw != self.words[w] { 158 added_bits = true; 159 self.words[w] = uw; 160 } 161 } 162 added_bits 163 } 164 } 165 166 impl Default for BitSet { default() -> BitSet167 fn default() -> BitSet { 168 BitSet::new() 169 } 170 } 171 172 impl BitAndAssign for BitSet { bitand_assign(&mut self, rhs: BitSet)173 fn bitand_assign(&mut self, rhs: BitSet) { 174 self.reserve_words(rhs.words.len()); 175 for w in 0..rhs.words.len() { 176 self.words[w] &= rhs.words[w]; 177 } 178 } 179 } 180 181 impl BitAnd<BitSet> for BitSet { 182 type Output = BitSet; 183 bitand(self, rhs: BitSet) -> BitSet184 fn bitand(self, rhs: BitSet) -> BitSet { 185 let mut res = self; 186 res.bitand_assign(rhs); 187 res 188 } 189 } 190 191 impl BitOrAssign for BitSet { bitor_assign(&mut self, rhs: BitSet)192 fn bitor_assign(&mut self, rhs: BitSet) { 193 self.reserve_words(rhs.words.len()); 194 for w in 0..rhs.words.len() { 195 self.words[w] |= rhs.words[w]; 196 } 197 } 198 } 199 200 impl BitOr<BitSet> for BitSet { 201 type Output = BitSet; 202 bitor(self, rhs: BitSet) -> BitSet203 fn bitor(self, rhs: BitSet) -> BitSet { 204 let mut res = self; 205 res.bitor_assign(rhs); 206 res 207 } 208 } 209 210 impl BitXorAssign for BitSet { bitxor_assign(&mut self, rhs: BitSet)211 fn bitxor_assign(&mut self, rhs: BitSet) { 212 self.reserve_words(rhs.words.len()); 213 for w in 0..rhs.words.len() { 214 self.words[w] ^= rhs.words[w]; 215 } 216 } 217 } 218 219 impl BitXor<BitSet> for BitSet { 220 type Output = BitSet; 221 bitxor(self, rhs: BitSet) -> BitSet222 fn bitxor(self, rhs: BitSet) -> BitSet { 223 let mut res = self; 224 res.bitxor_assign(rhs); 225 res 226 } 227 } 228 229 impl Not for BitSet { 230 type Output = BitSet; 231 not(self) -> BitSet232 fn not(self) -> BitSet { 233 let mut res = self; 234 for w in 0..res.words.len() { 235 res.words[w] = !res.words[w]; 236 } 237 res 238 } 239 } 240