Table of Contents

Class TraceBlockEncoder

Namespace
Typhon.Profiler
Assembly
Typhon.Profiler.dll

Block encoder/decoder for the .typhon-trace on-disk format and the TCP live-stream protocol. Works on variable-size record byte streams (as produced by TraceRecordRing.Drain) — the old fixed-stride TraceEvent[] path was removed in the Phase 3 rewrite.

public static class TraceBlockEncoder
Inheritance
TraceBlockEncoder
Inherited Members

Remarks

A block has a 12-byte header followed by an LZ4-compressed byte stream:

[4B uncompressedBytes] [4B compressedBytes] [4B recordCount] [compressedBytes bytes of LZ4 data]

No delta encoding: the old encoder delta-encoded timestamps per-event, which worked because every event had a TimestampTicks field at a fixed byte offset. With variable records, timestamps live at different offsets depending on record kind, so field-aware delta encoding would need a kind switch. LZ4 handles the byte-level redundancy well enough on its own — Phase 3 measurements show the payload compression ratio is within ~5% of the old delta-encoded version, for a much simpler encoder.

Fields

BlockHeaderSize

Size of the block header in bytes.

public const int BlockHeaderSize = 12

Field Value

int

Methods

DecodeBlock(ReadOnlySpan<byte>, int, Span<byte>)

Decompress a block's LZ4 payload into rawBuffer. The caller then walks the decoded bytes as a sequence of size-prefixed records (u16 size field at the start of each record).

public static void DecodeBlock(ReadOnlySpan<byte> compressedData, int uncompressedBytes, Span<byte> rawBuffer)

Parameters

compressedData ReadOnlySpan<byte>

LZ4-compressed payload (exactly compressedBytes from the header).

uncompressedBytes int

Expected decompressed size in bytes (from the header).

rawBuffer Span<byte>

Scratch buffer for decompression, must be at least uncompressedBytes bytes.

Exceptions

InvalidDataException

If LZ4 decoding produces an unexpected size.

EncodeBlock(ReadOnlySpan<byte>, int, Span<byte>, Span<byte>)

LZ4-compress records into compressedBuffer and write the 12-byte block header to blockHeader.

public static int EncodeBlock(ReadOnlySpan<byte> records, int recordCount, Span<byte> compressedBuffer, Span<byte> blockHeader)

Parameters

records ReadOnlySpan<byte>

Raw record bytes (as produced by TraceRecordRing.Drain).

recordCount int

Number of records in records — used for diagnostics and block header accounting.

compressedBuffer Span<byte>

Output buffer for LZ4 payload. Must be at least MaximumOutputSize(int)(records.Length) bytes.

blockHeader Span<byte>

Destination for the 12-byte block header; must be exactly BlockHeaderSize bytes.

Returns

int

Number of bytes written to compressedBuffer.

ReadBlockHeader(ReadOnlySpan<byte>)

Reads a block header and returns its fields.

public static (int UncompressedBytes, int CompressedBytes, int RecordCount) ReadBlockHeader(ReadOnlySpan<byte> blockHeader)

Parameters

blockHeader ReadOnlySpan<byte>

Returns

(int UncompressedBytes, int CompressedBytes, int RecordCount)