@@ -70,67 +70,64 @@ impl<I: Idx> IntervalSet<I> {
7070 /// Returns true if we increased the number of elements present.
7171 pub fn insert_range ( & mut self , range : impl RangeBounds < I > + Clone ) -> bool {
7272 let start = inclusive_start ( range. clone ( ) ) ;
73- let Some ( mut end) = inclusive_end ( self . domain , range) else {
73+ let Some ( end) = inclusive_end ( self . domain , range) else {
7474 // empty range
7575 return false ;
7676 } ;
7777 if start > end {
7878 return false ;
7979 }
8080
81- loop {
82- // This condition looks a bit weird, but actually makes sense.
83- //
84- // if r.0 == end + 1, then we're actually adjacent, so we want to
85- // continue to the next range. We're looking here for the first
86- // range which starts *non-adjacently* to our end.
87- let next = self . map . partition_point ( |r| r. 0 <= end + 1 ) ;
88- if let Some ( last) = next. checked_sub ( 1 ) {
89- let ( prev_start, prev_end) = & mut self . map [ last] ;
90- if * prev_end + 1 >= start {
91- // If the start for the inserted range is adjacent to the
92- // end of the previous, we can extend the previous range.
93- if start < * prev_start {
94- // Our range starts before the one we found. We'll need
95- // to *remove* it, and then try again.
96- //
97- // FIXME: This is not so efficient; we may need to
98- // recurse a bunch of times here. Instead, it's probably
99- // better to do something like drain_filter(...) on the
100- // map to be able to delete or modify all the ranges in
101- // start..=end and then potentially re-insert a new
102- // range.
103- end = std:: cmp:: max ( end, * prev_end) ;
104- self . map . remove ( last) ;
105- } else {
106- // We overlap with the previous range, increase it to
107- // include us.
108- //
109- // Make sure we're actually going to *increase* it though --
110- // it may be that end is just inside the previously existing
111- // set.
112- return if end > * prev_end {
113- * prev_end = end;
114- true
115- } else {
116- false
117- } ;
81+ // This condition looks a bit weird, but actually makes sense.
82+ //
83+ // if r.0 == end + 1, then we're actually adjacent, so we want to
84+ // continue to the next range. We're looking here for the first
85+ // range which starts *non-adjacently* to our end.
86+ let next = self . map . partition_point ( |r| r. 0 <= end + 1 ) ;
87+ if let Some ( right) = next. checked_sub ( 1 ) {
88+ let ( prev_start, prev_end) = self . map [ right] ;
89+ if prev_end + 1 >= start {
90+ // If the start for the inserted range is adjacent to the
91+ // end of the previous, we can extend the previous range.
92+ if start < prev_start {
93+ // The first range which ends *non-adjacently* to our start.
94+ // And we can ensure that left <= right.
95+ let left = self . map . partition_point ( |l| l. 1 + 1 < start) ;
96+ let min = std:: cmp:: min ( self . map [ left] . 0 , start) ;
97+ let max = std:: cmp:: max ( prev_end, end) ;
98+ self . map [ right] = ( min, max) ;
99+ if left != right {
100+ self . map . drain ( left..right) ;
118101 }
119- } else {
120- // Otherwise, we don't overlap, so just insert
121- self . map . insert ( last + 1 , ( start, end) ) ;
122102 return true ;
123- }
124- } else {
125- if self . map . is_empty ( ) {
126- // Quite common in practice, and expensive to call memcpy
127- // with length zero.
128- self . map . push ( ( start, end) ) ;
129103 } else {
130- self . map . insert ( next, ( start, end) ) ;
104+ // We overlap with the previous range, increase it to
105+ // include us.
106+ //
107+ // Make sure we're actually going to *increase* it though --
108+ // it may be that end is just inside the previously existing
109+ // set.
110+ return if end > prev_end {
111+ self . map [ right] . 1 = end;
112+ true
113+ } else {
114+ false
115+ } ;
131116 }
117+ } else {
118+ // Otherwise, we don't overlap, so just insert
119+ self . map . insert ( right + 1 , ( start, end) ) ;
132120 return true ;
133121 }
122+ } else {
123+ if self . map . is_empty ( ) {
124+ // Quite common in practice, and expensive to call memcpy
125+ // with length zero.
126+ self . map . push ( ( start, end) ) ;
127+ } else {
128+ self . map . insert ( next, ( start, end) ) ;
129+ }
130+ return true ;
134131 }
135132 }
136133
0 commit comments