@@ -82,26 +82,93 @@ impl Gtid {
82
82
83
83
/// Add an interval but does not check assume interval is correctly formed
84
84
fn add_interval_unchecked ( & mut self , interval : & ( u64 , u64 ) ) {
85
- let mut interval = * interval;
85
+ let interval = * interval;
86
86
87
- // TODO: Do it in place with a filter.
88
- let mut new: Vec < ( u64 , u64 ) > = Vec :: with_capacity ( self . intervals . len ( ) ) ;
89
- for current in self . intervals . iter ( ) {
90
- if interval. 0 == current. 1 {
91
- interval = ( current. 0 , interval. 1 ) ;
92
- continue ;
87
+ // self.intervals was empty
88
+ if self . intervals . is_empty ( ) {
89
+ self . intervals . push ( interval) ;
90
+ return ;
91
+ }
92
+ if let Some ( & first) = self . intervals . first ( ) {
93
+ // if interval is strictly before intervals
94
+ if interval. 1 < first. 0 {
95
+ self . intervals . insert ( 0 , interval) ;
96
+ return ;
93
97
}
94
98
95
- if interval. 1 == current. 0 {
96
- interval = ( interval. 0 , current. 1 ) ;
97
- continue ;
99
+ // if interval merge before interval
100
+ if interval. 1 == first. 0 {
101
+ // unwrapping is ok as intervals is not empty
102
+
103
+ let first = self . intervals . first_mut ( ) . unwrap ( ) ;
104
+ * first = ( interval. 0 , first. 1 ) ;
105
+ return ;
98
106
}
99
- new. push ( * current) ;
100
107
}
101
108
102
- new. push ( interval) ;
103
- new. sort ( ) ;
104
- self . intervals = new;
109
+ if let Some ( & last) = self . intervals . last ( ) {
110
+ if interval. 0 > last. 1 {
111
+ self . intervals . push ( interval) ;
112
+ return ;
113
+ }
114
+
115
+ if interval. 0 == last. 1 {
116
+ // unwrapping is ok as intervals is not empty
117
+
118
+ let last = self . intervals . last_mut ( ) . unwrap ( ) ;
119
+ * last = ( last. 0 , interval. 1 ) ;
120
+ return ;
121
+ }
122
+ }
123
+
124
+ match self
125
+ . intervals
126
+ . binary_search_by ( |elem| elem. 1 . cmp ( & interval. 0 ) )
127
+ {
128
+ Err ( idx) => {
129
+ // error case so it won't merge with previous
130
+ // it may merge before the item currently at idx
131
+ if idx == self . intervals . len ( ) {
132
+ // previously treated
133
+ unreachable ! ( )
134
+ }
135
+ // we can unwrap as the case interval is after the last element is treated before
136
+ let next = self . intervals . get ( idx) . unwrap ( ) ;
137
+ // interval merges with next
138
+ if next. 0 == interval. 1 {
139
+ * self . intervals . get_mut ( idx) . unwrap ( ) = ( interval. 0 , next. 1 ) ;
140
+ } else {
141
+ // just add interval, nothing to merge
142
+ self . intervals . insert ( idx, interval) ;
143
+ }
144
+ }
145
+ Ok ( idx) => {
146
+ // ok case it will merge with current
147
+ // it may merge with next
148
+
149
+ let before = self . intervals [ idx] ;
150
+ let after = self . intervals [ idx + 1 ] ;
151
+
152
+ // interval merges with before and after
153
+ if interval. 0 == before. 1 && interval. 1 == after. 0 {
154
+ * self . intervals . get_mut ( idx) . unwrap ( ) = ( before. 0 , after. 1 ) ;
155
+ self . intervals . remove ( idx + 1 ) ;
156
+ } else if
157
+ // interval merges with before
158
+ interval. 0 == before. 1 {
159
+ * self . intervals . get_mut ( idx) . unwrap ( ) = ( before. 0 , interval. 1 ) ;
160
+ } else if
161
+ // interval merges with after
162
+ interval. 1 == after. 0 {
163
+ unreachable ! ( "should have been treated in the error branch before" ) ;
164
+ // *self.intervals.get_mut(idx + 1).unwrap() = (interval.0, after.1);
165
+ } else {
166
+ // interval does not merge
167
+ unreachable ! ( "should have been treated in the error branch before" ) ;
168
+ // self.intervals.insert(idx + 1, interval)
169
+ }
170
+ }
171
+ }
105
172
}
106
173
107
174
/// Add a raw interval into the gtid.
0 commit comments