88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- use array_vec:: ArrayVec ;
1211use indexed_vec:: { Idx , IndexVec } ;
1312use rustc_serialize;
13+ use smallvec:: SmallVec ;
1414use std:: fmt;
1515use std:: iter;
1616use std:: marker:: PhantomData ;
@@ -320,16 +320,17 @@ fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
320320const 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
330331impl < 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