8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use array_vec:: ArrayVec ;
12
11
use indexed_vec:: { Idx , IndexVec } ;
13
12
use rustc_serialize;
13
+ use smallvec:: SmallVec ;
14
14
use std:: fmt;
15
15
use std:: iter;
16
16
use std:: marker:: PhantomData ;
@@ -320,16 +320,17 @@ fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
320
320
const SPARSE_MAX : usize = 8 ;
321
321
322
322
/// 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.
325
326
///
326
- /// This type is used by HybridBitSet; do not use directly.
327
+ /// This type is used by ` HybridBitSet` ; do not use directly.
327
328
#[ derive( Clone , Debug ) ]
328
- pub struct SparseBitSet < T : Idx > ( ArrayVec < [ T ; SPARSE_MAX ] > ) ;
329
+ pub struct SparseBitSet < T : Idx > ( SmallVec < [ T ; SPARSE_MAX ] > ) ;
329
330
330
331
impl < T : Idx > SparseBitSet < T > {
331
332
fn new_empty ( ) -> Self {
332
- SparseBitSet ( ArrayVec :: new ( ) )
333
+ SparseBitSet ( SmallVec :: new ( ) )
333
334
}
334
335
335
336
fn len ( & self ) -> usize {
@@ -341,21 +342,26 @@ impl<T: Idx> SparseBitSet<T> {
341
342
}
342
343
343
344
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
+ }
347
355
} else {
356
+ // `elem` is larger than all existing elements.
348
357
self . 0 . push ( elem) ;
349
358
true
350
359
}
351
360
}
352
361
353
362
fn remove ( & mut self , elem : T ) -> bool {
354
363
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) ;
359
365
true
360
366
} else {
361
367
false
@@ -396,8 +402,8 @@ impl<T: Idx> SubtractFromBitSet<T> for SparseBitSet<T> {
396
402
}
397
403
398
404
/// 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` .
401
407
///
402
408
/// This type is especially efficient for sets that typically have a small
403
409
/// number of elements, but a large `domain_size`, and are cleared frequently.
@@ -479,7 +485,6 @@ impl<T: Idx> HybridBitSet<T> {
479
485
}
480
486
}
481
487
482
- /// Iteration order is unspecified.
483
488
pub fn iter ( & self ) -> HybridIter < T > {
484
489
match self {
485
490
HybridBitSet :: Sparse ( sparse, _) => HybridIter :: Sparse ( sparse. iter ( ) ) ,
0 commit comments