EventCollection

EventCollection(id) :: # (opaque)

Events retain application-defined identity independently of their extents. Input order is preserved for iteration and contributor lists; it is not time order.

from_entries : List({ id : id, span : PosixSpan }) -> Try(EventCollection(id), [DuplicateId(id), ..]) where [id.is_eq : id, id -> Bool, id.to_hash : id, Hasher -> Hasher]

Expected O(n) construction for constant-cost ID hashing/equality; the input list and ID payloads may remain shared. One entry per identity. Duplicate IDs are errors, even for equal spans.

to_entries : EventCollection(id) -> List({ id : id, span : PosixSpan })
iter : EventCollection(id) -> Iter({ id : id, span : PosixSpan })
to_coverage : EventCollection(id) -> Coverage

Lossy projection: IDs and original segmentation cannot be recovered.

clip : EventCollection(id), Coverage -> List({ id : id, coverage : Coverage })

Retain each surviving identity once, with all of its clipped components. Empty intersections are omitted. Output retains source event order.

segments : EventCollection(id) -> List({ span : PosixSpan, contributors : List(id) })

Partition occupied time at every event boundary. Each segment contains exactly its active IDs, in source order. No per-microsecond enumeration. O(n log n + n² + c) work, O(n + c) output/storage, where c counts emitted contributor IDs. This scan is not an interval index or a coverage sweep.

to_inspect : EventCollection(id) -> Str

Constant-size diagnostics do not inspect application IDs or enumerate spans.