Skip to content

fix: write and read a chunk whose encoded bytes pass 2 GiB - #631

Merged
dfa1 merged 1 commit into
mainfrom
fix/629-fsst-large-offsets
Nov 1, 2026
Merged

dfa1 merged 1 commit into
mainfrom
fix/629-fsst-large-offsets

Conversation

@dfa1

@dfa1 dfa1 commented Nov 1, 2026

Copy link
Copy Markdown
Owner

Closes #629.

Three int limits stood between a large chunk and the u32 segment length the format allows (up to 4 GiB):

  • FsstEncodingEncoder kept the code offsets in an int[], overflowing once the compressed codes passed 2 GiB. They are a long[] now, as Rust's fsst_compress switches to i64 offsets past i32::MAX.
  • VortexWriter wrote a segment through one ByteBuffer view, which cannot pass 2 GiB. It writes in 1 GiB slices, still zero-copy.
  • SerializedArrayDecoder narrowed the segment length to int; it stays long (bounds still enforced by IoBounds.checkRange).

Test: FsstLargeChunkInteropIntegrationTest writes ~2.46 GB of slightly compressible binary under forced FSST, then vortex-jni and vortex-java read back the rows past 2 GiB; it fails with the original integer overflow without the fix. It needs several GB of memory, too much for CI runners, so it gets a new opt-in large tag, excluded locally and in the ci profile (documented in AGENTS.md and the integration POM).

Real data (Raincloud): peoples-speech-clean-validation (2.3 GB audio column in one 8192-row block) now imports; its 6.35 GB CSV export is byte-identical to the vortex-jni-written file's.

🤖 Generated with Claude Code

@dfa1
dfa1 force-pushed the fix/629-fsst-large-offsets branch from dd10b60 to f2898bd Compare November 1, 2026 18:30
Three int limits stood between a large chunk and the u32 segment length the
format allows (up to 4 GiB):

- FsstEncodingEncoder kept the code offsets in an int[], overflowing once the
  compressed codes passed 2 GiB. They are a long[] now, as Rust's
  fsst_compress switches to i64 offsets past i32::MAX.
- VortexWriter wrote a segment through one ByteBuffer view, which cannot pass
  2 GiB. It writes the segment in 1 GiB slices, still zero-copy.
- SerializedArrayDecoder narrowed the segment length to int; it stays long.

Found by the Raincloud corpus: peoples-speech-clean-validation (2.3 GB audio
column in one 8192-row block) now imports, and its CSV export is
byte-identical to the vortex-jni-written file's.

The cross-check needs ~2.5 GB of input, too big for CI runners, so it gets a
new opt-in `large` tag, excluded like `raincloud`.

Closes #629

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dfa1
dfa1 force-pushed the fix/629-fsst-large-offsets branch from f2898bd to 5b4357c Compare November 1, 2026 18:41
@dfa1
dfa1 merged commit 3b1503d into main Nov 1, 2026
6 checks passed
@dfa1
dfa1 deleted the fix/629-fsst-large-offsets branch November 1, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Writer: FSST integer overflow when a chunk's compressed strings exceed 2 GiB

1 participant