@@ -834,8 +834,16 @@ impl<V: Ord> FromIterator<(Bound<V>, Bound<V>)> for Ranges<V> {
834
834
fn from_iter < T : IntoIterator < Item = ( Bound < V > , Bound < V > ) > > ( iter : T ) -> Self {
835
835
// We have three constraints we need to fulfil:
836
836
// 1. The segments are sorted, from lowest to highest (through `Ord`): By sorting.
837
- // 2. Each segment contains at least one version (start < end): By `union`.
838
- // 3. There is at least one version between two segments: By `union`.
837
+ // 2. Each segment contains at least one version (start < end): By skipping invalid
838
+ // segments.
839
+ // 3. There is at least one version between two segments: By merging overlapping elements.
840
+ //
841
+ // Technically, the implementation has a O(n²) worst case complexity since we're inserting
842
+ // and removing. This has two motivations: One is that we don't have any performance
843
+ // critical usages of this method as of this writing, so we have no real world benchmark.
844
+ // The other is that we get the elements from an iterator, so to avoid moving elements
845
+ // around we would first need to build a different, sorted collection with extra
846
+ // allocation(s), before we could build our real segments. --Konsti
839
847
840
848
// For this implementation, we choose to only build a single smallvec and insert or remove
841
849
// in it, instead of e.g. collecting the segments into a sorted datastructure first and then
@@ -986,6 +994,9 @@ impl<V: Ord> FromIterator<(Bound<V>, Bound<V>)> for Ranges<V> {
986
994
// following: |------|
987
995
//
988
996
// final: |------| |------| |------|
997
+
998
+ // This line is O(n), which makes the algorithm O(n²), but it should be good
999
+ // enough for now.
989
1000
segments. insert ( insertion_point, segment) ;
990
1001
}
991
1002
}
0 commit comments