feat(compress): move block compressor dispatch policy to Rust

`ZSTD_selectBlockCompressor` already delegated scalar strategy/index
calculation to the Rust parameter module, but C still owned table selection
and dictionary-mode offsets. Keep the configuration-dependent C function-
pointer tables and NULL entries for excluded compressors as private leaves,
and pass those tables through a narrow ABI state so Rust owns row versus
ordinary selection, dictionary-mode indexing, and selected callback
publication. The legacy C selector signature remains intact for the LDM
caller.

Test Plan:
- `rustfmt --edition 2021 --check rust/src/zstd_compress.rs` -- passed.
- `git diff --check` and `git diff --cached --check` -- passed.
- Heavy cargo/make/test/fuzzer verification not run per the enforced 40 GiB
  serial verification limit.
This commit is contained in:
2026-07-20 02:56:36 +02:00
parent 6c0bcced58
commit 73e0a5e629
2 changed files with 249 additions and 36 deletions
+48 -34
View File
@@ -1793,7 +1793,6 @@ size_t ZSTD_rust_params_getBlockSize(size_t maxBlockSize, U32 windowLog);
int ZSTD_rust_params_resolveExternalSequenceValidation(int mode);
int ZSTD_rust_params_rowMatchFinderSupported(int strategy);
int ZSTD_rust_params_rowMatchFinderUsed(int strategy, int mode);
int ZSTD_rust_params_selectBlockCompressor(int strategy, int mode);
int ZSTD_rust_params_resolveRowMatchFinderMode(
int mode, ZSTD_compressionParameters cParams);
int ZSTD_rust_params_resolveBlockSplitterMode(
@@ -1811,6 +1810,23 @@ int ZSTD_rust_params_getCParamMode(int cdict_present, int cdict_strategy,
int params_attachDictPref,
int params_forceWindow);
typedef struct {
const ZSTD_BlockCompressor_f* blockCompressors;
const ZSTD_BlockCompressor_f* rowBlockCompressors;
ZSTD_BlockCompressor_f* selectedCompressor;
} ZSTD_rust_selectBlockCompressorState;
size_t ZSTD_rust_selectBlockCompressor(
const ZSTD_rust_selectBlockCompressorState* state,
int strategy, int useRowMatchFinder, int dictMode);
typedef char ZSTD_rust_select_block_compressor_state_layout[
(offsetof(ZSTD_rust_selectBlockCompressorState, blockCompressors) == 0
&& offsetof(ZSTD_rust_selectBlockCompressorState, rowBlockCompressors)
== sizeof(void*)
&& offsetof(ZSTD_rust_selectBlockCompressorState, selectedCompressor)
== 2 * sizeof(void*)
&& sizeof(ZSTD_rust_selectBlockCompressorState) == 3 * sizeof(void*))
? 1 : -1];
/* CCtx parameter state is mirrored by rust/src/zstd_compress_params_api.rs.
* Rust owns parameter bounds and clamping; C exposes only the
* build-configuration values required by that narrow ABI. */
@@ -5123,43 +5139,41 @@ ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_Para
NULL,
NULL }
};
ZSTD_BlockCompressor_f selectedCompressor;
int selectedCompressorIndex;
static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = {
{
ZSTD_COMPRESSBLOCK_GREEDY_ROW,
ZSTD_COMPRESSBLOCK_LAZY_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_ROW
},
{
ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW,
ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW
},
{
ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW,
ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW
},
{
ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW,
ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW
}
};
ZSTD_rust_selectBlockCompressorState state;
ZSTD_BlockCompressor_f selectedCompressor = NULL;
size_t selectionResult;
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat));
DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder);
selectedCompressorIndex = ZSTD_rust_params_selectBlockCompressor(
(int)strat, (int)useRowMatchFinder);
if (selectedCompressorIndex < 3) {
static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = {
{
ZSTD_COMPRESSBLOCK_GREEDY_ROW,
ZSTD_COMPRESSBLOCK_LAZY_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_ROW
},
{
ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW,
ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW
},
{
ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW,
ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW
},
{
ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW,
ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW,
ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW
}
};
DEBUGLOG(5, "Selecting a row-based matchfinder");
assert(useRowMatchFinder != ZSTD_ps_auto);
selectedCompressor = rowBasedBlockCompressors[(int)dictMode][selectedCompressorIndex];
} else {
selectedCompressor = blockCompressor[(int)dictMode][selectedCompressorIndex - 3];
}
state.blockCompressors = &blockCompressor[0][0];
state.rowBlockCompressors = &rowBasedBlockCompressors[0][0];
state.selectedCompressor = &selectedCompressor;
selectionResult = ZSTD_rust_selectBlockCompressor(
&state, (int)strat, (int)useRowMatchFinder, (int)dictMode);
assert(!ERR_isError(selectionResult));
assert(selectedCompressor != NULL);
return selectedCompressor;
}