• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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