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/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 a4b95f053..ad57cce8c 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 = (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; @@ -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 65d7990c3..d6354be7f 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -974,7 +974,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 ac5586cc7..51dc34729 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -106,10 +106,16 @@ 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_LBMIN 64 +#define ZSTD_LBMAX (128 << 10) + +/* 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 */ ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */