empty : Coverage
Coverage
Coverage :: # (opaque)
Canonical finite coverage on the POSIX microsecond axis. Members are nonempty, sorted, disjoint, and do not touch.
Example
Combine occupied spans, then subtract them from a finite availability window.
Overlapping or touching spans coalesce. Keep bookings in EventCollection
when their individual identities matter; coverage deliberately forgets them.
import time.Coverage
import time.PosixSpan
import time.PosixDelta
expect {
window = PosixSpan.from_seconds(0, 10, RejectSubmicrosecond)?
busy = Coverage.from_spans([
PosixSpan.from_seconds(2, 4, RejectSubmicrosecond)?,
PosixSpan.from_seconds(4, 6, RejectSubmicrosecond)?,
])
free = Coverage.difference(Coverage.from_spans([window]), busy)
expected_width = PosixDelta.from_microseconds(6000000)
Coverage.member_count(busy) == 1 and
Coverage.member_count(free) == 2 and
Coverage.coordinate_width(free) == Ok(expected_width)
}
Examples assume a package dependency named time.
from_spans : List(PosixSpan) -> Coverage
from_sorted_spans : List(PosixSpan) -> Try(Coverage, [UnsortedInput, ..])
Validate start ordering in O(n); merge overlap and touch.
Returns the canonical spans. Roc may share their backing storage.
member_count : Coverage -> U64
Iterate whole canonical spans, never individual microseconds.
fact_count : Coverage -> U64
Indexed semantic facts visit canonical spans, never their coordinates. An allocated span list uses at least 16 bytes per member, leaving room for the fixed fact headers when its length is counted in U64.
to_inspect : Coverage -> Str
coordinate_width : Coverage -> Try(PosixDelta, [OutOfRange, ..])
fold_overlaps : Coverage, PosixSpan, state, (state, PosixSpan -> state) -> state
Fold whole overlapping members, not clipped intersections. O(log n + k).
overlapping_spans : Coverage, PosixSpan -> List(PosixSpan)
union : Coverage, Coverage -> Coverage
intersection : Coverage, Coverage -> Coverage
difference : Coverage, Coverage -> Coverage
complement_within : Coverage, PosixSpan -> Coverage
Complement relative to one finite window; seek before emitting gaps.
SortedBuilder
Coverage.SortedBuilder :: # (opaque)
Incremental construction from start-ordered spans, including across input chunks. Retains canonical output plus one pending span, not all raw input. This materializes coverage; it is not a lazy output iterator. Retaining a builder/snapshot can cause subsequent List appends to copy shared storage.
empty : SortedBuilder
member_count : SortedBuilder -> U64
Constant comparison work; owned append is amortized, shared append may copy retained output. Equal starts are valid; decreasing starts fail.
append_bounded : SortedBuilder, PosixSpan, U64 -> Try([Added(SortedBuilder), Full], [UnsortedInput, ..])
Full leaves the input builder unchanged and performs no output append. The limit counts canonical members, so touching/overlapping input can still merge at capacity. An already larger builder also returns Full.
append_retaining : SortedBuilder, PosixSpan, U64 -> Try([Added(SortedBuilder), Full(SortedBuilder)], [UnsortedInput, ..])
Internal cursor integration: return ownership of an unchanged full builder so callers need not retain an alias across a successful append. The public append_bounded adapter uses this same validation and merge.
to_coverage : SortedBuilder -> Coverage
No revalidation or sorting. Appending the pending member can copy a shared list; this does not detach earlier snapshots' backing storage.
to_inspect : SortedBuilder -> Str