feat(compress): move CCtx reset storage policy into Rust
Move the post-match-state CCtx storage reservation and publication policy into Rust while keeping the private C workspace and context layouts behind narrow callbacks. The Rust leaf now preserves the sequence, LDM, external-sequence, literal, buffered-input/output, bucket, and entropy-code allocation order, including zeroing and reset callbacks. C remains responsible for workspace resize/layout, private field publication, allocator callbacks, and the LDM window reset details. ABI layout assertions and fake-callback tests cover ordinary, LDM/external-producer, and allocation-failure paths. Test Plan: - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo fmt --manifest-path rust/Cargo.toml - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml cctx_storage --lib (3 passed) - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --lib (683 passed) - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040 && make -B -C programs -j1 zstd (passed; existing fileio const-cast warnings) - ulimit -v 41943040 && make -C tests -j1 test-zstream ZSTREAM_TESTTIME=-T1s (84 tests and both short fuzz rounds passed; existing zstreamtest warning)
This commit is contained in:
+293
-55
@@ -1274,6 +1274,121 @@ typedef char ZSTD_rust_cctx_reset_plan_layout[
|
|||||||
&& offsetof(ZSTD_rustCCtxResetPlan, needsIndexReset) == 8 * sizeof(size_t)
|
&& offsetof(ZSTD_rustCCtxResetPlan, needsIndexReset) == 8 * sizeof(size_t)
|
||||||
&& sizeof(ZSTD_rustCCtxResetPlan) == 9 * sizeof(size_t))
|
&& sizeof(ZSTD_rustCCtxResetPlan) == 9 * sizeof(size_t))
|
||||||
? 1 : -1];
|
? 1 : -1];
|
||||||
|
typedef void (*ZSTD_rust_resetCCtxStorageSetPointer_f)(
|
||||||
|
void* context, int pointerKind, void* pointer);
|
||||||
|
typedef void (*ZSTD_rust_resetCCtxStorageSetSize_f)(
|
||||||
|
void* context, int sizeKind, size_t value);
|
||||||
|
typedef void (*ZSTD_rust_resetCCtxStorageSetInt_f)(
|
||||||
|
void* context, int intKind, int value);
|
||||||
|
typedef void* (*ZSTD_rust_resetCCtxStorageReserve_f)(
|
||||||
|
void* context, int reserveKind, size_t size);
|
||||||
|
typedef int (*ZSTD_rust_resetCCtxStorageReserveFailed_f)(void* context);
|
||||||
|
typedef void (*ZSTD_rust_resetCCtxStorageZero_f)(
|
||||||
|
void* context, void* pointer, size_t size);
|
||||||
|
typedef void (*ZSTD_rust_resetCCtxStorageCallback_f)(void* context);
|
||||||
|
typedef struct {
|
||||||
|
void* callbackContext;
|
||||||
|
int ldmEnable;
|
||||||
|
int hasExtSeqProd;
|
||||||
|
U32 hashLog;
|
||||||
|
U32 bucketSizeLog;
|
||||||
|
size_t blockSize;
|
||||||
|
size_t maxNbSeq;
|
||||||
|
size_t maxNbLdmSeq;
|
||||||
|
size_t maxNbExternalSeq;
|
||||||
|
size_t buffInSize;
|
||||||
|
size_t buffOutSize;
|
||||||
|
size_t seqDefSize;
|
||||||
|
size_t ldmEntrySize;
|
||||||
|
size_t rawSeqSize;
|
||||||
|
size_t externalSequenceSize;
|
||||||
|
size_t byteSize;
|
||||||
|
size_t wildcopyOverlength;
|
||||||
|
int bufferedPolicy;
|
||||||
|
ZSTD_rust_resetCCtxStorageSetPointer_f setPointer;
|
||||||
|
ZSTD_rust_resetCCtxStorageSetSize_f setSize;
|
||||||
|
ZSTD_rust_resetCCtxStorageSetInt_f setInt;
|
||||||
|
ZSTD_rust_resetCCtxStorageReserve_f reserve;
|
||||||
|
ZSTD_rust_resetCCtxStorageReserveFailed_f reserveFailed;
|
||||||
|
ZSTD_rust_resetCCtxStorageZero_f zero;
|
||||||
|
ZSTD_rust_resetCCtxStorageCallback_f windowInit;
|
||||||
|
ZSTD_rust_resetCCtxStorageCallback_f resetExternalSequences;
|
||||||
|
} ZSTD_rust_resetCCtxStorageState;
|
||||||
|
typedef char ZSTD_rust_reset_cctx_storage_state_layout[
|
||||||
|
(offsetof(ZSTD_rust_resetCCtxStorageState, callbackContext) == 0
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, ldmEnable) == sizeof(void*)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, hasExtSeqProd)
|
||||||
|
== sizeof(void*) + sizeof(int)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, hashLog)
|
||||||
|
> offsetof(ZSTD_rust_resetCCtxStorageState, hasExtSeqProd)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, bucketSizeLog)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, hashLog) + sizeof(U32)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, blockSize)
|
||||||
|
> offsetof(ZSTD_rust_resetCCtxStorageState, bucketSizeLog)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, maxNbSeq)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, blockSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, maxNbLdmSeq)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, maxNbSeq) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, maxNbExternalSeq)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, maxNbLdmSeq) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, buffInSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, maxNbExternalSeq) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, buffOutSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, buffInSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, seqDefSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, buffOutSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, ldmEntrySize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, seqDefSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, rawSeqSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, ldmEntrySize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, externalSequenceSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, rawSeqSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, byteSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, externalSequenceSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, wildcopyOverlength)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, byteSize) + sizeof(size_t)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, bufferedPolicy)
|
||||||
|
> offsetof(ZSTD_rust_resetCCtxStorageState, wildcopyOverlength)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, setSize)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, setPointer) + sizeof(void*)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, setInt)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, setSize) + sizeof(void*)
|
||||||
|
&& offsetof(ZSTD_rust_resetCCtxStorageState, reserve)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, setInt) + sizeof(void*)
|
||||||
|
&& sizeof(ZSTD_rust_resetCCtxStorageState)
|
||||||
|
== offsetof(ZSTD_rust_resetCCtxStorageState, resetExternalSequences)
|
||||||
|
+ sizeof(void*))
|
||||||
|
? 1 : -1];
|
||||||
|
enum {
|
||||||
|
ZSTD_RUST_RESET_CCTX_RESERVE_ALIGNED64 = 0,
|
||||||
|
ZSTD_RUST_RESET_CCTX_RESERVE_BUFFER = 1
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_SEQ_START = 0,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_LDM_HASH = 1,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_LDM_SEQUENCES = 2,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_EXTERNAL_SEQUENCES = 3,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_LITERALS = 4,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_INPUT_BUFFER = 5,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_OUTPUT_BUFFER = 6,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_LL_CODE = 7,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_ML_CODE = 8,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_OF_CODE = 9,
|
||||||
|
ZSTD_RUST_RESET_CCTX_POINTER_LDM_BUCKETS = 10
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
ZSTD_RUST_RESET_CCTX_SIZE_MAX_NB_SEQ = 0,
|
||||||
|
ZSTD_RUST_RESET_CCTX_SIZE_MAX_NB_LIT = 1,
|
||||||
|
ZSTD_RUST_RESET_CCTX_SIZE_MAX_NB_LDM_SEQ = 2,
|
||||||
|
ZSTD_RUST_RESET_CCTX_SIZE_EXTERNAL_SEQ_CAPACITY = 3,
|
||||||
|
ZSTD_RUST_RESET_CCTX_SIZE_INPUT_BUFFER = 4,
|
||||||
|
ZSTD_RUST_RESET_CCTX_SIZE_OUTPUT_BUFFER = 5
|
||||||
|
};
|
||||||
|
enum {
|
||||||
|
ZSTD_RUST_RESET_CCTX_INT_BUFFERED_POLICY = 0,
|
||||||
|
ZSTD_RUST_RESET_CCTX_INT_INITIALIZED = 1
|
||||||
|
};
|
||||||
|
size_t ZSTD_rust_resetCCtxStorage(const ZSTD_rust_resetCCtxStorageState* state);
|
||||||
size_t ZSTD_rust_estimateCCtxWorkspaceSize(
|
size_t ZSTD_rust_estimateCCtxWorkspaceSize(
|
||||||
ZSTD_compressionParameters cParams,
|
ZSTD_compressionParameters cParams,
|
||||||
int ldmEnable, U32 ldmHashLog, U32 ldmBucketSizeLog,
|
int ldmEnable, U32 ldmHashLog, U32 ldmBucketSizeLog,
|
||||||
@@ -3650,6 +3765,152 @@ static int ZSTD_dictTooBig(size_t const loadedDictSize)
|
|||||||
return ZSTD_rust_dictTooBig(loadedDictSize);
|
return ZSTD_rust_dictTooBig(loadedDictSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ZSTD_CCtx* cctx;
|
||||||
|
ZSTD_cwksp* ws;
|
||||||
|
} ZSTD_rust_resetCCtxStorageContext;
|
||||||
|
|
||||||
|
static void ZSTD_rust_resetCCtxStorage_setPointer(
|
||||||
|
void* opaque, int pointerKind, void* pointer)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
ZSTD_CCtx* const cctx = context->cctx;
|
||||||
|
switch (pointerKind) {
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_SEQ_START:
|
||||||
|
cctx->seqStore.sequencesStart = (SeqDef*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_LDM_HASH:
|
||||||
|
cctx->ldmState.hashTable = (ldmEntry_t*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_LDM_SEQUENCES:
|
||||||
|
cctx->ldmSequences = (rawSeq*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_EXTERNAL_SEQUENCES:
|
||||||
|
cctx->extSeqBuf = (ZSTD_Sequence*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_LITERALS:
|
||||||
|
cctx->seqStore.litStart = (BYTE*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_INPUT_BUFFER:
|
||||||
|
cctx->inBuff = (char*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_OUTPUT_BUFFER:
|
||||||
|
cctx->outBuff = (char*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_LL_CODE:
|
||||||
|
cctx->seqStore.llCode = (BYTE*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_ML_CODE:
|
||||||
|
cctx->seqStore.mlCode = (BYTE*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_OF_CODE:
|
||||||
|
cctx->seqStore.ofCode = (BYTE*)pointer;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_POINTER_LDM_BUCKETS:
|
||||||
|
cctx->ldmState.bucketOffsets = (BYTE*)pointer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZSTD_rust_resetCCtxStorage_setSize(
|
||||||
|
void* opaque, int sizeKind, size_t value)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
ZSTD_CCtx* const cctx = context->cctx;
|
||||||
|
switch (sizeKind) {
|
||||||
|
case ZSTD_RUST_RESET_CCTX_SIZE_MAX_NB_SEQ:
|
||||||
|
cctx->seqStore.maxNbSeq = value;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_SIZE_MAX_NB_LIT:
|
||||||
|
cctx->seqStore.maxNbLit = value;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_SIZE_MAX_NB_LDM_SEQ:
|
||||||
|
cctx->maxNbLdmSequences = value;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_SIZE_EXTERNAL_SEQ_CAPACITY:
|
||||||
|
cctx->extSeqBufCapacity = value;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_SIZE_INPUT_BUFFER:
|
||||||
|
cctx->inBuffSize = value;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_SIZE_OUTPUT_BUFFER:
|
||||||
|
cctx->outBuffSize = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZSTD_rust_resetCCtxStorage_setInt(
|
||||||
|
void* opaque, int intKind, int value)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
ZSTD_CCtx* const cctx = context->cctx;
|
||||||
|
switch (intKind) {
|
||||||
|
case ZSTD_RUST_RESET_CCTX_INT_BUFFERED_POLICY:
|
||||||
|
cctx->bufferedPolicy = (ZSTD_buffered_policy_e)value;
|
||||||
|
break;
|
||||||
|
case ZSTD_RUST_RESET_CCTX_INT_INITIALIZED:
|
||||||
|
cctx->initialized = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* ZSTD_rust_resetCCtxStorage_reserve(
|
||||||
|
void* opaque, int reserveKind, size_t size)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
switch (reserveKind) {
|
||||||
|
case ZSTD_RUST_RESET_CCTX_RESERVE_ALIGNED64:
|
||||||
|
return ZSTD_cwksp_reserve_aligned64(context->ws, size);
|
||||||
|
case ZSTD_RUST_RESET_CCTX_RESERVE_BUFFER:
|
||||||
|
return ZSTD_cwksp_reserve_buffer(context->ws, size);
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ZSTD_rust_resetCCtxStorage_reserveFailed(void* opaque)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
return ZSTD_cwksp_reserve_failed(context->ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZSTD_rust_resetCCtxStorage_zero(
|
||||||
|
void* opaque, void* pointer, size_t size)
|
||||||
|
{
|
||||||
|
(void)opaque;
|
||||||
|
ZSTD_memset(pointer, 0, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZSTD_rust_resetCCtxStorage_windowInit(void* opaque)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
ZSTD_window_init(&context->cctx->ldmState.window);
|
||||||
|
context->cctx->ldmState.loadedDictEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ZSTD_rust_resetCCtxStorage_resetExternalSequences(void* opaque)
|
||||||
|
{
|
||||||
|
ZSTD_rust_resetCCtxStorageContext* const context =
|
||||||
|
(ZSTD_rust_resetCCtxStorageContext*)opaque;
|
||||||
|
ZSTD_referenceExternalSequences(context->cctx, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*! ZSTD_resetCCtx_internal() :
|
/*! ZSTD_resetCCtx_internal() :
|
||||||
* @param loadedDictSize The size of the dictionary to be loaded
|
* @param loadedDictSize The size of the dictionary to be loaded
|
||||||
* into the context, if any. If no dictionary is used, or the
|
* into the context, if any. If no dictionary is used, or the
|
||||||
@@ -3708,6 +3969,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
size_t maxNbLdmSeq;
|
size_t maxNbLdmSeq;
|
||||||
size_t neededSpace;
|
size_t neededSpace;
|
||||||
ZSTD_indexResetPolicy_e needsIndexReset;
|
ZSTD_indexResetPolicy_e needsIndexReset;
|
||||||
|
ZSTD_rust_resetCCtxStorageContext storageContext;
|
||||||
|
ZSTD_rust_resetCCtxStorageState storageState;
|
||||||
resetState.cParams = params->cParams;
|
resetState.cParams = params->cParams;
|
||||||
resetState.ldmEnable = (int)params->ldmParams.enableLdm;
|
resetState.ldmEnable = (int)params->ldmParams.enableLdm;
|
||||||
resetState.ldmHashLog = params->ldmParams.hashLog;
|
resetState.ldmHashLog = params->ldmParams.hashLog;
|
||||||
@@ -3737,6 +4000,35 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
maxNbLdmSeq = resetPlan.maxNbLdmSeq;
|
maxNbLdmSeq = resetPlan.maxNbLdmSeq;
|
||||||
neededSpace = resetPlan.neededSpace;
|
neededSpace = resetPlan.neededSpace;
|
||||||
needsIndexReset = (ZSTD_indexResetPolicy_e)resetPlan.needsIndexReset;
|
needsIndexReset = (ZSTD_indexResetPolicy_e)resetPlan.needsIndexReset;
|
||||||
|
storageContext.cctx = zc;
|
||||||
|
storageContext.ws = ws;
|
||||||
|
storageState.callbackContext = &storageContext;
|
||||||
|
storageState.ldmEnable = (int)params->ldmParams.enableLdm;
|
||||||
|
storageState.hasExtSeqProd = ZSTD_hasExtSeqProd(params);
|
||||||
|
storageState.hashLog = params->ldmParams.hashLog;
|
||||||
|
storageState.bucketSizeLog = params->ldmParams.bucketSizeLog;
|
||||||
|
storageState.blockSize = blockSize;
|
||||||
|
storageState.maxNbSeq = maxNbSeq;
|
||||||
|
storageState.maxNbLdmSeq = maxNbLdmSeq;
|
||||||
|
storageState.maxNbExternalSeq = resetPlan.maxNbExternalSeq;
|
||||||
|
storageState.buffInSize = buffInSize;
|
||||||
|
storageState.buffOutSize = buffOutSize;
|
||||||
|
storageState.seqDefSize = sizeof(SeqDef);
|
||||||
|
storageState.ldmEntrySize = sizeof(ldmEntry_t);
|
||||||
|
storageState.rawSeqSize = sizeof(rawSeq);
|
||||||
|
storageState.externalSequenceSize = sizeof(ZSTD_Sequence);
|
||||||
|
storageState.byteSize = sizeof(BYTE);
|
||||||
|
storageState.wildcopyOverlength = WILDCOPY_OVERLENGTH;
|
||||||
|
storageState.bufferedPolicy = (int)zbuff;
|
||||||
|
storageState.setPointer = ZSTD_rust_resetCCtxStorage_setPointer;
|
||||||
|
storageState.setSize = ZSTD_rust_resetCCtxStorage_setSize;
|
||||||
|
storageState.setInt = ZSTD_rust_resetCCtxStorage_setInt;
|
||||||
|
storageState.reserve = ZSTD_rust_resetCCtxStorage_reserve;
|
||||||
|
storageState.reserveFailed = ZSTD_rust_resetCCtxStorage_reserveFailed;
|
||||||
|
storageState.zero = ZSTD_rust_resetCCtxStorage_zero;
|
||||||
|
storageState.windowInit = ZSTD_rust_resetCCtxStorage_windowInit;
|
||||||
|
storageState.resetExternalSequences =
|
||||||
|
ZSTD_rust_resetCCtxStorage_resetExternalSequences;
|
||||||
|
|
||||||
if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
|
if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0);
|
||||||
|
|
||||||
@@ -3803,65 +4095,11 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
needsIndexReset,
|
needsIndexReset,
|
||||||
ZSTD_resetTarget_CCtx), "");
|
ZSTD_resetTarget_CCtx), "");
|
||||||
|
|
||||||
zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef));
|
FORWARD_IF_ERROR(ZSTD_rust_resetCCtxStorage(&storageState), "");
|
||||||
|
|
||||||
/* ldm hash table */
|
|
||||||
if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
|
|
||||||
/* TODO: avoid memset? */
|
|
||||||
size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog;
|
|
||||||
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t));
|
|
||||||
ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
|
|
||||||
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq));
|
|
||||||
zc->maxNbLdmSequences = maxNbLdmSeq;
|
|
||||||
|
|
||||||
ZSTD_window_init(&zc->ldmState.window);
|
|
||||||
zc->ldmState.loadedDictEnd = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reserve space for block-level external sequences */
|
|
||||||
if (ZSTD_hasExtSeqProd(params)) {
|
|
||||||
size_t const maxNbExternalSeq = resetPlan.maxNbExternalSeq;
|
|
||||||
zc->extSeqBufCapacity = maxNbExternalSeq;
|
|
||||||
zc->extSeqBuf =
|
|
||||||
(ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* buffers */
|
|
||||||
|
|
||||||
/* ZSTD_wildcopy() is used to copy into the literals buffer,
|
|
||||||
* so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
|
|
||||||
*/
|
|
||||||
zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH);
|
|
||||||
zc->seqStore.maxNbLit = blockSize;
|
|
||||||
|
|
||||||
zc->bufferedPolicy = zbuff;
|
|
||||||
zc->inBuffSize = buffInSize;
|
|
||||||
zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);
|
|
||||||
zc->outBuffSize = buffOutSize;
|
|
||||||
zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);
|
|
||||||
|
|
||||||
/* ldm bucketOffsets table */
|
|
||||||
if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
|
|
||||||
/* TODO: avoid memset? */
|
|
||||||
size_t const numBuckets =
|
|
||||||
((size_t)1) << (params->ldmParams.hashLog -
|
|
||||||
params->ldmParams.bucketSizeLog);
|
|
||||||
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets);
|
|
||||||
ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sequences storage */
|
|
||||||
ZSTD_referenceExternalSequences(zc, NULL, 0);
|
|
||||||
zc->seqStore.maxNbSeq = maxNbSeq;
|
|
||||||
zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
|
||||||
zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
|
||||||
zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
|
||||||
|
|
||||||
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
|
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
|
||||||
assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace));
|
assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace));
|
||||||
|
|
||||||
zc->initialized = 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -166,8 +166,9 @@ CDict advanced private workspace construction, private static-CCtx and
|
|||||||
static-CDict workspace construction and dictionary-content allocation/loading,
|
static-CDict workspace construction and dictionary-content allocation/loading,
|
||||||
and advanced-CDict dictionary-content loading remain in C. Rust now owns
|
and advanced-CDict dictionary-content loading remain in C. Rust now owns
|
||||||
advanced-CDict custom-memory validation, workspace-size query/allocation,
|
advanced-CDict custom-memory validation, workspace-size query/allocation,
|
||||||
allocation/create/init cleanup ordering, the CCtx workspace-size formula, and
|
allocation/create/init cleanup ordering, the CCtx workspace-size formula, the
|
||||||
the scalar CCtx-reset plan and match-state reset policy/order; C retains
|
scalar CCtx-reset plan, post-match-state storage reservation order, and
|
||||||
|
match-state reset policy/order; C retains
|
||||||
private layout-size inputs, workspace resize/layout, private field publication,
|
private layout-size inputs, workspace resize/layout, private field publication,
|
||||||
and allocator callbacks. Private CCtx reset/matchfinder/workspace operations
|
and allocator callbacks. Private CCtx reset/matchfinder/workspace operations
|
||||||
and codec/adaptive-policy
|
and codec/adaptive-policy
|
||||||
|
|||||||
@@ -6020,6 +6020,363 @@ pub unsafe extern "C" fn ZSTD_rust_planCCtxReset(state: *const ZSTD_rustCCtxRese
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResetCCtxStorageSetPointer = unsafe extern "C" fn(*mut c_void, c_int, *mut c_void);
|
||||||
|
type ResetCCtxStorageSetSize = unsafe extern "C" fn(*mut c_void, c_int, usize);
|
||||||
|
type ResetCCtxStorageSetInt = unsafe extern "C" fn(*mut c_void, c_int, c_int);
|
||||||
|
type ResetCCtxStorageReserve = unsafe extern "C" fn(*mut c_void, c_int, usize) -> *mut c_void;
|
||||||
|
type ResetCCtxStorageReserveFailed = unsafe extern "C" fn(*mut c_void) -> c_int;
|
||||||
|
type ResetCCtxStorageZero = unsafe extern "C" fn(*mut c_void, *mut c_void, usize);
|
||||||
|
type ResetCCtxStorageCallback = unsafe extern "C" fn(*mut c_void);
|
||||||
|
|
||||||
|
const RESET_CCTX_RESERVE_ALIGNED64: c_int = 0;
|
||||||
|
const RESET_CCTX_RESERVE_BUFFER: c_int = 1;
|
||||||
|
|
||||||
|
const RESET_CCTX_POINTER_SEQ_START: c_int = 0;
|
||||||
|
const RESET_CCTX_POINTER_LDM_HASH: c_int = 1;
|
||||||
|
const RESET_CCTX_POINTER_LDM_SEQUENCES: c_int = 2;
|
||||||
|
const RESET_CCTX_POINTER_EXTERNAL_SEQUENCES: c_int = 3;
|
||||||
|
const RESET_CCTX_POINTER_LITERALS: c_int = 4;
|
||||||
|
const RESET_CCTX_POINTER_INPUT_BUFFER: c_int = 5;
|
||||||
|
const RESET_CCTX_POINTER_OUTPUT_BUFFER: c_int = 6;
|
||||||
|
const RESET_CCTX_POINTER_LL_CODE: c_int = 7;
|
||||||
|
const RESET_CCTX_POINTER_ML_CODE: c_int = 8;
|
||||||
|
const RESET_CCTX_POINTER_OF_CODE: c_int = 9;
|
||||||
|
const RESET_CCTX_POINTER_LDM_BUCKETS: c_int = 10;
|
||||||
|
|
||||||
|
const RESET_CCTX_SIZE_MAX_NB_SEQ: c_int = 0;
|
||||||
|
const RESET_CCTX_SIZE_MAX_NB_LIT: c_int = 1;
|
||||||
|
const RESET_CCTX_SIZE_MAX_NB_LDM_SEQ: c_int = 2;
|
||||||
|
const RESET_CCTX_SIZE_EXTERNAL_SEQ_CAPACITY: c_int = 3;
|
||||||
|
const RESET_CCTX_SIZE_INPUT_BUFFER: c_int = 4;
|
||||||
|
const RESET_CCTX_SIZE_OUTPUT_BUFFER: c_int = 5;
|
||||||
|
|
||||||
|
const RESET_CCTX_INT_BUFFERED_POLICY: c_int = 0;
|
||||||
|
const RESET_CCTX_INT_INITIALIZED: c_int = 1;
|
||||||
|
|
||||||
|
/// C-owned workspace/layout projection for the post-match-state reset tail.
|
||||||
|
///
|
||||||
|
/// Rust owns the reservation order and size policy. C retains the private
|
||||||
|
/// `ZSTD_CCtx`/`ldmState_t` layouts and implements the workspace callbacks.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ZSTD_rust_resetCCtxStorageState {
|
||||||
|
pub callbackContext: *mut c_void,
|
||||||
|
pub ldmEnable: c_int,
|
||||||
|
pub hasExtSeqProd: c_int,
|
||||||
|
pub hashLog: c_uint,
|
||||||
|
pub bucketSizeLog: c_uint,
|
||||||
|
pub blockSize: usize,
|
||||||
|
pub maxNbSeq: usize,
|
||||||
|
pub maxNbLdmSeq: usize,
|
||||||
|
pub maxNbExternalSeq: usize,
|
||||||
|
pub buffInSize: usize,
|
||||||
|
pub buffOutSize: usize,
|
||||||
|
pub seqDefSize: usize,
|
||||||
|
pub ldmEntrySize: usize,
|
||||||
|
pub rawSeqSize: usize,
|
||||||
|
pub externalSequenceSize: usize,
|
||||||
|
pub byteSize: usize,
|
||||||
|
pub wildcopyOverlength: usize,
|
||||||
|
pub bufferedPolicy: c_int,
|
||||||
|
pub setPointer: Option<ResetCCtxStorageSetPointer>,
|
||||||
|
pub setSize: Option<ResetCCtxStorageSetSize>,
|
||||||
|
pub setInt: Option<ResetCCtxStorageSetInt>,
|
||||||
|
pub reserve: Option<ResetCCtxStorageReserve>,
|
||||||
|
pub reserveFailed: Option<ResetCCtxStorageReserveFailed>,
|
||||||
|
pub zero: Option<ResetCCtxStorageZero>,
|
||||||
|
pub windowInit: Option<ResetCCtxStorageCallback>,
|
||||||
|
pub resetExternalSequences: Option<ResetCCtxStorageCallback>,
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
assert!(size_of::<ResetCCtxStorageSetPointer>() == size_of::<usize>());
|
||||||
|
assert!(size_of::<ResetCCtxStorageSetSize>() == size_of::<usize>());
|
||||||
|
assert!(size_of::<ResetCCtxStorageSetInt>() == size_of::<usize>());
|
||||||
|
assert!(size_of::<ResetCCtxStorageReserve>() == size_of::<usize>());
|
||||||
|
assert!(size_of::<ResetCCtxStorageReserveFailed>() == size_of::<usize>());
|
||||||
|
assert!(size_of::<ResetCCtxStorageZero>() == size_of::<usize>());
|
||||||
|
assert!(size_of::<ResetCCtxStorageCallback>() == size_of::<usize>());
|
||||||
|
assert!(offset_of!(ZSTD_rust_resetCCtxStorageState, callbackContext) == 0);
|
||||||
|
assert!(offset_of!(ZSTD_rust_resetCCtxStorageState, ldmEnable) == size_of::<usize>());
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, hasExtSeqProd)
|
||||||
|
== size_of::<usize>() + size_of::<c_int>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, hashLog)
|
||||||
|
> offset_of!(ZSTD_rust_resetCCtxStorageState, hasExtSeqProd)
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, bucketSizeLog)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, hashLog) + size_of::<c_uint>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, blockSize)
|
||||||
|
> offset_of!(ZSTD_rust_resetCCtxStorageState, bucketSizeLog)
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, maxNbSeq)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, blockSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, maxNbLdmSeq)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, maxNbSeq) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, maxNbExternalSeq)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, maxNbLdmSeq) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, buffInSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, maxNbExternalSeq) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, buffOutSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, buffInSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, seqDefSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, buffOutSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, ldmEntrySize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, seqDefSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, rawSeqSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, ldmEntrySize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, externalSequenceSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, rawSeqSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, byteSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, externalSequenceSize)
|
||||||
|
+ size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, wildcopyOverlength)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, byteSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, bufferedPolicy)
|
||||||
|
> offset_of!(ZSTD_rust_resetCCtxStorageState, wildcopyOverlength)
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, setSize)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, setPointer) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, setInt)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, setSize) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(ZSTD_rust_resetCCtxStorageState, reserve)
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, setInt) + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
size_of::<ZSTD_rust_resetCCtxStorageState>()
|
||||||
|
== offset_of!(ZSTD_rust_resetCCtxStorageState, resetExternalSequences)
|
||||||
|
+ size_of::<usize>()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Reserve and publish the private CCtx storage that follows match-state reset.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn ZSTD_rust_resetCCtxStorage(
|
||||||
|
state: *const ZSTD_rust_resetCCtxStorageState,
|
||||||
|
) -> usize {
|
||||||
|
if state.is_null() {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
}
|
||||||
|
let state = unsafe { &*state };
|
||||||
|
if state.callbackContext.is_null() {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
}
|
||||||
|
let Some(set_pointer) = state.setPointer else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(set_size) = state.setSize else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(set_int) = state.setInt else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(reserve_callback) = state.reserve else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(reserve_failed) = state.reserveFailed else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(zero) = state.zero else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(window_init) = state.windowInit else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let Some(reset_external_sequences) = state.resetExternalSequences else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
|
||||||
|
let reserve = |kind: c_int, size: usize| -> Result<*mut c_void, usize> {
|
||||||
|
let pointer = unsafe { reserve_callback(state.callbackContext, kind, size) };
|
||||||
|
if unsafe { reserve_failed(state.callbackContext) } != 0 {
|
||||||
|
Err(ERROR(ZstdErrorCode::MemoryAllocation))
|
||||||
|
} else {
|
||||||
|
Ok(pointer)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let publish_pointer = |kind: c_int, pointer: *mut c_void| unsafe {
|
||||||
|
set_pointer(state.callbackContext, kind, pointer)
|
||||||
|
};
|
||||||
|
let publish_size =
|
||||||
|
|kind: c_int, value: usize| unsafe { set_size(state.callbackContext, kind, value) };
|
||||||
|
|
||||||
|
let sequence_start = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
state.maxNbSeq.wrapping_mul(state.seqDefSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_SEQ_START, sequence_start);
|
||||||
|
|
||||||
|
if state.ldmEnable == ZSTD_RUST_PS_ENABLE {
|
||||||
|
if state.bucketSizeLog > state.hashLog {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
}
|
||||||
|
let Some(hash_size) = 1usize.checked_shl(state.hashLog) else {
|
||||||
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
|
};
|
||||||
|
let hash_table = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
hash_size.wrapping_mul(state.ldmEntrySize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_LDM_HASH, hash_table);
|
||||||
|
unsafe {
|
||||||
|
zero(
|
||||||
|
state.callbackContext,
|
||||||
|
hash_table,
|
||||||
|
hash_size.wrapping_mul(state.ldmEntrySize),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let ldm_sequences = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
state.maxNbLdmSeq.wrapping_mul(state.rawSeqSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_LDM_SEQUENCES, ldm_sequences);
|
||||||
|
publish_size(RESET_CCTX_SIZE_MAX_NB_LDM_SEQ, state.maxNbLdmSeq);
|
||||||
|
unsafe { window_init(state.callbackContext) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.hasExtSeqProd != 0 {
|
||||||
|
let external_sequences = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
state
|
||||||
|
.maxNbExternalSeq
|
||||||
|
.wrapping_mul(state.externalSequenceSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_EXTERNAL_SEQUENCES, external_sequences);
|
||||||
|
publish_size(
|
||||||
|
RESET_CCTX_SIZE_EXTERNAL_SEQ_CAPACITY,
|
||||||
|
state.maxNbExternalSeq,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let literals = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_BUFFER,
|
||||||
|
state.blockSize.wrapping_add(state.wildcopyOverlength),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_LITERALS, literals);
|
||||||
|
publish_size(RESET_CCTX_SIZE_MAX_NB_LIT, state.blockSize);
|
||||||
|
unsafe {
|
||||||
|
set_int(
|
||||||
|
state.callbackContext,
|
||||||
|
RESET_CCTX_INT_BUFFERED_POLICY,
|
||||||
|
state.bufferedPolicy,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let input_buffer = match reserve(RESET_CCTX_RESERVE_BUFFER, state.buffInSize) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_INPUT_BUFFER, input_buffer);
|
||||||
|
publish_size(RESET_CCTX_SIZE_INPUT_BUFFER, state.buffInSize);
|
||||||
|
|
||||||
|
let output_buffer = match reserve(RESET_CCTX_RESERVE_BUFFER, state.buffOutSize) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_OUTPUT_BUFFER, output_buffer);
|
||||||
|
publish_size(RESET_CCTX_SIZE_OUTPUT_BUFFER, state.buffOutSize);
|
||||||
|
|
||||||
|
if state.ldmEnable == ZSTD_RUST_PS_ENABLE {
|
||||||
|
let bucket_count = match 1usize.checked_shl(state.hashLog - state.bucketSizeLog) {
|
||||||
|
Some(count) => count,
|
||||||
|
None => return ERROR(ZstdErrorCode::Generic),
|
||||||
|
};
|
||||||
|
let bucket_offsets = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_BUFFER,
|
||||||
|
bucket_count.wrapping_mul(state.byteSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_LDM_BUCKETS, bucket_offsets);
|
||||||
|
unsafe {
|
||||||
|
zero(
|
||||||
|
state.callbackContext,
|
||||||
|
bucket_offsets,
|
||||||
|
bucket_count.wrapping_mul(state.byteSize),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { reset_external_sequences(state.callbackContext) };
|
||||||
|
publish_size(RESET_CCTX_SIZE_MAX_NB_SEQ, state.maxNbSeq);
|
||||||
|
|
||||||
|
let ll_code = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_BUFFER,
|
||||||
|
state.maxNbSeq.wrapping_mul(state.byteSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_LL_CODE, ll_code);
|
||||||
|
let ml_code = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_BUFFER,
|
||||||
|
state.maxNbSeq.wrapping_mul(state.byteSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_ML_CODE, ml_code);
|
||||||
|
let of_code = match reserve(
|
||||||
|
RESET_CCTX_RESERVE_BUFFER,
|
||||||
|
state.maxNbSeq.wrapping_mul(state.byteSize),
|
||||||
|
) {
|
||||||
|
Ok(pointer) => pointer,
|
||||||
|
Err(error) => return error,
|
||||||
|
};
|
||||||
|
publish_pointer(RESET_CCTX_POINTER_OF_CODE, of_code);
|
||||||
|
unsafe { set_int(state.callbackContext, RESET_CCTX_INT_INITIALIZED, 1) };
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_estimate_cctx_size(
|
fn max_estimate_cctx_size(
|
||||||
estimate0: usize,
|
estimate0: usize,
|
||||||
@@ -13975,6 +14332,283 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
enum ResetCCtxStorageTestEvent {
|
||||||
|
Reserve(c_int, usize),
|
||||||
|
Pointer(c_int),
|
||||||
|
Size(c_int, usize),
|
||||||
|
Int(c_int, c_int),
|
||||||
|
Zero(usize),
|
||||||
|
WindowInit,
|
||||||
|
ResetExternalSequences,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct ResetCCtxStorageTestContext {
|
||||||
|
events: Vec<ResetCCtxStorageTestEvent>,
|
||||||
|
reserve_count: usize,
|
||||||
|
reserve_failure: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn reset_cctx_storage_test_context(
|
||||||
|
context: *mut c_void,
|
||||||
|
) -> &'static mut ResetCCtxStorageTestContext {
|
||||||
|
unsafe { &mut *context.cast::<ResetCCtxStorageTestContext>() }
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_set_pointer(
|
||||||
|
context: *mut c_void,
|
||||||
|
kind: c_int,
|
||||||
|
_pointer: *mut c_void,
|
||||||
|
) {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context
|
||||||
|
.events
|
||||||
|
.push(ResetCCtxStorageTestEvent::Pointer(kind));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_set_size(
|
||||||
|
context: *mut c_void,
|
||||||
|
kind: c_int,
|
||||||
|
value: usize,
|
||||||
|
) {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context
|
||||||
|
.events
|
||||||
|
.push(ResetCCtxStorageTestEvent::Size(kind, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_set_int(
|
||||||
|
context: *mut c_void,
|
||||||
|
kind: c_int,
|
||||||
|
value: c_int,
|
||||||
|
) {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context
|
||||||
|
.events
|
||||||
|
.push(ResetCCtxStorageTestEvent::Int(kind, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_reserve(
|
||||||
|
context: *mut c_void,
|
||||||
|
kind: c_int,
|
||||||
|
size: usize,
|
||||||
|
) -> *mut c_void {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context
|
||||||
|
.events
|
||||||
|
.push(ResetCCtxStorageTestEvent::Reserve(kind, size));
|
||||||
|
let pointer = (0x1000usize + context.reserve_count * 0x1000) as *mut c_void;
|
||||||
|
context.reserve_count += 1;
|
||||||
|
pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_reserve_failed(context: *mut c_void) -> c_int {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
c_int::from(context.reserve_failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_zero(
|
||||||
|
context: *mut c_void,
|
||||||
|
_pointer: *mut c_void,
|
||||||
|
size: usize,
|
||||||
|
) {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context.events.push(ResetCCtxStorageTestEvent::Zero(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_window_init(context: *mut c_void) {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context.events.push(ResetCCtxStorageTestEvent::WindowInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_storage_test_reset_external_sequences(context: *mut c_void) {
|
||||||
|
let context = unsafe { reset_cctx_storage_test_context(context) };
|
||||||
|
context
|
||||||
|
.events
|
||||||
|
.push(ResetCCtxStorageTestEvent::ResetExternalSequences);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_cctx_storage_test_state(
|
||||||
|
context: &mut ResetCCtxStorageTestContext,
|
||||||
|
ldm_enable: c_int,
|
||||||
|
has_ext_seq_prod: c_int,
|
||||||
|
block_size: usize,
|
||||||
|
max_nb_seq: usize,
|
||||||
|
max_nb_ldm_seq: usize,
|
||||||
|
max_nb_external_seq: usize,
|
||||||
|
buff_in_size: usize,
|
||||||
|
buff_out_size: usize,
|
||||||
|
) -> ZSTD_rust_resetCCtxStorageState {
|
||||||
|
ZSTD_rust_resetCCtxStorageState {
|
||||||
|
callbackContext: (context as *mut ResetCCtxStorageTestContext).cast(),
|
||||||
|
ldmEnable: ldm_enable,
|
||||||
|
hasExtSeqProd: has_ext_seq_prod,
|
||||||
|
hashLog: 4,
|
||||||
|
bucketSizeLog: 2,
|
||||||
|
blockSize: block_size,
|
||||||
|
maxNbSeq: max_nb_seq,
|
||||||
|
maxNbLdmSeq: max_nb_ldm_seq,
|
||||||
|
maxNbExternalSeq: max_nb_external_seq,
|
||||||
|
buffInSize: buff_in_size,
|
||||||
|
buffOutSize: buff_out_size,
|
||||||
|
seqDefSize: size_of::<SeqDef>(),
|
||||||
|
ldmEntrySize: 8,
|
||||||
|
rawSeqSize: 12,
|
||||||
|
externalSequenceSize: size_of::<ZSTD_Sequence>(),
|
||||||
|
byteSize: 1,
|
||||||
|
wildcopyOverlength: 8,
|
||||||
|
bufferedPolicy: ZSTD_BM_BUFFERED,
|
||||||
|
setPointer: Some(reset_cctx_storage_test_set_pointer),
|
||||||
|
setSize: Some(reset_cctx_storage_test_set_size),
|
||||||
|
setInt: Some(reset_cctx_storage_test_set_int),
|
||||||
|
reserve: Some(reset_cctx_storage_test_reserve),
|
||||||
|
reserveFailed: Some(reset_cctx_storage_test_reserve_failed),
|
||||||
|
zero: Some(reset_cctx_storage_test_zero),
|
||||||
|
windowInit: Some(reset_cctx_storage_test_window_init),
|
||||||
|
resetExternalSequences: Some(reset_cctx_storage_test_reset_external_sequences),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cctx_storage_preserves_ordinary_reservation_and_publication_order() {
|
||||||
|
let mut context = ResetCCtxStorageTestContext::default();
|
||||||
|
let state = reset_cctx_storage_test_state(
|
||||||
|
&mut context,
|
||||||
|
ZSTD_RUST_PS_DISABLE,
|
||||||
|
0,
|
||||||
|
128,
|
||||||
|
4,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(unsafe { ZSTD_rust_resetCCtxStorage(&state) }, 0);
|
||||||
|
assert_eq!(
|
||||||
|
context.events,
|
||||||
|
[
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
4 * size_of::<SeqDef>()
|
||||||
|
),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_SEQ_START),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 136),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LITERALS),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_MAX_NB_LIT, 128),
|
||||||
|
ResetCCtxStorageTestEvent::Int(RESET_CCTX_INT_BUFFERED_POLICY, ZSTD_BM_BUFFERED),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 0),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_INPUT_BUFFER),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_INPUT_BUFFER, 0),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 0),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_OUTPUT_BUFFER),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_OUTPUT_BUFFER, 0),
|
||||||
|
ResetCCtxStorageTestEvent::ResetExternalSequences,
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_MAX_NB_SEQ, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LL_CODE),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_ML_CODE),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_OF_CODE),
|
||||||
|
ResetCCtxStorageTestEvent::Int(RESET_CCTX_INT_INITIALIZED, 1),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cctx_storage_preserves_ldm_and_external_sequence_order() {
|
||||||
|
let mut context = ResetCCtxStorageTestContext::default();
|
||||||
|
let state = reset_cctx_storage_test_state(
|
||||||
|
&mut context,
|
||||||
|
ZSTD_RUST_PS_ENABLE,
|
||||||
|
1,
|
||||||
|
128,
|
||||||
|
4,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
17,
|
||||||
|
19,
|
||||||
|
);
|
||||||
|
let external_size = 3 * size_of::<ZSTD_Sequence>();
|
||||||
|
|
||||||
|
assert_eq!(unsafe { ZSTD_rust_resetCCtxStorage(&state) }, 0);
|
||||||
|
assert_eq!(
|
||||||
|
context.events,
|
||||||
|
[
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
4 * size_of::<SeqDef>()
|
||||||
|
),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_SEQ_START),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_ALIGNED64, 16 * 8),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LDM_HASH),
|
||||||
|
ResetCCtxStorageTestEvent::Zero(16 * 8),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_ALIGNED64, 2 * 12),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LDM_SEQUENCES),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_MAX_NB_LDM_SEQ, 2),
|
||||||
|
ResetCCtxStorageTestEvent::WindowInit,
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_ALIGNED64, external_size),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_EXTERNAL_SEQUENCES),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_EXTERNAL_SEQ_CAPACITY, 3),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 136),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LITERALS),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_MAX_NB_LIT, 128),
|
||||||
|
ResetCCtxStorageTestEvent::Int(RESET_CCTX_INT_BUFFERED_POLICY, ZSTD_BM_BUFFERED),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 17),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_INPUT_BUFFER),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_INPUT_BUFFER, 17),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 19),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_OUTPUT_BUFFER),
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_OUTPUT_BUFFER, 19),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LDM_BUCKETS),
|
||||||
|
ResetCCtxStorageTestEvent::Zero(4),
|
||||||
|
ResetCCtxStorageTestEvent::ResetExternalSequences,
|
||||||
|
ResetCCtxStorageTestEvent::Size(RESET_CCTX_SIZE_MAX_NB_SEQ, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_LL_CODE),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_ML_CODE),
|
||||||
|
ResetCCtxStorageTestEvent::Reserve(RESET_CCTX_RESERVE_BUFFER, 4),
|
||||||
|
ResetCCtxStorageTestEvent::Pointer(RESET_CCTX_POINTER_OF_CODE),
|
||||||
|
ResetCCtxStorageTestEvent::Int(RESET_CCTX_INT_INITIALIZED, 1),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cctx_storage_propagates_reservation_failure_before_publication() {
|
||||||
|
let mut context = ResetCCtxStorageTestContext {
|
||||||
|
reserve_failure: true,
|
||||||
|
..ResetCCtxStorageTestContext::default()
|
||||||
|
};
|
||||||
|
let state = reset_cctx_storage_test_state(
|
||||||
|
&mut context,
|
||||||
|
ZSTD_RUST_PS_DISABLE,
|
||||||
|
0,
|
||||||
|
128,
|
||||||
|
4,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { ZSTD_rust_resetCCtxStorage(&state) },
|
||||||
|
ERROR(ZstdErrorCode::MemoryAllocation)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
context.events,
|
||||||
|
[ResetCCtxStorageTestEvent::Reserve(
|
||||||
|
RESET_CCTX_RESERVE_ALIGNED64,
|
||||||
|
4 * size_of::<SeqDef>()
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn estimate_cctx_workspace_size_keeps_static_and_buffer_components_separate() {
|
fn estimate_cctx_workspace_size_keeps_static_and_buffer_components_separate() {
|
||||||
let sizing = cctx_workspace_test_sizing();
|
let sizing = cctx_workspace_test_sizing();
|
||||||
|
|||||||
Reference in New Issue
Block a user