Skip to content

Release 1.3.0 - #3

Merged
engineering87 merged 34 commits into
mainfrom
develop
Oct 24, 2026
Merged

engineering87 merged 34 commits into
mainfrom
develop

Conversation

@engineering87

Copy link
Copy Markdown
Owner

Release 1.3.0

Summary

This PR merges develop into main for v1.3.0. It adds TimeProvider support across all collections and a new TemporalCache, and fixes several concurrency and correctness bugs. It does not intentionally change existing public behavior.

✨ New features

  • TimeProvider support in every temporal collection, so tests can control time.
  • TemporalCache<TKey, TValue>: new collection with TTL and sliding expiration (with benchmarks and README docs).
  • TemporalQueue: TryDequeue / TryPeek.
  • Extensions:
    • inclusive directional lookups and Try* variants
    • count-before / count-after queries
  • TemporalIntervalTree: new methods that make the semantics explicit:
    • GetOverlapping(from, to) returns intervals that overlap the range.
    • CountOverlapping(from, to) counts the same intervals as GetOverlapping.
    • RemoveEndedBefore(cutoff) removes intervals with End < cutoff.
    • The existing methods keep their current behavior. Their semantics (overlap, Start-based or End-based) are now documented.

⚡ Performance

  • TemporalDictionary: range queries and removals use binary search; Add appends in O(1) thanks to monotonic timestamps.
  • TemporalMultimap: global range queries use a k-way merge.

🐛 Bug fixes

  • TemporalIntervalTree: distinct values with the same hash code are no longer dropped or removed by mistake.
  • Ordering under concurrency: TemporalCircularBuffer.Add, TemporalQueue.Enqueue, TemporalDictionary.Add and TemporalMultimap.AddValue now keep items in chronological order when several threads write at once.
  • TemporalDictionary: pruning no longer removes a key that another thread has just re-created.
  • TemporalSegmentedArray: no longer throws IndexOutOfRangeException when adding after TrimExcess.
  • TemporalPriorityQueue: no longer throws on null priorities; they are sorted first.
  • TimeNormalization: catches only ArgumentException instead of every exception; docs fixed.
  • Earlier fixes: GetNearest tie-breaking, a monotonic sequence tie-breaker, and fixes for concurrency races, an overflow risk and dead code.

🧪 Tests

  • Migrated to xUnit v3.
  • Added global.json so dotnet test runs on Microsoft.Testing.Platform (required by the .NET 10 SDK).
  • New regression and concurrency tests (hash collisions, null values, ordering under concurrency, TrimExcess, interval-tree semantics).
  • 794 / 794 tests passing on net9.0 and net10.0.

📦 Packaging & docs

  • Version bumped to 1.3.0, with full PackageReleaseNotes.
  • New project logo (assets/logo.svg) shown in the README.
  • NuGet package icon (assets/icon.png, 128×128).
  • Dependencies updated.

⚠️ Notes

  • Mixed semantics in TemporalIntervalTree: some methods use overlap, others use only Start or End. For example, CountInRange counts by Start, while GetInRange uses overlap. This is now documented; making it consistent is planned for 2.0 and will be a breaking change.

…, swapped ranges, DateTime overloads, ordering, and nearest ties
…fety

- Fix race condition in TemporalDictionary.Add where concurrent
  RemoveOlderThan/RemoveRange could orphan a list, silently losing items
- Fix GetNearest tie-breaking in TemporalMultimap and TemporalSegmentedArray
  to prefer the later item (>= time), consistent with all other collections
- Prevent IndexOutOfRangeException in TemporalSegmentedArray when
  segmentCapacity == 1 by requiring minimum capacity of 2
- Remove unused TimestampOnlyComparerImpl from TemporalDictionary
- Update related tests to match corrected tie-breaking behavior
@engineering87
engineering87 merged commit 4ac7672 into main Oct 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant