refactor(compress): move sequence generation policy to Rust
ZSTD_generateSequences() previously mixed public parameter validation, temporary-output allocation, sequence-collector setup, compression, and cleanup inside the C translation unit. Move that ordering into Rust behind callbacks so private ZSTD_CCtx and SeqCollector layouts remain C-owned. The adapter retains C allocation, context access, and the existing ZSTD_compress2 operation, while Rust guarantees temporary-output cleanup after collector setup failures and compression errors and preserves the original target-block-size and worker parameter checks. Focused callback tests cover validation-before-allocation, cleanup on setup failure, and successful callback ordering/count publication. Test Plan: - `cargo fmt --manifest-path rust/Cargo.toml --all -- --check` -- passed - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml generate_sequences --lib` -- passed (3 tests) - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --all-targets` -- passed (762 tests) - `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` -- passed - `ulimit -v 41943040; make -j1` -- passed
This commit is contained in:
@@ -5454,39 +5454,104 @@ static void ZSTD_initBuildSeqStoreState(
|
||||
|
||||
/* ZSTD_sequenceBound() lives in rust/src/zstd_compress_api.rs. */
|
||||
|
||||
typedef size_t (*ZSTD_rust_generateSequencesGetParameter_f)(
|
||||
void* context, int param, int* value);
|
||||
typedef void* (*ZSTD_rust_generateSequencesAllocate_f)(
|
||||
void* context, size_t size);
|
||||
typedef void (*ZSTD_rust_generateSequencesFree_f)(
|
||||
void* context, void* pointer);
|
||||
typedef size_t (*ZSTD_rust_generateSequencesSetCollector_f)(
|
||||
void* context, ZSTD_Sequence* outSeqs, size_t outSeqsSize);
|
||||
typedef size_t (*ZSTD_rust_generateSequencesCompress2_f)(
|
||||
void* context, void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize);
|
||||
typedef size_t (*ZSTD_rust_generateSequencesGetCount_f)(void* context);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
ZSTD_rust_generateSequencesGetParameter_f getParameter;
|
||||
ZSTD_rust_generateSequencesAllocate_f allocate;
|
||||
ZSTD_rust_generateSequencesFree_f free;
|
||||
ZSTD_rust_generateSequencesSetCollector_f setCollector;
|
||||
ZSTD_rust_generateSequencesCompress2_f compress2;
|
||||
ZSTD_rust_generateSequencesGetCount_f getCount;
|
||||
} ZSTD_rust_generateSequencesState;
|
||||
typedef char ZSTD_rust_generate_sequences_state_layout[
|
||||
(offsetof(ZSTD_rust_generateSequencesState, callbackContext) == 0
|
||||
&& offsetof(ZSTD_rust_generateSequencesState, getParameter)
|
||||
== sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_generateSequencesState, allocate)
|
||||
== 2 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_generateSequencesState, free)
|
||||
== 3 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_generateSequencesState, setCollector)
|
||||
== 4 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_generateSequencesState, compress2)
|
||||
== 5 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_generateSequencesState, getCount)
|
||||
== 6 * sizeof(void*)
|
||||
&& sizeof(ZSTD_rust_generateSequencesState) == 7 * sizeof(void*))
|
||||
? 1 : -1];
|
||||
size_t ZSTD_rust_generateSequences(
|
||||
const ZSTD_rust_generateSequencesState* state,
|
||||
ZSTD_Sequence* outSeqs, size_t outSeqsSize,
|
||||
const void* src, size_t srcSize);
|
||||
|
||||
static size_t ZSTD_rust_generateSequences_getParameter(
|
||||
void* context, int param, int* value)
|
||||
{
|
||||
return ZSTD_CCtx_getParameter(
|
||||
(const ZSTD_CCtx*)context, (ZSTD_cParameter)param, value);
|
||||
}
|
||||
|
||||
static void* ZSTD_rust_generateSequences_allocate(void* context, size_t size)
|
||||
{
|
||||
(void)context;
|
||||
return ZSTD_customMalloc(size, ZSTD_defaultCMem);
|
||||
}
|
||||
|
||||
static void ZSTD_rust_generateSequences_free(void* context, void* pointer)
|
||||
{
|
||||
(void)context;
|
||||
ZSTD_customFree(pointer, ZSTD_defaultCMem);
|
||||
}
|
||||
|
||||
static size_t ZSTD_rust_generateSequences_setCollector(
|
||||
void* context, ZSTD_Sequence* outSeqs, size_t outSeqsSize)
|
||||
{
|
||||
ZSTD_CCtx* const zc = (ZSTD_CCtx*)context;
|
||||
zc->seqCollector.collectSequences = 1;
|
||||
zc->seqCollector.seqStart = outSeqs;
|
||||
zc->seqCollector.seqIndex = 0;
|
||||
zc->seqCollector.maxSequences = outSeqsSize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t ZSTD_rust_generateSequences_compress2(
|
||||
void* context, void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize)
|
||||
{
|
||||
return ZSTD_compress2((ZSTD_CCtx*)context, dst, dstCapacity, src, srcSize);
|
||||
}
|
||||
|
||||
static size_t ZSTD_rust_generateSequences_getCount(void* context)
|
||||
{
|
||||
return ((const ZSTD_CCtx*)context)->seqCollector.seqIndex;
|
||||
}
|
||||
|
||||
size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
|
||||
size_t outSeqsSize, const void* src, size_t srcSize)
|
||||
{
|
||||
const size_t dstCapacity = ZSTD_compressBound(srcSize);
|
||||
void* dst; /* Make C90 happy. */
|
||||
SeqCollector seqCollector;
|
||||
{
|
||||
int targetCBlockSize;
|
||||
FORWARD_IF_ERROR(ZSTD_CCtx_getParameter(zc, ZSTD_c_targetCBlockSize, &targetCBlockSize), "");
|
||||
RETURN_ERROR_IF(targetCBlockSize != 0, parameter_unsupported, "targetCBlockSize != 0");
|
||||
}
|
||||
{
|
||||
int nbWorkers;
|
||||
FORWARD_IF_ERROR(ZSTD_CCtx_getParameter(zc, ZSTD_c_nbWorkers, &nbWorkers), "");
|
||||
RETURN_ERROR_IF(nbWorkers != 0, parameter_unsupported, "nbWorkers != 0");
|
||||
}
|
||||
|
||||
dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
|
||||
RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
|
||||
|
||||
seqCollector.collectSequences = 1;
|
||||
seqCollector.seqStart = outSeqs;
|
||||
seqCollector.seqIndex = 0;
|
||||
seqCollector.maxSequences = outSeqsSize;
|
||||
zc->seqCollector = seqCollector;
|
||||
|
||||
{
|
||||
const size_t ret = ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);
|
||||
ZSTD_customFree(dst, ZSTD_defaultCMem);
|
||||
FORWARD_IF_ERROR(ret, "ZSTD_compress2 failed");
|
||||
}
|
||||
assert(zc->seqCollector.seqIndex <= ZSTD_sequenceBound(srcSize));
|
||||
return zc->seqCollector.seqIndex;
|
||||
ZSTD_rust_generateSequencesState const state = {
|
||||
zc,
|
||||
ZSTD_rust_generateSequences_getParameter,
|
||||
ZSTD_rust_generateSequences_allocate,
|
||||
ZSTD_rust_generateSequences_free,
|
||||
ZSTD_rust_generateSequences_setCollector,
|
||||
ZSTD_rust_generateSequences_compress2,
|
||||
ZSTD_rust_generateSequences_getCount
|
||||
};
|
||||
return ZSTD_rust_generateSequences(
|
||||
&state, outSeqs, outSeqsSize, src, srcSize);
|
||||
}
|
||||
|
||||
/* ZSTD_mergeBlockDelimiters() lives in rust/src/zstd_compress_api.rs. */
|
||||
|
||||
Reference in New Issue
Block a user