]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
additional tests and documentation updates + allow maxBlockSize to be set to 0 (goes...
authorDanielle Rozenblit <drozenblit@fb.com>
Thu, 12 Jan 2023 21:41:50 +0000 (13:41 -0800)
committerDanielle Rozenblit <drozenblit@fb.com>
Thu, 12 Jan 2023 21:41:50 +0000 (13:41 -0800)
lib/compress/zstd_compress.c
lib/zstd.h
tests/zstreamtest.c

index 6872d3364b197930fbccd43aff2f3483bd958000..2ff1fa2097f1557fd6eb2e71ebd9e811c924edfa 100644 (file)
@@ -983,7 +983,8 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
         return CCtxParams->enableMatchFinderFallback;
 
     case ZSTD_c_maxBlockSize:
-        BOUNDCHECK(ZSTD_c_maxBlockSize, value);
+        if (value!=0)    /* 0 ==> default */
+            BOUNDCHECK(ZSTD_c_maxBlockSize, value);
         CCtxParams->maxBlockSize = value;
         return CCtxParams->maxBlockSize;
 
index 0c0fc1afc919d5e4ef3df3260c43d61d7e92c205..9d1d507ffcb8e1f5b66215a01d2d1807e4b3294b 100644 (file)
@@ -2071,8 +2071,13 @@ ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const vo
 #define ZSTD_c_enableMatchFinderFallback ZSTD_c_experimentalParam17
 
 /*  ZSTD_c_maxBlockSize
+ *  Allowed values are between 1KB and ZSTD_BLOCKSIZE_MAX (128KB).
+ *  The default is ZSTD_BLOCKSIZE_MAX, and setting to 0 will set to the default.
  *
- *  Default is ZSTD_BLOCKSIZE_MAX.
+ *  This parameter can be used to set an upper bound on the blocksize
+ *  that overrides the default ZSTD_BLOCKSIZE_MAX. It cannot be used to set upper
+ *  bounds greater than ZSTD_BLOCKSIZE_MAX or bounds lower than 1KB (will make
+ *  compressBound() innacurate). Only currently meant to be used for testing.
  *
  */
 #define ZSTD_c_maxBlockSize ZSTD_c_experimentalParam18
index bd829fbb1ca54b75f96a61865d72d7bc7f9e4362..3b8512310e917ccb24c99798b10fb8ba46371546 100644 (file)
@@ -1930,41 +1930,97 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests)
     DISPLAYLEVEL(3, "test%3i : Testing maxBlockSize PR#3418: ", testNb++);
     {
         ZSTD_CCtx* cctx = ZSTD_createCCtx();
-        size_t const srcSize = 2 << 10;
-        void* const src = CNBuffer;
-        size_t const dstSize = ZSTD_compressBound(srcSize);
-        void* const dst1 = compressedBuffer;
-        void* const dst2 = (BYTE*)compressedBuffer + dstSize;
-        size_t size1, size2;
-        void* const checkBuf = malloc(srcSize);
-
-        memset(src, 'x', srcSize);
 
         /* Quick test to make sure maxBlockSize bounds are enforced */
         assert(ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, ZSTD_BLOCKSIZE_MAX_MIN - 1)));
         assert(ZSTD_isError(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, ZSTD_BLOCKSIZE_MAX + 1)));
 
-        /* maxBlockSize = 1KB */
-        CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 1 << 10));
-        size1 = ZSTD_compress2(cctx, dst1, dstSize, src, srcSize);
+        /* Test maxBlockSize < windowSize and windowSize < maxBlockSize*/
+        {
+            size_t srcSize = 2 << 10;
+            void* const src = CNBuffer;
+            size_t dstSize = ZSTD_compressBound(srcSize);
+            void* const dst1 = compressedBuffer;
+            void* const dst2 = (BYTE*)compressedBuffer + dstSize;
+            size_t size1, size2;
+            void* const checkBuf = malloc(srcSize);
+            memset(src, 'x', srcSize);
+
+            /* maxBlockSize = 1KB */
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 1u << 10));
+            size1 = ZSTD_compress2(cctx, dst1, dstSize, src, srcSize);
+
+            if (ZSTD_isError(size1)) goto _output_error;
+            CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst1, size1));
+            CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+
+            /* maxBlockSize = 3KB */
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 3u << 10));
+            size2 = ZSTD_compress2(cctx, dst2, dstSize, src, srcSize);
+
+            if (ZSTD_isError(size2)) goto _output_error;
+            CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst2, size2));
+            CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+
+            assert(size1 - size2 == 4); /* We add another RLE block with header + character */
+            assert(memcmp(dst1, dst2, size2) != 0); /* Compressed output should not be equal */
+
+            /* maxBlockSize = 1KB, windowLog = 10 */
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 1u << 10));
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 10));
+            size1 = ZSTD_compress2(cctx, dst1, dstSize, src, srcSize);
+
+            if (ZSTD_isError(size1)) goto _output_error;
+            CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst1, size1));
+            CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+
+            /* maxBlockSize = 3KB, windowLog = 10 */
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 3u << 10));
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, 10));
+            size2 = ZSTD_compress2(cctx, dst2, dstSize, src, srcSize);
+
+            if (ZSTD_isError(size2)) goto _output_error;
+            CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst2, size2));
+            CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+
+            assert(size1 == size2);
+            assert(memcmp(dst1, dst2, size1) == 0); /* Compressed output should be equal */
+
+            free(checkBuf);
+        }
+
+        ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters);
 
-        if (ZSTD_isError(size1)) goto _output_error;
-        CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst1, size1));
-        CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+        /* Test maxBlockSize = 0 is valid */
+        {   size_t srcSize = 256 << 10;
+            void* const src = CNBuffer;
+            size_t dstSize = ZSTD_compressBound(srcSize);
+            void* const dst1 = compressedBuffer;
+            void* const dst2 = (BYTE*)compressedBuffer + dstSize;
+            size_t size1, size2;
+            void* const checkBuf = malloc(srcSize);
 
-        /* maxBlockSize = 3KB */
-        CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 3 << 10));
-        size2 = ZSTD_compress2(cctx, dst2, dstSize, src, srcSize);
+            /* maxBlockSize = 0 */
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, 0));
+            size1 = ZSTD_compress2(cctx, dst1, dstSize, src, srcSize);
 
-        if (ZSTD_isError(size2)) goto _output_error;
-        CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst2, size2));
-        CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+            if (ZSTD_isError(size1)) goto _output_error;
+            CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst1, size1));
+            CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
 
-        /* Compressed output should not be equal */
-        assert(memcmp(dst1, dst2, dstSize) != 0);
-        assert(size1 - size2 == 4); /* We add another RLE block with header + character */
+            /* maxBlockSize = ZSTD_BLOCKSIZE_MAX */
+            CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_maxBlockSize, ZSTD_BLOCKSIZE_MAX));
+            size2 = ZSTD_compress2(cctx, dst2, dstSize, src, srcSize);
+
+            if (ZSTD_isError(size2)) goto _output_error;
+            CHECK_Z(ZSTD_decompress(checkBuf, srcSize, dst2, size2));
+            CHECK(memcmp(src, checkBuf, srcSize) != 0, "Corruption!");
+
+            assert(size1 == size2);
+            assert(memcmp(dst1, dst2, size1) == 0); /* Compressed output should be equal */
+            free(checkBuf);
+        }
         ZSTD_freeCCtx(cctx);
-        free(checkBuf);
     }
     DISPLAYLEVEL(3, "OK \n");