Skip to content

Commit 15d6f2c

Browse files
committed
---
yaml --- r: 153126 b: refs/heads/try2 c: a7f335a h: refs/heads/master v: v3
1 parent 202f400 commit 15d6f2c

File tree

2 files changed

+89
-55
lines changed

2 files changed

+89
-55
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: da0d4be378d289e9e90a48deec674d42205ae4c9
8+
refs/heads/try2: a7f335a09ccfa0777847cd7b36d117322b965ad1
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/libcollections/bitv.rs

Lines changed: 88 additions & 54 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, Zip};
18+
use core::iter::{Map, Take, Zip};
1919
use core::ops;
2020
use core::slice;
2121
use core::uint;
@@ -382,21 +382,6 @@ impl cmp::PartialEq for Bitv {
382382

383383
impl cmp::Eq for Bitv {}
384384

385-
#[inline]
386-
fn iterate_bits(base: uint, bits: uint, f: |uint| -> bool) -> bool {
387-
if bits == 0 {
388-
return true;
389-
}
390-
for i in range(0u, uint::BITS) {
391-
if bits & (1 << i) != 0 {
392-
if !f(base + i) {
393-
return false;
394-
}
395-
}
396-
}
397-
return true;
398-
}
399-
400385
/// An iterator for `Bitv`.
401386
pub struct Bits<'a> {
402387
bitv: &'a Bitv,
@@ -553,39 +538,45 @@ impl BitvSet {
553538
BitPositions {set: self, next_idx: 0}
554539
}
555540

556-
pub fn difference(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
557-
for (i, w1, w2) in self.commons(other) {
558-
if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
559-
return false
560-
}
561-
};
562-
/* everything we have that they don't also shows up */
563-
self.outliers(other).advance(|(mine, i, w)|
564-
!mine || iterate_bits(i, w, |b| f(&b))
565-
)
566-
}
567-
568-
pub fn symmetric_difference(&self, other: &BitvSet, f: |&uint| -> bool)
569-
-> bool {
570-
for (i, w1, w2) in self.commons(other) {
571-
if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
572-
return false
573-
}
574-
};
575-
self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
541+
pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
542+
TwoBitPositions {
543+
set: self,
544+
other: other,
545+
merge: |w1, w2| w1 & !w2,
546+
current_word: 0,
547+
next_idx: 0
548+
}
576549
}
577550

578-
pub fn intersection(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
579-
self.commons(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b)))
551+
pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
552+
TwoBitPositions {
553+
set: self,
554+
other: other,
555+
merge: |w1, w2| w1 ^ w2,
556+
current_word: 0,
557+
next_idx: 0
558+
}
580559
}
581560

582-
pub fn union(&self, other: &BitvSet, f: |&uint| -> bool) -> bool {
583-
for (i, w1, w2) in self.commons(other) {
584-
if !iterate_bits(i, w1 | w2, |b| f(&b)) {
585-
return false
586-
}
587-
};
588-
self.outliers(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
561+
pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take<TwoBitPositions<'a>> {
562+
let min = cmp::min(self.capacity(), other.capacity());
563+
TwoBitPositions {
564+
set: self,
565+
other: other,
566+
merge: |w1, w2| w1 & w2,
567+
current_word: 0,
568+
next_idx: 0
569+
}.take(min)
570+
}
571+
572+
pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> {
573+
TwoBitPositions {
574+
set: self,
575+
other: other,
576+
merge: |w1, w2| w1 | w2,
577+
current_word: 0,
578+
next_idx: 0
579+
}
589580
}
590581
}
591582

@@ -634,7 +625,7 @@ impl Set<uint> for BitvSet {
634625
}
635626

636627
fn is_disjoint(&self, other: &BitvSet) -> bool {
637-
self.intersection(other, |_| false)
628+
self.intersection(other).count() > 0
638629
}
639630

