]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
added function to control monotonic memory budget increase of ZSTD_defaultCParameters[0]
authorYann Collet <cyan@fb.com>
Wed, 28 Jun 2017 22:34:56 +0000 (15:34 -0700)
committerYann Collet <cyan@fb.com>
Wed, 28 Jun 2017 22:34:56 +0000 (15:34 -0700)
It's a runtime test, based on assert(),
played once, on first ZSTD_getCParams() usage,
when ZSTD_DEBUG is enabled.

doc/zstd_manual.html
lib/compress/zstd_compress.c
lib/zstd.h

index 6d524ae32eb76d1d2ce97c8c5c56629203e8762d..bb6f0eac9201a4d5c041d84fb07c35f08f2a677b 100644 (file)
@@ -412,9 +412,9 @@ size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
 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_estimateDCtxSize(void);
 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.
index c781232c6006548d8228108bc75444aeeee65e22..c2adc56ab51397bbc65b0f3256a5890123506fcf 100644 (file)
@@ -4098,6 +4098,43 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
 },
 };
 
+/* 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 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
     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); }
 }
index 08358f0dfe33ab6fa2ac1041bdd040d117d24a3a..75bdb48954c341faa8d833ec8f980ee321bc3075 100644 (file)
@@ -496,9 +496,9 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
 /*! 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_estimateCCtxSize_advanced(ZSTD_compressionParameters cPa
 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.