ddn.encoding.rle

ddn.encoding.rle — run-length encoding, DDN-RLE/1 dialect.

Typed runs over uint/ulong elements. The byte dialect (M031, encodeUint32 and friends below) is a sequence of tokens: a varint header (count << 1) | kind — kind 0 RUN (one W-byte little-endian value repeated count times), kind 1 LITERAL (count values) — with the element width W ∈ {1,2,4,8} supplied by the caller, never carried in the stream. Design record: doc/DDN-ENCODING.md D20–D25.

This file's typed layer (run detection and bounded expansion) is usable independently of the byte codec.

Contract highlights: per-token commit atomicity with precise prefix reporting on capacity failure, checked count × W arithmetic, no allocation, no throwing (@nogc nothrow), CTFE.

Example:

import ddn.encoding.rle;

const uint[5] vals = [7, 7, 7, 8, 9];
assert(rle.runLengthAtUint32(vals[]) == 3);
uint[3] out_;
assert(rle.expandRunUint32(7, 3, out_[]).value == 3
   && out_[] == [7, 7, 7]);

Types 2

structRleError

Recoverable RLE failure with bounded context.

bytes/values carry the committed prefix at detection (INVALID_VALUE: values is the offending value index and bytes == 0).

Fields
Code codeWhich failure happened.
size_t bytesBytes consumed when detected (encode prefix or decode input).
size_t valuesValues written (or the offending index) when detected.
Nested Templates
CodeFailure classification.

A decoded stream: values written and bytes consumed.

Fields
size_t valuesValues written to the destination.
size_t bytesBytes consumed from the input (the whole stream on success).

Functions 14

fnsize_t runLengthAtUint32(scope const(uint)[] values) @safe pure nothrow @nogcLength of the run of equal values starting at `values[0]` (`≥ 1` for non-empty input; `0` for empty input).
fnsize_t runLengthAtUint64(scope const(ulong)[] values) @safe pure nothrow @nogcDitto (`ulong` elements).
fnResult!(size_t, RleError) expandRunUint32(uint value, size_t count, return scope uint[] dst) @safe pure nothrow @nogcWrites `count` copies of `value` into `dst` (bounded expansion).
fnResult!(size_t, RleError) expandRunUint64(ulong value, size_t count, return scope ulong[] dst) @safe pure nothrow @nogcDitto (`ulong` elements).
fnsize_t maxEncodedSize(size_t count, ubyte widthBytes) @safe pure nothrow @nogcMaximum byte length `encode*` can emit for `count` values at element width `widthBytes` (conservative: a varint header per token plus payload; greedy literals pair up, single values may stand alone...
private fnbool _widthOk(ubyte widthBytes, bool wide) @safe nothrow @nogc
fnResult!(size_t, RleError) encodeUint32(scope const(uint)[] values, ubyte widthBytes, return scope ubyte[] dst) @safe nothrow @nogcEncodes values into a `DDN-RLE/1` stream at element width `W`.
fnResult!(size_t, RleError) encodeUint64(scope const(ulong)[] values, ubyte widthBytes, return scope ubyte[] dst) @safe nothrow @nogcDitto (`ulong` elements; `W` in `{1,2,4,8}`).
private fnResult!(size_t, RleError) _encode(V)( scope const(V)[] values, ubyte widthBytes, scope ubyte[] dst) static @safe nothrow @nogc
private fnsize_t _putHeader(scope ubyte[] dst, ulong header) static @safe nothrow @nogc
private fnsize_t _putValue(V)(scope ubyte[] dst, size_t at, V v, ubyte widthBytes) static @safe nothrow @nogc
fnResult!(RleDecoded, RleError) decodeUint32(scope const(ubyte)[] src, ubyte widthBytes, return scope uint[] dst) @safe nothrow @nogcDecodes a whole `DDN-RLE/1` stream at element width `W`.
fnResult!(RleDecoded, RleError) decodeUint64(scope const(ubyte)[] src, ubyte widthBytes, return scope ulong[] dst) @safe nothrow @nogcDitto (`ulong` elements; `W` in `{1,2,4,8}`).
private fnResult!(RleDecoded, RleError) _decode(V)( scope const(ubyte)[] src, ubyte widthBytes, scope V[] dst) static @safe nothrow @nogc

Variables 1

private enumvarmaxTokenCount = 2_147_483_647