]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_index/src/bit_set.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / compiler / rustc_index / src / bit_set.rs
CommitLineData
e74abb32 1use crate::vec::{Idx, IndexVec};
3dfed10e 2use arrayvec::ArrayVec;
0bf4aa26
XL
3use std::fmt;
4use std::iter;
5use std::marker::PhantomData;
6use std::mem;
3c0e092e 7use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl};
0bf4aa26 8use std::slice;
416331ca 9
3dfed10e
XL
10use rustc_macros::{Decodable, Encodable};
11
dc9dc135 12#[cfg(test)]
416331ca 13mod tests;
0bf4aa26
XL
14
15pub type Word = u64;
16pub const WORD_BYTES: usize = mem::size_of::<Word>();
17pub const WORD_BITS: usize = WORD_BYTES * 8;
18
94222f64
XL
19pub trait BitRelations<Rhs> {
20 fn union(&mut self, other: &Rhs) -> bool;
21 fn subtract(&mut self, other: &Rhs) -> bool;
22 fn intersect(&mut self, other: &Rhs) -> bool;
23}
24
3c0e092e
XL
25#[inline]
26fn inclusive_start_end<T: Idx>(
27 range: impl RangeBounds<T>,
28 domain: usize,
29) -> Option<(usize, usize)> {
30 // Both start and end are inclusive.
31 let start = match range.start_bound().cloned() {
32 Bound::Included(start) => start.index(),
33 Bound::Excluded(start) => start.index() + 1,
34 Bound::Unbounded => 0,
35 };
36 let end = match range.end_bound().cloned() {
37 Bound::Included(end) => end.index(),
38 Bound::Excluded(end) => end.index().checked_sub(1)?,
39 Bound::Unbounded => domain - 1,
40 };
41 assert!(end < domain);
42 if start > end {
43 return None;
44 }
45 Some((start, end))
46}
47
94222f64
XL
48macro_rules! bit_relations_inherent_impls {
49 () => {
50 /// Sets `self = self | other` and returns `true` if `self` changed
51 /// (i.e., if new bits were added).
52 pub fn union<Rhs>(&mut self, other: &Rhs) -> bool
53 where
54 Self: BitRelations<Rhs>,
55 {
56 <Self as BitRelations<Rhs>>::union(self, other)
57 }
58
59 /// Sets `self = self - other` and returns `true` if `self` changed.
60 /// (i.e., if any bits were removed).
61 pub fn subtract<Rhs>(&mut self, other: &Rhs) -> bool
62 where
63 Self: BitRelations<Rhs>,
64 {
65 <Self as BitRelations<Rhs>>::subtract(self, other)
66 }
67
68 /// Sets `self = self & other` and return `true` if `self` changed.
69 /// (i.e., if any bits were removed).
70 pub fn intersect<Rhs>(&mut self, other: &Rhs) -> bool
71 where
72 Self: BitRelations<Rhs>,
73 {
74 <Self as BitRelations<Rhs>>::intersect(self, other)
75 }
76 };
77}
78
e74abb32
XL
79/// A fixed-size bitset type with a dense representation.
80///
81/// NOTE: Use [`GrowableBitSet`] if you need support for resizing after creation.
0bf4aa26
XL
82///
83/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
84/// just be `usize`.
85///
86/// All operations that involve an element will panic if the element is equal
87/// to or greater than the domain size. All operations that involve two bitsets
88/// will panic if the bitsets have differing domain sizes.
e74abb32 89///
a2a8927a 90#[derive(Eq, PartialEq, Hash, Decodable, Encodable)]
1b1a35ee 91pub struct BitSet<T> {
0bf4aa26
XL
92 domain_size: usize,
93 words: Vec<Word>,
94 marker: PhantomData<T>,
95}
96
1b1a35ee
XL
97impl<T> BitSet<T> {
98 /// Gets the domain size.
99 pub fn domain_size(&self) -> usize {
100 self.domain_size
101 }
102}
103
0bf4aa26 104impl<T: Idx> BitSet<T> {
9fa01778 105 /// Creates a new, empty bitset with a given `domain_size`.
0bf4aa26
XL
106 #[inline]
107 pub fn new_empty(domain_size: usize) -> BitSet<T> {
108 let num_words = num_words(domain_size);
dfeec247 109 BitSet { domain_size, words: vec![0; num_words], marker: PhantomData }
0bf4aa26
XL
110 }
111
9fa01778 112 /// Creates a new, filled bitset with a given `domain_size`.
0bf4aa26
XL
113 #[inline]
114 pub fn new_filled(domain_size: usize) -> BitSet<T> {
115 let num_words = num_words(domain_size);
dfeec247 116 let mut result = BitSet { domain_size, words: vec![!0; num_words], marker: PhantomData };
0bf4aa26
XL
117 result.clear_excess_bits();
118 result
119 }
120
0bf4aa26
XL
121 /// Clear all elements.
122 #[inline]
123 pub fn clear(&mut self) {
124 for word in &mut self.words {
125 *word = 0;
126 }
127 }
128
129 /// Clear excess bits in the final word.
130 fn clear_excess_bits(&mut self) {
131 let num_bits_in_final_word = self.domain_size % WORD_BITS;
132 if num_bits_in_final_word > 0 {
133 let mask = (1 << num_bits_in_final_word) - 1;
134 let final_word_idx = self.words.len() - 1;
135 self.words[final_word_idx] &= mask;
136 }
137 }
138
0bf4aa26
XL
139 /// Count the number of set bits in the set.
140 pub fn count(&self) -> usize {
141 self.words.iter().map(|e| e.count_ones() as usize).sum()
142 }
143
9fa01778 144 /// Returns `true` if `self` contains `elem`.
0bf4aa26
XL
145 #[inline]
146 pub fn contains(&self, elem: T) -> bool {
147 assert!(elem.index() < self.domain_size);
148 let (word_index, mask) = word_index_and_mask(elem);
149 (self.words[word_index] & mask) != 0
150 }
151
152 /// Is `self` is a (non-strict) superset of `other`?
153 #[inline]
154 pub fn superset(&self, other: &BitSet<T>) -> bool {
155 assert_eq!(self.domain_size, other.domain_size);
156 self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b)
157 }
158
159 /// Is the set empty?
160 #[inline]
161 pub fn is_empty(&self) -> bool {
162 self.words.iter().all(|a| *a == 0)
163 }
164
9fa01778 165 /// Insert `elem`. Returns whether the set has changed.
0bf4aa26
XL
166 #[inline]
167 pub fn insert(&mut self, elem: T) -> bool {
168 assert!(elem.index() < self.domain_size);
169 let (word_index, mask) = word_index_and_mask(elem);
170 let word_ref = &mut self.words[word_index];
171 let word = *word_ref;
172 let new_word = word | mask;
173 *word_ref = new_word;
174 new_word != word
175 }
176
3c0e092e
XL
177 #[inline]
178 pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
179 let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
180 return;
181 };
182
183 let (start_word_index, start_mask) = word_index_and_mask(start);
184 let (end_word_index, end_mask) = word_index_and_mask(end);
185
186 // Set all words in between start and end (exclusively of both).
187 for word_index in (start_word_index + 1)..end_word_index {
188 self.words[word_index] = !0;
189 }
190
191 if start_word_index != end_word_index {
192 // Start and end are in different words, so we handle each in turn.
193 //
194 // We set all leading bits. This includes the start_mask bit.
195 self.words[start_word_index] |= !(start_mask - 1);
196 // And all trailing bits (i.e. from 0..=end) in the end word,
197 // including the end.
198 self.words[end_word_index] |= end_mask | end_mask - 1;
199 } else {
200 self.words[start_word_index] |= end_mask | (end_mask - start_mask);
201 }
202 }
203
0bf4aa26
XL
204 /// Sets all bits to true.
205 pub fn insert_all(&mut self) {
206 for word in &mut self.words {
207 *word = !0;
208 }
209 self.clear_excess_bits();
210 }
211
9fa01778 212 /// Returns `true` if the set has changed.
0bf4aa26
XL
213 #[inline]
214 pub fn remove(&mut self, elem: T) -> bool {
215 assert!(elem.index() < self.domain_size);
216 let (word_index, mask) = word_index_and_mask(elem);
217 let word_ref = &mut self.words[word_index];
218 let word = *word_ref;
219 let new_word = word & !mask;
220 *word_ref = new_word;
221 new_word != word
222 }
223
9fa01778 224 /// Gets a slice of the underlying words.
0bf4aa26
XL
225 pub fn words(&self) -> &[Word] {
226 &self.words
227 }
228
229 /// Iterates over the indices of set bits in a sorted order.
230 #[inline]
416331ca 231 pub fn iter(&self) -> BitIter<'_, T> {
e74abb32 232 BitIter::new(&self.words)
0bf4aa26
XL
233 }
234
235 /// Duplicates the set as a hybrid set.
236 pub fn to_hybrid(&self) -> HybridBitSet<T> {
237 // Note: we currently don't bother trying to make a Sparse set.
238 HybridBitSet::Dense(self.to_owned())
239 }
dc9dc135
XL
240
241 /// Set `self = self | other`. In contrast to `union` returns `true` if the set contains at
242 /// least one bit that is not in `other` (i.e. `other` is not a superset of `self`).
243 ///
244 /// This is an optimization for union of a hybrid bitset.
245 fn reverse_union_sparse(&mut self, sparse: &SparseBitSet<T>) -> bool {
246 assert!(sparse.domain_size == self.domain_size);
247 self.clear_excess_bits();
248
249 let mut not_already = false;
250 // Index of the current word not yet merged.
251 let mut current_index = 0;
252 // Mask of bits that came from the sparse set in the current word.
253 let mut new_bit_mask = 0;
254 for (word_index, mask) in sparse.iter().map(|x| word_index_and_mask(*x)) {
255 // Next bit is in a word not inspected yet.
256 if word_index > current_index {
257 self.words[current_index] |= new_bit_mask;
258 // Were there any bits in the old word that did not occur in the sparse set?
259 not_already |= (self.words[current_index] ^ new_bit_mask) != 0;
260 // Check all words we skipped for any set bit.
dfeec247 261 not_already |= self.words[current_index + 1..word_index].iter().any(|&x| x != 0);
dc9dc135
XL
262 // Update next word.
263 current_index = word_index;
264 // Reset bit mask, no bits have been merged yet.
265 new_bit_mask = 0;
266 }
267 // Add bit and mark it as coming from the sparse set.
268 // self.words[word_index] |= mask;
269 new_bit_mask |= mask;
270 }
271 self.words[current_index] |= new_bit_mask;
272 // Any bits in the last inspected word that were not in the sparse set?
273 not_already |= (self.words[current_index] ^ new_bit_mask) != 0;
274 // Any bits in the tail? Note `clear_excess_bits` before.
dfeec247 275 not_already |= self.words[current_index + 1..].iter().any(|&x| x != 0);
dc9dc135
XL
276
277 not_already
278 }
94222f64 279
3c0e092e
XL
280 fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
281 let (start, end) = inclusive_start_end(range, self.domain_size)?;
282 let (start_word_index, _) = word_index_and_mask(start);
283 let (end_word_index, end_mask) = word_index_and_mask(end);
284
285 let end_word = self.words[end_word_index] & (end_mask | (end_mask - 1));
286 if end_word != 0 {
287 let pos = max_bit(end_word) + WORD_BITS * end_word_index;
288 if start <= pos {
289 return Some(T::new(pos));
290 }
291 }
292
293 // We exclude end_word_index from the range here, because we don't want
294 // to limit ourselves to *just* the last word: the bits set it in may be
295 // after `end`, so it may not work out.
296 if let Some(offset) =
297 self.words[start_word_index..end_word_index].iter().rposition(|&w| w != 0)
298 {
299 let word_idx = start_word_index + offset;
300 let start_word = self.words[word_idx];
301 let pos = max_bit(start_word) + WORD_BITS * word_idx;
302 if start <= pos {
303 return Some(T::new(pos));
304 }
305 }
306
307 None
308 }
309
94222f64 310 bit_relations_inherent_impls! {}
0bf4aa26
XL
311}
312
94222f64
XL
313// dense REL dense
314impl<T: Idx> BitRelations<BitSet<T>> for BitSet<T> {
315 fn union(&mut self, other: &BitSet<T>) -> bool {
316 assert_eq!(self.domain_size, other.domain_size);
317 bitwise(&mut self.words, &other.words, |a, b| a | b)
318 }
319
320 fn subtract(&mut self, other: &BitSet<T>) -> bool {
321 assert_eq!(self.domain_size, other.domain_size);
322 bitwise(&mut self.words, &other.words, |a, b| a & !b)
323 }
324
325 fn intersect(&mut self, other: &BitSet<T>) -> bool {
326 assert_eq!(self.domain_size, other.domain_size);
327 bitwise(&mut self.words, &other.words, |a, b| a & b)
328 }
0bf4aa26
XL
329}
330
94222f64
XL
331// Applies a function to mutate a bitset, and returns true if any
332// of the applications return true
333fn sequential_update<T: Idx>(
334 mut self_update: impl FnMut(T) -> bool,
335 it: impl Iterator<Item = T>,
336) -> bool {
337 let mut changed = false;
338 for elem in it {
339 changed |= self_update(elem);
340 }
341 changed
0bf4aa26
XL
342}
343
94222f64
XL
344// Optimization of intersection for SparseBitSet that's generic
345// over the RHS
346fn sparse_intersect<T: Idx>(
347 set: &mut SparseBitSet<T>,
348 other_contains: impl Fn(&T) -> bool,
349) -> bool {
350 let size = set.elems.len();
351 set.elems.retain(|elem| other_contains(elem));
352 set.elems.len() != size
353}
354
355// Optimization of dense/sparse intersection. The resulting set is
356// guaranteed to be at most the size of the sparse set, and hence can be
357// represented as a sparse set. Therefore the sparse set is copied and filtered,
358// then returned as the new set.
359fn dense_sparse_intersect<T: Idx>(
360 dense: &BitSet<T>,
361 sparse: &SparseBitSet<T>,
362) -> (SparseBitSet<T>, bool) {
363 let mut sparse_copy = sparse.clone();
364 sparse_intersect(&mut sparse_copy, |el| dense.contains(*el));
365 let n = sparse_copy.len();
366 (sparse_copy, n != dense.count())
367}
368
369// hybrid REL dense
370impl<T: Idx> BitRelations<BitSet<T>> for HybridBitSet<T> {
371 fn union(&mut self, other: &BitSet<T>) -> bool {
372 assert_eq!(self.domain_size(), other.domain_size);
373 match self {
374 HybridBitSet::Sparse(sparse) => {
375 // `self` is sparse and `other` is dense. To
376 // merge them, we have two available strategies:
377 // * Densify `self` then merge other
378 // * Clone other then integrate bits from `self`
379 // The second strategy requires dedicated method
380 // since the usual `union` returns the wrong
381 // result. In the dedicated case the computation
382 // is slightly faster if the bits of the sparse
383 // bitset map to only few words of the dense
384 // representation, i.e. indices are near each
385 // other.
386 //
387 // Benchmarking seems to suggest that the second
388 // option is worth it.
389 let mut new_dense = other.clone();
390 let changed = new_dense.reverse_union_sparse(sparse);
391 *self = HybridBitSet::Dense(new_dense);
392 changed
393 }
394
395 HybridBitSet::Dense(dense) => dense.union(other),
396 }
397 }
398
399 fn subtract(&mut self, other: &BitSet<T>) -> bool {
400 assert_eq!(self.domain_size(), other.domain_size);
401 match self {
402 HybridBitSet::Sparse(sparse) => {
403 sequential_update(|elem| sparse.remove(elem), other.iter())
404 }
405 HybridBitSet::Dense(dense) => dense.subtract(other),
406 }
407 }
408
409 fn intersect(&mut self, other: &BitSet<T>) -> bool {
410 assert_eq!(self.domain_size(), other.domain_size);
411 match self {
412 HybridBitSet::Sparse(sparse) => sparse_intersect(sparse, |elem| other.contains(*elem)),
413 HybridBitSet::Dense(dense) => dense.intersect(other),
414 }
0bf4aa26
XL
415 }
416}
417
94222f64
XL
418// dense REL hybrid
419impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> {
420 fn union(&mut self, other: &HybridBitSet<T>) -> bool {
421 assert_eq!(self.domain_size, other.domain_size());
422 match other {
423 HybridBitSet::Sparse(sparse) => {
424 sequential_update(|elem| self.insert(elem), sparse.iter().cloned())
425 }
426 HybridBitSet::Dense(dense) => self.union(dense),
427 }
428 }
429
430 fn subtract(&mut self, other: &HybridBitSet<T>) -> bool {
431 assert_eq!(self.domain_size, other.domain_size());
432 match other {
433 HybridBitSet::Sparse(sparse) => {
434 sequential_update(|elem| self.remove(elem), sparse.iter().cloned())
435 }
436 HybridBitSet::Dense(dense) => self.subtract(dense),
437 }
438 }
439
440 fn intersect(&mut self, other: &HybridBitSet<T>) -> bool {
441 assert_eq!(self.domain_size, other.domain_size());
442 match other {
443 HybridBitSet::Sparse(sparse) => {
444 let (updated, changed) = dense_sparse_intersect(self, sparse);
445
446 // We can't directly assign the SparseBitSet to the BitSet, and
447 // doing `*self = updated.to_dense()` would cause a drop / reallocation. Instead,
448 // the BitSet is cleared and `updated` is copied into `self`.
449 self.clear();
450 for elem in updated.iter() {
451 self.insert(*elem);
452 }
453 changed
454 }
455 HybridBitSet::Dense(dense) => self.intersect(dense),
456 }
457 }
458}
459
460// hybrid REL hybrid
461impl<T: Idx> BitRelations<HybridBitSet<T>> for HybridBitSet<T> {
462 fn union(&mut self, other: &HybridBitSet<T>) -> bool {
463 assert_eq!(self.domain_size(), other.domain_size());
464 match self {
465 HybridBitSet::Sparse(_) => {
466 match other {
467 HybridBitSet::Sparse(other_sparse) => {
468 // Both sets are sparse. Add the elements in
469 // `other_sparse` to `self` one at a time. This
470 // may or may not cause `self` to be densified.
471 let mut changed = false;
472 for elem in other_sparse.iter() {
473 changed |= self.insert(*elem);
474 }
475 changed
476 }
477
478 HybridBitSet::Dense(other_dense) => self.union(other_dense),
479 }
480 }
481
482 HybridBitSet::Dense(self_dense) => self_dense.union(other),
483 }
484 }
485
486 fn subtract(&mut self, other: &HybridBitSet<T>) -> bool {
487 assert_eq!(self.domain_size(), other.domain_size());
488 match self {
489 HybridBitSet::Sparse(self_sparse) => {
490 sequential_update(|elem| self_sparse.remove(elem), other.iter())
491 }
492 HybridBitSet::Dense(self_dense) => self_dense.subtract(other),
493 }
494 }
495
496 fn intersect(&mut self, other: &HybridBitSet<T>) -> bool {
497 assert_eq!(self.domain_size(), other.domain_size());
498 match self {
499 HybridBitSet::Sparse(self_sparse) => {
500 sparse_intersect(self_sparse, |elem| other.contains(*elem))
501 }
502 HybridBitSet::Dense(self_dense) => match other {
503 HybridBitSet::Sparse(other_sparse) => {
504 let (updated, changed) = dense_sparse_intersect(self_dense, other_sparse);
505 *self = HybridBitSet::Sparse(updated);
506 changed
507 }
508 HybridBitSet::Dense(other_dense) => self_dense.intersect(other_dense),
509 },
510 }
0bf4aa26
XL
511 }
512}
513
1b1a35ee
XL
514impl<T> Clone for BitSet<T> {
515 fn clone(&self) -> Self {
516 BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData }
517 }
518
519 fn clone_from(&mut self, from: &Self) {
520 if self.domain_size != from.domain_size {
521 self.words.resize(from.domain_size, 0);
522 self.domain_size = from.domain_size;
523 }
524
525 self.words.copy_from_slice(&from.words);
526 }
527}
528
0bf4aa26 529impl<T: Idx> fmt::Debug for BitSet<T> {
9fa01778 530 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
dfeec247 531 w.debug_list().entries(self.iter()).finish()
0bf4aa26
XL
532 }
533}
534
535impl<T: Idx> ToString for BitSet<T> {
536 fn to_string(&self) -> String {
537 let mut result = String::new();
538 let mut sep = '[';
539
540 // Note: this is a little endian printout of bytes.
541
542 // i tracks how many bits we have printed so far.
543 let mut i = 0;
544 for word in &self.words {
545 let mut word = *word;
dfeec247
XL
546 for _ in 0..WORD_BYTES {
547 // for each byte in `word`:
0bf4aa26
XL
548 let remain = self.domain_size - i;
549 // If less than a byte remains, then mask just that many bits.
550 let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
551 assert!(mask <= 0xFF);
552 let byte = word & mask;
553
554 result.push_str(&format!("{}{:02x}", sep, byte));
555
dfeec247
XL
556 if remain <= 8 {
557 break;
558 }
0bf4aa26
XL
559 word >>= 8;
560 i += 8;
561 sep = '-';
562 }
563 sep = '|';
564 }
565 result.push(']');
566
567 result
568 }
569}
570
571pub struct BitIter<'a, T: Idx> {
e74abb32
XL
572 /// A copy of the current word, but with any already-visited bits cleared.
573 /// (This lets us use `trailing_zeros()` to find the next set bit.) When it
574 /// is reduced to 0, we move onto the next word.
575 word: Word,
576
577 /// The offset (measured in bits) of the current word.
578 offset: usize,
579
580 /// Underlying iterator over the words.
581 iter: slice::Iter<'a, Word>,
582
dfeec247 583 marker: PhantomData<T>,
0bf4aa26
XL
584}
585
e74abb32
XL
586impl<'a, T: Idx> BitIter<'a, T> {
587 #[inline]
588 fn new(words: &'a [Word]) -> BitIter<'a, T> {
589 // We initialize `word` and `offset` to degenerate values. On the first
590 // call to `next()` we will fall through to getting the first word from
591 // `iter`, which sets `word` to the first word (if there is one) and
592 // `offset` to 0. Doing it this way saves us from having to maintain
593 // additional state about whether we have started.
594 BitIter {
595 word: 0,
ba9703b0 596 offset: usize::MAX - (WORD_BITS - 1),
e74abb32
XL
597 iter: words.iter(),
598 marker: PhantomData,
599 }
600 }
601}
602
0bf4aa26
XL
603impl<'a, T: Idx> Iterator for BitIter<'a, T> {
604 type Item = T;
605 fn next(&mut self) -> Option<T> {
606 loop {
e74abb32
XL
607 if self.word != 0 {
608 // Get the position of the next set bit in the current word,
609 // then clear the bit.
610 let bit_pos = self.word.trailing_zeros() as usize;
611 let bit = 1 << bit_pos;
612 self.word ^= bit;
dfeec247 613 return Some(T::new(bit_pos + self.offset));
0bf4aa26
XL
614 }
615
e74abb32
XL
616 // Move onto the next word. `wrapping_add()` is needed to handle
617 // the degenerate initial value given to `offset` in `new()`.
618 let word = self.iter.next()?;
619 self.word = *word;
620 self.offset = self.offset.wrapping_add(WORD_BITS);
0bf4aa26
XL
621 }
622 }
623}
624
0bf4aa26
XL
625#[inline]
626fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
dfeec247
XL
627where
628 Op: Fn(Word, Word) -> Word,
0bf4aa26
XL
629{
630 assert_eq!(out_vec.len(), in_vec.len());
17df50a5 631 let mut changed = 0;
cdc7bbd5 632 for (out_elem, in_elem) in iter::zip(out_vec, in_vec) {
0bf4aa26
XL
633 let old_val = *out_elem;
634 let new_val = op(old_val, *in_elem);
635 *out_elem = new_val;
17df50a5
XL
636 // This is essentially equivalent to a != with changed being a bool, but
637 // in practice this code gets auto-vectorized by the compiler for most
638 // operators. Using != here causes us to generate quite poor code as the
639 // compiler tries to go back to a boolean on each loop iteration.
640 changed |= old_val ^ new_val;
0bf4aa26 641 }
17df50a5 642 changed != 0
0bf4aa26
XL
643}
644
645const SPARSE_MAX: usize = 8;
646
647/// A fixed-size bitset type with a sparse representation and a maximum of
3dfed10e
XL
648/// `SPARSE_MAX` elements. The elements are stored as a sorted `ArrayVec` with
649/// no duplicates.
0bf4aa26
XL
650///
651/// This type is used by `HybridBitSet`; do not use directly.
652#[derive(Clone, Debug)]
1b1a35ee 653pub struct SparseBitSet<T> {
0bf4aa26 654 domain_size: usize,
cdc7bbd5 655 elems: ArrayVec<T, SPARSE_MAX>,
0bf4aa26
XL
656}
657
658impl<T: Idx> SparseBitSet<T> {
659 fn new_empty(domain_size: usize) -> Self {
3dfed10e 660 SparseBitSet { domain_size, elems: ArrayVec::new() }
0bf4aa26
XL
661 }
662
663 fn len(&self) -> usize {
664 self.elems.len()
665 }
666
667 fn is_empty(&self) -> bool {
668 self.elems.len() == 0
669 }
670
671 fn contains(&self, elem: T) -> bool {
672 assert!(elem.index() < self.domain_size);
673 self.elems.contains(&elem)
674 }
675
676 fn insert(&mut self, elem: T) -> bool {
677 assert!(elem.index() < self.domain_size);
a2a8927a 678 let changed = if let Some(i) = self.elems.iter().position(|&e| e.index() >= elem.index()) {
0bf4aa26
XL
679 if self.elems[i] == elem {
680 // `elem` is already in the set.
681 false
682 } else {
683 // `elem` is smaller than one or more existing elements.
684 self.elems.insert(i, elem);
685 true
686 }
687 } else {
688 // `elem` is larger than all existing elements.
689 self.elems.push(elem);
690 true
691 };
692 assert!(self.len() <= SPARSE_MAX);
693 changed
694 }
695
696 fn remove(&mut self, elem: T) -> bool {
697 assert!(elem.index() < self.domain_size);
698 if let Some(i) = self.elems.iter().position(|&e| e == elem) {
699 self.elems.remove(i);
700 true
701 } else {
702 false
703 }
704 }
705
706 fn to_dense(&self) -> BitSet<T> {
707 let mut dense = BitSet::new_empty(self.domain_size);
708 for elem in self.elems.iter() {
709 dense.insert(*elem);
710 }
711 dense
712 }
713
9fa01778 714 fn iter(&self) -> slice::Iter<'_, T> {
0bf4aa26
XL
715 self.elems.iter()
716 }
0bf4aa26 717
a2a8927a
XL
718 bit_relations_inherent_impls! {}
719}
720
721impl<T: Idx + Ord> SparseBitSet<T> {
3c0e092e
XL
722 fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
723 let mut last_leq = None;
724 for e in self.iter() {
725 if range.contains(e) {
726 last_leq = Some(*e);
727 }
728 }
729 last_leq
730 }
0bf4aa26
XL
731}
732
733/// A fixed-size bitset type with a hybrid representation: sparse when there
734/// are up to a `SPARSE_MAX` elements in the set, but dense when there are more
735/// than `SPARSE_MAX`.
736///
737/// This type is especially efficient for sets that typically have a small
738/// number of elements, but a large `domain_size`, and are cleared frequently.
739///
740/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
741/// just be `usize`.
742///
743/// All operations that involve an element will panic if the element is equal
744/// to or greater than the domain size. All operations that involve two bitsets
745/// will panic if the bitsets have differing domain sizes.
1b1a35ee
XL
746#[derive(Clone)]
747pub enum HybridBitSet<T> {
0bf4aa26
XL
748 Sparse(SparseBitSet<T>),
749 Dense(BitSet<T>),
750}
751
1b1a35ee
XL
752impl<T: Idx> fmt::Debug for HybridBitSet<T> {
753 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
754 match self {
755 Self::Sparse(b) => b.fmt(w),
756 Self::Dense(b) => b.fmt(w),
757 }
758 }
759}
760
0bf4aa26
XL
761impl<T: Idx> HybridBitSet<T> {
762 pub fn new_empty(domain_size: usize) -> Self {
763 HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
764 }
765
1b1a35ee 766 pub fn domain_size(&self) -> usize {
0bf4aa26
XL
767 match self {
768 HybridBitSet::Sparse(sparse) => sparse.domain_size,
769 HybridBitSet::Dense(dense) => dense.domain_size,
770 }
771 }
772
773 pub fn clear(&mut self) {
774 let domain_size = self.domain_size();
775 *self = HybridBitSet::new_empty(domain_size);
776 }
777
778 pub fn contains(&self, elem: T) -> bool {
779 match self {
780 HybridBitSet::Sparse(sparse) => sparse.contains(elem),
781 HybridBitSet::Dense(dense) => dense.contains(elem),
782 }
783 }
784
785 pub fn superset(&self, other: &HybridBitSet<T>) -> bool {
786 match (self, other) {
787 (HybridBitSet::Dense(self_dense), HybridBitSet::Dense(other_dense)) => {
788 self_dense.superset(other_dense)
789 }
790 _ => {
791 assert!(self.domain_size() == other.domain_size());
792 other.iter().all(|elem| self.contains(elem))
793 }
794 }
795 }
796
797 pub fn is_empty(&self) -> bool {
798 match self {
799 HybridBitSet::Sparse(sparse) => sparse.is_empty(),
800 HybridBitSet::Dense(dense) => dense.is_empty(),
801 }
802 }
803
3c0e092e
XL
804 /// Returns the previous element present in the bitset from `elem`,
805 /// inclusively of elem. That is, will return `Some(elem)` if elem is in the
806 /// bitset.
a2a8927a
XL
807 pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T>
808 where
809 T: Ord,
810 {
3c0e092e
XL
811 match self {
812 HybridBitSet::Sparse(sparse) => sparse.last_set_in(range),
813 HybridBitSet::Dense(dense) => dense.last_set_in(range),
814 }
815 }
816
0bf4aa26
XL
817 pub fn insert(&mut self, elem: T) -> bool {
818 // No need to check `elem` against `self.domain_size` here because all
819 // the match cases check it, one way or another.
820 match self {
821 HybridBitSet::Sparse(sparse) if sparse.len() < SPARSE_MAX => {
822 // The set is sparse and has space for `elem`.
823 sparse.insert(elem)
824 }
825 HybridBitSet::Sparse(sparse) if sparse.contains(elem) => {
826 // The set is sparse and does not have space for `elem`, but
827 // that doesn't matter because `elem` is already present.
828 false
829 }
830 HybridBitSet::Sparse(sparse) => {
831 // The set is sparse and full. Convert to a dense set.
832 let mut dense = sparse.to_dense();
833 let changed = dense.insert(elem);
834 assert!(changed);
835 *self = HybridBitSet::Dense(dense);
836 changed
837 }
838 HybridBitSet::Dense(dense) => dense.insert(elem),
839 }
840 }
841
3c0e092e
XL
842 pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
843 // No need to check `elem` against `self.domain_size` here because all
844 // the match cases check it, one way or another.
845 let start = match elems.start_bound().cloned() {
846 Bound::Included(start) => start.index(),
847 Bound::Excluded(start) => start.index() + 1,
848 Bound::Unbounded => 0,
849 };
850 let end = match elems.end_bound().cloned() {
851 Bound::Included(end) => end.index() + 1,
852 Bound::Excluded(end) => end.index(),
853 Bound::Unbounded => self.domain_size() - 1,
854 };
5099ac24 855 let Some(len) = end.checked_sub(start) else { return };
3c0e092e
XL
856 match self {
857 HybridBitSet::Sparse(sparse) if sparse.len() + len < SPARSE_MAX => {
858 // The set is sparse and has space for `elems`.
859 for elem in start..end {
860 sparse.insert(T::new(elem));
861 }
862 }
863 HybridBitSet::Sparse(sparse) => {
864 // The set is sparse and full. Convert to a dense set.
865 let mut dense = sparse.to_dense();
866 dense.insert_range(elems);
867 *self = HybridBitSet::Dense(dense);
868 }
869 HybridBitSet::Dense(dense) => dense.insert_range(elems),
870 }
871 }
872
0bf4aa26
XL
873 pub fn insert_all(&mut self) {
874 let domain_size = self.domain_size();
875 match self {
876 HybridBitSet::Sparse(_) => {
877 *self = HybridBitSet::Dense(BitSet::new_filled(domain_size));
878 }
879 HybridBitSet::Dense(dense) => dense.insert_all(),
880 }
881 }
882
883 pub fn remove(&mut self, elem: T) -> bool {
884 // Note: we currently don't bother going from Dense back to Sparse.
885 match self {
886 HybridBitSet::Sparse(sparse) => sparse.remove(elem),
887 HybridBitSet::Dense(dense) => dense.remove(elem),
888 }
889 }
890
0bf4aa26
XL
891 /// Converts to a dense set, consuming itself in the process.
892 pub fn to_dense(self) -> BitSet<T> {
893 match self {
894 HybridBitSet::Sparse(sparse) => sparse.to_dense(),
895 HybridBitSet::Dense(dense) => dense,
896 }
897 }
898
9fa01778 899 pub fn iter(&self) -> HybridIter<'_, T> {
0bf4aa26
XL
900 match self {
901 HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()),
902 HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()),
903 }
904 }
0bf4aa26 905
94222f64 906 bit_relations_inherent_impls! {}
0bf4aa26
XL
907}
908
909pub enum HybridIter<'a, T: Idx> {
910 Sparse(slice::Iter<'a, T>),
911 Dense(BitIter<'a, T>),
912}
913
914impl<'a, T: Idx> Iterator for HybridIter<'a, T> {
915 type Item = T;
916
917 fn next(&mut self) -> Option<T> {
918 match self {
e74abb32 919 HybridIter::Sparse(sparse) => sparse.next().copied(),
0bf4aa26
XL
920 HybridIter::Dense(dense) => dense.next(),
921 }
922 }
923}
924
925/// A resizable bitset type with a dense representation.
926///
927/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
928/// just be `usize`.
929///
930/// All operations that involve an element will panic if the element is equal
931/// to or greater than the domain size.
932#[derive(Clone, Debug, PartialEq)]
933pub struct GrowableBitSet<T: Idx> {
934 bit_set: BitSet<T>,
935}
936
5099ac24
FG
937impl<T: Idx> Default for GrowableBitSet<T> {
938 fn default() -> Self {
939 GrowableBitSet::new_empty()
940 }
941}
942
0bf4aa26
XL
943impl<T: Idx> GrowableBitSet<T> {
944 /// Ensure that the set can hold at least `min_domain_size` elements.
945 pub fn ensure(&mut self, min_domain_size: usize) {
946 if self.bit_set.domain_size < min_domain_size {
947 self.bit_set.domain_size = min_domain_size;
948 }
949
950 let min_num_words = num_words(min_domain_size);
951 if self.bit_set.words.len() < min_num_words {
952 self.bit_set.words.resize(min_num_words, 0)
953 }
954 }
955
956 pub fn new_empty() -> GrowableBitSet<T> {
957 GrowableBitSet { bit_set: BitSet::new_empty(0) }
958 }
959
48663c56
XL
960 pub fn with_capacity(capacity: usize) -> GrowableBitSet<T> {
961 GrowableBitSet { bit_set: BitSet::new_empty(capacity) }
0bf4aa26
XL
962 }
963
9fa01778 964 /// Returns `true` if the set has changed.
0bf4aa26
XL
965 #[inline]
966 pub fn insert(&mut self, elem: T) -> bool {
967 self.ensure(elem.index() + 1);
968 self.bit_set.insert(elem)
969 }
970
5869c6ff
XL
971 /// Returns `true` if the set has changed.
972 #[inline]
973 pub fn remove(&mut self, elem: T) -> bool {
974 self.ensure(elem.index() + 1);
975 self.bit_set.remove(elem)
976 }
977
978 #[inline]
979 pub fn is_empty(&self) -> bool {
980 self.bit_set.is_empty()
981 }
982
0bf4aa26
XL
983 #[inline]
984 pub fn contains(&self, elem: T) -> bool {
985 let (word_index, mask) = word_index_and_mask(elem);
c295e0f8 986 self.bit_set.words.get(word_index).map_or(false, |word| (word & mask) != 0)
0bf4aa26
XL
987 }
988}
989
990/// A fixed-size 2D bit matrix type with a dense representation.
991///
992/// `R` and `C` are index types used to identify rows and columns respectively;
993/// typically newtyped `usize` wrappers, but they can also just be `usize`.
994///
995/// All operations that involve a row and/or column index will panic if the
996/// index exceeds the relevant bound.
a2a8927a 997#[derive(Clone, Eq, PartialEq, Hash, Decodable, Encodable)]
0bf4aa26
XL
998pub struct BitMatrix<R: Idx, C: Idx> {
999 num_rows: usize,
1000 num_columns: usize,
1001 words: Vec<Word>,
1002 marker: PhantomData<(R, C)>,
1003}
1004
1005impl<R: Idx, C: Idx> BitMatrix<R, C> {
9fa01778 1006 /// Creates a new `rows x columns` matrix, initially empty.
0bf4aa26
XL
1007 pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix<R, C> {
1008 // For every element, we need one bit for every other
1009 // element. Round up to an even number of words.
1010 let words_per_row = num_words(num_columns);
1011 BitMatrix {
1012 num_rows,
1013 num_columns,
1014 words: vec![0; num_rows * words_per_row],
1015 marker: PhantomData,
1016 }
1017 }
1018
dc9dc135
XL
1019 /// Creates a new matrix, with `row` used as the value for every row.
1020 pub fn from_row_n(row: &BitSet<C>, num_rows: usize) -> BitMatrix<R, C> {
1021 let num_columns = row.domain_size();
1022 let words_per_row = num_words(num_columns);
1023 assert_eq!(words_per_row, row.words().len());
1024 BitMatrix {
1025 num_rows,
1026 num_columns,
1027 words: iter::repeat(row.words()).take(num_rows).flatten().cloned().collect(),
1028 marker: PhantomData,
1029 }
1030 }
1031
1032 pub fn rows(&self) -> impl Iterator<Item = R> {
1033 (0..self.num_rows).map(R::new)
1034 }
1035
0bf4aa26
XL
1036 /// The range of bits for a given row.
1037 fn range(&self, row: R) -> (usize, usize) {
1038 let words_per_row = num_words(self.num_columns);
1039 let start = row.index() * words_per_row;
1040 (start, start + words_per_row)
1041 }
1042
1043 /// Sets the cell at `(row, column)` to true. Put another way, insert
1044 /// `column` to the bitset for `row`.
1045 ///
9fa01778 1046 /// Returns `true` if this changed the matrix.
0bf4aa26
XL
1047 pub fn insert(&mut self, row: R, column: C) -> bool {
1048 assert!(row.index() < self.num_rows && column.index() < self.num_columns);
1049 let (start, _) = self.range(row);
1050 let (word_index, mask) = word_index_and_mask(column);
1051 let words = &mut self.words[..];
1052 let word = words[start + word_index];
1053 let new_word = word | mask;
1054 words[start + word_index] = new_word;
1055 word != new_word
1056 }
1057
1058 /// Do the bits from `row` contain `column`? Put another way, is
1059 /// the matrix cell at `(row, column)` true? Put yet another way,
1060 /// if the matrix represents (transitive) reachability, can
1061 /// `row` reach `column`?
1062 pub fn contains(&self, row: R, column: C) -> bool {
1063 assert!(row.index() < self.num_rows && column.index() < self.num_columns);
1064 let (start, _) = self.range(row);
1065 let (word_index, mask) = word_index_and_mask(column);
1066 (self.words[start + word_index] & mask) != 0
1067 }
1068
9fa01778 1069 /// Returns those indices that are true in rows `a` and `b`. This
3dfed10e 1070 /// is an *O*(*n*) operation where *n* is the number of elements
0bf4aa26
XL
1071 /// (somewhat independent from the actual size of the
1072 /// intersection, in particular).
1073 pub fn intersect_rows(&self, row1: R, row2: R) -> Vec<C> {
1074 assert!(row1.index() < self.num_rows && row2.index() < self.num_rows);
1075 let (row1_start, row1_end) = self.range(row1);
1076 let (row2_start, row2_end) = self.range(row2);
1077 let mut result = Vec::with_capacity(self.num_columns);
1078 for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() {
1079 let mut v = self.words[i] & self.words[j];
1080 for bit in 0..WORD_BITS {
1081 if v == 0 {
1082 break;
1083 }
1084 if v & 0x1 != 0 {
1085 result.push(C::new(base * WORD_BITS + bit));
1086 }
1087 v >>= 1;
1088 }
1089 }
1090 result
1091 }
1092
9fa01778
XL
1093 /// Adds the bits from row `read` to the bits from row `write`, and
1094 /// returns `true` if anything changed.
0bf4aa26
XL
1095 ///
1096 /// This is used when computing transitive reachability because if
1097 /// you have an edge `write -> read`, because in that case
1098 /// `write` can reach everything that `read` can (and
1099 /// potentially more).
1100 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1101 assert!(read.index() < self.num_rows && write.index() < self.num_rows);
1102 let (read_start, read_end) = self.range(read);
1103 let (write_start, write_end) = self.range(write);
1104 let words = &mut self.words[..];
1105 let mut changed = false;
cdc7bbd5 1106 for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) {
0bf4aa26
XL
1107 let word = words[write_index];
1108 let new_word = word | words[read_index];
1109 words[write_index] = new_word;
1110 changed |= word != new_word;
1111 }
1112 changed
1113 }
1114
dc9dc135
XL
1115 /// Adds the bits from `with` to the bits from row `write`, and
1116 /// returns `true` if anything changed.
1117 pub fn union_row_with(&mut self, with: &BitSet<C>, write: R) -> bool {
1118 assert!(write.index() < self.num_rows);
1119 assert_eq!(with.domain_size(), self.num_columns);
1120 let (write_start, write_end) = self.range(write);
1121 let mut changed = false;
cdc7bbd5 1122 for (read_index, write_index) in iter::zip(0..with.words().len(), write_start..write_end) {
dc9dc135
XL
1123 let word = self.words[write_index];
1124 let new_word = word | with.words()[read_index];
1125 self.words[write_index] = new_word;
1126 changed |= word != new_word;
1127 }
1128 changed
1129 }
1130
1131 /// Sets every cell in `row` to true.
1132 pub fn insert_all_into_row(&mut self, row: R) {
1133 assert!(row.index() < self.num_rows);
1134 let (start, end) = self.range(row);
3c0e092e
XL
1135 let words = &mut self.words[..];
1136 for index in start..end {
1137 words[index] = !0;
dc9dc135
XL
1138 }
1139 self.clear_excess_bits(row);
1140 }
1141
1142 /// Clear excess bits in the final word of the row.
1143 fn clear_excess_bits(&mut self, row: R) {
1144 let num_bits_in_final_word = self.num_columns % WORD_BITS;
1145 if num_bits_in_final_word > 0 {
1146 let mask = (1 << num_bits_in_final_word) - 1;
1147 let (_, end) = self.range(row);
1148 let final_word_idx = end - 1;
1149 self.words[final_word_idx] &= mask;
1150 }
1151 }
1152
1153 /// Gets a slice of the underlying words.
1154 pub fn words(&self) -> &[Word] {
1155 &self.words
1156 }
1157
0bf4aa26
XL
1158 /// Iterates through all the columns set to true in a given row of
1159 /// the matrix.
416331ca 1160 pub fn iter(&self, row: R) -> BitIter<'_, C> {
0bf4aa26
XL
1161 assert!(row.index() < self.num_rows);
1162 let (start, end) = self.range(row);
e74abb32 1163 BitIter::new(&self.words[start..end])
0bf4aa26 1164 }
dc9dc135
XL
1165
1166 /// Returns the number of elements in `row`.
1167 pub fn count(&self, row: R) -> usize {
1168 let (start, end) = self.range(row);
1169 self.words[start..end].iter().map(|e| e.count_ones() as usize).sum()
1170 }
0bf4aa26
XL
1171}
1172
f035d41b
XL
1173impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
1174 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1175 /// Forces its contents to print in regular mode instead of alternate mode.
1176 struct OneLinePrinter<T>(T);
1177 impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
1178 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1179 write!(fmt, "{:?}", self.0)
1180 }
1181 }
1182
1183 write!(fmt, "BitMatrix({}x{}) ", self.num_rows, self.num_columns)?;
1184 let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
1185 fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
1186 }
1187}
1188
0bf4aa26
XL
1189/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately
1190/// sparse representation.
1191///
1192/// Initially, every row has no explicit representation. If any bit within a
1193/// row is set, the entire row is instantiated as `Some(<HybridBitSet>)`.
1194/// Furthermore, any previously uninstantiated rows prior to it will be
1195/// instantiated as `None`. Those prior rows may themselves become fully
1196/// instantiated later on if any of their bits are set.
1197///
1198/// `R` and `C` are index types used to identify rows and columns respectively;
1199/// typically newtyped `usize` wrappers, but they can also just be `usize`.
1200#[derive(Clone, Debug)]
1201pub struct SparseBitMatrix<R, C>
1202where
1203 R: Idx,
1204 C: Idx,
1205{
1206 num_columns: usize,
1207 rows: IndexVec<R, Option<HybridBitSet<C>>>,
1208}
1209
1210impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
9fa01778 1211 /// Creates a new empty sparse bit matrix with no rows or columns.
0bf4aa26 1212 pub fn new(num_columns: usize) -> Self {
dfeec247 1213 Self { num_columns, rows: IndexVec::new() }
0bf4aa26
XL
1214 }
1215
1216 fn ensure_row(&mut self, row: R) -> &mut HybridBitSet<C> {
c295e0f8 1217 // Instantiate any missing rows up to and including row `row` with an empty HybridBitSet.
0bf4aa26 1218 // Then replace row `row` with a full HybridBitSet if necessary.
c295e0f8 1219 self.rows.get_or_insert_with(row, || HybridBitSet::new_empty(self.num_columns))
0bf4aa26
XL
1220 }
1221
1222 /// Sets the cell at `(row, column)` to true. Put another way, insert
1223 /// `column` to the bitset for `row`.
1224 ///
9fa01778 1225 /// Returns `true` if this changed the matrix.
0bf4aa26
XL
1226 pub fn insert(&mut self, row: R, column: C) -> bool {
1227 self.ensure_row(row).insert(column)
1228 }
1229
94222f64
XL
1230 /// Sets the cell at `(row, column)` to false. Put another way, delete
1231 /// `column` from the bitset for `row`. Has no effect if `row` does not
1232 /// exist.
1233 ///
1234 /// Returns `true` if this changed the matrix.
1235 pub fn remove(&mut self, row: R, column: C) -> bool {
1236 match self.rows.get_mut(row) {
1237 Some(Some(row)) => row.remove(column),
1238 _ => false,
1239 }
1240 }
1241
1242 /// Sets all columns at `row` to false. Has no effect if `row` does
1243 /// not exist.
1244 pub fn clear(&mut self, row: R) {
1245 if let Some(Some(row)) = self.rows.get_mut(row) {
1246 row.clear();
1247 }
1248 }
1249
0bf4aa26
XL
1250 /// Do the bits from `row` contain `column`? Put another way, is
1251 /// the matrix cell at `(row, column)` true? Put yet another way,
1252 /// if the matrix represents (transitive) reachability, can
1253 /// `row` reach `column`?
1254 pub fn contains(&self, row: R, column: C) -> bool {
1255 self.row(row).map_or(false, |r| r.contains(column))
1256 }
1257
9fa01778
XL
1258 /// Adds the bits from row `read` to the bits from row `write`, and
1259 /// returns `true` if anything changed.
0bf4aa26
XL
1260 ///
1261 /// This is used when computing transitive reachability because if
1262 /// you have an edge `write -> read`, because in that case
1263 /// `write` can reach everything that `read` can (and
1264 /// potentially more).
1265 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1266 if read == write || self.row(read).is_none() {
1267 return false;
1268 }
1269
1270 self.ensure_row(write);
1271 if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) {
1272 write_row.union(read_row)
1273 } else {
1274 unreachable!()
1275 }
1276 }
1277
0bf4aa26
XL
1278 /// Insert all bits in the given row.
1279 pub fn insert_all_into_row(&mut self, row: R) {
1280 self.ensure_row(row).insert_all();
1281 }
1282
1283 pub fn rows(&self) -> impl Iterator<Item = R> {
1284 self.rows.indices()
1285 }
1286
1287 /// Iterates through all the columns set to true in a given row of
1288 /// the matrix.
3c0e092e 1289 pub fn iter<'a>(&'a self, row: R) -> impl Iterator<Item = C> + 'a {
0bf4aa26
XL
1290 self.row(row).into_iter().flat_map(|r| r.iter())
1291 }
1292
1293 pub fn row(&self, row: R) -> Option<&HybridBitSet<C>> {
dfeec247 1294 if let Some(Some(row)) = self.rows.get(row) { Some(row) } else { None }
0bf4aa26 1295 }
94222f64
XL
1296
1297 /// Interescts `row` with `set`. `set` can be either `BitSet` or
1298 /// `HybridBitSet`. Has no effect if `row` does not exist.
1299 ///
1300 /// Returns true if the row was changed.
1301 pub fn intersect_row<Set>(&mut self, row: R, set: &Set) -> bool
1302 where
1303 HybridBitSet<C>: BitRelations<Set>,
1304 {
1305 match self.rows.get_mut(row) {
1306 Some(Some(row)) => row.intersect(set),
1307 _ => false,
1308 }
1309 }
1310
1311 /// Subtracts `set from `row`. `set` can be either `BitSet` or
1312 /// `HybridBitSet`. Has no effect if `row` does not exist.
1313 ///
1314 /// Returns true if the row was changed.
1315 pub fn subtract_row<Set>(&mut self, row: R, set: &Set) -> bool
1316 where
1317 HybridBitSet<C>: BitRelations<Set>,
1318 {
1319 match self.rows.get_mut(row) {
1320 Some(Some(row)) => row.subtract(set),
1321 _ => false,
1322 }
1323 }
1324
1325 /// Unions `row` with `set`. `set` can be either `BitSet` or
1326 /// `HybridBitSet`.
1327 ///
1328 /// Returns true if the row was changed.
1329 pub fn union_row<Set>(&mut self, row: R, set: &Set) -> bool
1330 where
1331 HybridBitSet<C>: BitRelations<Set>,
1332 {
1333 self.ensure_row(row).union(set)
1334 }
0bf4aa26
XL
1335}
1336
1337#[inline]
1338fn num_words<T: Idx>(domain_size: T) -> usize {
1339 (domain_size.index() + WORD_BITS - 1) / WORD_BITS
1340}
1341
1342#[inline]
1343fn word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1344 let elem = elem.index();
1345 let word_index = elem / WORD_BITS;
1346 let mask = 1 << (elem % WORD_BITS);
1347 (word_index, mask)
1348}
3dfed10e 1349
3c0e092e
XL
1350#[inline]
1351fn max_bit(word: Word) -> usize {
1352 WORD_BITS - 1 - word.leading_zeros() as usize
1353}
1354
3dfed10e
XL
1355/// Integral type used to represent the bit set.
1356pub trait FiniteBitSetTy:
1357 BitAnd<Output = Self>
1358 + BitAndAssign
1359 + BitOrAssign
1360 + Clone
1361 + Copy
1362 + Shl
1363 + Not<Output = Self>
1364 + PartialEq
1365 + Sized
1366{
1367 /// Size of the domain representable by this type, e.g. 64 for `u64`.
1368 const DOMAIN_SIZE: u32;
1369
1370 /// Value which represents the `FiniteBitSet` having every bit set.
1371 const FILLED: Self;
1372 /// Value which represents the `FiniteBitSet` having no bits set.
1373 const EMPTY: Self;
1374
1375 /// Value for one as the integral type.
1376 const ONE: Self;
1377 /// Value for zero as the integral type.
1378 const ZERO: Self;
1379
1380 /// Perform a checked left shift on the integral type.
1381 fn checked_shl(self, rhs: u32) -> Option<Self>;
1382 /// Perform a checked right shift on the integral type.
1383 fn checked_shr(self, rhs: u32) -> Option<Self>;
1384}
1385
1386impl FiniteBitSetTy for u32 {
1387 const DOMAIN_SIZE: u32 = 32;
1388
1389 const FILLED: Self = Self::MAX;
1390 const EMPTY: Self = Self::MIN;
1391
1392 const ONE: Self = 1u32;
1393 const ZERO: Self = 0u32;
1394
1395 fn checked_shl(self, rhs: u32) -> Option<Self> {
1396 self.checked_shl(rhs)
1397 }
1398
1399 fn checked_shr(self, rhs: u32) -> Option<Self> {
1400 self.checked_shr(rhs)
1401 }
1402}
1403
1404impl std::fmt::Debug for FiniteBitSet<u32> {
1405 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1406 write!(f, "{:032b}", self.0)
1407 }
1408}
1409
1410impl FiniteBitSetTy for u64 {
1411 const DOMAIN_SIZE: u32 = 64;
1412
1413 const FILLED: Self = Self::MAX;
1414 const EMPTY: Self = Self::MIN;
1415
1416 const ONE: Self = 1u64;
1417 const ZERO: Self = 0u64;
1418
1419 fn checked_shl(self, rhs: u32) -> Option<Self> {
1420 self.checked_shl(rhs)
1421 }
1422
1423 fn checked_shr(self, rhs: u32) -> Option<Self> {
1424 self.checked_shr(rhs)
1425 }
1426}
1427
1428impl std::fmt::Debug for FiniteBitSet<u64> {
1429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1430 write!(f, "{:064b}", self.0)
1431 }
1432}
1433
1434impl FiniteBitSetTy for u128 {
1435 const DOMAIN_SIZE: u32 = 128;
1436
1437 const FILLED: Self = Self::MAX;
1438 const EMPTY: Self = Self::MIN;
1439
1440 const ONE: Self = 1u128;
1441 const ZERO: Self = 0u128;
1442
1443 fn checked_shl(self, rhs: u32) -> Option<Self> {
1444 self.checked_shl(rhs)
1445 }
1446
1447 fn checked_shr(self, rhs: u32) -> Option<Self> {
1448 self.checked_shr(rhs)
1449 }
1450}
1451
1452impl std::fmt::Debug for FiniteBitSet<u128> {
1453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1454 write!(f, "{:0128b}", self.0)
1455 }
1456}
1457
1458/// A fixed-sized bitset type represented by an integer type. Indices outwith than the range
1459/// representable by `T` are considered set.
1460#[derive(Copy, Clone, Eq, PartialEq, Decodable, Encodable)]
1461pub struct FiniteBitSet<T: FiniteBitSetTy>(pub T);
1462
1463impl<T: FiniteBitSetTy> FiniteBitSet<T> {
1464 /// Creates a new, empty bitset.
1465 pub fn new_empty() -> Self {
1466 Self(T::EMPTY)
1467 }
1468
1469 /// Sets the `index`th bit.
1470 pub fn set(&mut self, index: u32) {
1471 self.0 |= T::ONE.checked_shl(index).unwrap_or(T::ZERO);
1472 }
1473
1474 /// Unsets the `index`th bit.
1475 pub fn clear(&mut self, index: u32) {
1476 self.0 &= !T::ONE.checked_shl(index).unwrap_or(T::ZERO);
1477 }
1478
1479 /// Sets the `i`th to `j`th bits.
1480 pub fn set_range(&mut self, range: Range<u32>) {
1481 let bits = T::FILLED
1482 .checked_shl(range.end - range.start)
1483 .unwrap_or(T::ZERO)
1484 .not()
1485 .checked_shl(range.start)
1486 .unwrap_or(T::ZERO);
1487 self.0 |= bits;
1488 }
1489
1490 /// Is the set empty?
1491 pub fn is_empty(&self) -> bool {
1492 self.0 == T::EMPTY
1493 }
1494
1495 /// Returns the domain size of the bitset.
1496 pub fn within_domain(&self, index: u32) -> bool {
1497 index < T::DOMAIN_SIZE
1498 }
1499
1500 /// Returns if the `index`th bit is set.
1501 pub fn contains(&self, index: u32) -> Option<bool> {
1502 self.within_domain(index)
1503 .then(|| ((self.0.checked_shr(index).unwrap_or(T::ONE)) & T::ONE) == T::ONE)
1504 }
1505}
1506
1507impl<T: FiniteBitSetTy> Default for FiniteBitSet<T> {
1508 fn default() -> Self {
1509 Self::new_empty()
1510 }
1511}