What's new in v3.1
Performance — RangeSet<TRange, T> now exploits its sorted, disjoint, non-adjacent invariant for sub-linear queries and merge-join set operations. No public API or results changed — only the time complexity:
| Operation | Before | After |
|---|---|---|
Contains(T), Contains(IRange<T>), Overlaps(IRange<T>) |
O(n) linear scan | O(log n) binary search on lower bounds |
Union(RangeSet, RangeSet) |
re-sort of concatenation | O(n + m) merge of two pre-sorted streams |
Intersect(RangeSet, RangeSet) |
O(n · m) nested loop | O(n + m) two-pointer merge-join |
Except(RangeSet, RangeSet) |
per-element re-normalization | O(n + m) two-pointer walk |
Except from Infinite |
O(|other|²) | O(|other|) single-pass complement walk |
From single-element input |
list + sort + merge | zero-allocation fast path |
New API — RangeSet<TRange, T>.LowerBoundComparer exposes the set's internal lower-bound ordering as a public IComparer<TRange> singleton, for sorting arbitrary List<TRange>s the same way the set does. Also available as RangeLowerBoundComparer<TRange, T>.Instance. See RangeSet — Sorting ranges externally.
Bug fix — Quoted range bounds now unescape PostgreSQL \" → " and \\ → \ on parse, so element types whose stringification can contain quotes or backslashes round-trip correctly. See Parsing — Quoted bounds.