refactor(ldm): move block compressor policy to Rust

Move LDM block-compressor strategy validation, selection ordering, and callback error propagation into Rust while retaining dictionary-mode lookup, MatchState mutation, and the actual codec callback in C. Invalid preflight inputs now use the existing generic error path, and valid strategies preserve the original optimal-parser boundary.

Test Plan: ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check; make -j1; ./tests/rustLibSmoke; make -j1 -C tests test (all shell tests, large streaming tests, native tester, fuzzer phases, and zstream tester passed).
This commit is contained in:
2026-07-20 18:25:45 +02:00
parent 6caba856d4
commit 03d0d4edac
2 changed files with 124 additions and 15 deletions
+45 -13
View File
@@ -262,7 +262,8 @@ size_t ZSTD_rust_ldm_generateSequences(
const void* src, size_t srcSize, int overflowCorrectFrequently);
size_t ZSTD_rust_ldm_blockCompress(
void* rawSeqStore, void* blockContext, void* seqStore, U32 rep[ZSTD_REP_NUM],
const void* src, size_t srcSize, U32 minMatch, int strategy);
const void* src, size_t srcSize, U32 minMatch, int strategy,
int useRowMatchFinder);
U32 ZSTD_rust_ldm_limitTableUpdate(U32 curr, U32 nextToUpdate);
enum {
@@ -280,15 +281,43 @@ size_t ZSTD_ldm_rust_compressLiterals(
const void* src, size_t srcSize);
void ZSTD_ldm_rust_setLdmSeqStore(void* blockContext, const void* rawSeqStore);
typedef size_t (*ZSTD_rust_ldm_select_block_compressor_f)(
void* blockContext, int useRowMatchFinder);
const U64* ZSTD_ldm_rust_gearTable(void)
{
return ZSTD_ldm_gearTab;
}
typedef struct {
ZSTD_MatchState_t* ms;
void* callbackContext;
ZSTD_rust_ldm_select_block_compressor_f selectBlockCompressor;
ZSTD_BlockCompressor_f blockCompressor;
} ZSTD_rust_ldm_block_context;
typedef char ZSTD_rust_ldm_block_context_layout[
(offsetof(ZSTD_rust_ldm_block_context, callbackContext) == 0
&& offsetof(ZSTD_rust_ldm_block_context, selectBlockCompressor)
== sizeof(void*)
&& offsetof(ZSTD_rust_ldm_block_context, blockCompressor)
== 2 * sizeof(void*)
&& sizeof(ZSTD_rust_ldm_block_context) == 3 * sizeof(void*))
? 1 : -1];
/* Rust owns when block-compressor selection happens and how its status is
* handled. This callback retains the dictionary-mode inspection and the
* private MatchState/compressor selection in C. */
static size_t ZSTD_rust_ldm_selectBlockCompressor(
void* blockContext, int useRowMatchFinder)
{
ZSTD_rust_ldm_block_context* const context =
(ZSTD_rust_ldm_block_context*)blockContext;
ZSTD_MatchState_t* const ms = (ZSTD_MatchState_t*)context->callbackContext;
context->blockCompressor = ZSTD_selectBlockCompressor(
ms->cParams.strategy, (ZSTD_ParamSwitch_e)useRowMatchFinder,
ZSTD_matchState_dictMode(ms));
assert(context->blockCompressor != NULL);
return context->blockCompressor == NULL ? ERROR(GENERIC) : 0;
}
static void ZSTD_rust_ldm_fillFastTables(ZSTD_MatchState_t* ms, const BYTE* end)
{
@@ -313,10 +342,10 @@ static void ZSTD_rust_ldm_fillFastTables(ZSTD_MatchState_t* ms, const BYTE* end)
void ZSTD_ldm_rust_prepareBlock(void* blockContext, const void* anchor)
{
ZSTD_rust_ldm_block_context* const context = (ZSTD_rust_ldm_block_context*)blockContext;
U32 const curr = (U32)((const BYTE*)anchor - context->ms->window.base);
context->ms->nextToUpdate = ZSTD_rust_ldm_limitTableUpdate(
curr, context->ms->nextToUpdate);
ZSTD_rust_ldm_fillFastTables(context->ms, (const BYTE*)anchor);
ZSTD_MatchState_t* const ms = (ZSTD_MatchState_t*)context->callbackContext;
U32 const curr = (U32)((const BYTE*)anchor - ms->window.base);
ms->nextToUpdate = ZSTD_rust_ldm_limitTableUpdate(curr, ms->nextToUpdate);
ZSTD_rust_ldm_fillFastTables(ms, (const BYTE*)anchor);
}
size_t ZSTD_ldm_rust_compressLiterals(
@@ -324,13 +353,16 @@ size_t ZSTD_ldm_rust_compressLiterals(
const void* src, size_t srcSize)
{
ZSTD_rust_ldm_block_context* const context = (ZSTD_rust_ldm_block_context*)blockContext;
return context->blockCompressor(context->ms, (SeqStore_t*)seqStore, rep, src, srcSize);
ZSTD_MatchState_t* const ms = (ZSTD_MatchState_t*)context->callbackContext;
assert(context->blockCompressor != NULL);
return context->blockCompressor(ms, (SeqStore_t*)seqStore, rep, src, srcSize);
}
void ZSTD_ldm_rust_setLdmSeqStore(void* blockContext, const void* rawSeqStore)
{
ZSTD_rust_ldm_block_context* const context = (ZSTD_rust_ldm_block_context*)blockContext;
context->ms->ldmSeqStore = (const RawSeqStore_t*)rawSeqStore;
ZSTD_MatchState_t* const ms = (ZSTD_MatchState_t*)context->callbackContext;
ms->ldmSeqStore = (const RawSeqStore_t*)rawSeqStore;
}
size_t ZSTD_ldm_getTableSize(ldmParams_t params)
@@ -372,11 +404,11 @@ size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore,
void const* src, size_t srcSize)
{
ZSTD_rust_ldm_block_context context;
context.ms = ms;
context.blockCompressor = ZSTD_selectBlockCompressor(
ms->cParams.strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms));
assert(context.blockCompressor != NULL);
context.callbackContext = ms;
context.selectBlockCompressor = ZSTD_rust_ldm_selectBlockCompressor;
context.blockCompressor = NULL;
return ZSTD_rust_ldm_blockCompress(
rawSeqStore, &context, seqStore, rep, src, srcSize,
ms->cParams.minMatch, (int)ms->cParams.strategy);
ms->cParams.minMatch, (int)ms->cParams.strategy,
(int)useRowMatchFinder);
}