Skip to content

Commit 9978cbc

Browse files
committed
generalize BitMatrix to be NxM and not just NxN
1 parent 8150494 commit 9978cbc

File tree

2 files changed

+69
-17
lines changed

2 files changed

+69
-17
lines changed

src/librustc_data_structures/bitvec.rs

+67-16
Original file line numberDiff line numberDiff line change
@@ -124,32 +124,32 @@ impl FromIterator<bool> for BitVector {
124124
}
125125
}
126126

127-
/// A "bit matrix" is basically a square matrix of booleans
128-
/// represented as one gigantic bitvector. In other words, it is as if
129-
/// you have N bitvectors, each of length N. Note that `elements` here is `N`/
127+
/// A "bit matrix" is basically a matrix of booleans represented as
128+
/// one gigantic bitvector. In other words, it is as if you have
129+
/// `rows` bitvectors, each of length `columns`.
130130
#[derive(Clone)]
131131
pub struct BitMatrix {
132-
elements: usize,
132+
columns: usize,
133133
vector: Vec<u64>,
134134
}
135135

136136
impl BitMatrix {
137-
// Create a new `elements x elements` matrix, initially empty.
138-
pub fn new(elements: usize) -> BitMatrix {
137+
// Create a new `rows x columns` matrix, initially empty.
138+
pub fn new(rows: usize, columns: usize) -> BitMatrix {
139139
// For every element, we need one bit for every other
140140
// element. Round up to an even number of u64s.
141-
let u64s_per_elem = u64s(elements);
141+
let u64s_per_row = u64s(columns);
142142
BitMatrix {
143-
elements: elements,
144-
vector: vec![0; elements * u64s_per_elem],
143+
columns: columns,
144+
vector: vec![0; rows * u64s_per_row],
145145
}
146146
}
147147

148-
/// The range of bits for a given element.
149-
fn range(&self, element: usize) -> (usize, usize) {
150-
let u64s_per_elem = u64s(self.elements);
151-
let start = element * u64s_per_elem;
152-
(start, start + u64s_per_elem)
148+
/// The range of bits for a given row.
149+
fn range(&self, row: usize) -> (usize, usize) {
150+
let u64s_per_row = u64s(self.columns);
151+
let start = row * u64s_per_row;
152+
(start, start + u64s_per_row)
153153
}
154154

155155
pub fn add(&mut self, source: usize, target: usize) -> bool {
@@ -179,7 +179,7 @@ impl BitMatrix {
179179
pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
180180
let (a_start, a_end) = self.range(a);
181181
let (b_start, b_end) = self.range(b);
182-
let mut result = Vec::with_capacity(self.elements);
182+
let mut result = Vec::with_capacity(self.columns);
183183
for (base, (i, j)) in (a_start..a_end).zip(b_start..b_end).enumerate() {
184184
let mut v = self.vector[i] & self.vector[j];
185185
for bit in 0..64 {
@@ -215,6 +215,15 @@ impl BitMatrix {
215215
}
216216
changed
217217
}
218+
219+
pub fn iter<'a>(&'a self, row: usize) -> BitVectorIter<'a> {
220+
let (start, end) = self.range(row);
221+
BitVectorIter {
222+
iter: self.vector[start..end].iter(),
223+
current: 0,
224+
idx: 0,
225+
}
226+
}
218227
}
219228

220229
fn u64s(elements: usize) -> usize {
@@ -300,7 +309,7 @@ fn grow() {
300309

301310
#[test]
302311
fn matrix_intersection() {
303-
let mut vec1 = BitMatrix::new(200);
312+
let mut vec1 = BitMatrix::new(200, 200);
304313

305314
// (*) Elements reachable from both 2 and 65.
306315

@@ -328,3 +337,45 @@ fn matrix_intersection() {
328337
let intersection = vec1.intersection(2, 65);
329338
assert_eq!(intersection, &[10, 64, 160]);
330339
}
340+
341+
#[test]
342+
fn matrix_iter() {
343+
let mut matrix = BitMatrix::new(64, 100);
344+
matrix.add(3, 22);
345+
matrix.add(3, 75);
346+
matrix.add(2, 99);
347+
matrix.add(4, 0);
348+
matrix.merge(3, 5);
349+
350+
let expected = [99];
351+
let mut iter = expected.iter();
352+
for i in matrix.iter(2) {
353+
let j = *iter.next().unwrap();
354+
assert_eq!(i, j);
355+
}
356+
assert!(iter.next().is_none());
357+
358+
let expected = [22, 75];
359+
let mut iter = expected.iter();
360+
for i in matrix.iter(3) {
361+
let j = *iter.next().unwrap();
362+
assert_eq!(i, j);
363+
}
364+
assert!(iter.next().is_none());
365+
366+
let expected = [0];
367+
let mut iter = expected.iter();
368+
for i in matrix.iter(4) {
369+
let j = *iter.next().unwrap();
370+
assert_eq!(i, j);
371+
}
372+
assert!(iter.next().is_none());
373+
374+
let expected = [22, 75];
375+
let mut iter = expected.iter();
376+
for i in matrix.iter(5) {
377+
let j = *iter.next().unwrap();
378+
assert_eq!(i, j);
379+
}
380+
assert!(iter.next().is_none());
381+
}

src/librustc_data_structures/transitive_relation.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ impl<T: Debug + PartialEq> TransitiveRelation<T> {
252252
}
253253

254254
fn compute_closure(&self) -> BitMatrix {
255-
let mut matrix = BitMatrix::new(self.elements.len());
255+
let mut matrix = BitMatrix::new(self.elements.len(),
256+
self.elements.len());
256257
let mut changed = true;
257258
while changed {
258259
changed = false;

0 commit comments

Comments
 (0)