OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // An Interval<T> is a data structure used to represent a contiguous, mutable | 5 // An Interval<T> is a data structure used to represent a contiguous, mutable |
6 // range over an ordered type T. Supported operations include testing a value to | 6 // range over an ordered type T. Supported operations include testing a value to |
7 // see whether it is included in the interval, comparing two intervals, and | 7 // see whether it is included in the interval, comparing two intervals, and |
8 // performing their union, intersection, and difference. For the purposes of | 8 // performing their union, intersection, and difference. For the purposes of |
9 // this library, an "ordered type" is any type that induces a total order on its | 9 // this library, an "ordered type" is any type that induces a total order on its |
10 // values via its less-than operator (operator<()). Examples of such types are | 10 // values via its less-than operator (operator<()). Examples of such types are |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 bool Intersects(const Interval& i, Interval* out) const; | 150 bool Intersects(const Interval& i, Interval* out) const; |
151 | 151 |
152 // Sets *this to be the intersection of itself with i. Returns true iff | 152 // Sets *this to be the intersection of itself with i. Returns true iff |
153 // *this was modified. | 153 // *this was modified. |
154 bool IntersectWith(const Interval& i); | 154 bool IntersectWith(const Interval& i); |
155 | 155 |
156 // Calculates the smallest interval containing both *this i, and updates *this | 156 // Calculates the smallest interval containing both *this i, and updates *this |
157 // to represent that interval, and returns true iff *this was modified. | 157 // to represent that interval, and returns true iff *this was modified. |
158 bool SpanningUnion(const Interval& i); | 158 bool SpanningUnion(const Interval& i); |
159 | 159 |
160 // Determines the difference between two intervals by finding all points that | |
161 // are contained in *this but not in i, coalesces those points into the | |
162 // largest possible contiguous intervals, and appends those intervals to the | |
163 // *difference vector. Intuitively this can be thought of as "erasing" i from | |
164 // *this. This will either completely erase *this (leaving nothing behind), | |
165 // partially erase some of *this from the left or right side (leaving some | |
166 // residual behind), or erase a hole in the middle of *this (leaving behind an | |
167 // interval on either side). Therefore, 0, 1, or 2 intervals will be appended | |
168 // to *difference. The method returns true iff the intersection of *this and i | |
169 // is non-empty. The caller owns the vector and the Interval* pointers | |
170 // inside it. The difference vector is required to be non-null. | |
171 bool Difference(const Interval& i, std::vector<Interval*>* difference) const; | |
172 | |
173 // Determines the difference between two intervals as in | 160 // Determines the difference between two intervals as in |
174 // Difference(Interval&, vector*), but stores the results directly in out | 161 // Difference(Interval&, vector*), but stores the results directly in out |
175 // parameters rather than dynamically allocating an Interval* and appending | 162 // parameters rather than dynamically allocating an Interval* and appending |
176 // it to a vector. If two results are generated, the one with the smaller | 163 // it to a vector. If two results are generated, the one with the smaller |
177 // value of min() will be stored in *lo and the other in *hi. Otherwise (if | 164 // value of min() will be stored in *lo and the other in *hi. Otherwise (if |
178 // fewer than two results are generated), unused arguments will be set to the | 165 // fewer than two results are generated), unused arguments will be set to the |
179 // empty interval (it is possible that *lo will be empty and *hi non-empty). | 166 // empty interval (it is possible that *lo will be empty and *hi non-empty). |
180 // The method returns true iff the intersection of *this and i is non-empty. | 167 // The method returns true iff the intersection of *this and i is non-empty. |
181 bool Difference(const Interval& i, Interval* lo, Interval* hi) const; | 168 bool Difference(const Interval& i, Interval* lo, Interval* hi) const; |
182 | 169 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 } | 246 } |
260 if (i.max() > max()) { | 247 if (i.max() > max()) { |
261 SetMax(i.max()); | 248 SetMax(i.max()); |
262 modified = true; | 249 modified = true; |
263 } | 250 } |
264 return modified; | 251 return modified; |
265 } | 252 } |
266 | 253 |
267 template <typename T> | 254 template <typename T> |
268 bool Interval<T>::Difference(const Interval& i, | 255 bool Interval<T>::Difference(const Interval& i, |
269 std::vector<Interval*>* difference) const { | |
270 if (Empty()) { | |
271 // <empty> - <i> = <empty> | |
272 return false; | |
273 } | |
274 if (i.Empty()) { | |
275 // <this> - <empty> = <this> | |
276 difference->push_back(new Interval(*this)); | |
277 return false; | |
278 } | |
279 if (min() < i.max() && min() >= i.min() && max() > i.max()) { | |
280 // [------ this ------) | |
281 // [------ i ------) | |
282 // [-- result ---) | |
283 difference->push_back(new Interval(i.max(), max())); | |
284 return true; | |
285 } | |
286 if (max() > i.min() && max() <= i.max() && min() < i.min()) { | |
287 // [------ this ------) | |
288 // [------ i ------) | |
289 // [- result -) | |
290 difference->push_back(new Interval(min(), i.min())); | |
291 return true; | |
292 } | |
293 if (min() < i.min() && max() > i.max()) { | |
294 // [------- this --------) | |
295 // [---- i ----) | |
296 // [ R1 ) [ R2 ) | |
297 // There are two results: R1 and R2. | |
298 difference->push_back(new Interval(min(), i.min())); | |
299 difference->push_back(new Interval(i.max(), max())); | |
300 return true; | |
301 } | |
302 if (min() >= i.min() && max() <= i.max()) { | |
303 // [--- this ---) | |
304 // [------ i --------) | |
305 // Intersection is <this>, so difference yields the empty interval. | |
306 // Nothing is appended to *difference. | |
307 return true; | |
308 } | |
309 // No intersection. Append <this>. | |
310 difference->push_back(new Interval(*this)); | |
311 return false; | |
312 } | |
313 | |
314 template <typename T> | |
315 bool Interval<T>::Difference(const Interval& i, | |
316 Interval* lo, | 256 Interval* lo, |
317 Interval* hi) const { | 257 Interval* hi) const { |
318 // Initialize *lo and *hi to empty | 258 // Initialize *lo and *hi to empty |
319 *lo = {}; | 259 *lo = {}; |
320 *hi = {}; | 260 *hi = {}; |
321 if (Empty()) | 261 if (Empty()) |
322 return false; | 262 return false; |
323 if (i.Empty()) { | 263 if (i.Empty()) { |
324 *lo = *this; | 264 *lo = *this; |
325 return false; | 265 return false; |
(...skipping 27 matching lines...) Expand all Loading... |
353 // Intersection is <this>, so difference yields the empty interval. | 293 // Intersection is <this>, so difference yields the empty interval. |
354 return true; | 294 return true; |
355 } | 295 } |
356 *lo = *this; // No intersection. | 296 *lo = *this; // No intersection. |
357 return false; | 297 return false; |
358 } | 298 } |
359 | 299 |
360 } // namespace net | 300 } // namespace net |
361 | 301 |
362 #endif // NET_QUIC_INTERVAL_H_ | 302 #endif // NET_QUIC_INTERVAL_H_ |
OLD | NEW |