Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make offload API compatible with static CCtx #3854

Merged
merged 6 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions lib/compress/zstd_compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -7084,14 +7084,27 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH
}

void ZSTD_registerSequenceProducer(
ZSTD_CCtx* zc, void* extSeqProdState,
ZSTD_CCtx* zc,
void* extSeqProdState,
ZSTD_sequenceProducer_F extSeqProdFunc
) {
assert(zc != NULL);
ZSTD_CCtxParams_registerSequenceProducer(
&zc->requestedParams, extSeqProdState, extSeqProdFunc
);
}

void ZSTD_CCtxParams_registerSequenceProducer(
ZSTD_CCtx_params* params,
void* extSeqProdState,
ZSTD_sequenceProducer_F extSeqProdFunc
) {
assert(params != NULL);
if (extSeqProdFunc != NULL) {
zc->requestedParams.extSeqProdFunc = extSeqProdFunc;
zc->requestedParams.extSeqProdState = extSeqProdState;
params->extSeqProdFunc = extSeqProdFunc;
params->extSeqProdState = extSeqProdState;
} else {
zc->requestedParams.extSeqProdFunc = NULL;
zc->requestedParams.extSeqProdState = NULL;
params->extSeqProdFunc = NULL;
params->extSeqProdState = NULL;
}
}
19 changes: 16 additions & 3 deletions lib/zstd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1665,9 +1665,6 @@ ZSTDLIB_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
*
* Note : only single-threaded compression is supported.
* ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1.
*
* Note 2 : ZSTD_estimateCCtxSize* functions are not compatible with the Block-Level Sequence Producer API at this time.
* Size estimates assume that no external sequence producer is registered.
*/
ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int maxCompressionLevel);
ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
Expand Down Expand Up @@ -2824,6 +2821,22 @@ ZSTD_registerSequenceProducer(
ZSTD_sequenceProducer_F sequenceProducer
);

/*! ZSTD_CCtxParams_registerSequenceProducer() :
* Same as ZSTD_registerSequenceProducer(), but operates on ZSTD_CCtx_params.
* This is used for accurate size estimation with ZSTD_estimateCCtxSize_usingCCtxParams(),
* which is needed when creating a ZSTD_CCtx with ZSTD_initStaticCCtx().
*
* If you are using the external sequence producer API in a scenario where ZSTD_initStaticCCtx()
* is required, then this function is for you. Otherwise, you probably don't need it.
*
* See tests/zstreamtest.c for example usage. */
ZSTDLIB_STATIC_API void
ZSTD_CCtxParams_registerSequenceProducer(
ZSTD_CCtx_params* params,
void* sequenceProducerState,
ZSTD_sequenceProducer_F sequenceProducer
);


/*********************************************************************
* Buffer-less and synchronous inner streaming functions (DEPRECATED)
Expand Down
54 changes: 53 additions & 1 deletion tests/zstreamtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1920,7 +1920,7 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests)
DISPLAYLEVEL(3, "test%3i : Block-Level External Sequence Producer API: ", testNb++);
{
size_t const dstBufSize = ZSTD_compressBound(CNBufferSize);
BYTE* const dstBuf = (BYTE*)malloc(ZSTD_compressBound(dstBufSize));
BYTE* const dstBuf = (BYTE*)malloc(dstBufSize);
size_t const checkBufSize = CNBufferSize;
BYTE* const checkBuf = (BYTE*)malloc(checkBufSize);
int enableFallback;
Expand Down Expand Up @@ -2356,6 +2356,58 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests)
}
DISPLAYLEVEL(3, "OK \n");

DISPLAYLEVEL(3, "test%3i : Testing external sequence producer with static CCtx: ", testNb++);
{
size_t const dstBufSize = ZSTD_compressBound(CNBufferSize);
BYTE* const dstBuf = (BYTE*)malloc(dstBufSize);
size_t const checkBufSize = CNBufferSize;
BYTE* const checkBuf = (BYTE*)malloc(checkBufSize);
ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
ZSTD_CCtx* staticCCtx;
void* cctxBuf;
EMF_testCase seqProdState;

CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_validateSequences, 1));
CHECK_Z(ZSTD_CCtxParams_setParameter(params, ZSTD_c_enableSeqProducerFallback, 0));
ZSTD_CCtxParams_registerSequenceProducer(params, &seqProdState, zstreamSequenceProducer);

{
size_t const cctxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
cctxBuf = malloc(cctxSize);
staticCCtx = ZSTD_initStaticCCtx(cctxBuf, cctxSize);
ZSTD_CCtx_setParametersUsingCCtxParams(staticCCtx, params);
}

// Check that compression with external sequence producer succeeds when expected
seqProdState = EMF_LOTS_OF_SEQS;
{
size_t dResult;
size_t const cResult = ZSTD_compress2(staticCCtx, dstBuf, dstBufSize, CNBuffer, CNBufferSize);
CHECK(ZSTD_isError(cResult), "EMF: Compression error: %s", ZSTD_getErrorName(cResult));
dResult = ZSTD_decompress(checkBuf, checkBufSize, dstBuf, cResult);
CHECK(ZSTD_isError(dResult), "EMF: Decompression error: %s", ZSTD_getErrorName(dResult));
CHECK(dResult != CNBufferSize, "EMF: Corruption!");
CHECK(memcmp(CNBuffer, checkBuf, CNBufferSize) != 0, "EMF: Corruption!");
}

// Check that compression with external sequence producer fails when expected
seqProdState = EMF_BIG_ERROR;
{
size_t const cResult = ZSTD_compress2(staticCCtx, dstBuf, dstBufSize, CNBuffer, CNBufferSize);
CHECK(!ZSTD_isError(cResult), "EMF: Should have raised an error!");
CHECK(
ZSTD_getErrorCode(cResult) != ZSTD_error_sequenceProducer_failed,
"EMF: Wrong error code: %s", ZSTD_getErrorName(cResult)
);
}

free(dstBuf);
free(checkBuf);
free(cctxBuf);
ZSTD_freeCCtxParams(params);
}
DISPLAYLEVEL(3, "OK \n");

_end:
FUZ_freeDictionary(dictionary);
ZSTD_freeCStream(zc);
Expand Down