Columnar encoding kernel for MoonBit: the Parquet page-level encoding family as a reusable, verifiable, pluggable library.
Dependencies
moon run examples/encode_demo
moon run examples/encode_demo | sort -t$'\t' -k4,4nmoon check --deny-warn # type-check, warnings are errors
moon test # wasm-gc, the default target
moon test --target native # and js: backend-differing paths need both
moon package --list # what a release archive would containlet column = @colenc_types.ColBuf::Int64s([1L, 4L, 9L])
let out = Buffer()
let stats = @colenc.encode_column(
column, @colenc_types.DeltaBinaryPacked, out,
) catch {
e => abort(@colenc_types.EncodingError::message(e))
}
let back = @colenc.decode_column(
out.to_bytes(), @colenc_types.Int64, @colenc_types.DeltaBinaryPacked, 3,
)| # | Family | Applies to | Criteria | Choice bits aligned with the reference |
|---|---|---|---|---|
| E0 | PLAIN | all six physical types | round trip + container | length prefixes, LSB-first booleans |
| E1 | RLE / bit-packed hybrid | boolean values, dictionary indices | round trip + byte diff | eight-value buffering, 63-group literal cap |
| E2 | Dictionary | INT32/INT64/FLOAT/DOUBLE/BYTE_ARRAY | round trip + byte diff | first-appearance order, max(1, bit_width_for(size-1)) |
| E3 | DELTA_BINARY_PACKED | INT32/INT64 | round trip + byte diff | block 128 (INT32) / 256 (INT64), four miniblocks |
| E4 | DELTA_LENGTH_BYTE_ARRAY | BYTE_ARRAY | round trip + byte diff | lengths as E3, then concatenated bytes |
| E5 | DELTA_BYTE_ARRAY | BYTE_ARRAY | round trip + byte diff | prefix lengths as E3, suffixes as E4 |
| E6 | BYTE_STREAM_SPLIT | FLOAT/DOUBLE | round trip + byte diff + container | one plane per byte position, little-endian |
| E7 | FSST | BYTE_ARRAY | round trip + scoreboard | colenc framing: symbol table, escape 255 |
| Column | Encoding | Ratio to PLAIN |
|---|---|---|
| 1000 monotonic INT64 | DELTA_BINARY_PACKED | 0.3% |
| 1000 varied INT32 | DELTA_BINARY_PACKED | 27.0% |
| 8 distinct INT32 | Dictionary | 10.3% |
| 4 distinct strings | Dictionary | 3.4% |
| length-varied strings | DELTA_LENGTH_BYTE_ARRAY | 67.3% |
| shared-prefix strings | DELTA_BYTE_ARRAY | 9.0% |
| float/double columns | BYTE_STREAM_SPLIT | 100% (size neutral by design) |
| repetitive strings | FSST | 60.4% – 74.5% |
| Neighbour | What it does | The seam |
|---|---|---|
| Parquet container libraries (e.g. mizchi/parquet) | file structure, footer, page organization | they own the container, colenc owns page-level encoding |
| Arrow IPC libraries (e.g. MoonArrow) | inter-process format | IPC is a format, column encoding is intra-page compression |
| Byte-stream compressors (fzstd, flate, zlib, …) | compress bytes | different layer, usable after column encoding |
| Columnar engines (e.g. moonlake) | planning, execution | colenc is their storage substrate; the dependency is one-way |
types/ neutral model: PhysicalType / Encoding / ColBuf / errors
primitives/ L1: varint, zigzag, bit packing, bit width
encoders/ L2: PLAIN, RLE hybrid, dictionary, delta family, BSS, FSST
facade.mbt L3: encode_column / decode_column + dictionary entry points
examples/ runnable demo
harness/ acceptance rig: fixtures, byte diffs, containers, judges
docs/ public roadmap, and the throughput scoreboardfn decode_column(data : BytesView, ty : PhysicalType, encoding : Encoding, count : Int) -> ColBuf raise EncodingErrorfn decode_dictionary(dictionary : BytesView, indices : BytesView, ty : PhysicalType, count : Int, dictionary_size : Int) -> ColBuf raise EncodingErrorfn encode_column(column : ColBuf, encoding : Encoding, out : Buffer) -> EncodingStats raise EncodingErrorfn encode_dictionary(column : ColBuf, max_dictionary_bytes? : Int) -> DictionaryEncoding? raise EncodingErrorInstall
Download zipColumnar encoding kernel for MoonBit: the Parquet page-level encoding family as a reusable, verifiable, pluggable library.
Dependencies