Add optimized sparse-hybrid / dense-hybrid intersect
This commit is contained in:
parent
415d5e860f
commit
2110ac303e
@ -267,6 +267,16 @@ fn sparse_intersect<T: Idx>(
|
|||||||
set.elems.len() != size
|
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> {
|
impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> {
|
||||||
fn union(&mut self, other: &HybridBitSet<T>) -> bool {
|
fn union(&mut self, other: &HybridBitSet<T>) -> bool {
|
||||||
assert_eq!(self.domain_size, other.domain_size());
|
assert_eq!(self.domain_size, other.domain_size());
|
||||||
@ -292,11 +302,9 @@ fn intersect(&mut self, other: &HybridBitSet<T>) -> bool {
|
|||||||
assert_eq!(self.domain_size, other.domain_size());
|
assert_eq!(self.domain_size, other.domain_size());
|
||||||
match other {
|
match other {
|
||||||
HybridBitSet::Sparse(sparse) => {
|
HybridBitSet::Sparse(sparse) => {
|
||||||
let n = self.count();
|
let (updated, changed) = dense_sparse_intersect(self, sparse);
|
||||||
let mut sparse_copy = sparse.clone();
|
*self = updated.to_dense();
|
||||||
sparse_intersect(&mut sparse_copy, |el| !self.contains(*el));
|
changed
|
||||||
*self = sparse_copy.to_dense();
|
|
||||||
self.count() != n
|
|
||||||
}
|
}
|
||||||
HybridBitSet::Dense(dense) => self.intersect(dense),
|
HybridBitSet::Dense(dense) => self.intersect(dense),
|
||||||
}
|
}
|
||||||
@ -364,7 +372,14 @@ fn intersect(&mut self, other: &HybridBitSet<T>) -> bool {
|
|||||||
HybridBitSet::Sparse(self_sparse) => {
|
HybridBitSet::Sparse(self_sparse) => {
|
||||||
sparse_intersect(self_sparse, |elem| other.contains(*elem))
|
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),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user