Skip to content

Commit dd4fa90

Browse files
committed
Clean up the implementations of Bitv and BitvSet.
Functions that add bits now ensure that any unused bits are set to 0. `into_bitv` sanitizes the nbits of the Bitv/BitvSet it returns by setting the nbits to the current capacity. Fix a bug with `union_with` and `symmetric_difference` with due to not updating nbits properly Add test cases to the _with functions Remove `get_mut_ref` This is a [breaking-change]. The things you will need to fix are: 1. BitvSet's `unwrap()` has been renamed to `into_bitv` 2. BitvSet's `get_mut_ref()` has been removed. Use `into_bitv()` and `from_bitv()` instead.
1 parent 63fe80e commit dd4fa90

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)