From 9f76eebd1748a709d94991848f43346638d6880d Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 12 Apr 2018 16:54:07 -0700 Subject: [PATCH 1/3] Add ZSTD_CCtx_resetParameters() function * Fix docs for `ZSTD_CCtx_reset()`. * Add `ZSTD_CCtx_resetParameters()`. Fixes #1094. --- lib/compress/zstd_compress.c | 12 ++++++++++-- lib/zstd.h | 9 +++++++-- tests/fuzzer.c | 6 ++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 590e92c8e..ecda036b5 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -72,9 +72,11 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_calloc(sizeof(ZSTD_CCtx), customMem); if (!cctx) return NULL; cctx->customMem = customMem; - cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT; - cctx->requestedParams.fParams.contentSizeFlag = 1; cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + { size_t const err = ZSTD_CCtx_resetParameters(cctx); + assert(!ZSTD_isError(err)); + (void)err; + } return cctx; } } @@ -671,6 +673,12 @@ void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) cctx->cdict = NULL; } +size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx) +{ + if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); + return ZSTD_CCtxParams_reset(&cctx->requestedParams); +} + /** ZSTD_checkCParams() : control CParam values remain within authorized range. @return : 0, or an error code if one value is beyond authorized range */ diff --git a/lib/zstd.h b/lib/zstd.h index 913c599bb..aaec49fe7 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -1142,11 +1142,16 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre * Useful after an error, or to interrupt an ongoing compression job and start a new one. * Any internal data not yet flushed is cancelled. * Dictionary (if any) is dropped. - * All parameters are back to default values (compression level is ZSTD_CLEVEL_DEFAULT). - * After a reset, all compression parameters can be modified again. */ ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx); +/*! ZSTD_CCtx_resetParameters() : + * All parameters are back to default values (compression level is ZSTD_CLEVEL_DEFAULT). + * Resetting parameters is only possible during frame initialization (before starting compression). + * @return 0 or an error code (which can be checked with ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx); + typedef enum { diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 33d27cda7..9b49ddd08 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -433,6 +433,12 @@ static int basicUnitTests(U32 seed, double compressibility) CHECK_EQ(value, 7); CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_p_hashLog, &value)); CHECK_EQ(value, ZSTD_HASHLOG_MIN); + /* Reset the parameters */ + ZSTD_CCtx_resetParameters(cctx); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_p_compressionLevel, &value)); + CHECK_EQ(value, 3); + CHECK_Z(ZSTD_CCtx_getParameter(cctx, ZSTD_p_hashLog, &value)); + CHECK_EQ(value, 0); ZSTD_freeCCtx(cctx); } From c0987986e52d507b64de966890c416061b0b6eb7 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 13 Apr 2018 11:26:40 -0700 Subject: [PATCH 2/3] Only reset CDict in ZSTD_CCtx_resetParameters() --- lib/compress/zstd_compress.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index ecda036b5..7a5043284 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -659,23 +659,18 @@ size_t ZSTD_CCtx_refPrefix_advanced( return 0; } -static void ZSTD_startNewCompression(ZSTD_CCtx* cctx) +/*! ZSTD_CCtx_reset() : + * Also dumps dictionary */ +void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) { cctx->streamStage = zcss_init; cctx->pledgedSrcSizePlusOne = 0; } -/*! ZSTD_CCtx_reset() : - * Also dumps dictionary */ -void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) -{ - ZSTD_startNewCompression(cctx); - cctx->cdict = NULL; -} - size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx) { if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); + cctx->cdict = NULL; return ZSTD_CCtxParams_reset(&cctx->requestedParams); } @@ -3189,7 +3184,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, ip = iend; op += cSize; zcs->frameEnded = 1; - ZSTD_startNewCompression(zcs); + ZSTD_CCtx_reset(zcs); someMoreWork = 0; break; } /* complete loading into inBuffer */ @@ -3242,7 +3237,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (zcs->frameEnded) { DEBUGLOG(5, "Frame completed directly in outBuffer"); someMoreWork = 0; - ZSTD_startNewCompression(zcs); + ZSTD_CCtx_reset(zcs); } break; } @@ -3270,7 +3265,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (zcs->frameEnded) { DEBUGLOG(5, "Frame completed on flush"); someMoreWork = 0; - ZSTD_startNewCompression(zcs); + ZSTD_CCtx_reset(zcs); break; } zcs->streamStage = zcss_load; @@ -3367,7 +3362,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); if ( ZSTD_isError(flushMin) || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ - ZSTD_startNewCompression(cctx); + ZSTD_CCtx_reset(cctx); } return flushMin; } } From e8c9dc5cea3b150b04059651e9322d81875e6958 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 13 Apr 2018 12:43:38 -0700 Subject: [PATCH 3/3] Fix documentation --- lib/zstd.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/zstd.h b/lib/zstd.h index aaec49fe7..387586c1e 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -1141,13 +1141,15 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre * Return a CCtx to clean state. * Useful after an error, or to interrupt an ongoing compression job and start a new one. * Any internal data not yet flushed is cancelled. - * Dictionary (if any) is dropped. + * The parameters and dictionary are kept unchanged, to reset them use ZSTD_CCtx_resetParameters(). */ ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx); /*! ZSTD_CCtx_resetParameters() : * All parameters are back to default values (compression level is ZSTD_CLEVEL_DEFAULT). + * Dictionary (if any) is dropped. * Resetting parameters is only possible during frame initialization (before starting compression). + * To reset the context use ZSTD_CCtx_reset(). * @return 0 or an error code (which can be checked with ZSTD_isError()). */ ZSTDLIB_API size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx);