feat(compress): move sequence checksums into Rust

Project the sequence API's XXH64 state directly through the Rust ABI boundary
so Rust owns checksum updates, digest ordering, and little-endian frame
checksum serialization.  Keep the C callback limited to private CCtx and
sequence-state initialization, remove the three checksum callback shims, and
update the cross-language layout assertions for the smaller state.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo fmt --all -- --check
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --lib zstd_compress::tests::sequence_api -- --nocapture
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --all-targets -- -D warnings
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test
- ulimit -v 41943040; make -j1
- ulimit -v 41943040; make -j1 -C tests test-zstream ZSTREAM_TESTTIME=-T2s
- ulimit -v 41943040; make -j1 -C tests test-fuzzer FUZZERTEST=-T3s FUZZER_FLAGS=--no-big-tests
This commit is contained in:
2026-07-20 00:23:13 +02:00
parent 4a8345f596
commit cce9254703
2 changed files with 41 additions and 82 deletions
+15 -49
View File
@@ -2742,28 +2742,21 @@ typedef char ZSTD_rust_sequence_literals_state_layout[
== 6 * sizeof(void*) + 4 * sizeof(int) + 3 * sizeof(void*))
? 1 : -1];
/* The public sequence APIs keep their CCtx initialization and checksum state
* in C, while Rust owns frame-header serialization, ordering, and output
* accounting. The two block-loop projections above are populated by the
/* The public sequence APIs keep their CCtx initialization in C, while Rust
* owns frame-header/checksum serialization, ordering, and output accounting.
* The checksum state and two block-loop projections are populated by the
* initialization callback after the private CCtx has been initialized. */
typedef struct ZSTD_rust_sequenceApiState_s ZSTD_rust_sequenceApiState;
typedef size_t (*ZSTD_rust_sequenceApiInit_f)(
void* context, size_t pledgedSrcSize,
ZSTD_rust_sequenceApiState* state);
typedef void (*ZSTD_rust_sequenceApiUpdateChecksum_f)(
void* context, const void* src, size_t srcSize);
typedef U32 (*ZSTD_rust_sequenceApiDigestChecksum_f)(void* context);
typedef void (*ZSTD_rust_sequenceApiWriteChecksum_f)(
void* context, void* dst, U32 checksum);
struct ZSTD_rust_sequenceApiState_s {
void* callbackContext;
ZSTD_rust_sequenceCompressionState* sequenceState;
ZSTD_rust_sequenceLiteralsState* sequenceLiteralsState;
ZSTD_rust_sequenceApiInit_f init;
ZSTD_rust_sequenceApiUpdateChecksum_f updateChecksum;
ZSTD_rust_sequenceApiDigestChecksum_f digestChecksum;
ZSTD_rust_sequenceApiWriteChecksum_f writeChecksum;
XXH64_state_t* checksumState;
int checksumFlag;
int blockDelimiters;
int validateSequences;
@@ -2792,30 +2785,26 @@ typedef char ZSTD_rust_sequence_api_state_layout[
== 2 * sizeof(void*)
&& offsetof(ZSTD_rust_sequenceApiState, init)
== 3 * sizeof(void*)
&& offsetof(ZSTD_rust_sequenceApiState, updateChecksum)
&& offsetof(ZSTD_rust_sequenceApiState, checksumState)
== 4 * sizeof(void*)
&& offsetof(ZSTD_rust_sequenceApiState, digestChecksum)
== 5 * sizeof(void*)
&& offsetof(ZSTD_rust_sequenceApiState, writeChecksum)
== 6 * sizeof(void*)
&& offsetof(ZSTD_rust_sequenceApiState, checksumFlag)
== 7 * sizeof(void*)
== 5 * sizeof(void*)
&& offsetof(ZSTD_rust_sequenceApiState, blockDelimiters)
== 7 * sizeof(void*) + sizeof(int)
== 5 * sizeof(void*) + sizeof(int)
&& offsetof(ZSTD_rust_sequenceApiState, validateSequences)
== 7 * sizeof(void*) + 2 * sizeof(int)
== 5 * sizeof(void*) + 2 * sizeof(int)
&& offsetof(ZSTD_rust_sequenceApiState, noDictIDFlag)
== 7 * sizeof(void*) + 3 * sizeof(int)
== 5 * sizeof(void*) + 3 * sizeof(int)
&& offsetof(ZSTD_rust_sequenceApiState, contentSizeFlag)
== 7 * sizeof(void*) + 4 * sizeof(int)
== 5 * sizeof(void*) + 4 * sizeof(int)
&& offsetof(ZSTD_rust_sequenceApiState, format)
== 7 * sizeof(void*) + 5 * sizeof(int)
== 5 * sizeof(void*) + 5 * sizeof(int)
&& offsetof(ZSTD_rust_sequenceApiState, windowLog)
== 7 * sizeof(void*) + 6 * sizeof(int)
== 5 * sizeof(void*) + 6 * sizeof(int)
&& offsetof(ZSTD_rust_sequenceApiState, dictID)
== 7 * sizeof(void*) + 6 * sizeof(int) + sizeof(U32)
== 5 * sizeof(void*) + 6 * sizeof(int) + sizeof(U32)
&& sizeof(ZSTD_rust_sequenceApiState)
== (sizeof(void*) == 8 ? 88 : 60))
== (sizeof(void*) == 8 ? 72 : 52))
? 1 : -1];
typedef char ZSTD_rust_stats_seqdef_layout[(sizeof(SeqDef) == 8) ? 1 : -1];
@@ -8037,27 +8026,6 @@ static size_t ZSTD_rust_sequenceApi_init(
return 0;
}
static void ZSTD_rust_sequenceApi_updateChecksum(
void* context, const void* src, size_t srcSize)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
(void)XXH64_update(&cctx->xxhState, src, srcSize);
}
static U32 ZSTD_rust_sequenceApi_digestChecksum(void* context)
{
ZSTD_CCtx const* const cctx = (ZSTD_CCtx const*)context;
return (U32)XXH64_digest(&cctx->xxhState);
}
static void ZSTD_rust_sequenceApi_writeChecksum(
void* context, void* dst, U32 checksum)
{
(void)context;
DEBUGLOG(4, "Write checksum : %08X", (unsigned)checksum);
MEM_writeLE32((char*)dst, checksum);
}
static void ZSTD_rust_sequenceApi_initState(
ZSTD_rust_sequenceApiState* state,
ZSTD_CCtx* cctx,
@@ -8068,9 +8036,7 @@ static void ZSTD_rust_sequenceApi_initState(
state->sequenceState = sequenceState;
state->sequenceLiteralsState = sequenceLiteralsState;
state->init = ZSTD_rust_sequenceApi_init;
state->updateChecksum = ZSTD_rust_sequenceApi_updateChecksum;
state->digestChecksum = ZSTD_rust_sequenceApi_digestChecksum;
state->writeChecksum = ZSTD_rust_sequenceApi_writeChecksum;
state->checksumState = &cctx->xxhState;
state->checksumFlag = 0;
state->blockDelimiters = 0;
state->validateSequences = 0;