Skip to content

Commit 953d685

Browse files
committed
Add remaining impl for hybrid X dense
1 parent e854027 commit 953d685

File tree

1 file changed

+51
-21
lines changed

1 file changed

+51
-21
lines changed

compiler/rustc_index/src/bit_set.rs

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ impl<T: Idx> BitSet<T> {
230230
bit_relations_inherent_impls! {}
231231
}
232232

233+
// dense REL dense
233234
impl<T: Idx> BitRelations<BitSet<T>> for BitSet<T> {
234235
fn union(&mut self, other: &BitSet<T>) -> bool {
235236
assert_eq!(self.domain_size, other.domain_size);
@@ -285,6 +286,53 @@ fn dense_sparse_intersect<T: Idx>(
285286
(sparse_copy, n != dense.count())
286287
}
287288

289+
// hybrid REL dense
290+
impl<T: Idx> BitRelations<BitSet<T>> for HybridBitSet<T> {
291+
fn union(&mut self, other: &BitSet<T>) -> bool {
292+
match self {
293+
HybridBitSet::Sparse(sparse) => {
294+
// `self` is sparse and `other` is dense. To
295+
// merge them, we have two available strategies:
296+
// * Densify `self` then merge other
297+
// * Clone other then integrate bits from `self`
298+
// The second strategy requires dedicated method
299+
// since the usual `union` returns the wrong
300+
// result. In the dedicated case the computation
301+
// is slightly faster if the bits of the sparse
302+
// bitset map to only few words of the dense
303+
// representation, i.e. indices are near each
304+
// other.
305+
//
306+
// Benchmarking seems to suggest that the second
307+
// option is worth it.
308+
let mut new_dense = other.clone();
309+
let changed = new_dense.reverse_union_sparse(sparse);
310+
*self = HybridBitSet::Dense(new_dense);
311+
changed
312+
}
313+
314+
HybridBitSet::Dense(dense) => dense.union(other),
315+
}
316+
}
317+
318+
fn subtract(&mut self, other: &BitSet<T>) -> bool {
319+
match self {
320+
HybridBitSet::Sparse(sparse) => {
321+
sequential_update(|elem| sparse.remove(elem), other.iter())
322+
}
323+
HybridBitSet::Dense(dense) => dense.subtract(other),
324+
}
325+
}
326+
327+
fn intersect(&mut self, other: &BitSet<T>) -> bool {
328+
match self {
329+
HybridBitSet::Sparse(sparse) => sparse_intersect(sparse, |elem| other.contains(*elem)),
330+
HybridBitSet::Dense(dense) => dense.intersect(other),
331+
}
332+
}
333+
}
334+
335+
// dense REL hybrid
288336
impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> {
289337
fn union(&mut self, other: &HybridBitSet<T>) -> bool {
290338
assert_eq!(self.domain_size, other.domain_size());
@@ -326,13 +374,14 @@ impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> {
326374
}
327375
}
328376

377+
// hybrid REL hybrid
329378
impl<T: Idx> BitRelations<HybridBitSet<T>> for HybridBitSet<T> {
330379
fn union(&mut self, other: &HybridBitSet<T>) -> bool {
331380
assert_eq!(self.domain_size(), other.domain_size());
332381
match self {
333382
HybridBitSet::Sparse(self_sparse) => {
334383
match other {
335-
HybridBitSet::Sparse(other_sparse) => {
384+
HybridBitSet::Sparse(_) => {
336385
// Both sets are sparse. Add the elements in
337386
// `other_sparse` to `self` one at a time. This
338387
// may or may not cause `self` to be densified.
@@ -344,26 +393,7 @@ impl<T: Idx> BitRelations<HybridBitSet<T>> for HybridBitSet<T> {
344393
changed
345394
}
346395

347-
HybridBitSet::Dense(other_dense) => {
348-
// `self` is sparse and `other` is dense. To
349-
// merge them, we have two available strategies:
350-
// * Densify `self` then merge other
351-
// * Clone other then integrate bits from `self`
352-
// The second strategy requires dedicated method
353-
// since the usual `union` returns the wrong
354-
// result. In the dedicated case the computation
355-
// is slightly faster if the bits of the sparse
356-
// bitset map to only few words of the dense
357-
// representation, i.e. indices are near each
358-
// other.
359-
//
360-
// Benchmarking seems to suggest that the second
361-
// option is worth it.
362-
let mut new_dense = other_dense.clone();
363-
let changed = new_dense.reverse_union_sparse(self_sparse);
364-
*self = HybridBitSet::Dense(new_dense);
365-
changed
366-
}
396+
HybridBitSet::Dense(other_dense) => self.union(other_dense),
367397
}
368398
}
369399

0 commit comments

Comments
 (0)