Skip to content

Commit 79d056f

Browse files
committed
auto merge of #17558 : kaseyc/rust/fix_bitvset_union, r=aturon
Updates the other_op function shared by the union/intersect/difference/symmetric_difference -with functions to fix an issue where certain elements would not be present in the result. To fix this, when other op is called, we resize self's nbits to account for any new elements that may be added to the set. Example: ```rust let mut a = BitvSet::new(); let mut b = BitvSet::new(); a.insert(0); b.insert(5); a.union_with(&b); println!("{}", a); //Prints "{0}" instead of "{0, 5}" ```
2 parents eb04229 + dd4fa90 commit 79d056f

File tree

1 file changed

+131
-57
lines changed

1 file changed

+131
-57
lines changed

src/libcollections/bitv.rs

+131-57
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,20 @@ impl Bitv {
235235
/// }
236236
/// ```
237237
pub fn with_capacity(nbits: uint, init: bool) -> Bitv {
238-
Bitv {
238+
let mut bitv = Bitv {
239239
storage: Vec::from_elem((nbits + uint::BITS - 1) / uint::BITS,
240240
if init { !0u } else { 0u }),
241241
nbits: nbits
242+
};
243+
244+
// Zero out any unused bits in the highest word if necessary
245+
let used_bits = bitv.nbits % uint::BITS;
246+
if init && used_bits != 0 {
247+
let largest_used_word = (bitv.nbits + uint::BITS - 1) / uint::BITS - 1;
248+
*bitv.storage.get_mut(largest_used_word) &= (1 << used_bits) - 1;
242249
}
250+
251+
bitv
243252
}
244253

245254
/// Retrieves the value at index `i`.
@@ -629,9 +638,9 @@ impl Bitv {
629638
/// ```
630639
pub fn reserve(&mut self, size: uint) {
631640
let old_size = self.storage.len();
632-
let size = (size + uint::BITS - 1) / uint::BITS;
633-
if old_size < size {
634-
self.storage.grow(size - old_size, 0);
641+
let new_size = (size + uint::BITS - 1) / uint::BITS;
642+
if old_size < new_size {
643+
self.storage.grow(new_size - old_size, 0);
635644
}
636645
}
637646

@@ -686,8 +695,15 @@ impl Bitv {
686695
}
687696
// Allocate new words, if needed
688697
if new_nwords > self.storage.len() {
689-
let to_add = new_nwords - self.storage.len();
690-
self.storage.grow(to_add, full_value);
698+
let to_add = new_nwords - self.storage.len();
699+
self.storage.grow(to_add, full_value);
700+
701+
// Zero out and unused bits in the new tail word
702+
if value {
703+
let tail_word = new_nwords - 1;
704+
let used_bits = new_nbits % uint::BITS;
705+
*self.storage.get_mut(tail_word) &= (1 << used_bits) - 1;
706+
}
691707
}
692708
// Adjust internal bit count
693709
self.nbits = new_nbits;
@@ -970,9 +986,8 @@ impl<'a> RandomAccessIterator<bool> for Bits<'a> {
970986
/// }
971987
///
972988
/// // Can convert back to a `Bitv`
973-
/// let bv: Bitv = s.unwrap();
974-
/// assert!(bv.eq_vec([true, true, false, true,
975-
/// false, false, false, false]));
989+
/// let bv: Bitv = s.into_bitv();
990+
/// assert!(bv.get(3));
976991
/// ```
977992
#[deriving(Clone)]
978993
pub struct BitvSet(Bitv);
@@ -993,7 +1008,8 @@ impl FromIterator<bool> for BitvSet {
9931008
impl Extendable<bool> for BitvSet {
9941009
#[inline]
9951010
fn extend<I: Iterator<bool>>(&mut self, iterator: I) {
996-
self.get_mut_ref().extend(iterator);
1011+
let &BitvSet(ref mut self_bitv) = self;
1012+
self_bitv.extend(iterator);
9971013
}
9981014
}
9991015

@@ -1049,7 +1065,8 @@ impl BitvSet {
10491065
/// ```
10501066
#[inline]
10511067
pub fn with_capacity(nbits: uint) -> BitvSet {
1052-
BitvSet(Bitv::with_capacity(nbits, false))
1068+
let bitv = Bitv::with_capacity(nbits, false);
1069+
BitvSet::from_bitv(bitv)
10531070
}
10541071

10551072
/// Creates a new bit vector set from the given bit vector.
@@ -1068,7 +1085,9 @@ impl BitvSet {
10681085
/// }
10691086
/// ```
10701087
#[inline]
1071-
pub fn from_bitv(bitv: Bitv) -> BitvSet {
1088+
pub fn from_bitv(mut bitv: Bitv) -> BitvSet {
1089+
// Mark every bit as valid
1090+
bitv.nbits = bitv.capacity();
10721091
BitvSet(bitv)
10731092
}
10741093

@@ -1102,7 +1121,10 @@ impl BitvSet {
11021121
/// ```
11031122
pub fn reserve(&mut self, size: uint) {
11041123
let &BitvSet(ref mut bitv) = self;
1105-
bitv.reserve(size)
1124+
bitv.reserve(size);
1125+
if bitv.nbits < size {
1126+
bitv.nbits = bitv.capacity();
1127+
}
11061128
}
11071129

11081130
/// Consumes this set to return the underlying bit vector.
@@ -1116,11 +1138,12 @@ impl BitvSet {
11161138
/// s.insert(0);
11171139
/// s.insert(3);
11181140
///
1119-
/// let bv = s.unwrap();
1120-
/// assert!(bv.eq_vec([true, false, false, true]));
1141+
/// let bv = s.into_bitv();
1142+
/// assert!(bv.get(0));
1143+
/// assert!(bv.get(3));
11211144
/// ```
11221145
#[inline]
1123-
pub fn unwrap(self) -> Bitv {
1146+
pub fn into_bitv(self) -> Bitv {
11241147
let BitvSet(bitv) = self;
11251148
bitv
11261149
}
@@ -1144,38 +1167,15 @@ impl BitvSet {
11441167
bitv
11451168
}
11461169

1147-
/// Returns a mutable reference to the underlying bit vector.
1148-
///
1149-
/// # Example
1150-
///
1151-
/// ```
1152-
/// use std::collections::BitvSet;
1153-
///
1154-
/// let mut s = BitvSet::new();
1155-
/// s.insert(0);
1156-
/// assert_eq!(s.contains(&0), true);
1157-
/// {
1158-
/// // Will free the set during bv's lifetime
1159-
/// let bv = s.get_mut_ref();
1160-
/// bv.set(0, false);
1161-
/// }
1162-
/// assert_eq!(s.contains(&0), false);
1163-
/// ```
1164-
#[inline]
1165-
pub fn get_mut_ref<'a>(&'a mut self) -> &'a mut Bitv {
1166-
let &BitvSet(ref mut bitv) = self;
1167-
bitv
1168-
}
1169-
11701170
#[inline]
11711171
fn other_op(&mut self, other: &BitvSet, f: |uint, uint| -> uint) {
1172+
// Expand the vector if necessary
1173+
self.reserve(other.capacity());
1174+
11721175
// Unwrap Bitvs
11731176
let &BitvSet(ref mut self_bitv) = self;
11741177
let &BitvSet(ref other_bitv) = other;
11751178

1176-
// Expand the vector if necessary
1177-
self_bitv.reserve(other_bitv.capacity());
1178-
11791179
// virtually pad other with 0's for equal lengths
11801180
let mut other_words = {
11811181
let (_, result) = match_words(self_bitv, other_bitv);
@@ -1376,9 +1376,10 @@ impl BitvSet {
13761376
///
13771377
/// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
13781378
/// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
1379+
/// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
13791380
///
13801381
/// a.union_with(&b);
1381-
/// assert_eq!(a.unwrap(), bitv::from_bytes([res]));
1382+
/// assert_eq!(a, res);
13821383
/// ```
13831384
#[inline]
13841385
pub fn union_with(&mut self, other: &BitvSet) {
@@ -1399,9 +1400,10 @@ impl BitvSet {
13991400
///
14001401
/// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
14011402
/// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
1403+
/// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
14021404
///
14031405
/// a.intersect_with(&b);
1404-
/// assert_eq!(a.unwrap(), bitv::from_bytes([res]));
1406+
/// assert_eq!(a, res);
14051407
/// ```
14061408
#[inline]
14071409
pub fn intersect_with(&mut self, other: &BitvSet) {
@@ -1424,15 +1426,17 @@ impl BitvSet {
14241426
///
14251427
/// let mut bva = BitvSet::from_bitv(bitv::from_bytes([a]));
14261428
/// let bvb = BitvSet::from_bitv(bitv::from_bytes([b]));
1429+
/// let bva_b = BitvSet::from_bitv(bitv::from_bytes([a_b]));
1430+
/// let bvb_a = BitvSet::from_bitv(bitv::from_bytes([b_a]));
14271431
///
14281432
/// bva.difference_with(&bvb);
1429-
/// assert_eq!(bva.unwrap(), bitv::from_bytes([a_b]));
1433+
/// assert_eq!(bva, bva_b);
14301434
///
14311435
/// let bva = BitvSet::from_bitv(bitv::from_bytes([a]));
14321436
/// let mut bvb = BitvSet::from_bitv(bitv::from_bytes([b]));
14331437
///
14341438
/// bvb.difference_with(&bva);
1435-
/// assert_eq!(bvb.unwrap(), bitv::from_bytes([b_a]));
1439+
/// assert_eq!(bvb, bvb_a);
14361440
/// ```
14371441
#[inline]
14381442
pub fn difference_with(&mut self, other: &BitvSet) {
@@ -1454,9 +1458,10 @@ impl BitvSet {
14541458
///
14551459
/// let mut a = BitvSet::from_bitv(bitv::from_bytes([a]));
14561460
/// let b = BitvSet::from_bitv(bitv::from_bytes([b]));
1461+
/// let res = BitvSet::from_bitv(bitv::from_bytes([res]));
14571462
///
14581463
/// a.symmetric_difference_with(&b);
1459-
/// assert_eq!(a.unwrap(), bitv::from_bytes([res]));
1464+
/// assert_eq!(a, res);
14601465
/// ```
14611466
#[inline]
14621467
pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
@@ -1538,20 +1543,14 @@ impl MutableSet<uint> for BitvSet {
15381543
if self.contains(&value) {
15391544
return false;
15401545
}
1546+
1547+
// Ensure we have enough space to hold the new element
15411548
if value >= self.capacity() {
15421549
let new_cap = cmp::max(value + 1, self.capacity() * 2);
15431550
self.reserve(new_cap);
15441551
}
1552+
15451553
let &BitvSet(ref mut bitv) = self;
1546-
if value >= bitv.nbits {
1547-
// If we are increasing nbits, make sure we mask out any previously-unconsidered bits
1548-
let old_rem = bitv.nbits % uint::BITS;
1549-
if old_rem != 0 {
1550-
let old_last_word = (bitv.nbits + uint::BITS - 1) / uint::BITS - 1;
1551-
*bitv.storage.get_mut(old_last_word) &= (1 << old_rem) - 1;
1552-
}
1553-
bitv.nbits = value + 1;
1554-
}
15551554
bitv.set(value, true);
15561555
return true;
15571556
}
@@ -2225,14 +2224,15 @@ mod tests {
22252224
assert!(a.insert(160));
22262225
assert!(a.insert(19));
22272226
assert!(a.insert(24));
2227+
assert!(a.insert(200));
22282228

22292229
assert!(b.insert(1));
22302230
assert!(b.insert(5));
22312231
assert!(b.insert(9));
22322232
assert!(b.insert(13));
22332233
assert!(b.insert(19));
22342234

2235-
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
2235+
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
22362236
let actual = a.union(&b).collect::<Vec<uint>>();
22372237
assert_eq!(actual.as_slice(), expected.as_slice());
22382238
}
@@ -2281,6 +2281,27 @@ mod tests {
22812281
assert!(c.is_disjoint(&b))
22822282
}
22832283

2284+
#[test]
2285+
fn test_bitv_set_union_with() {
2286+
//a should grow to include larger elements
2287+
let mut a = BitvSet::new();
2288+
a.insert(0);
2289+
let mut b = BitvSet::new();
2290+
b.insert(5);
2291+
let expected = BitvSet::from_bitv(from_bytes([0b10000100]));
2292+
a.union_with(&b);
2293+
assert_eq!(a, expected);
2294+
2295+
// Standard
2296+
let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
2297+
let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
2298+
let c = a.clone();
2299+
a.union_with(&b);
2300+
b.union_with(&c);
2301+
assert_eq!(a.len(), 4);
2302+
assert_eq!(b.len(), 4);
2303+
}
2304+
22842305
#[test]
22852306
fn test_bitv_set_intersect_with() {
22862307
// Explicitly 0'ed bits
@@ -2311,6 +2332,59 @@ mod tests {
23112332
assert_eq!(b.len(), 2);
23122333
}
23132334

2335+
#[test]
2336+
fn test_bitv_set_difference_with() {
2337+
// Explicitly 0'ed bits
2338+
let mut a = BitvSet::from_bitv(from_bytes([0b00000000]));
2339+
let b = BitvSet::from_bitv(from_bytes([0b10100010]));
2340+
a.difference_with(&b);
2341+
assert!(a.is_empty());
2342+
2343+
// Uninitialized bits should behave like 0's
2344+
let mut a = BitvSet::new();
2345+
let b = BitvSet::from_bitv(from_bytes([0b11111111]));
2346+
a.difference_with(&b);
2347+
assert!(a.is_empty());
2348+
2349+
// Standard
2350+
let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
2351+
let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
2352+
let c = a.clone();
2353+
a.difference_with(&b);
2354+
b.difference_with(&c);
2355+
assert_eq!(a.len(), 1);
2356+
assert_eq!(b.len(), 1);
2357+
}
2358+
2359+
#[test]
2360+
fn test_bitv_set_symmetric_difference_with() {
2361+
//a should grow to include larger elements
2362+
let mut a = BitvSet::new();
2363+
a.insert(0);
2364+
a.insert(1);
2365+
let mut b = BitvSet::new();
2366+
b.insert(1);
2367+
b.insert(5);
2368+
let expected = BitvSet::from_bitv(from_bytes([0b10000100]));
2369+
a.symmetric_difference_with(&b);
2370+
assert_eq!(a, expected);
2371+
2372+
let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
2373+
let b = BitvSet::new();
2374+
let c = a.clone();
2375+
a.symmetric_difference_with(&b);
2376+
assert_eq!(a, c);
2377+
2378+
// Standard
2379+
let mut a = BitvSet::from_bitv(from_bytes([0b11100010]));
2380+
let mut b = BitvSet::from_bitv(from_bytes([0b01101010]));
2381+
let c = a.clone();
2382+
a.symmetric_difference_with(&b);
2383+
b.symmetric_difference_with(&c);
2384+
assert_eq!(a.len(), 2);
2385+
assert_eq!(b.len(), 2);
2386+
}
2387+
23142388
#[test]
23152389
fn test_bitv_set_eq() {
23162390
let a = BitvSet::from_bitv(from_bytes([0b10100010]));

0 commit comments

Comments
 (0)