Skip to content

Commit 687cc29

Browse files
committed
Remove array_vec.rs.
`SparseBitSet` is the only remaining user of `ArrayVec`. This commit switches it to using `SmallVec`, and removes `array_vec.rs`. Why the switch? Although `SparseBitSet` is size-limited and doesn't need the ability to spill to the heap, `SmallVec` has many more features than `ArrayVec`. In particular, it's now possible to keep `SparseBitSet`'s elements in sorted order, which gives in-order iteration, which is a requirement for the next commit.
1 parent c42765a commit 687cc29

File tree

3 files changed

+21
-322
lines changed

3 files changed

+21
-322
lines changed

src/librustc_data_structures/array_vec.rs

-305
This file was deleted.

src/librustc_data_structures/bit_set.rs

+21-16
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use array_vec::ArrayVec;
1211
use indexed_vec::{Idx, IndexVec};
1312
use rustc_serialize;
13+
use smallvec::SmallVec;
1414
use std::fmt;
1515
use std::iter;
1616
use std::marker::PhantomData;
@@ -320,16 +320,17 @@ fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
320320
const SPARSE_MAX: usize = 8;
321321

322322
/// A fixed-size bitset type with a sparse representation and a maximum of
323-
/// SPARSE_MAX elements. The elements are stored as an unsorted vector with no
324-
/// duplicates.
323+
/// `SPARSE_MAX` elements. The elements are stored as a sorted `SmallVec` with
324+
/// no duplicates; although `SmallVec` can spill its elements to the heap, that
325+
/// never happens within this type because of the `SPARSE_MAX` limit.
325326
///
326-
/// This type is used by HybridBitSet; do not use directly.
327+
/// This type is used by `HybridBitSet`; do not use directly.
327328
#[derive(Clone, Debug)]
328-
pub struct SparseBitSet<T: Idx>(ArrayVec<[T; SPARSE_MAX]>);
329+
pub struct SparseBitSet<T: Idx>(SmallVec<[T; SPARSE_MAX]>);
329330

330331
impl<T: Idx> SparseBitSet<T> {
331332
fn new_empty() -> Self {
332-
SparseBitSet(ArrayVec::new())
333+
SparseBitSet(SmallVec::new())
333334
}
334335

335336
fn len(&self) -> usize {
@@ -341,21 +342,26 @@ impl<T: Idx> SparseBitSet<T> {
341342
}
342343

343344
fn insert(&mut self, elem: T) -> bool {
344-
// Ensure there are no duplicates.
345-
if self.0.contains(&elem) {
346-
false
345+
assert!(self.len() < SPARSE_MAX);
346+
if let Some(i) = self.0.iter().position(|&e| e >= elem) {
347+
if self.0[i] == elem {
348+
// `elem` is already in the set.
349+
false
350+
} else {
351+
// `elem` is smaller than one or more existing elements.
352+
self.0.insert(i, elem);
353+
true
354+
}
347355
} else {
356+
// `elem` is larger than all existing elements.
348357
self.0.push(elem);
349358
true
350359
}
351360
}
352361

353362
fn remove(&mut self, elem: T) -> bool {
354363
if let Some(i) = self.0.iter().position(|&e| e == elem) {
355-
// Swap the found element to the end, then pop it.
356-
let len = self.0.len();
357-
self.0.swap(i, len - 1);
358-
self.0.pop();
364+
self.0.remove(i);
359365
true
360366
} else {
361367
false
@@ -396,8 +402,8 @@ impl<T: Idx> SubtractFromBitSet<T> for SparseBitSet<T> {
396402
}
397403

398404
/// A fixed-size bitset type with a hybrid representation: sparse when there
399-
/// are up to a SPARSE_MAX elements in the set, but dense when there are more
400-
/// than SPARSE_MAX.
405+
/// are up to a `SPARSE_MAX` elements in the set, but dense when there are more
406+
/// than `SPARSE_MAX`.
401407
///
402408
/// This type is especially efficient for sets that typically have a small
403409
/// number of elements, but a large `domain_size`, and are cleared frequently.
@@ -479,7 +485,6 @@ impl<T: Idx> HybridBitSet<T> {
479485
}
480486
}
481487

482-
/// Iteration order is unspecified.
483488
pub fn iter(&self) -> HybridIter<T> {
484489
match self {
485490
HybridBitSet::Sparse(sparse, _) => HybridIter::Sparse(sparse.iter()),

0 commit comments

Comments
 (0)