Skip to content

Commit 964e069

Browse files
committed
use chunks api for SparseBitMatrix and add a subset fn
1 parent accfdcc commit 964e069

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

src/librustc_data_structures/bitvec.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::collections::BTreeMap;
11+
use indexed_vec::{Idx, IndexVec};
1212
use std::collections::btree_map::Entry;
13-
use std::marker::PhantomData;
13+
use std::collections::BTreeMap;
1414
use std::iter::FromIterator;
15-
use indexed_vec::{Idx, IndexVec};
15+
use std::marker::PhantomData;
1616

1717
type Word = u128;
1818
const WORD_BITS: usize = 128;
@@ -317,14 +317,25 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
317317
if read != write {
318318
let (bit_set_read, bit_set_write) = self.vector.pick2_mut(read, write);
319319

320-
for read_val in bit_set_read.iter() {
321-
changed = changed | bit_set_write.insert(read_val);
320+
for read_chunk in bit_set_read.chunks() {
321+
changed = changed | bit_set_write.insert_chunk(read_chunk).any();
322322
}
323323
}
324324

325325
changed
326326
}
327327

328+
/// True if `sub` is a subset of `sup`
329+
pub fn subset(&self, sub: R, sup: R) -> bool {
330+
sub == sup || {
331+
let bit_set_sub = &self.vector[sub];
332+
let bit_set_sup = &self.vector[sup];
333+
bit_set_sub
334+
.chunks()
335+
.all(|read_chunk| read_chunk.bits_eq(bit_set_sup.contains_chunk(read_chunk)))
336+
}
337+
}
338+
328339
/// Iterates through all the columns set to true in a given row of
329340
/// the matrix.
330341
pub fn iter<'a>(&'a self, row: R) -> impl Iterator<Item = C> + 'a {
@@ -346,6 +357,7 @@ pub struct SparseChunk<I> {
346357
}
347358

348359
impl<I: Idx> SparseChunk<I> {
360+
#[inline]
349361
pub fn one(index: I) -> Self {
350362
let index = index.index();
351363
let key_usize = index / 128;
@@ -358,10 +370,16 @@ impl<I: Idx> SparseChunk<I> {
358370
}
359371
}
360372

373+
#[inline]
361374
pub fn any(&self) -> bool {
362375
self.bits != 0
363376
}
364377

378+
#[inline]
379+
pub fn bits_eq(&self, other: SparseChunk<I>) -> bool {
380+
self.bits == other.bits
381+
}
382+
365383
pub fn iter(&self) -> impl Iterator<Item = I> {
366384
let base = self.key as usize * 128;
367385
let mut bits = self.bits;
@@ -394,6 +412,10 @@ impl<I: Idx> SparseBitSet<I> {
394412
self.chunk_bits.len() * 128
395413
}
396414

415+
/// Returns a chunk containing only those bits that are already
416+
/// present. You can test therefore if `self` contains all the
417+
/// bits in chunk already by doing `chunk ==
418+
/// self.contains_chunk(chunk)`.
397419
pub fn contains_chunk(&self, chunk: SparseChunk<I>) -> SparseChunk<I> {
398420
SparseChunk {
399421
bits: self.chunk_bits
@@ -403,6 +425,11 @@ impl<I: Idx> SparseBitSet<I> {
403425
}
404426
}
405427

428+
/// Modifies `self` to contain all the bits from `chunk` (in
429+
/// addition to any pre-existing bits); returns a new chunk that
430+
/// contains only those bits that were newly added. You can test
431+
/// if anything was inserted by invoking `any()` on the returned
432+
/// value.
406433
pub fn insert_chunk(&mut self, chunk: SparseChunk<I>) -> SparseChunk<I> {
407434
if chunk.bits == 0 {
408435
return chunk;

0 commit comments

Comments
 (0)