From 2110ac303ed53b77806c06c963b8fa086f87e909 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Wed, 25 Aug 2021 15:10:33 -0700 Subject: [PATCH] Add optimized sparse-hybrid / dense-hybrid intersect --- compiler/rustc_index/src/bit_set.rs | 27 +++++++++++++++++++++------ 1 file 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( set.elems.len() != size } +fn dense_sparse_intersect( + dense: &BitSet, + sparse: &SparseBitSet, +) -> (SparseBitSet, 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 BitRelations> for BitSet { fn union(&mut self, other: &HybridBitSet) -> bool { assert_eq!(self.domain_size, other.domain_size()); @@ -292,11 +302,9 @@ fn intersect(&mut self, other: &HybridBitSet) -> bool { 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 @@ fn intersect(&mut self, other: &HybridBitSet) -> bool { 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), + }, } } }