3.2 KiB
bitset
Purpose
Implements the wire-format bitset codec for the mesh protocol. Bitsets carry chunk presence (cd:advertise) and chunk-need maps (cd:request kind:'bitset'); their on-wire representation is a deterministic, magic-prefixed, length-tagged envelope so receivers can detect and reject payloads that bypassed the mandated framing layer (DMP-21). This module also provides the raw bit-manipulation helpers (chunkIdsToRawBitset, rawBitsetToChunkIds, popcount) that the rest of the package consumes.
Features
BITSET_MAGIC(4-byte"DMPB"prefix) +BITSET_HEADER_SIZE(12-byte fixed header).encodeBitset(rawBytes, bitLength)— wraps a raw bit-packed buffer with the header.decodeBitset(wire)— verifies magic, decodes header, returns{ raw, bitLength }; throwsDMP.CODEC_MISMATCHfor missing magic / truncated headers / length mismatches.chunkIdsToRawBitset(ids, bitLength)— packs a chunk-id list into a raw bit-packed buffer with strict bounds checking.rawBitsetToChunkIds(bytes, bitLength)— inverse, with padding-zero enforcement (DMP-08).popcount(bytes)— population count (Hamming weight) over a raw byte array; used by trust accounting.- All length / padding violations raise
DMP.BITSET_LENGTH_MISMATCHorDMP.BITSET_PADDING_NONZERO.
Usage: Basic Example
import {
chunkIdsToRawBitset,
decodeBitset,
encodeBitset,
rawBitsetToChunkIds,
} from "@suaveplan/drive-mesh-protocol";
const raw = chunkIdsToRawBitset([0, 5, 17], 18);
const wire = encodeBitset(raw, 18);
const back = decodeBitset(wire);
const ids = rawBitsetToChunkIds(back.raw, back.bitLength); // [0, 5, 17]
Usage: Advanced Example
import {
BITSET_HEADER_SIZE,
BITSET_MAGIC,
encodeBitset,
popcount,
} from "@suaveplan/drive-mesh-protocol";
function buildPresence(present: number[], totalChunks: number): Uint8Array {
const raw = chunkIdsToRawBitset(present, totalChunks);
const wire = encodeBitset(raw, totalChunks);
console.log(
`${present.length}/${totalChunks} chunks; ${popcount(raw)} set bits;` +
` wire size ${wire.length} (${BITSET_HEADER_SIZE}-byte header)`
);
return wire;
}
API Reference
BITSET_MAGIC: Uint8Array— 4-byte prefix0x44 0x4d 0x50 0x42.BITSET_HEADER_SIZE: 12— magic + bitLength + rawByteLen.encodeBitset(rawBytes: Uint8Array, bitLength: number): Uint8Array.decodeBitset(wire: Uint8Array): { raw: Uint8Array; bitLength: number }.chunkIdsToRawBitset(chunkIds: readonly number[], bitLength: number): Uint8Array.rawBitsetToChunkIds(bytes: Uint8Array, bitLength: number): number[].popcount(bytes: Uint8Array): number.
Implementation Notes
The wire format does NOT compress the bitset body — the documented bitpacker-compressed mandate is satisfied by the magic + length envelope, which is itself a length-prefixed, self-describing frame. The compressRle fast path in @suaveplan/bitpacker-compressed is non-bijective on inputs containing isolated [X, 0, …] triples and is therefore unsuitable for arbitrary bitset bytes; switching to gzip would force the codec async and break the hot path. The trade-off is intentional and documented inline in the source.