Status: draft for the C++-first implementation on colin/alp-codec.
FLOAT and DOUBLE only.ALP must not reuse the TS_2DIFF float-adaptation path. In particular it must not use TS_2DIFF's page precision (maxPointNumber), page overflow bitmap, page_blocks_ buffering, or PageMeta parsing.
ALP has its own block metadata because the algorithm needs it: exponent/factor indices, frame-of-reference base, bit width, and exceptions. This metadata is block-local and is part of the ALP payload. A TsFile page is only a container; the ALP block boundary is a flush boundary.
All integers are little-endian. value_size is 4 for FLOAT and 8 for DOUBLE.
| field | size | description |
|---|---|---|
| version | 1 | format version, currently 1 |
| data_type | 1 | 0 = float, 1 = double |
| reserved | 2 | zero |
| value_count | 4 | total values in the page |
| block_count | 4 | number of ALP blocks |
| reserved | 4 | zero |
| field | size | description |
|---|---|---|
| scheme | 1 | 0 = ALP, 1 = PLAIN fallback |
| factor | 1 | ALP factor index |
| exponent | 1 | ALP exponent index |
| flags | 1 | bit 0 = exceptions present |
| value_count | 4 | values in this block |
| exception_count | 4 | number of exceptions |
| body_bytes | 4 | padded body size in bytes |
| for_base | 8 | signed frame-of-reference base, int32 for float and int64 for double |
| bit_width | 1 | 0..32 for float, 0..64 for double |
| reserved | 3 | zero |
The header is followed by:
scheme == ALP with exceptions: an exception bitmap of ceil(value_count / 8) bytes, followed by exception_count raw value_size values in increasing position order;scheme == ALP: the bit-packed body;scheme == PLAIN: value_count * value_size raw values.The packed body is padded with zero bytes to a multiple of 32 bytes after adding 16 bytes of guard space, so SIMD/word loads may safely read past the logical end of the stream. body_bytes records the padded size.
The body stores adjusted integers using an LSB-first word stream. For float each word is 32 bits; for double each word is 64 bits. Value i occupies bit_width bits starting at bit i * bit_width. A zero bit width means every non-exception value equals for_base.
This layout is deliberately different from TsFile's existing MSB-first pack8 layout. It is defined by the scalar reference implementation, and SIMD kernels must produce and consume the same bytes.
(factor, exponent) combination using the estimated compressed size.-0.0, outside the safe integer range, or when the reference decode does not reproduce the original bit pattern.PLAIN.The encoder's exception check must use the same decode routine as the decoder. This is required for correctness: a value classified as a non-exception must be bit-exactly reproducible by the decoder.
PLAIN, copy raw values.ALP, unpack adjusted integers, add for_base, apply the reference decode, and overwrite exception positions from the exception array.read_batch_float and read_batch_double so the SIMD path can work on whole blocks rather than one value at a time.SIMDe is already a TsFile C++ dependency. The ALP kernels will use the existing ENABLE_SIMD switch and TsFile::SIMDe target.
simde__m256i and simde_mm256_*, matching the existing encoding code style.-mavx2 or /arch:AVX2 on x86. Do not apply AVX2 flags to baseline TsFile translation units.