diff options
| author | Will Crichton <wcrichto@cs.stanford.edu> | 2021-08-25 15:10:33 -0700 |
|---|---|---|
| committer | Will Crichton <wcrichto@cs.stanford.edu> | 2021-08-25 15:10:33 -0700 |
| commit | 2110ac303ed53b77806c06c963b8fa086f87e909 (patch) | |
| tree | 1ab2a54f1d6e1ab1f7feb851720790565f7c938d | |
| parent | 415d5e860f2ef823564a8f0e704d4f35e5d07db8 (diff) | |
| download | rust-2110ac303ed53b77806c06c963b8fa086f87e909.tar.gz rust-2110ac303ed53b77806c06c963b8fa086f87e909.zip | |
Add optimized sparse-hybrid / dense-hybrid intersect
| -rw-r--r-- | compiler/rustc_index/src/bit_set.rs | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 46b1c554a61..8793d56792a 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -267,6 +267,16 @@ fn sparse_intersect<T: Idx>( set.elems.len() != size } +fn dense_sparse_intersect<T: Idx>( + dense: &BitSet<T>, + sparse: &SparseBitSet<T>, +) -> (SparseBitSet<T>, bool) { + let n = dense.count(); + let mut sparse_copy = sparse.clone(); + sparse_intersect(&mut sparse_copy, |el| !dense.contains(*el)); + (sparse_copy, dense.count() != n) +} + impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> { fn union(&mut self, other: &HybridBitSet<T>) -> bool { assert_eq!(self.domain_size, other.domain_size()); @@ -292,11 +302,9 @@ impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> { assert_eq!(self.domain_size, other.domain_size()); match other { HybridBitSet::Sparse(sparse) => { - let n = self.count(); - let mut sparse_copy = sparse.clone(); - sparse_intersect(&mut sparse_copy, |el| !self.contains(*el)); - *self = sparse_copy.to_dense(); - self.count() != n + let (updated, changed) = dense_sparse_intersect(self, sparse); + *self = updated.to_dense(); + changed } HybridBitSet::Dense(dense) => self.intersect(dense), } @@ -364,7 +372,14 @@ impl<T: Idx> BitRelations<HybridBitSet<T>> for HybridBitSet<T> { HybridBitSet::Sparse(self_sparse) => { sparse_intersect(self_sparse, |elem| other.contains(*elem)) } - HybridBitSet::Dense(self_dense) => self_dense.intersect(other), + HybridBitSet::Dense(self_dense) => match other { + HybridBitSet::Sparse(other_sparse) => { + let (updated, changed) = dense_sparse_intersect(self_dense, other_sparse); + *self = HybridBitSet::Sparse(updated); + changed + } + HybridBitSet::Dense(other_dense) => self_dense.intersect(other_dense), + }, } } } |
