transforms
ptwm_core::transforms::burrows_wheeler
BurrowsWheeler op — block-wise Burrows–Wheeler Transform (BWT).
ptwm_core::transforms::burrows_wheeler
BurrowsWheeler op — block-wise Burrows–Wheeler Transform (BWT).
ptwm_core::transforms::burrows_wheeler
crates/ptwm-core/src/transforms/burrows_wheeler.rs:1mod burrows_wheeler`BurrowsWheeler` op — block-wise Burrows–Wheeler Transform (BWT).
The BWT is a reversible permutation of a byte block that clusters
bytes sharing the same following context into long runs. It carries no
compression on its own; its value is as a *preprocessing* stage: after
the bit-reorder + byte-split chain the exponent plane is mostly long
runs of similar bytes, and BWT — followed by
[`crate::transforms::MoveToFront`] and an entropy coder — extracts the
remaining structure that a block-local Huffman / rANS pass cannot see.
This is the classic bzip2 pipeline.
Encode is `O(n log² n)` (prefix-doubling rotation sort); decode is
`O(n)` (LF-mapping walk). The asymmetry is intentional — this op
targets a release-time high-ratio mode where slow encode is acceptable
but fast decode matters.
## Block structure and wire layout
The input is split into fixed-size blocks of [`BWT_BLOCK_SIZE`] bytes
(the final block may be shorter). Each block is transformed
independently and emitted as:
```text
[ primary_index : u32 little-endian ] [ transformed bytes ]
```
The `primary_index` is the row of the sorted-rotation matrix that holds
the original block — the standard datum the inverse needs. Block
boundaries are recovered on decode without extra metadata: every block
but the last contributes exactly `BWT_BLOCK_SIZE` payload bytes, so a
greedy walk (`4 + min(BWT_BLOCK_SIZE, remaining)` per block) re-derives
them unambiguously. The output is therefore `n + 4·⌈n / BWT_BLOCK_SIZE⌉`
bytes long.
## Element widths
BWT is defined on the raw byte stream. The op requires a `Byte`-width,
non-nibble-packed plane — its production target is the byte-wide
exponent plane — and rejects everything else.
Round-trip is exact for every input: `inverse(forward(x)) == x`.
ptwm_core::transforms::burrows_wheeler::BurrowsWheeler
crates/ptwm-core/src/transforms/burrows_wheeler.rs:59pub struct BurrowsWheeler;Block-wise Burrows–Wheeler Transform.
ptwm_core::transforms::burrows_wheeler::BWT_BLOCK_SIZE
crates/ptwm-core/src/transforms/burrows_wheeler.rs:52pub const BWT_BLOCK_SIZEBWT block size in bytes. Larger blocks compress slightly better but cost `O(block log² block)` to sort; 256 KiB is a balance comparable to bzip2's tunable range while keeping per-block encode time bounded.