xref: /aosp_15_r20/external/mesa3d/src/compiler/rust/bitset.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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