Skip to content

Releases: engineering87/TemporalCollections

TemporalCollections - v1.2.0

22 Nov 16:35
021a933

Choose a tag to compare

A significant update that brings modern runtime support, two powerful new temporal data structures, and multiple enhancements across the library.

🔧 Runtime & Platform Updates

▶️ Full Support for .NET 10

TemporalCollections now targets .NET 10, providing:

  • Improved JIT optimizations
  • Better memory throughput
  • Enhanced threading and synchronization primitives
  • Access to the latest C# features and platform APIs

Backward compatibility with previous .NET versions remains intact where applicable.

🆕 New Temporal Data Structures

1. TemporalSegmentedArray

A highly optimized segmented array for time-ordered workloads, designed for:

  • ingestion-heavy event streams
  • high-frequency telemetry pipelines
  • log/trace collection
  • sliding-window analytics

🔍 Highlights:

  • Amortized O(1) append for monotonic timestamps
  • Segmented storage for memory efficiency
  • Fast range queries (O(log S + K))
  • Efficient segment-level cleanup and retention

2. TemporalMultimap<TKey, TValue>

A temporal multimap where each key maps to multiple timestamped values, while still enabling global temporal queries.

Perfect for:

  • user/session histories
  • audit logs
  • grouped event streams
  • entity timelines

📌 Key Features:

  • Per-key temporal ordering
  • Global time-based queries across all keys
  • Efficient per-key and global retention methods
  • Strict monotonic timestamps for consistency

📚 Documentation Improvements

The README has been fully updated to reflect:

  • the two new data structures
  • their usage guidance
  • Big-O performance comparisons
  • expanded examples
  • updated threading and locking model overview

These updates help developers understand when and how to use each structure effectively.

🛠 Internal Enhancements

This release includes several internal improvements:

  • Better timestamp boundary validation
  • More consistent behavior across all ITimeQueryable implementations
  • Minor refactoring for clarity and maintainability
  • Uniform time semantics based on DateTimeOffset
  • Additional safety in concurrent operations

All changes are fully backward-compatible.

📦 Summary of Changes

Added

  • TemporalSegmentedArray<T>
  • TemporalMultimap<TKey, TValue>
  • Full .NET 10 support

Improved

  • README documentation
  • Performance characteristics in several collections
  • Thread-safety consistency
  • Internal cleanup and retention logic

Fixed

  • Minor inconsistencies in time-range handling
  • Edge cases in nearest-item selection

✔️ Upgrade Notes

If you're already using TemporalCollections:

  • No breaking changes were introduced
  • All APIs remain backward compatible
  • You may simply update your package reference:

TemporalCollections - v1.1.0

20 Aug 10:49

Choose a tag to compare

This release introduces important improvements to the temporal model, new APIs for querying collections, and performance optimizations across all data structures.

✨ What's New

🔄 Timestamp handling with DateTimeOffset

  • All temporal collections now use DateTimeOffset instead of DateTime for timestamp management.
  • This ensures precise and unambiguous handling of time values across time zones and UTC/local contexts.

📚 New API methods

  • Added CountSince(DateTimeOffset from)
    Counts the number of items with timestamp greater than or equal to the specified cutoff.

  • Added GetNearest(DateTimeOffset time)
    Retrieves the item whose timestamp is closest to the specified time.
    Returns null if the collection is empty.

🧩 Extension methods

  • Introduced non-mutating, value-centric extension methods for ITimeQueryable<T>:
    • ToValueList()
    • ToValueArray()
    • Values(), ValuesInRange(from, to)
    • LatestValueOrDefault(), EarliestValueOrDefault()
    • ToValueHashSet(), ToValueDictionary(...), ToValueQueue(), ToValueStack(), ToReadOnlyValueCollection()
  • These helpers materialize or enumerate only the values without re-inserting items, so original timestamps are preserved.

⚡ Performance optimizations

  • Improved query and cleanup performance for all temporal data structures:
    • TemporalQueue, TemporalStack
    • TemporalSet, TemporalSlidingWindowSet
    • TemporalDictionary, TemporalSortedList
    • TemporalPriorityQueue, TemporalCircularBuffer, TemporalIntervalTree
  • Reduced allocations and optimized iteration in common query patterns.

TemporalCollections - First Public Release

14 Aug 14:34
d59e3e8

Choose a tag to compare

A set of thread-safe .NET collections with built-in UTC timestamps and a unified ITimeQueryable<T> API for range queries, cleanup, and temporal analytics. Timestamps are strictly monotonic, ensuring deterministic ordering even under high concurrency.

🚀 Highlights
Unified time API via ITimeQueryable<T>:

  • GetInRange, RemoveOlderThan, CountInRange, GetTimeSpan, RemoveRange, GetBefore, GetAfter, GetEarliest, GetLatest, Clear.
  • Deterministic ordering: results are returned in ascending timestamp order (strict before/after semantics).
  • Concurrency-ready: internal locking/lock-free primitives where appropriate.
  • Stable comparer for TemporalItem<T> to avoid drops in ordered sets when timestamps collide.

📦 Included Collections

  • TemporalSortedList<T>: sorted by timestamp; fast window queries (binary searches).
  • TemporalCircularBuffer<T>: fixed-capacity, overwrites oldest; O(1) add, ordered snapshots.
  • TemporalQueue<T>: FIFO with timestamps; time-based pruning and queries.
  • TemporalStack<T>: LIFO with timestamps; time-based pruning and queries.
  • TemporalPriorityQueue<TPriority, TValue>: priority + timestamp (stable by time for ties).
  • TemporalDictionary<TKey, TValue>: multi-value per key with timestamps; per-key and global queries.
  • TemporalSlidingWindowSet<T>: deduplicated set with sliding window expiration.
  • TemporalIntervalTree<T>: interval storage (start/end) with overlap queries (timestamp = start).

🧭 Unified ITimeQueryable (Summary)

  • Inclusive range: GetInRange(from, to), CountInRange(from, to), RemoveRange(from, to) (throws if to < from).
  • Cleanup: RemoveOlderThan(cutoff), Clear().
  • Navigation: GetBefore(time), GetAfter(time), GetEarliest(), GetLatest().
  • Span: GetTimeSpan() = latest.Timestamp - earliest.Timestamp.