refactor(compress): move CDict source selection to Rust

ZSTD_compressBegin_internal already routes attach-versus-reload policy through
Rust, but its C insertion callback still inspected a non-null ZSTD_CDict and
selected dictContent, dictContentSize, and dictContentType. That left source
selection coupled to the private CDict layout and kept the Rust bridge from
receiving the same selected source for direct and prepared dictionaries.

Project the three CDict content fields into the repr(C) begin state. Rust now
selects either those fields or the direct dictionary arguments before invoking
the C callback. The callback keeps the private CCtx insertion path and no
longer branches on CDict. ABI offsets and sizes are asserted on both sides,
with focused by-reference and forced-CDict tests covering pointer, size, type,
reset order, and dictionary-result publication.

Test Plan:
- `cargo check --manifest-path rust/Cargo.toml --lib --tests` -- passed under
  `ulimit -v 41943040; CARGO_BUILD_JOBS=1`.
- Serial GCC/Clang syntax-only checks for `lib/compress/zstd_compress.c` --
  passed under the same cap; only existing warnings were reported.
- `cargo clippy` for lib, benches, and tests with `-D warnings`, plus nightly
  format check -- passed serially under the same cap.
- `cargo test --manifest-path rust/Cargo.toml --lib zstd_compress_dictionary
  -- --test-threads=1` -- compiled but standalone linking failed on the three
  pre-existing C bridge symbols `ZSTD_rust_dctx_trace_view`,
  `ZSTD_rust_dctx_view`, and `ZSTD_rust_block_context_init`.
- Full native, upstream, and fuzzer tests were not run per scope.
This commit is contained in:
2026-07-21 10:13:54 +02:00
parent 639865d138
commit af91fb23ab
2 changed files with 147 additions and 57 deletions
+33 -27
View File
@@ -3077,12 +3077,15 @@ typedef size_t (*ZSTD_rust_compressBeginResetUsingCDict_f)(
void* context, const void* cdict, const void* params,
U64 pledgedSrcSize, int zbuff);
typedef size_t (*ZSTD_rust_compressBeginInsertDictionary_f)(
void* context, const void* cdict, const void* dict,
size_t dictSize, int dictContentType, int dtlm);
void* context, const void* dict, size_t dictSize,
int dictContentType, int dtlm);
typedef struct {
void* callbackContext;
const void* params;
const void* cdict;
const void* cdictDictContent;
size_t cdictDictContentSize;
int cdictDictContentType;
const size_t* cdictContentSize;
const int* cdictCompressionLevel;
const ZSTD_dictAttachPref_e* attachDictPref;
@@ -3104,37 +3107,43 @@ typedef char ZSTD_rust_compress_begin_state_layout[
(offsetof(ZSTD_rust_compressBeginState, callbackContext) == 0
&& offsetof(ZSTD_rust_compressBeginState, params) == sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, cdict) == 2 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, cdictContentSize)
&& offsetof(ZSTD_rust_compressBeginState, cdictDictContent)
== 3 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, cdictCompressionLevel)
&& offsetof(ZSTD_rust_compressBeginState, cdictDictContentSize)
== 4 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, attachDictPref)
== 5 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, dict)
&& offsetof(ZSTD_rust_compressBeginState, cdictDictContentType)
== 4 * sizeof(void*) + sizeof(size_t)
&& offsetof(ZSTD_rust_compressBeginState, cdictContentSize)
== 6 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, dictSize)
&& offsetof(ZSTD_rust_compressBeginState, cdictCompressionLevel)
== 7 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, dictContentType)
&& offsetof(ZSTD_rust_compressBeginState, attachDictPref)
== 8 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, dtlm)
&& offsetof(ZSTD_rust_compressBeginState, dict)
== 9 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, pledgedSrcSize)
&& offsetof(ZSTD_rust_compressBeginState, dictSize)
== 10 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, zbuff)
&& offsetof(ZSTD_rust_compressBeginState, dictContentType)
== 11 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, forceLoad)
&& offsetof(ZSTD_rust_compressBeginState, dtlm)
== 12 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, dictID)
&& offsetof(ZSTD_rust_compressBeginState, pledgedSrcSize)
== 13 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, dictContentSize)
&& offsetof(ZSTD_rust_compressBeginState, zbuff)
== 14 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, resetInternal)
&& offsetof(ZSTD_rust_compressBeginState, forceLoad)
== 15 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, resetUsingCDict)
&& offsetof(ZSTD_rust_compressBeginState, dictID)
== 16 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, insertDictionary)
&& offsetof(ZSTD_rust_compressBeginState, dictContentSize)
== 17 * sizeof(void*)
&& sizeof(ZSTD_rust_compressBeginState) == 18 * sizeof(void*))
&& offsetof(ZSTD_rust_compressBeginState, resetInternal)
== 18 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, resetUsingCDict)
== 19 * sizeof(void*)
&& offsetof(ZSTD_rust_compressBeginState, insertDictionary)
== 20 * sizeof(void*)
&& sizeof(ZSTD_rust_compressBeginState) == 21 * sizeof(void*))
? 1 : -1];
typedef size_t (*ZSTD_rust_resetCCtxUsingCDictAttach_f)(
@@ -6743,16 +6752,10 @@ static size_t ZSTD_rust_compressBegin_resetUsingCDict(
}
static size_t ZSTD_rust_compressBegin_insertDictionary(
void* context, const void* cdict, const void* dict,
size_t dictSize, int dictContentType, int dtlm)
void* context, const void* dict, size_t dictSize,
int dictContentType, int dtlm)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
if (cdict != NULL) {
ZSTD_CDict const* const dictionary = (const ZSTD_CDict*)cdict;
dict = dictionary->dictContent;
dictSize = dictionary->dictContentSize;
dictContentType = (int)dictionary->dictContentType;
}
return ZSTD_compress_insertDictionary(
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
&cctx->ldmState, &cctx->workspace, &cctx->appliedParams,
@@ -6790,6 +6793,9 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
state.callbackContext = cctx;
state.params = params;
state.cdict = cdict;
state.cdictDictContent = cdict == NULL ? NULL : cdict->dictContent;
state.cdictDictContentSize = cdict == NULL ? 0 : cdict->dictContentSize;
state.cdictDictContentType = cdict == NULL ? 0 : (int)cdict->dictContentType;
state.cdictContentSize = cdict == NULL ? NULL : &cdict->dictContentSize;
state.cdictCompressionLevel = cdict == NULL ? NULL : &cdict->compressionLevel;
state.attachDictPref = &params->attachDictPref;