1
Fork 0

Rollup merge of #55127 - ljedrz:simplify_hybridbitset, r=matthewjasper

Remove HybridBitSet::dummy

This simplifies some of the `HybridBitSet` code.

cc @nnethercote
This commit is contained in:
kennytm 2018-10-18 10:47:33 +08:00
commit eda6e06852
No known key found for this signature in database
GPG key ID: FEF6C8051D0E013C

View file

@ -423,15 +423,6 @@ pub enum HybridBitSet<T: Idx> {
} }
impl<T: Idx> HybridBitSet<T> { impl<T: Idx> HybridBitSet<T> {
// FIXME: This function is used in conjunction with `mem::replace()` in
// several pieces of awful code below. I can't work out how else to appease
// the borrow checker.
fn dummy() -> Self {
// The cheapest HybridBitSet to construct, which is only used to get
// around the borrow checker.
HybridBitSet::Sparse(SparseBitSet::new_empty(0))
}
pub fn new_empty(domain_size: usize) -> Self { pub fn new_empty(domain_size: usize) -> Self {
HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size)) HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
} }
@ -487,20 +478,14 @@ impl<T: Idx> HybridBitSet<T> {
// that doesn't matter because `elem` is already present. // that doesn't matter because `elem` is already present.
false false
} }
HybridBitSet::Sparse(_) => { HybridBitSet::Sparse(sparse) => {
// The set is sparse and full. Convert to a dense set. // The set is sparse and full. Convert to a dense set.
match mem::replace(self, HybridBitSet::dummy()) { let mut dense = sparse.to_dense();
HybridBitSet::Sparse(sparse) => { let changed = dense.insert(elem);
let mut dense = sparse.to_dense(); assert!(changed);
let changed = dense.insert(elem); *self = HybridBitSet::Dense(dense);
assert!(changed); changed
*self = HybridBitSet::Dense(dense);
changed
}
_ => unreachable!()
}
} }
HybridBitSet::Dense(dense) => dense.insert(elem), HybridBitSet::Dense(dense) => dense.insert(elem),
} }
} }
@ -525,33 +510,26 @@ impl<T: Idx> HybridBitSet<T> {
pub fn union(&mut self, other: &HybridBitSet<T>) -> bool { pub fn union(&mut self, other: &HybridBitSet<T>) -> bool {
match self { match self {
HybridBitSet::Sparse(_) => { HybridBitSet::Sparse(self_sparse) => {
match other { match other {
HybridBitSet::Sparse(other_sparse) => { HybridBitSet::Sparse(other_sparse) => {
// Both sets are sparse. Add the elements in // Both sets are sparse. Add the elements in
// `other_sparse` to `self_hybrid` one at a time. This // `other_sparse` to `self` one at a time. This
// may or may not cause `self_hybrid` to be densified. // may or may not cause `self` to be densified.
assert_eq!(self.domain_size(), other.domain_size()); assert_eq!(self.domain_size(), other.domain_size());
let mut self_hybrid = mem::replace(self, HybridBitSet::dummy());
let mut changed = false; let mut changed = false;
for elem in other_sparse.iter() { for elem in other_sparse.iter() {
changed |= self_hybrid.insert(*elem); changed |= self.insert(*elem);
} }
*self = self_hybrid;
changed changed
} }
HybridBitSet::Dense(other_dense) => { HybridBitSet::Dense(other_dense) => {
// `self` is sparse and `other` is dense. Densify // `self` is sparse and `other` is dense. Densify
// `self` and then do the bitwise union. // `self` and then do the bitwise union.
match mem::replace(self, HybridBitSet::dummy()) { let mut new_dense = self_sparse.to_dense();
HybridBitSet::Sparse(self_sparse) => { let changed = new_dense.union(other_dense);
let mut new_dense = self_sparse.to_dense(); *self = HybridBitSet::Dense(new_dense);
let changed = new_dense.union(other_dense); changed
*self = HybridBitSet::Dense(new_dense);
changed
}
_ => unreachable!()
}
} }
} }
} }