640631
fn is_subset(&self, other: &BitvSet) -> bool {
@@ -737,6 +728,14 @@ pub struct BitPositions<'a> {
737728
next_idx: uint
738729
}
739730

731+
pub struct TwoBitPositions<'a> {
732+
set: &'a BitvSet,
733+
other: &'a BitvSet,
734+
merge: |uint, uint|: 'a -> uint,
735+
current_word: uint,
736+
next_idx: uint
737+
}
738+
740739
impl<'a> Iterator<uint> for BitPositions<'a> {
741740
#[inline]
742741
fn next(&mut self) -> Option<uint> {
@@ -757,6 +756,41 @@ impl<'a> Iterator<uint> for BitPositions<'a> {
757756
}
758757
}
759758

759+
impl<'a> Iterator<uint> for TwoBitPositions<'a> {
760+
#[inline]
761+
fn next(&mut self) -> Option<uint> {
762+
while self.next_idx < self.set.capacity() ||
763+
self.next_idx < self.other.capacity() {
764+
let bit_idx = self.next_idx % uint::BITS;
765+
if bit_idx == 0 {
766+
let &BitvSet(ref s_bitv) = self.set;
767+
let &BitvSet(ref o_bitv) = self.other;
768+
// Merging the two words is a bit of an awkward dance since
769+
// one Bitv might be longer than the other
770+
let word_idx = self.next_idx / uint::BITS;
771+
let w1 = if word_idx < s_bitv.storage.len() {
772+
*s_bitv.storage.get(word_idx)
773+
} else { 0 };
774+
let w2 = if word_idx < o_bitv.storage.len() {
775+
*o_bitv.storage.get(word_idx)
776+
} else { 0 };
777+
self.current_word = (self.merge)(w1, w2);
778+
}
779+
780+
self.next_idx += 1;
781+
if self.current_word & (1 << bit_idx) != 0 {
782+
return Some(self.next_idx - 1);
783+
}
784+
}
785+
return None;
786+
}
787+
788+
fn size_hint(&self) -> (uint, Option<uint>) {
789+
let cap = cmp::max(self.set.capacity(), self.other.capacity());
790+
(0, Some(cap - self.next_idx))
791+
}
792+
}
793+
760794
#[cfg(test)]
761795
mod tests {
762796
use std::prelude::*;
@@ -1274,8 +1308,8 @@ mod tests {
12741308

12751309
let mut i = 0;
12761310
let expected = [3, 5, 11, 77];
1277-
a.intersection(&b, |x| {
1278-
assert_eq!(*x, expected[i]);
1311+
a.intersection(&b).advance(|x| {
1312+
assert_eq!(x, expected[i]);
12791313
i += 1;
12801314
true
12811315
});
@@ -1298,8 +1332,8 @@ mod tests {
12981332

12991333
let mut i = 0;
13001334
let expected = [1, 5, 500];
1301-
a.difference(&b, |x| {
1302-
assert_eq!(*x, expected[i]);
1335+
a.difference(&b).advance(|x| {
1336+
assert_eq!(x, expected[i]);
13031337
i += 1;
13041338
true
13051339
});
@@ -1324,8 +1358,8 @@ mod tests {
13241358

13251359
let mut i = 0;
13261360
let expected = [1, 5, 11, 14, 220];
1327-
a.symmetric_difference(&b, |x| {
1328-
assert_eq!(*x, expected[i]);
1361+
a.symmetric_difference(&b).advance(|x| {
1362+
assert_eq!(x, expected[i]);
13291363
i += 1;
13301364
true
13311365
});
@@ -1353,8 +1387,8 @@ mod tests {
13531387

13541388
let mut i = 0;
13551389
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
1356-
a.union(&b, |x| {
1357-
assert_eq!(*x, expected[i]);
1390+
a.union(&b).advance(|x| {
1391+
assert_eq!(x, expected[i]);
13581392
i += 1;
13591393
true
13601394
});

0 commit comments

Comments
 (0)