From 02be2a830f20e5801386be87d7f816776a068516 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 25 Oct 2021 08:09:04 -0700 Subject: [PATCH 1/3] build macro ZSTD_DECODER_INTERNAL_BUFFER just to make the topic more accessible for potential users. --- lib/README.md | 10 +++++----- lib/decompress/zstd_decompress_internal.h | 9 +++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/README.md b/lib/README.md index 9cbeb8d4f..aab0869af 100644 --- a/lib/README.md +++ b/lib/README.md @@ -155,11 +155,11 @@ The file structure is designed to make this selection manually achievable for an - The build macro `ZSTD_NO_INTRINSICS` can be defined to disable all explicit intrinsics. Compiler builtins are still used. -- The build macro `ZSTD_LITBUFFEREXTRASIZE` can be set to control the amount of extra memory used - during decompression to store literals. This defaults to 64kB. Reducing it can reduce the - memory footprint required for decompression by increasing the portion of the literal buffer that - is stored in the unwritten portion of the dst buffer, at the cost of performance impact for - decompression. +- The build macro `ZSTD_DECODER_INTERNAL_BUFFER` can be set to control + the amount of extra memory used during decompression to store literals. + This defaults to 64kB. Reducing this value reduces the memory footprint of + `ZSTD_DCtx` decompression contexts, + but might also result in a small decompression speed cost. #### Windows : using MinGW+MSYS to create DLL diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index ac5586cc7..7f555911d 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -106,10 +106,15 @@ typedef struct { size_t ddictPtrCount; } ZSTD_DDictHashSet; -#ifndef ZSTD_LITBUFFEREXTRASIZE -#define ZSTD_LITBUFFEREXTRASIZE (1 << 16) /* extra buffer reduces amount of dst required to store litBuffer */ +#ifndef ZSTD_DECODER_INTERNAL_BUFFER +# define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16) #endif +#define ZSTD_LBMAX (128 << 10) + +/* extra buffer, compensates amount of dst required to store litBuffer */ +#define ZSTD_LITBUFFEREXTRASIZE MIN(ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) + typedef enum { ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */ ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */ From 518f06b2818cc77425ac502eb1c8575359f16431 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 26 Oct 2021 08:21:31 -0700 Subject: [PATCH 2/3] added minimum for decoder buffer also : introduced macro BOUNDED() --- lib/common/zstd_internal.h | 1 + lib/compress/zstd_compress.c | 4 ++-- lib/compress/zstd_lazy.c | 2 +- lib/decompress/zstd_decompress.c | 2 +- lib/decompress/zstd_decompress_internal.h | 5 +++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index eaa0afc90..aeafac2fa 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -57,6 +57,7 @@ extern "C" { #undef MAX #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define BOUNDED(min,val,max) (MAX(min,MIN(val,max))) /*-************************************* diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index edfd7eb07..656d3fdfa 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1465,7 +1465,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( const size_t buffOutSize, const U64 pledgedSrcSize) { - size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << cParams->windowLog), pledgedSrcSize)); + size_t const windowSize = BOUNDED(1, 1 << cParams->windowLog, pledgedSrcSize); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); U32 const divider = (cParams->minMatch==3) ? 3 : 4; size_t const maxNbSeq = blockSize / divider; @@ -1783,7 +1783,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, if (ms->tagTable) ZSTD_memset(ms->tagTable, 0, tagTableSize); } { /* Switch to 32-entry rows if searchLog is 5 (or more) */ - U32 const rowLog = MAX(MIN(cParams->searchLog, 6), 4); + U32 const rowLog = BOUNDED(4, cParams->searchLog, 6); assert(cParams->hashLog >= rowLog); ms->rowHashLog = cParams->hashLog - rowLog; } diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 78cc5b09b..566da2d45 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1086,7 +1086,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const * processing. */ void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) { - const U32 rowLog = MAX(MIN(ms->cParams.searchLog, 6), 4); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); const U32 rowMask = (1u << rowLog) - 1; const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */); diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index b5ccac53c..47ca874bf 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1123,7 +1123,7 @@ static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t return dctx->expected; if (dctx->bType != bt_raw) return dctx->expected; - return MIN(MAX(inputSize, 1), dctx->expected); + return BOUNDED(1, inputSize, dctx->expected); } ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index 7f555911d..51dc34729 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -110,10 +110,11 @@ typedef struct { # define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16) #endif +#define ZSTD_LBMIN 64 #define ZSTD_LBMAX (128 << 10) -/* extra buffer, compensates amount of dst required to store litBuffer */ -#define ZSTD_LITBUFFEREXTRASIZE MIN(ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) +/* extra buffer, compensates when dst is not large enough to store litBuffer */ +#define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) typedef enum { ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */ From 2b2a5c449a7b522c6ea2626d82b8412826e2cfb2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 26 Oct 2021 08:38:17 -0700 Subject: [PATCH 3/3] fix minor cast warning --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 656d3fdfa..4bd3abde6 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1465,7 +1465,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( const size_t buffOutSize, const U64 pledgedSrcSize) { - size_t const windowSize = BOUNDED(1, 1 << cParams->windowLog, pledgedSrcSize); + size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize); U32 const divider = (cParams->minMatch==3) ? 3 : 4; size_t const maxNbSeq = blockSize / divider;