Interface ICacheChunkSink
Abstraction over "where flushed chunks go" for IncrementalCacheBuilder. Two implementations:
FileCacheSink wraps TraceFileCacheWriter and produces a complete sidecar cache file
(replay path); AppendOnlyChunkSink (live path) writes only chunk bytes to a temp file and skips the trailer.
public interface ICacheChunkSink : IDisposable
- Inherited Members
Remarks
The sink is fully responsible for laying out compressed chunk bytes — the builder hands raw uncompressed records and the
resulting (offset, length) come back so the builder can record the chunk in its in-memory manifest. For replay sinks,
trailer sections are also written via WriteTrailer(IReadOnlyList<TickSummary>, in GlobalMetricsFixed, IReadOnlyList<SystemAggregateDuration>, IReadOnlyList<ChunkManifestEntry>, IReadOnlyDictionary<int, string>, ReadOnlySpan<byte>, in CacheHeader, IReadOnlyList<SystemTickSummary>, IReadOnlyList<QueueTickSummary>, IReadOnlyList<PostTickSummary>, IReadOnlyDictionary<ushort, string>, IReadOnlyList<SystemArchetypeTouchSummary>) at finalize time. For live sinks, those sections live in
memory only and the trailer call is a no-op (SupportsTrailer returns false).
Properties
SupportsTrailer
True if this sink writes a trailer (TickSummaries / GlobalMetrics / ChunkManifest / SpanNameTable + cache header).
bool SupportsTrailer { get; }
Property Value
Methods
AppendChunk(ReadOnlySpan<byte>)
LZ4-compress and append a chunk's records to the sink's underlying storage. Returns the byte offset and lengths needed to populate the matching ChunkManifestEntry.
(long CacheOffset, uint CompressedLength, uint UncompressedLength) AppendChunk(ReadOnlySpan<byte> uncompressedRecords)
Parameters
uncompressedRecordsReadOnlySpan<byte>
Returns
WriteTrailer(IReadOnlyList<TickSummary>, in GlobalMetricsFixed, IReadOnlyList<SystemAggregateDuration>, IReadOnlyList<ChunkManifestEntry>, IReadOnlyDictionary<int, string>, ReadOnlySpan<byte>, in CacheHeader, IReadOnlyList<SystemTickSummary>, IReadOnlyList<QueueTickSummary>, IReadOnlyList<PostTickSummary>, IReadOnlyDictionary<ushort, string>, IReadOnlyList<SystemArchetypeTouchSummary>)
Write trailer sections + finalize the cache header. Replay sinks (FileCacheSink) implement this; live sinks throw. Idempotent guard not required — builder calls this at most once on dispose.
void WriteTrailer(IReadOnlyList<TickSummary> tickSummaries, in GlobalMetricsFixed globalMetrics, IReadOnlyList<SystemAggregateDuration> systemAggregates, IReadOnlyList<ChunkManifestEntry> chunkManifest, IReadOnlyDictionary<int, string> spanNames, ReadOnlySpan<byte> sourceMetadataBytes, in CacheHeader headerTemplate, IReadOnlyList<SystemTickSummary> systemTickSummaries, IReadOnlyList<QueueTickSummary> queueTickSummaries, IReadOnlyList<PostTickSummary> postTickSummaries, IReadOnlyDictionary<ushort, string> queueIdToName, IReadOnlyList<SystemArchetypeTouchSummary> systemArchetypeTouches)
Parameters
tickSummariesIReadOnlyList<TickSummary>Per-tick overview rows (one entry per tick processed). Written to the TickSummaries section. Order is the order in which the builder accumulated them — typically tick-number ascending; the cache reader does not re-sort.
globalMetricsGlobalMetricsFixedSession-wide aggregates (start/end µs, max/p95 tick durations, total events, total ticks, per-system invocation counts). Computed once at finalize and written to the GlobalMetrics section.
systemAggregatesIReadOnlyList<SystemAggregateDuration>Per-system invocation count + cumulative duration across the whole session. Companion to
globalMetrics; written into the GlobalMetrics section as a fixed-size table.chunkManifestIReadOnlyList<ChunkManifestEntry>Byte-offset index into the trailing FoldedChunkData blob — one entry per chunk previously produced by AppendChunk(ReadOnlySpan<byte>). Drives random-access tick-range fetches at read time.
spanNamesIReadOnlyDictionary<int, string>SpanId → display-name lookup table for trace events that carry a
SpanIdreference. Written to the SpanNameTable section. Empty dictionary is valid.sourceMetadataBytesReadOnlySpan<byte>Optional verbatim source metadata (header + system / archetype / component-type tables, in
TraceFileWriterwire format). When non-empty, the sink emits a SourceMetadata section; the caller must set IsSelfContained onheaderTemplateso loaders project metadata from these bytes instead of opening a sibling source file. Pass Empty for source-derived caches.headerTemplateCacheHeaderCache-file header to finalize. The sink fills in section-table offsets / lengths and writes the result at the file head; caller-supplied fields (magic, version, chunker version, identifier, flags) are preserved verbatim.
systemTickSummariesIReadOnlyList<SystemTickSummary>v12 (#311). Per-tick per-system rollup rows (duration, ready/start/end µs, entities processed, etc.) backing the Workbench Data API's
system/<name>tracks. Written to the SystemTickSummaries section. Empty list is valid for v11-derived caches and produces an empty section that readers tolerate.queueTickSummariesIReadOnlyList<QueueTickSummary>v12 (#311). Per-tick per-event-queue rollup rows (peak depth, end-of-tick depth, overflow count, produced/consumed) backing the
queue/<name>tracks. Written to the QueueTickSummaries section. Empty list is valid for v11-derived caches.postTickSummariesIReadOnlyList<PostTickSummary>v12 (#311). Per-tick post-serial-block rollup rows (WAL flush, write-tick-fence, subscription output, etc.) backing the
posttick/<phase>tracks. Written to the PostTickSummaries section. Empty list is valid for v11-derived caches.queueIdToNameIReadOnlyDictionary<ushort, string>v12 (#311). QueueId → display-name lookup for the entries in
queueTickSummaries. Written to the QueueNameTable section. Empty dictionary is valid.systemArchetypeTouchesIReadOnlyList<SystemArchetypeTouchSummary>v15 (#327). Per-(tick, system, archetype) entity-touch rows backing the Workbench Data Flow module's
archetype/,system-archetype/, andcomponent-family/*tracks. Written to the SystemArchetypeTouches section. Empty list is valid (older traces or sessions withTelemetryConfig.SchedulerArchetypeTouchesActive = false).
Exceptions
- NotSupportedException
Thrown by live sinks (e.g.
AppendOnlyChunkSink) — see SupportsTrailer. Callers should gate on that flag rather than catching the exception.