@@ -544,14 +544,15 @@ where
544
544
///
545
545
/// The iterator element type is `RangeInclusive<K>`.
546
546
pub fn gaps < ' a > ( & ' a self , outer_range : & ' a RangeInclusive < K > ) -> Gaps < ' a , K , V , StepFnsT > {
547
+ let overlap_iter = self . overlapping ( outer_range) ;
547
548
Gaps {
548
- done : false ,
549
- outer_range,
550
- keys : self . btm . keys ( ) ,
549
+ candidate_needs_plus_one : false ,
550
+ candidate_start : outer_range. start ( ) ,
551
+ query_end : outer_range. end ( ) ,
552
+ btm_range_iter : overlap_iter. btm_range_iter ,
551
553
// We'll start the candidate range at the start of the outer range
552
554
// without checking what's there. Each time we yield an item,
553
555
// we'll skip any ranges we find before the next gap.
554
- candidate_start : outer_range. start ( ) . clone ( ) ,
555
556
_phantom : PhantomData ,
556
557
}
557
558
}
@@ -801,10 +802,10 @@ pub struct Gaps<'a, K, V, StepFnsT> {
801
802
/// avoid overflowing when dealing with inclusive ranges.
802
803
///
803
804
/// All other things here are ignored if `done` is `true`.
804
- done : bool ,
805
- outer_range : & ' a RangeInclusive < K > ,
806
- keys : alloc :: collections :: btree_map :: Keys < ' a , RangeInclusiveStartWrapper < K > , V > ,
807
- candidate_start : K ,
805
+ candidate_needs_plus_one : bool ,
806
+ candidate_start : & ' a K ,
807
+ query_end : & ' a K ,
808
+ btm_range_iter : alloc :: collections :: btree_map :: Range < ' a , RangeInclusiveStartWrapper < K > , V > ,
808
809
_phantom : PhantomData < StepFnsT > ,
809
810
}
810
811
@@ -824,49 +825,47 @@ where
824
825
type Item = RangeInclusive < K > ;
825
826
826
827
fn next ( & mut self ) -> Option < Self :: Item > {
827
- if self . done {
828
- // We've already passed the end of the outer range;
829
- // there are no more gaps to find.
830
- return None ;
831
- }
828
+ for overlap in self . btm_range_iter . by_ref ( ) {
829
+ let overlap = overlap. 0 ;
832
830
833
- for item in & mut self . keys {
834
- let range = & item. range ;
835
- if * range. end ( ) < self . candidate_start {
836
- // We're already completely past it; ignore it.
837
- } else if * range. start ( ) <= self . candidate_start {
838
- // We're inside it; move past it.
839
- if * range. end ( ) >= * self . outer_range . end ( ) {
840
- // Special case: it goes all the way to the end so we
841
- // can't safely skip past it. (Might overflow.)
842
- self . done = true ;
843
- return None ;
844
- }
845
- self . candidate_start = StepFnsT :: add_one ( range. end ( ) ) ;
846
- } else if * range. start ( ) <= * self . outer_range . end ( ) {
847
- // It starts before the end of the outer range,
848
- // so move past it and then yield a gap.
849
- let gap = self . candidate_start . clone ( ) ..=StepFnsT :: sub_one ( range. start ( ) ) ;
850
- if * range. end ( ) >= * self . outer_range . end ( ) {
851
- // Special case: it goes all the way to the end so we
852
- // can't safely skip past it. (Might overflow.)
853
- self . done = true ;
854
- } else {
855
- self . candidate_start = StepFnsT :: add_one ( range. end ( ) ) ;
856
- }
831
+ // If the range in the map has advanced beyond the query range, return
832
+ // any tail gap.
833
+ if * self . query_end < * overlap. start ( ) {
834
+ break ;
835
+ }
836
+
837
+ let candidate_needs_plus_one =
838
+ core:: mem:: replace ( & mut self . candidate_needs_plus_one , true ) ;
839
+
840
+ let cur_candidate_start = core:: mem:: replace ( & mut self . candidate_start , overlap. end ( ) ) ;
841
+
842
+ let cur_candidate_start = if candidate_needs_plus_one {
843
+ StepFnsT :: add_one ( cur_candidate_start)
844
+ } else {
845
+ cur_candidate_start. clone ( )
846
+ } ;
847
+
848
+ if cur_candidate_start < * overlap. start ( ) {
849
+ let gap = cur_candidate_start..=StepFnsT :: sub_one ( overlap. start ( ) ) ;
857
850
return Some ( gap) ;
858
851
}
859
852
}
860
853
861
854
// Now that we've run out of items, the only other possible
862
855
// gap is one at the end of the outer range.
863
- self . done = true ;
864
- if self . candidate_start <= * self . outer_range . end ( ) {
856
+ let candidate_needs_plus_one = core:: mem:: replace ( & mut self . candidate_needs_plus_one , true ) ;
857
+
858
+ let cur_candidate_start = core:: mem:: replace ( & mut self . candidate_start , self . query_end ) ;
859
+ if candidate_needs_plus_one {
860
+ if * cur_candidate_start < * self . query_end {
861
+ return Some ( StepFnsT :: add_one ( cur_candidate_start) ..=self . query_end . clone ( ) ) ;
862
+ }
863
+ } else if * cur_candidate_start <= * self . query_end {
865
864
// There's a gap at the end!
866
- Some ( self . candidate_start . clone ( ) ..=self . outer_range . end ( ) . clone ( ) )
867
- } else {
868
- None
865
+ return Some ( cur_candidate_start. clone ( ) ..=self . query_end . clone ( ) ) ;
869
866
}
867
+
868
+ None
870
869
}
871
870
}
872
871
0 commit comments