Skip to content

Commit 8ef0165

Browse files
committed
collections::bitv: clean up and unit test BitvSet::is_subset
1 parent 78b6741 commit 8ef0165

File tree

1 file changed

+36
-55
lines changed

1 file changed

+36
-55
lines changed

src/libcollections/bitv.rs

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use core::prelude::*;
1515
use core::cmp;
1616
use core::default::Default;
1717
use core::fmt;
18-
use core::iter::{Map, Take, Zip};
18+
use core::iter::Take;
1919
use core::ops;
2020
use core::slice;
2121
use core::uint;
@@ -825,23 +825,16 @@ impl Set<uint> for BitvSet {
825825
self.intersection(other).count() > 0
826826
}
827827

828+
#[inline]
828829
fn is_subset(&self, other: &BitvSet) -> bool {
829-
for (_, w1, w2) in self.commons(other) {
830-
if w1 & w2 != w1 {
831-
return false;
832-
}
833-
}
834-
/* If anything is not ours, then everything is not ours so we're
835-
definitely a subset in that case. Otherwise if there's any stray
836-
ones that 'other' doesn't have, we're not a subset. */
837-
for (mine, _, w) in self.outliers(other) {
838-
if !mine {
839-
return true;
840-
} else if w != 0 {
841-
return false;
842-
}
843-
}
844-
return true;
830+
let &BitvSet(ref self_bitv) = self;
831+
let &BitvSet(ref other_bitv) = other;
832+
833+
// Check that `self` intersect `other` is self
834+
self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
835+
.all(|((_, w1), (_, w2))| w1 & w2 == w1) &&
836+
// Check that `self` setminus `other` is empty
837+
self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
845838
}
846839

847840
#[inline]
@@ -883,44 +876,6 @@ impl MutableSet<uint> for BitvSet {
883876
}
884877
}
885878

886-
impl BitvSet {
887-
/// Visits each of the words that the two bit vectors (`self` and `other`)
888-
/// both have in common. The three yielded arguments are (bit location,
889-
/// w1, w2) where the bit location is the number of bits offset so far,
890-
/// and w1/w2 are the words coming from the two vectors self, other.
891-
fn commons<'a>(&'a self, other: &'a BitvSet)
892-
-> Map<((uint, uint), (uint, uint)), (uint, uint, uint),
893-
Zip<MaskWords<'a>, MaskWords<'a>>> {
894-
let &BitvSet(ref self_bitv) = self;
895-
let &BitvSet(ref other_bitv) = other;
896-
self_bitv.mask_words(0).zip(other_bitv.mask_words(0))
897-
.map(|((i, w1), (_, w2))| (i * uint::BITS, w1, w2))
898-
}
899-
900-
/// Visits each word in `self` or `other` that extends beyond the other. This
901-
/// will only iterate through one of the vectors, and it only iterates
902-
/// over the portion that doesn't overlap with the other one.
903-
///
904-
/// The yielded arguments are a `bool`, the bit offset, and a word. The `bool`
905-
/// is true if the word comes from `self`, and `false` if it comes from
906-
/// `other`.
907-
fn outliers<'a>(&'a self, other: &'a BitvSet)
908-
-> Map<(uint, uint), (bool, uint, uint), MaskWords<'a>> {
909-
let slen = self.capacity() / uint::BITS;
910-
let olen = other.capacity() / uint::BITS;
911-
let &BitvSet(ref self_bitv) = self;
912-
let &BitvSet(ref other_bitv) = other;
913-
914-
if olen < slen {
915-
self_bitv.mask_words(olen)
916-
.map(|(i, w)| (true, i * uint::BITS, w))
917-
} else {
918-
other_bitv.mask_words(slen)
919-
.map(|(i, w)| (false, i * uint::BITS, w))
920-
}
921-
}
922-
}
923-
924879
pub struct BitPositions<'a> {
925880
set: &'a BitvSet,
926881
next_idx: uint
@@ -1594,6 +1549,32 @@ mod tests {
15941549
assert_eq!(i, expected.len());
15951550
}
15961551

1552+
#[test]
1553+
fn test_bitv_set_subset() {
1554+
let mut set1 = BitvSet::new();
1555+
let mut set2 = BitvSet::new();
1556+
1557+
assert!(set1.is_subset(&set2)); // {} {}
1558+
set2.insert(100);
1559+
assert!(set1.is_subset(&set2)); // {} { 1 }
1560+
set2.insert(200);
1561+
assert!(set1.is_subset(&set2)); // {} { 1, 2 }
1562+
set1.insert(200);
1563+
assert!(set1.is_subset(&set2)); // { 2 } { 1, 2 }
1564+
set1.insert(300);
1565+
assert!(!set1.is_subset(&set2)); // { 2, 3 } { 1, 2 }
1566+
set2.insert(300);
1567+
assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3 }
1568+
set2.insert(400);
1569+
assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3, 4 }
1570+
set2.remove(&100);
1571+
assert!(set1.is_subset(&set2)); // { 2, 3 } { 2, 3, 4 }
1572+
set2.remove(&300);
1573+
assert!(!set1.is_subset(&set2)); // { 2, 3 } { 2, 4 }
1574+
set1.remove(&300);
1575+
assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
1576+
}
1577+
15971578
#[test]
15981579
fn test_bitv_remove() {
15991580
let mut a = BitvSet::new();

0 commit comments

Comments
 (0)