added function to control monotonic memory budget increase of ZSTD_defaultCParameters[0]
It's a runtime test, based on assert(),
played once, on first ZSTD_getCParams() usage,
when ZSTD_DEBUG is enabled.
diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
index 6d524ae..bb6f0ea 100644
--- a/doc/zstd_manual.html
+++ b/doc/zstd_manual.html
@@ -412,9 +412,9 @@
size_t ZSTD_estimateDCtxSize(void);
</b><p> These functions make it possible to estimate memory usage
of a future {D,C}Ctx, before its creation.
- The objective is to guide decision before allocation.
- ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large".
- If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
+ ZSTD_estimateCCtxSize() will provide a budget large for any compression level up to selected one.
+ It will also consider src size to be arbitrarily "large", which is worst case.
+ If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
Note : CCtx estimation is only correct for single-threaded compression
</p></pre><BR>
@@ -423,8 +423,9 @@
size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
size_t ZSTD_estimateDStreamSize(size_t windowSize);
size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
-</b><p> ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large".
- If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
+</b><p> ZSTD_estimateCStreamSize() will provide a budget large for any compression level up to selected one.
+ It will also consider src size to be arbitrarily "large", which is worst case.
+ If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
Note : CStream estimation is only correct for single-threaded compression.
ZSTD_DStream memory budget depends on window Size.
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index c781232..c2adc56 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -4098,6 +4098,43 @@
},
};
+/* This function just controls
+ * the monotonic memory budget increase of ZSTD_defaultCParameters[0].
+ * Run only once, on first ZSTD_getCParams() usage, when ZSTD_DEBUG is enabled
+ */
+MEM_STATIC void ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(void)
+{
+# define ZSTD_TABLECOST(h,c) ((1<<(h)) + (1<<(c)))
+# define ZDCP_FIELD(l,field) (ZSTD_defaultCParameters[0][l].field)
+# define ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(l) { \
+ assert(ZDCP_FIELD(l,windowLog) <= ZDCP_FIELD(l+1,windowLog) ); \
+ assert(ZSTD_TABLECOST(ZDCP_FIELD(l,hashLog), ZDCP_FIELD(l,chainLog)) <= ZSTD_TABLECOST(ZDCP_FIELD(l+1,hashLog), ZDCP_FIELD(l+1,chainLog)) ); \
+ }
+
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(1);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(2);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(3);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(4);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(5);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(6);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(7);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(8);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(9);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(10);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(11);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(12);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(13);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(14);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(15);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(16);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(17);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(18);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(19);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(20);
+ ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(21);
+ assert(ZSTD_maxCLevel()==22);
+}
+
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
* Size values are optional, provide 0 if not known or unused */
@@ -4108,6 +4145,15 @@
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
+
+#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
+ static int g_monotonicTest = 1;
+ if (g_monotonicTest) {
+ ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget();
+ g_monotonicTest=0;
+ }
+#endif
+
{ ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel];
return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); }
}
diff --git a/lib/zstd.h b/lib/zstd.h
index 08358f0..75bdb48 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -496,9 +496,9 @@
/*! ZSTD_estimate*() :
* These functions make it possible to estimate memory usage
* of a future {D,C}Ctx, before its creation.
- * The objective is to guide decision before allocation.
- * ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large".
- * If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
+ * ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one.
+ * It will also consider src size to be arbitrarily "large", which is worst case.
+ * If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
@@ -506,8 +506,9 @@
ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
/*! ZSTD_estimate?StreamSize() :
- * ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large".
- * If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
+ * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one.
+ * It will also consider src size to be arbitrarily "large", which is worst case.
+ * If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.