// copy on write so we can cache a..Start intervals and sets of that public virtual void AddImpl(Interval addition) { //[email protected]("add "+addition+" to "+intervals.toString()); if (addition.IsEmpty) { return; } // find position in list // Use iterators as we modify list in place //for ( ListIterator iter = intervals.listIterator(); iter.hasNext(); ) for (int i = 0; i < intervals.Count; i++) { Interval r = intervals[i]; if (addition.Equals(r)) { return; } Interval?union = addition.Union(r); if (union != null) { // next to each other, make a single larger interval intervals[i] = union.Value; // make sure we didn't just create an interval that // should be merged with next interval in list if (i < intervals.Count - 1) { i++; Interval next = intervals[i]; Interval?union2 = union.Value.Union(next); if (union2 != null) { // if we bump up against or overlap next, merge intervals.RemoveAt(i); i--; intervals[i] = union2.Value; } } return; } if (addition.Start < r.Start) { // insert before r //iter.previous(); //iter.add( addition ); intervals.Insert(i, addition); return; } // if disjoint and after r, a future iteration will handle it } // ok, must be after last interval (and disjoint from last interval) // just add it intervals.Add(addition); }
protected virtual void Add(Interval addition) { //[email protected]("add "+addition+" to "+intervals.toString()); if (addition.EndInclusive < addition.Start) { return; } // find position in list //for (ListIterator iter = intervals.listIterator(); iter.hasNext();) { int n = intervals.Count; for (int i = 0; i < n; i++) { Interval r = (Interval)intervals[i]; if (addition.Equals(r)) { return; } if (addition.adjacent(r) || !addition.disjoint(r)) { // next to each other, make a single larger interval Interval bigger = addition.union(r); intervals[i] = bigger; // make sure we didn't just create an interval that // should be merged with next interval in list if ((i + 1) < n) { i++; Interval next = (Interval)intervals[i]; if (bigger.adjacent(next) || !bigger.disjoint(next)) { // if we bump up against or overlap next, merge intervals.RemoveAt(i); // remove next one i--; intervals[i] = bigger.union(next); // set to 3 merged ones } } return; } if (addition.startsBeforeDisjoint(r)) { // insert before r intervals.Insert(i, addition); return; } // if disjoint and after r, a future iteration will handle it } // ok, must be after last interval (and disjoint from last interval) // just add it intervals.Add(addition); }