]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
context can be sized down even with constant parameters
authorYann Collet <cyan@fb.com>
Wed, 6 Jun 2018 22:04:12 +0000 (15:04 -0700)
committerYann Collet <cyan@fb.com>
Wed, 6 Jun 2018 22:04:12 +0000 (15:04 -0700)
when parameters are "equivalent",
the context is re-used in continue mode,
hence needed workspace size is not recalculated.
This incidentally also evades the size-down check and action.

This patch intercepts the "continue mode"
so that the size-down check and action is actually triggered.

lib/compress/zstd_compress.c
tests/fuzzer.c

index 341636604cdd79285af64632bc863e76498bcb6d..e0c29ac44cce201e40a9e67217f5a48cac31bd28 100644 (file)
@@ -1054,10 +1054,10 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
     return ptr;
 }
 
-#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as ZSTD_WORKSPACETOOLARGE_FACTOR times larger than needed */
-#define ZSTD_WORKSPACETOOLARGE_MAX 128  /* when workspace is continuously too large
-                                         * at least that number of times,
-                                         * context's memory usage is actually wasteful,
+#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
+#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128  /* when workspace is continuously too large
+                                         * during at least this number of times,
+                                         * context's memory usage is considered wasteful,
                                          * because it's sized to handle a worst case scenario which rarely happens.
                                          * In which case, resize it down to free some memory */
 
@@ -1080,7 +1080,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
             DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
                         zc->appliedParams.cParams.windowLog, zc->blockSize);
             zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0);   /* if it was too large, it still is */
-            return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
+            if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION)
+                return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
     }   }
     DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
 
@@ -1117,7 +1118,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
 
             int const workSpaceTooSmall = zc->workSpaceSize < neededSpace;
             int const workSpaceTooLarge = zc->workSpaceSize > ZSTD_WORKSPACETOOLARGE_FACTOR * neededSpace;
-            int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAX);
+            int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION);
             zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0;
 
             DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
index 6e60b74cb462bd5dc5cbe910237401f550b0c6af..6660fb0625c5ebf8fd7b8f6a0f25372f3acc22fa 100644 (file)
@@ -490,8 +490,7 @@ static int basicUnitTests(U32 seed, double compressibility)
                                                    * make this test long enough so that it's not too much tied to the current definition within zstd_compress.c */
                 U32 u;
                 for (u=0; u<maxNbAttempts; u++) {
-                    size_t const srcSize = (FUZ_rand(&seed) & 4095) + 200;
-                    CHECK_Z(ZSTD_compressCCtx(largeCCtx, compressedBuffer, compressedBufferSize, CNBuffer, srcSize, -9));
+                    CHECK_Z(ZSTD_compressCCtx(largeCCtx, compressedBuffer, compressedBufferSize, CNBuffer, 1, 1));
                     if (ZSTD_sizeof_CCtx(largeCCtx) < largeCCtxSize) break;   /* sized down */
                 }
                 DISPLAYLEVEL(5, "size down after %u attempts : ", u);