From 91c9a247b67374b74753a7d3dcc8999db710b139 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 13 May 2021 15:44:12 -0700 Subject: [PATCH 001/274] [lib] Fix determinism bug in the optimal parser `ZSTD_insertBt1()` has a speed optimization that skips the prefix of very long matches. https://github.com/facebook/zstd/blob/40def70387f99b239f3f566ba399275a8fd44cde/lib/compress/zstd_opt.c#L476 This optimization is based off the length longest match found. However, when indices are reset, we only ensure that we can reference the whole window starting from `ip`. If the previous block ended with a long match then `nextToUpdate` could be much less than `ip`. It might be far enough back that `nextToUpdate < maxDist`, so it doesn't have a full window of data to reference. This can cause non-determinism bugs, because we may find a match that is beyond `ip - maxDist`, and may sometimes be un-referencable, and that match triggers the speed optimization. The fix is to base the `windowLow` off of the `target` of `ZSTD_updateTree_internal()`, because anything below that value will be obsolete by the time `ZSTD_updateTree_internal()` completes. --- lib/compress/zstd_opt.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 402a7e5c7..a880fadad 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -364,11 +364,13 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, * Binary Tree search ***************************************/ /** ZSTD_insertBt1() : add one or multiple positions to tree. - * ip : assumed <= iend-8 . + * @param ip assumed <= iend-8 . + * @param target The target of ZSTD_updateTree_internal() - we are filling to this position * @return : nb of positions added */ static U32 ZSTD_insertBt1( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, + U32 const target, U32 const mls, const int extDict) { const ZSTD_compressionParameters* const cParams = &ms->cParams; @@ -391,7 +393,10 @@ static U32 ZSTD_insertBt1( U32* smallerPtr = bt + 2*(curr&btMask); U32* largerPtr = smallerPtr + 1; U32 dummy32; /* to be nullified at the end */ - U32 const windowLow = ms->window.lowLimit; + /* windowLow is based on target because we're only need positions that will be + * in the window at the end of the tree update. + */ + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog); U32 matchEndIdx = curr+8+1; size_t bestLength = 8; U32 nbCompares = 1U << cParams->searchLog; @@ -404,6 +409,7 @@ static U32 ZSTD_insertBt1( DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr); + assert(curr <= target); assert(ip <= iend-8); /* required for h calculation */ hashTable[h] = curr; /* Update Hash Table */ @@ -492,7 +498,7 @@ void ZSTD_updateTree_internal( idx, target, dictMode); while(idx < target) { - U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict); + U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict); assert(idx < (U32)(idx + forward)); idx += forward; } @@ -893,7 +899,7 @@ static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_ */ U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock; ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot); - } + } ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes); } ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock); From 10b35b312b0280674c02b9c9227e2fff766410a9 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 13 May 2021 15:51:15 -0700 Subject: [PATCH 002/274] [lib] Fix off-by-one error in repcode checks The repcode checks disallowed repcodes that are equal to `windowLow`. This is slightly inefficient, but isn't a problem on its own. Together with the next commit, it cause non-determinism. --- lib/compress/zstd_double_fast.c | 4 ++-- lib/compress/zstd_fast.c | 4 ++-- lib/compress/zstd_lazy.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index d0d3a784d..b9e3c5e9f 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -409,7 +409,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */ - & (offset_1 < curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */ + & (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4; @@ -477,7 +477,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( U32 const repIndex2 = current2 - offset_2; const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */ - & (offset_2 < current2 - dictStartIndex)) + & (offset_2 <= current2 - dictStartIndex)) && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 4edc04dcc..b6a1a7e69 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -418,7 +418,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr); if ( ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ - & (offset_1 < curr+1 - dictStartIndex) ) /* note: we are searching at curr+1 */ + & (offset_1 <= curr+1 - dictStartIndex) ) /* note: we are searching at curr+1 */ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4; @@ -453,7 +453,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( U32 const current2 = (U32)(ip-base); U32 const repIndex2 = current2 - offset_2; const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; - if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 < curr - dictStartIndex)) /* intentional overflow */ + if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 <= curr - dictStartIndex)) /* intentional overflow */ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 3d523e847..0c4b49e4d 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1995,7 +1995,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - & (offset_1 < curr+1 - windowLow) ) /* note: we are searching at curr+1 */ + & (offset_1 <= curr+1 - windowLow) ) /* note: we are searching at curr+1 */ if (MEM_read32(ip+1) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; @@ -2027,7 +2027,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */ - & (offset_1 < curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ + & (offset_1 <= curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; @@ -2059,7 +2059,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */ - & (offset_1 < curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ + & (offset_1 <= curr - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; @@ -2106,7 +2106,7 @@ _storeSequence: const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ( ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow : do not test positions overlapping 2 memory segments */ - & (offset_2 < repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ + & (offset_2 <= repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; From 03c411129909eac5386b294b058a3f4c1f633315 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 13 May 2021 16:13:29 -0700 Subject: [PATCH 003/274] [lib] Fix dictionary invalidation logic Call `ZSTD_enforceMaxDist()` before each block with the beginning of the block. This ensures that `lowLimit` is updated to `dictLimit` whenever the ext-dict is out of range, so we can use prefix mode for speed. This can cause non-determinism because prefix mode and ext-dict mode match finders can return different results. It can also hurt speed because ext-dict match finders are slower. The scenario is: 1. Compress large data with a dictionary. 2. The dictionary goes out of bounds, so we invalidate it. 3. However, we still have `lowLimit < dictLimit`, since it is never updated. 4. We will call the ext-dict match finder instead of the prefix one. --- lib/compress/zstd_compress.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b7ee2980a..fbf67af8e 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3915,6 +3915,7 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, ZSTD_overflowCorrectIfNeeded( ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize); ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + ZSTD_window_enforceMaxDist(&ms->window, ip, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); /* Ensure hash/chain table insertion resumes no sooner than lowlimit */ if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; From 725c5e4e381966e2349712ed5f673c157fcbe27b Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 13 May 2021 16:16:47 -0700 Subject: [PATCH 004/274] [fuzz] Add determinism fuzzing to simple & dictionary round trip Compress the input twice in the `simple_round_trip` and `dictionary_round_trip` fuzzers with exactly the same parameters, but reusing the context. Then ensure that the compressed output is identical. --- tests/fuzz/dictionary_round_trip.c | 34 ++++++++++++++++++++++++++++-- tests/fuzz/fuzz_data_producer.c | 6 ++++++ tests/fuzz/fuzz_data_producer.h | 3 +++ tests/fuzz/simple_round_trip.c | 26 ++++++++++++++++++++--- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/tests/fuzz/dictionary_round_trip.c b/tests/fuzz/dictionary_round_trip.c index 7bff4bd6c..0b20e8d67 100644 --- a/tests/fuzz/dictionary_round_trip.c +++ b/tests/fuzz/dictionary_round_trip.c @@ -42,8 +42,23 @@ static size_t roundTripTest(void *result, size_t resultCapacity, src, srcSize, dict.buff, dict.size, cLevel); + FUZZ_ZASSERT(cSize); + // Compress a second time and check for determinism + { + size_t const cSize0 = cSize; + XXH64_hash_t const hash0 = XXH64(compressed, cSize, 0); + cSize = ZSTD_compress_usingDict(cctx, + compressed, compressedCapacity, + src, srcSize, + dict.buff, dict.size, + cLevel); + FUZZ_ASSERT(cSize == cSize0); + FUZZ_ASSERT(XXH64(compressed, cSize, 0) == hash0); + } } else { + size_t remainingBytes; dictContentType = FUZZ_dataProducer_uint32Range(producer, 0, 2); + remainingBytes = FUZZ_dataProducer_remainingBytes(producer); FUZZ_setRandomParameters(cctx, srcSize, producer); /* Disable checksum so we can use sizes smaller than compress bound. */ FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0)); @@ -51,14 +66,29 @@ static size_t roundTripTest(void *result, size_t resultCapacity, FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced( cctx, dict.buff, dict.size, dictContentType)); - else + else FUZZ_ZASSERT(ZSTD_CCtx_loadDictionary_advanced( cctx, dict.buff, dict.size, (ZSTD_dictLoadMethod_e)FUZZ_dataProducer_uint32Range(producer, 0, 1), dictContentType)); cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize); + FUZZ_ZASSERT(cSize); + // Compress a second time and check for determinism + { + size_t const cSize0 = cSize; + XXH64_hash_t const hash0 = XXH64(compressed, cSize, 0); + FUZZ_dataProducer_rollBack(producer, remainingBytes); + FUZZ_setRandomParameters(cctx, srcSize, producer); + FUZZ_ZASSERT(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0)); + if (refPrefix) + FUZZ_ZASSERT(ZSTD_CCtx_refPrefix_advanced( + cctx, dict.buff, dict.size, + dictContentType)); + cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize); + FUZZ_ASSERT(cSize == cSize0); + FUZZ_ASSERT(XXH64(compressed, cSize, 0) == hash0); + } } - FUZZ_ZASSERT(cSize); if (refPrefix) FUZZ_ZASSERT(ZSTD_DCtx_refPrefix_advanced( dctx, dict.buff, dict.size, diff --git a/tests/fuzz/fuzz_data_producer.c b/tests/fuzz/fuzz_data_producer.c index beb0155cf..eae8ee4b6 100644 --- a/tests/fuzz/fuzz_data_producer.c +++ b/tests/fuzz/fuzz_data_producer.c @@ -66,6 +66,12 @@ size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer){ return producer->size; } +void FUZZ_dataProducer_rollBack(FUZZ_dataProducer_t *producer, size_t remainingBytes) +{ + FUZZ_ASSERT(remainingBytes >= producer->size); + producer->size = remainingBytes; +} + int FUZZ_dataProducer_empty(FUZZ_dataProducer_t *producer) { return producer->size == 0; } diff --git a/tests/fuzz/fuzz_data_producer.h b/tests/fuzz/fuzz_data_producer.h index 045aaff83..62771a9f8 100644 --- a/tests/fuzz/fuzz_data_producer.h +++ b/tests/fuzz/fuzz_data_producer.h @@ -49,6 +49,9 @@ int32_t FUZZ_dataProducer_int32Range(FUZZ_dataProducer_t *producer, /* Returns the size of the remaining bytes of data in the producer */ size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer); +/* Rolls back the data producer state to have remainingBytes remaining */ +void FUZZ_dataProducer_rollBack(FUZZ_dataProducer_t *producer, size_t remainingBytes); + /* Returns true if the data producer is out of bytes */ int FUZZ_dataProducer_empty(FUZZ_dataProducer_t *producer); diff --git a/tests/fuzz/simple_round_trip.c b/tests/fuzz/simple_round_trip.c index c9fac26c5..9da986bc9 100644 --- a/tests/fuzz/simple_round_trip.c +++ b/tests/fuzz/simple_round_trip.c @@ -35,16 +35,36 @@ static size_t roundTripTest(void *result, size_t resultCapacity, size_t dSize; int targetCBlockSize = 0; if (FUZZ_dataProducer_uint32Range(producer, 0, 1)) { + size_t const remainingBytes = FUZZ_dataProducer_remainingBytes(producer); FUZZ_setRandomParameters(cctx, srcSize, producer); cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize); + FUZZ_ZASSERT(cSize); FUZZ_ZASSERT(ZSTD_CCtx_getParameter(cctx, ZSTD_c_targetCBlockSize, &targetCBlockSize)); + // Compress a second time and check for determinism + { + size_t const cSize0 = cSize; + XXH64_hash_t const hash0 = XXH64(compressed, cSize, 0); + FUZZ_dataProducer_rollBack(producer, remainingBytes); + FUZZ_setRandomParameters(cctx, srcSize, producer); + cSize = ZSTD_compress2(cctx, compressed, compressedCapacity, src, srcSize); + FUZZ_ASSERT(cSize == cSize0); + FUZZ_ASSERT(XXH64(compressed, cSize, 0) == hash0); + } } else { - int const cLevel = FUZZ_dataProducer_int32Range(producer, kMinClevel, kMaxClevel); - + int const cLevel = FUZZ_dataProducer_int32Range(producer, kMinClevel, kMaxClevel); cSize = ZSTD_compressCCtx( cctx, compressed, compressedCapacity, src, srcSize, cLevel); + FUZZ_ZASSERT(cSize); + // Compress a second time and check for determinism + { + size_t const cSize0 = cSize; + XXH64_hash_t const hash0 = XXH64(compressed, cSize, 0); + cSize = ZSTD_compressCCtx( + cctx, compressed, compressedCapacity, src, srcSize, cLevel); + FUZZ_ASSERT(cSize == cSize0); + FUZZ_ASSERT(XXH64(compressed, cSize, 0) == hash0); + } } - FUZZ_ZASSERT(cSize); dSize = ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize); FUZZ_ZASSERT(dSize); /* When superblock is enabled make sure we don't expand the block more than expected. From 51708b2c621bc74223feb21f5cdc6c3c59221cfe Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 14 May 2021 11:59:50 -0400 Subject: [PATCH 005/274] Fix CircleCI Config to Fully Remove `publish-github-release` Job --- .circleci/config.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c63473785..6a8c38642 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -99,16 +99,6 @@ workflows: branches: only: - regression - # Only run on release tags. - - publish-github-release: - requires: - - short-tests-0 - - short-tests-1 - filters: - branches: - ignore: /.*/ - tags: - only: /^v\d+\.\d+\.\d+$/ nightly: triggers: - schedule: From 25bda9053add6218a58d88c5b8119afa63165231 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 16:32:04 -0600 Subject: [PATCH 006/274] Add files via upload msvc suport avx2 path --- lib/compress/zstd_lazy.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 3d523e847..6df85e47c 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -873,7 +873,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ -#if !defined(ZSTD_NO_INTRINSICS) && defined(__SSE2__) /* SIMD SSE version */ +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) ||defined(__AVX__)) /* SIMD SSE version*/ #include typedef __m128i ZSTD_Vec128; @@ -894,7 +894,7 @@ static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)); } - +#if !defined(__AVX2__) typedef struct { __m128i fst; __m128i snd; @@ -921,6 +921,28 @@ static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); return fstMask | (sndMask << 16); } +#else//AVX2 +typedef struct { + __m256i v; +} ZSTD_Vec256; + +static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { + ZSTD_Vec256 v; + v.v = _mm256_load_si256((const __m256i*)ptr); + return v; +} + +static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { + ZSTD_Vec256 v; + v.v = _mm256_set1_epi32(val); + return v; +} + +static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { + return (ZSTD_VecMask)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x.v, y.v)); +} + +#endif #elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */ From 52f44bb365337054d30a8e0edf83dd7c612b4d32 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 16:33:07 -0600 Subject: [PATCH 007/274] Add files via upload msvc --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b7ee2980a..27a2798ad 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -222,7 +222,7 @@ static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_useR /* Returns row matchfinder usage enum given an initial mode and cParams */ static ZSTD_useRowMatchFinderMode_e ZSTD_resolveRowMatchFinderMode(ZSTD_useRowMatchFinderMode_e mode, const ZSTD_compressionParameters* const cParams) { -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(__ARM_NEON)) +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(__AVX__) || defined(__ARM_NEON)) int const kHasSIMD128 = 1; #else int const kHasSIMD128 = 0; From 77d54eb3b3116bf9606426730de818f33907aec3 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 16:40:32 -0600 Subject: [PATCH 008/274] Add files via upload --- lib/compress/zstd_compress.c | 2 +- lib/compress/zstd_lazy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 27a2798ad..584678f7a 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -222,7 +222,7 @@ static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_useR /* Returns row matchfinder usage enum given an initial mode and cParams */ static ZSTD_useRowMatchFinderMode_e ZSTD_resolveRowMatchFinderMode(ZSTD_useRowMatchFinderMode_e mode, const ZSTD_compressionParameters* const cParams) { -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(__AVX__) || defined(__ARM_NEON)) +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(_M_AMD64) || defined(__ARM_NEON)) int const kHasSIMD128 = 1; #else int const kHasSIMD128 = 0; diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 6df85e47c..50861891c 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -873,7 +873,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) ||defined(__AVX__)) /* SIMD SSE version*/ +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) ||defined(_M_AMD64)) /* SIMD SSE version*/ #include typedef __m128i ZSTD_Vec128; From 7012c6e7a4dbedad5b6a949a49ce941adc5e8df8 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sat, 15 May 2021 00:40:49 +0200 Subject: [PATCH 009/274] Initialize "potentially uninitialized" pointers. --- lib/compress/zstd_lazy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 3d523e847..0769fe82c 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1296,8 +1296,8 @@ size_t ZSTD_RowFindBestMatch_generic ( size_t ddsIdx; U32 ddsExtraAttempts; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ U32 dmsTag; - U32* dmsRow; - BYTE* dmsTagRow; + U32* dmsRow = NULL; + BYTE* dmsTagRow = NULL; if (dictMode == ZSTD_dedicatedDictSearch) { const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; From 0b9f4bb0ff1f313bea9e9166f693ec64a3a6a43e Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 16:47:24 -0600 Subject: [PATCH 010/274] Update zstd_lazy.c use 8bit --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 50861891c..e445d5a6d 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -934,7 +934,7 @@ static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { ZSTD_Vec256 v; - v.v = _mm256_set1_epi32(val); + v.v = _mm256_set1_epi8(val); return v; } From 69ac124b1209ccf12c8c5969f0d7a2124ccbe554 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 16:53:19 -0600 Subject: [PATCH 011/274] Update zstd_lazy.c --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index e445d5a6d..bccf2cc11 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -934,7 +934,7 @@ static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { ZSTD_Vec256 v; - v.v = _mm256_set1_epi8(val); + v.v = _mm256_set1_epi8((char)val); return v; } From 0e071214b5721f3415611d07d33469f8026c3bb0 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 17:03:30 -0600 Subject: [PATCH 012/274] Update zstd_lazy.c switch to unaligned load as I don't know if buffer will always be aligned to 32 bytes, and compilers aside from MSVC might actually use aligned loads --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index bccf2cc11..008b0a6b4 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -928,7 +928,7 @@ typedef struct { static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { ZSTD_Vec256 v; - v.v = _mm256_load_si256((const __m256i*)ptr); + v.v = _mm256_loadu_si256((const __m256i*)ptr); return v; } From 8f7ea1afeba1f3762e99413424df95b9faf4d2d8 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 19:02:34 -0600 Subject: [PATCH 013/274] Update zstd_lazy.c Switch to other comment style --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 008b0a6b4..cbe2adae1 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -921,7 +921,7 @@ static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); return fstMask | (sndMask << 16); } -#else//AVX2 +#else/* AVX2 */ typedef struct { __m256i v; } ZSTD_Vec256; From a62856bf65f381eb2f99d056005b4b39cb7c8725 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 19:10:24 -0600 Subject: [PATCH 014/274] Update zstd_lazy.c Remove the AVX2 part --- lib/compress/zstd_lazy.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index cbe2adae1..1add42095 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -894,7 +894,7 @@ static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)); } -#if !defined(__AVX2__) + typedef struct { __m128i fst; __m128i snd; @@ -921,28 +921,6 @@ static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); return fstMask | (sndMask << 16); } -#else/* AVX2 */ -typedef struct { - __m256i v; -} ZSTD_Vec256; - -static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { - ZSTD_Vec256 v; - v.v = _mm256_loadu_si256((const __m256i*)ptr); - return v; -} - -static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { - ZSTD_Vec256 v; - v.v = _mm256_set1_epi8((char)val); - return v; -} - -static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { - return (ZSTD_VecMask)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x.v, y.v)); -} - -#endif #elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */ From bb1cdd8c63046e66de63cf76448868bbc1dc6b72 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 19:11:28 -0600 Subject: [PATCH 015/274] Update zstd_lazy.c add space --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 1add42095..1f2208313 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -873,7 +873,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) ||defined(_M_AMD64)) /* SIMD SSE version*/ +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(_M_AMD64)) /* SIMD SSE version*/ #include typedef __m128i ZSTD_Vec128; From d688ab1e0cfcbe5a894f07bab4033978d99bebd3 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 19:18:12 -0600 Subject: [PATCH 016/274] Add files via upload AVX2 --- lib/compress/zstd_lazy.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 1f2208313..296814624 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -873,7 +873,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(_M_AMD64)) /* SIMD SSE version*/ +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) ||defined(_M_AMD64)) /* SIMD SSE version*/ #include typedef __m128i ZSTD_Vec128; @@ -894,7 +894,7 @@ static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)); } - +#if !defined(__AVX2__) typedef struct { __m128i fst; __m128i snd; @@ -921,6 +921,27 @@ static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); return fstMask | (sndMask << 16); } +#else/* AVX2 */ +typedef struct { + __m256i v; +} ZSTD_Vec256; + +static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { + ZSTD_Vec256 v; + v.v = _mm256_loadu_si256((const __m256i*)ptr); + return v; +} + +static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { + ZSTD_Vec256 v; + v.v = _mm256_set1_epi8((char)val); + return v; +} + +static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { + return (ZSTD_VecMask)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x.v, y.v)); +} +#endif #elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */ From bee0ef56475eb567b7c801812a1a5f8215b4ffd9 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 19:23:13 -0600 Subject: [PATCH 017/274] Update zstd_lazy.c It put the changes back when I tried to make a separate pull request, i don't understand githubs interface at all. --- lib/compress/zstd_lazy.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 296814624..1f2208313 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -873,7 +873,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) ||defined(_M_AMD64)) /* SIMD SSE version*/ +#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(_M_AMD64)) /* SIMD SSE version*/ #include typedef __m128i ZSTD_Vec128; @@ -894,7 +894,7 @@ static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)); } -#if !defined(__AVX2__) + typedef struct { __m128i fst; __m128i snd; @@ -921,27 +921,6 @@ static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); return fstMask | (sndMask << 16); } -#else/* AVX2 */ -typedef struct { - __m256i v; -} ZSTD_Vec256; - -static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { - ZSTD_Vec256 v; - v.v = _mm256_loadu_si256((const __m256i*)ptr); - return v; -} - -static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { - ZSTD_Vec256 v; - v.v = _mm256_set1_epi8((char)val); - return v; -} - -static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { - return (ZSTD_VecMask)_mm256_movemask_epi8(_mm256_cmpeq_epi8(x.v, y.v)); -} -#endif #elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */ From 7e429f62ba8643960d58589568d9b4ea1144ca03 Mon Sep 17 00:00:00 2001 From: heitbaum Date: Sat, 15 May 2021 15:04:02 +1000 Subject: [PATCH 018/274] [trace] remove zstd_trace.c reference from freestanding zstd_trace.c was removed as part of PR #2589 --- contrib/freestanding_lib/freestanding.py | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/freestanding_lib/freestanding.py b/contrib/freestanding_lib/freestanding.py index 197168721..a191f592f 100755 --- a/contrib/freestanding_lib/freestanding.py +++ b/contrib/freestanding_lib/freestanding.py @@ -27,7 +27,6 @@ SKIPPED_FILES = [ "common/pool.h", "common/threading.c", "common/threading.h", - "common/zstd_trace.c", "common/zstd_trace.h", "compress/zstdmt_compress.h", "compress/zstdmt_compress.c", From 54f78e3df8b6029e00ec5627d940a6dd1a80d71a Mon Sep 17 00:00:00 2001 From: Dan Nelson Date: Sat, 15 May 2021 10:20:37 -0500 Subject: [PATCH 019/274] ZSTD_VecMask_next: fix incorrect variable name in fallback code path --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 0c4b49e4d..fea4686f0 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1081,7 +1081,7 @@ static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; - return multiplyDeBruijnBitPosition[((U32)((v & -(int)v) * 0x077CB531U)) >> 27]; + return multiplyDeBruijnBitPosition[((U32)((val & -(int)val) * 0x077CB531U)) >> 27]; # endif } From 0b0b62d1cf5ceb0c1bd5c1e93807f834a9399365 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 15 May 2021 23:04:46 -0700 Subject: [PATCH 020/274] minor mention of RFC8878 more recent update --- doc/zstd_compression_format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zstd_compression_format.md b/doc/zstd_compression_format.md index 5c7deb9c4..bb244d437 100644 --- a/doc/zstd_compression_format.md +++ b/doc/zstd_compression_format.md @@ -1669,7 +1669,7 @@ or at least provide a meaningful error code explaining for which reason it canno Version changes --------------- -- 0.3.7 : clarifications for Repeat_Offsets +- 0.3.7 : clarifications for Repeat_Offsets, matching RFC8878 - 0.3.6 : clarifications for Dictionary_ID - 0.3.5 : clarifications for Block_Maximum_Size - 0.3.4 : clarifications for FSE decoding table From 61afa154cdd987de525c6f717a872e31af79b1a8 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 15 May 2021 23:09:42 -0700 Subject: [PATCH 021/274] improve tar compatibility This patch is supposed to improve compatibility with less featured tar variants "when the tar program used does not support historical options (without hyphen) nor the '-z' option." Patch proposed by Antonio Diaz Diaz --- tests/playTests.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index fa748c0cf..f57f61f3d 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1285,7 +1285,7 @@ println "\n===> tar extension tests " rm -f tmp tmp.tar tmp.tzst tmp.tgz tmp.txz tmp.tlz4 tmp1.zstd datagen > tmp -tar cf tmp.tar tmp +tar -cf tmp.tar tmp zstd tmp.tar -o tmp.tzst rm -f tmp.tar zstd -d tmp.tzst @@ -1293,21 +1293,21 @@ zstd -d tmp.tzst rm -f tmp.tar tmp.tzst if [ $GZIPMODE -eq 1 ]; then - tar czf tmp.tgz tmp + tar -c tmp | gzip > tmp.tgz zstd -d tmp.tgz [ -e tmp.tar ] || die ".tgz failed to decompress to .tar!" rm -f tmp.tar tmp.tgz fi if [ $LZMAMODE -eq 1 ]; then - tar c tmp | zstd --format=xz > tmp.txz + tar -c tmp | zstd --format=xz > tmp.txz zstd -d tmp.txz [ -e tmp.tar ] || die ".txz failed to decompress to .tar!" rm -f tmp.tar tmp.txz fi if [ $LZ4MODE -eq 1 ]; then - tar c tmp | zstd --format=lz4 > tmp.tlz4 + tar -c tmp | zstd --format=lz4 > tmp.tlz4 zstd -d tmp.tlz4 [ -e tmp.tar ] || die ".tlz4 failed to decompress to .tar!" rm -f tmp.tar tmp.tlz4 From 38ffe9658ea831cdf71f95a999916fa1d5f9b844 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 17 May 2021 13:04:55 -0400 Subject: [PATCH 022/274] [ci] Use *-latest for platforms to test on --- .github/workflows/generic-release.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/generic-release.yml b/.github/workflows/generic-release.yml index cb91fb255..1e47bba4d 100644 --- a/.github/workflows/generic-release.yml +++ b/.github/workflows/generic-release.yml @@ -17,7 +17,7 @@ jobs: # meson test osx: - runs-on: macos-10.15 + runs-on: macos-latest steps: - uses: actions/checkout@v2 - name: OS-X @@ -35,7 +35,7 @@ jobs: CC=clang make tsan-fuzztest zlib-wrapper: - runs-on: ubuntu-16.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: zlib wrapper test @@ -45,7 +45,7 @@ jobs: make -C zlibWrapper valgrindTest lz4-threadpool-partial-libs: - runs-on: ubuntu-16.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: LZ4, thread pool, and partial libs testslib wrapper test From 5a75417d2bb01d682fcc912c91d5ddf43906708b Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 17 May 2021 12:54:34 -0400 Subject: [PATCH 023/274] [ci] Add ARM tests back into CI --- .github/workflows/generic-dev.yml | 34 +++++++++++++++---------------- .travis.yml | 5 ----- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/.github/workflows/generic-dev.yml b/.github/workflows/generic-dev.yml index ae4ee7e9f..8f20f15b5 100644 --- a/.github/workflows/generic-dev.yml +++ b/.github/workflows/generic-dev.yml @@ -171,25 +171,23 @@ jobs: sudo apt-get install gcc-mingw-w64 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ CFLAGS="-Werror -O1" make zstd -# TODO: Broken test - fix and uncomment -# armbuild: -# runs-on: ubuntu-16.04 # doesn't work on latest -# steps: -# - uses: actions/checkout@v2 -# - name: ARM Build Test -# run: | -# make arminstall -# make armbuild + armbuild: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: ARM Build Test + run: | + make arminstall + make armbuild -# TODO: Broken test - fix and uncomment -# armfuzz: -# runs-on: ubuntu-16.04 # doesn't work on latest -# steps: -# - uses: actions/checkout@v2 -# - name: Qemu ARM emulation + Fuzz Test -# run: | -# make arminstall -# make armfuzz + armfuzz: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Qemu ARM emulation + Fuzz Test + run: | + make arminstall + make armfuzz bourne-shell: runs-on: ubuntu-latest diff --git a/.travis.yml b/.travis.yml index b0e70486d..16d1d4281 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,11 +55,6 @@ matrix: - make clean - make -C tests test-fuzzer-stackmode - - name: Qemu ARM emulation + Fuzz Test # ~13.5mn - script: - - make arminstall - - make armfuzz - # Introduced to check compat with old toolchains, to prevent e.g. #1872 - name: ARM Build Test (on Trusty) dist: trusty From c468e1b9cbca448e26883c7e88daf2798e71d685 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 18 May 2021 19:46:37 -0700 Subject: [PATCH 024/274] [test][regression] Update results.csv Changing the repcode search slightly, and changing when zstd is in ext-dict vs. prefix mode in edge cases, slightly changes the compressed results. --- tests/regression/results.csv | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index b94d5501e..1ed896dcd 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -11,10 +11,10 @@ silesia.tar, level 6, compress silesia.tar, level 7, compress simple, 4613541 silesia.tar, level 9, compress simple, 4555426 silesia.tar, level 13, compress simple, 4491764 -silesia.tar, level 16, compress simple, 4381332 -silesia.tar, level 19, compress simple, 4281605 +silesia.tar, level 16, compress simple, 4381350 +silesia.tar, level 19, compress simple, 4281562 silesia.tar, uncompressed literals, compress simple, 4861425 -silesia.tar, uncompressed literals optimal, compress simple, 4281605 +silesia.tar, uncompressed literals optimal, compress simple, 4281562 silesia.tar, huffman literals, compress simple, 6186042 github.tar, level -5, compress simple, 46856 github.tar, level -3, compress simple, 43754 @@ -134,8 +134,8 @@ silesia.tar, level 6, zstdcli, silesia.tar, level 7, zstdcli, 4614424 silesia.tar, level 9, zstdcli, 4556062 silesia.tar, level 13, zstdcli, 4491768 -silesia.tar, level 16, zstdcli, 4356831 -silesia.tar, level 19, zstdcli, 4264491 +silesia.tar, level 16, zstdcli, 4356838 +silesia.tar, level 19, zstdcli, 4264396 silesia.tar, no source size, zstdcli, 4861508 silesia.tar, long distance mode, zstdcli, 4853226 silesia.tar, multithreaded, zstdcli, 4861512 @@ -145,7 +145,7 @@ silesia.tar, small hash log, zstdcli, silesia.tar, small chain log, zstdcli, 4917022 silesia.tar, explicit params, zstdcli, 4821274 silesia.tar, uncompressed literals, zstdcli, 5129559 -silesia.tar, uncompressed literals optimal, zstdcli, 4307457 +silesia.tar, uncompressed literals optimal, zstdcli, 4307404 silesia.tar, huffman literals, zstdcli, 5347610 silesia.tar, multithreaded with advanced params, zstdcli, 5129559 github, level -5, zstdcli, 207285 @@ -278,8 +278,8 @@ silesia.tar, level 9, advanced silesia.tar, level 12 row 1, advanced one pass, 4529459 silesia.tar, level 12 row 2, advanced one pass, 4530256 silesia.tar, level 13, advanced one pass, 4491764 -silesia.tar, level 16, advanced one pass, 4356827 -silesia.tar, level 19, advanced one pass, 4264487 +silesia.tar, level 16, advanced one pass, 4356834 +silesia.tar, level 19, advanced one pass, 4264392 silesia.tar, no source size, advanced one pass, 4861425 silesia.tar, long distance mode, advanced one pass, 4847754 silesia.tar, multithreaded, advanced one pass, 4861508 @@ -289,7 +289,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced one pass, 4917041 silesia.tar, explicit params, advanced one pass, 4807380 silesia.tar, uncompressed literals, advanced one pass, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass, 4307453 +silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 silesia.tar, huffman literals, advanced one pass, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 github, level -5, advanced one pass, 205285 @@ -572,8 +572,8 @@ silesia.tar, level 9, advanced silesia.tar, level 12 row 1, advanced one pass small out, 4529459 silesia.tar, level 12 row 2, advanced one pass small out, 4530256 silesia.tar, level 13, advanced one pass small out, 4491764 -silesia.tar, level 16, advanced one pass small out, 4356827 -silesia.tar, level 19, advanced one pass small out, 4264487 +silesia.tar, level 16, advanced one pass small out, 4356834 +silesia.tar, level 19, advanced one pass small out, 4264392 silesia.tar, no source size, advanced one pass small out, 4861425 silesia.tar, long distance mode, advanced one pass small out, 4847754 silesia.tar, multithreaded, advanced one pass small out, 4861508 @@ -583,7 +583,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced one pass small out, 4917041 silesia.tar, explicit params, advanced one pass small out, 4807380 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307453 +silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 silesia.tar, huffman literals, advanced one pass small out, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 github, level -5, advanced one pass small out, 205285 @@ -843,7 +843,7 @@ silesia, multithreaded long distance mode, advanced silesia, small window log, advanced streaming, 7112062 silesia, small hash log, advanced streaming, 6526141 silesia, small chain log, advanced streaming, 4912197 -silesia, explicit params, advanced streaming, 4795887 +silesia, explicit params, advanced streaming, 4795884 silesia, uncompressed literals, advanced streaming, 5127982 silesia, uncompressed literals optimal, advanced streaming, 4317896 silesia, huffman literals, advanced streaming, 5331168 @@ -875,7 +875,7 @@ silesia.tar, multithreaded long distance mode, advanced silesia.tar, small window log, advanced streaming, 7118769 silesia.tar, small hash log, advanced streaming, 6529235 silesia.tar, small chain log, advanced streaming, 4917021 -silesia.tar, explicit params, advanced streaming, 4807401 +silesia.tar, explicit params, advanced streaming, 4807399 silesia.tar, uncompressed literals, advanced streaming, 5129461 silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 silesia.tar, huffman literals, advanced streaming, 5352360 @@ -1233,7 +1233,7 @@ silesia, multithreaded long distance mode, old stre silesia, small window log, old streaming advanced, 7112062 silesia, small hash log, old streaming advanced, 6526141 silesia, small chain log, old streaming advanced, 4912197 -silesia, explicit params, old streaming advanced, 4795887 +silesia, explicit params, old streaming advanced, 4795884 silesia, uncompressed literals, old streaming advanced, 4849552 silesia, uncompressed literals optimal, old streaming advanced, 4283237 silesia, huffman literals, old streaming advanced, 6183403 @@ -1259,7 +1259,7 @@ silesia.tar, multithreaded long distance mode, old stre silesia.tar, small window log, old streaming advanced, 7118772 silesia.tar, small hash log, old streaming advanced, 6529235 silesia.tar, small chain log, old streaming advanced, 4917021 -silesia.tar, explicit params, old streaming advanced, 4807401 +silesia.tar, explicit params, old streaming advanced, 4807399 silesia.tar, uncompressed literals, old streaming advanced, 4861427 silesia.tar, uncompressed literals optimal, old streaming advanced, 4264392 silesia.tar, huffman literals, old streaming advanced, 6190795 From 746f7976ab82b7c1d1c31349b4cd098f020de848 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 18 May 2021 20:22:36 -0700 Subject: [PATCH 025/274] [trace] Refine the ZSTD_HAVE_WEAK_SYMBOLS detection * Only enable for ELF on x86-64 or i386. * Also explicitly disable for AIX. Fixes #2658. --- lib/common/zstd_trace.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/common/zstd_trace.h b/lib/common/zstd_trace.h index 2da564077..f9121f7d8 100644 --- a/lib/common/zstd_trace.h +++ b/lib/common/zstd_trace.h @@ -17,10 +17,19 @@ extern "C" { #include -/* weak symbol support */ -#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && defined(__GNUC__) && \ +/* weak symbol support + * For now, enable conservatively: + * - Only GNUC + * - Only ELF + * - Only x86-64 and i386 + * Also, explicitly disable on platforms known not to work so they aren't + * forgotten in the future. + */ +#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \ + defined(__GNUC__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \ - !defined(__CYGWIN__) + !defined(__CYGWIN__) && !defined(_AIX) # define ZSTD_HAVE_WEAK_SYMBOLS 1 #else # define ZSTD_HAVE_WEAK_SYMBOLS 0 From bb0cd722b6417017d5c54b6403369cbbae5a9172 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 18 May 2021 11:54:19 -0400 Subject: [PATCH 026/274] Migrate travis CI tests --- .github/workflows/dev-long-tests.yml | 165 ++++++++++++++++ .../{generic-dev.yml => dev-short-tests.yml} | 181 +++++++----------- .github/workflows/generic-release.yml | 59 ------ .github/workflows/linux-kernel.yml | 13 -- .github/workflows/main.yml | 30 --- .travis.yml | 60 +++--- appveyor.yml | 43 ----- 7 files changed, 259 insertions(+), 292 deletions(-) create mode 100644 .github/workflows/dev-long-tests.yml rename .github/workflows/{generic-dev.yml => dev-short-tests.yml} (61%) delete mode 100644 .github/workflows/generic-release.yml delete mode 100644 .github/workflows/linux-kernel.yml delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/dev-long-tests.yml b/.github/workflows/dev-long-tests.yml new file mode 100644 index 000000000..773be83fa --- /dev/null +++ b/.github/workflows/dev-long-tests.yml @@ -0,0 +1,165 @@ +name: dev-long-tests +# Tests longer than 10mn + +concurrency: + group: long-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + branches: [ dev, release, actionsTest ] + +jobs: + make-test: + runs-on: ubuntu-latest + env: + DEVNULLRIGHTS: 1 + READFROMBLOCKDEVICE: 1 + steps: + - uses: actions/checkout@v2 + - name: make test + run: make test + + make-test-osx: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: OS-X test + run: make test # make -c lib all doesn't work because of the fact that it's not a tty + + tsan-zstreamtest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: thread sanitizer zstreamtest + run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream + + tsan-fuzztest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: thread sanitizer fuzztest + run: CC=clang make tsan-fuzztest + + gcc-8-asan-ubsan-testzstd: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: gcc-8 + ASan + UBSan + Test Zstd + run: | + make gcc8install + CC=gcc-8 make -j uasan-test-zstd + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 + /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} + # For reference : icc tests # icc tests are currently failing on Github Actions, likely to issues during installation stage # To be fixed later diff --git a/.github/workflows/generic-release.yml b/.github/workflows/generic-release.yml deleted file mode 100644 index 1e47bba4d..000000000 --- a/.github/workflows/generic-release.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: generic-release - -on: - pull_request: - # This will eventually only be for pushes to release - # but for dogfooding purposes, I'm running it even - # on dev pushes - branches: [ dev, release, actionsTest ] - -jobs: - # missing jobs - # - # ppc64le + fuzz test - # Qemu PPC64 + Fuzz test - # Qemu aarch64 + Fuzz Test (on Xenial) - # versions comp - # meson test - - osx: - runs-on: macos-latest - steps: - - uses: actions/checkout@v2 - - name: OS-X - run: | - make test - # make -c lib all (need to fix. not working right now) - - tsan: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: thread sanitizer - run: | - CC=clang make tsan-test-zstream - CC=clang make tsan-fuzztest - - zlib-wrapper: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: zlib wrapper test - run: | - make valgrindinstall - make -C zlibWrapper test - make -C zlibWrapper valgrindTest - - lz4-threadpool-partial-libs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: LZ4, thread pool, and partial libs testslib wrapper test - run: | - make lz4install - make -C tests test-lz4 - make check < /dev/null | tee # mess with lz4 console detection - make clean - make -C tests test-pool - make clean - bash tests/libzstd_partial_builds.sh diff --git a/.github/workflows/linux-kernel.yml b/.github/workflows/linux-kernel.yml deleted file mode 100644 index 124f77778..000000000 --- a/.github/workflows/linux-kernel.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: linux-kernel - -on: - pull_request: - branches: [ dev, release, actionsTest ] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Create linux kernel library + build + test - run: make -C contrib/linux-kernel test CFLAGS="-Werror -Wunused-const-variable -Wunused-but-set-variable" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 5e5aae112..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: CIFuzz -on: [pull_request] -jobs: - Fuzzing: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - sanitizer: [address, undefined] - steps: - - name: Build Fuzzers (${{ matrix.sanitizer }}) - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'zstd' - dry-run: false - sanitizer: ${{ matrix.sanitizer }} - - name: Run Fuzzers (${{ matrix.sanitizer }}) - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'zstd' - fuzz-seconds: 600 - dry-run: false - sanitizer: ${{ matrix.sanitizer }} - - name: Upload Crash - uses: actions/upload-artifact@v1 - if: failure() && steps.build.outcome == 'success' - with: - name: ${{ matrix.sanitizer }}-artifacts - path: ./out/artifacts diff --git a/.travis.yml b/.travis.yml index 16d1d4281..57db8f052 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ -# Medium Tests: Run on all commits/PRs to dev branch - +# Travis CI is used to test platforms that github-actions currently doesn't support +# without either self-hosting or some finnicky work-around. Also, some tests +# are troublesome to migrate since GH Actions runs tests not in a tty. language: c git: @@ -18,11 +19,10 @@ addons: env: global: - - FUZZERTEST=-T2mn - ZSTREAM_TESTTIME=-T2mn + - FUZZERTEST=-T1mn + ZSTREAM_TESTTIME=-T1mn DECODECORPUS_TESTTIME=-T1mn - matrix: fast_finish: true include: @@ -31,7 +31,8 @@ matrix: arch: arm64 script: - make check - + + # TODO: migrate to GH actions once warnings are fixed - name: Minimal Decompressor Macros # ~5mn script: - make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" @@ -43,17 +44,17 @@ matrix: - make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" - make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + # TODO: migrate to GH actions once newest clang staticanalyze warnings are fixed - name: static analyzer scanbuild # ~26mn dist: trusty # note : it's important to pin down a version of static analyzer, since different versions report different false positives script: - make staticAnalyze - - - name: Valgrind + Fuzz Test Stack Mode # ~ 7mn + + # GH actions can't run this command on OS-X, non-tty issues + - name: OS-X make all lib + os: osx script: - - make valgrindinstall - - make -C tests clean valgrindTest - - make clean - - make -C tests test-fuzzer-stackmode + - make -C lib all # Introduced to check compat with old toolchains, to prevent e.g. #1872 - name: ARM Build Test (on Trusty) @@ -68,58 +69,41 @@ matrix: - make ppcinstall - make ppcfuzz - # check release number (release only) + # check release number (release/new tag only) - name: Tag-Specific Test if: tag =~ ^v[0-9]\.[0-9] script: - make -C tests checkTag - tests/checkTag "$TRAVIS_BRANCH" - # tests for release branch and cron job only - - name: OS-X # ~13mn - if: branch = release - os: osx - script: - - make test - - make -C lib all - - - name: Versions Compatibility Test # 11.5mn - if: branch = release - script: - - make -C tests versionsTest - - - name: thread sanitizer # ~29mn - if: branch = release - script: - - make clang38install - - CC=clang-3.8 make tsan-test-zstream - - CC=clang-3.8 make tsan-fuzztest - - name: PPC64LE + Fuzz test # ~13mn - if: branch = release arch: ppc64le + env: + - FUZZER_FLAGS=--no-big-tests + - MOREFLAGS="-static" script: - cat /proc/cpuinfo - - make test + - make -C tests fuzztest - name: Qemu PPC64 + Fuzz test # ~13mn, presumed Big-Endian (?) dist: trusty # note : PPC64 cross-compilation for Qemu tests seems broken on Xenial - if: branch = release script: - make ppcinstall - make ppc64fuzz # note : we already have aarch64 tests on hardware - name: Qemu aarch64 + Fuzz Test (on Xenial) # ~14mn - if: branch = release dist: xenial script: - make arminstall - make aarch64fuzz + + - name: Versions Compatibility Test # 11.5mn + script: + - make -C tests versionsTest # meson dedicated test - name: Xenial (Meson + clang) # ~15mn - if: branch = release dist: bionic language: cpp compiler: clang diff --git a/appveyor.yml b/appveyor.yml index c6ab78688..a7eeb3f1f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -151,16 +151,6 @@ DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe && - ECHO *** && - ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% && - ECHO *** && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ ) - if [%HOST%]==[cmake-visual] ( @@ -224,23 +214,6 @@ PLATFORM: "x64" SCRIPT: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "x64" - CONFIGURATION: "Debug" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "Win32" - CONFIGURATION: "Debug" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "x64" - CONFIGURATION: "Release" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "Win32" - CONFIGURATION: "Release" - - COMPILER: "clang-cl" HOST: "cmake-visual" PLATFORM: "x64" @@ -266,9 +239,6 @@ COPY C:\msys64\usr\bin\make.exe C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin\make.exe && COPY C:\msys64\usr\bin\make.exe C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin\make.exe ) - - IF [%HOST%]==[visual] IF [%PLATFORM%]==[x64] ( - SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;" - ) build_script: - ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION% @@ -294,19 +264,6 @@ set "CC=%COMPILER%" && sh -c "%SCRIPT%" ) - - if [%HOST%]==[visual] ( - ECHO *** && - ECHO *** Building Visual Studio 2015 %PLATFORM%\%CONFIGURATION% && - ECHO *** && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2015_%PLATFORM%_%CONFIGURATION%.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ - ) - if [%HOST%]==[cmake-visual] ( ECHO *** && ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% && From 939276cd0c8f6f5b6eede93bb4db3779742ca778 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 24 May 2021 12:57:56 -0400 Subject: [PATCH 027/274] Add ldm and block splitter auto-enable to old api --- lib/compress/zstd_compress.c | 11 +++++++++++ tests/regression/Makefile | 2 +- tests/regression/results.csv | 16 ++++++++-------- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 8ca795bd7..6afecfa14 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -349,6 +349,17 @@ static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_par cctxParams->compressionLevel = compressionLevel; cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams); DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d", cctxParams->useRowMatchFinder); + + if (ZSTD_CParams_shouldEnableLdm(¶ms->cParams)) { + /* Enable LDM by default for optimal parser and window size >= 128MB */ + DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)"); + cctxParams->ldmParams.enableLdm = 1; + } + + if (ZSTD_CParams_useBlockSplitter(¶ms->cParams)) { + DEBUGLOG(4, "Block splitter enabled by default (window size >= 128K, strategy >= btopt)"); + cctxParams->splitBlocks = 1; + } } size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) diff --git a/tests/regression/Makefile b/tests/regression/Makefile index d0d7bcf0b..3a5a64e5b 100644 --- a/tests/regression/Makefile +++ b/tests/regression/Makefile @@ -15,7 +15,7 @@ CURL_LDFLAGS := $(shell curl-config --libs) -pthread PROGDIR := ../../programs LIBDIR := ../../lib -ZSTD_CPPFLAGS := -I$(PROGDIR) -I$(LIBDIR) -I$(LIBDIR)/common +ZSTD_CPPFLAGS := -I$(PROGDIR) -I$(LIBDIR) -I$(LIBDIR)/common -Wno-deprecated-declarations REGRESSION_CFLAGS = $(CFLAGS) $(CURL_CFLAGS) REGRESSION_CPPFLAGS = $(CPPFLAGS) $(ZSTD_CPPFLAGS) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 1ed896dcd..0734a539f 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -11,10 +11,10 @@ silesia.tar, level 6, compress silesia.tar, level 7, compress simple, 4613541 silesia.tar, level 9, compress simple, 4555426 silesia.tar, level 13, compress simple, 4491764 -silesia.tar, level 16, compress simple, 4381350 -silesia.tar, level 19, compress simple, 4281562 +silesia.tar, level 16, compress simple, 4356834 +silesia.tar, level 19, compress simple, 4264392 silesia.tar, uncompressed literals, compress simple, 4861425 -silesia.tar, uncompressed literals optimal, compress simple, 4281562 +silesia.tar, uncompressed literals optimal, compress simple, 4264392 silesia.tar, huffman literals, compress simple, 6186042 github.tar, level -5, compress simple, 46856 github.tar, level -3, compress simple, 43754 @@ -45,17 +45,17 @@ silesia, level 6, compress silesia, level 7, compress cctx, 4603381 silesia, level 9, compress cctx, 4546001 silesia, level 13, compress cctx, 4482135 -silesia, level 16, compress cctx, 4377465 -silesia, level 19, compress cctx, 4293330 +silesia, level 16, compress cctx, 4360251 +silesia, level 19, compress cctx, 4283237 silesia, long distance mode, compress cctx, 4849552 silesia, multithreaded, compress cctx, 4849552 silesia, multithreaded long distance mode, compress cctx, 4849552 silesia, small window log, compress cctx, 7084179 -silesia, small hash log, compress cctx, 6555021 -silesia, small chain log, compress cctx, 4931148 +silesia, small hash log, compress cctx, 6526141 +silesia, small chain log, compress cctx, 4912197 silesia, explicit params, compress cctx, 4794479 silesia, uncompressed literals, compress cctx, 4849552 -silesia, uncompressed literals optimal, compress cctx, 4293330 +silesia, uncompressed literals optimal, compress cctx, 4283237 silesia, huffman literals, compress cctx, 6178460 silesia, multithreaded with advanced params, compress cctx, 4849552 github, level -5, compress cctx, 205285 From d278bede332ace7406168c3c6159afca834560db Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 26 May 2021 13:38:36 -0400 Subject: [PATCH 028/274] Update apt-get prior to tests that install packages --- .github/workflows/dev-long-tests.yml | 4 +++- .github/workflows/dev-short-tests.yml | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dev-long-tests.yml b/.github/workflows/dev-long-tests.yml index 773be83fa..bc7e51218 100644 --- a/.github/workflows/dev-long-tests.yml +++ b/.github/workflows/dev-long-tests.yml @@ -47,6 +47,7 @@ jobs: - uses: actions/checkout@v2 - name: gcc-8 + ASan + UBSan + Test Zstd run: | + sudo apt-get -qqq update make gcc8install CC=gcc-8 make -j uasan-test-zstd Date: Wed, 26 May 2021 14:51:04 -0400 Subject: [PATCH 029/274] Add arm64 fuzz test to travis --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 57db8f052..32fedc887 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,12 @@ matrix: script: - make check + - name: arm64fuzz + os: linux + arch: arm64 + script: + - make -C tests fuzztest + # TODO: migrate to GH actions once warnings are fixed - name: Minimal Decompressor Macros # ~5mn script: From a80d268700d1a8496dd05de50833dfc6bdd750f0 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Sat, 29 May 2021 18:21:10 +0100 Subject: [PATCH 030/274] Optimize ZSTD_decodeSequence by another x% --- lib/common/bitstream.h | 10 +++ lib/decompress/zstd_decompress_block.c | 95 ++++++++++++-------------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index 2e5a933ad..1a494ee85 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -332,7 +332,17 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c U32 const regMask = sizeof(bitContainer)*8 - 1; /* if start > regMask, bitstream is corrupted, and result is undefined */ assert(nbBits < BIT_MASK_SIZE); + /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better + * than accessing memory. When bmi2 instruction is not present, we consider + * such cpus old (pre-Haswell, 2013) and their performance is not of that + * importance. + */ +#if defined(__x86_64__) || defined(_M_X86) + U64 const one = 1; + return (bitContainer >> (start & regMask)) & ((one << nbBits) - 1); +#else return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; +#endif } MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 349dcdc33..6c40be416 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -905,20 +905,10 @@ ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqS } FORCE_INLINE_TEMPLATE void -ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD) +ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits) { - ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state]; - U32 const nbBits = DInfo.nbBits; size_t const lowBits = BIT_readBits(bitD, nbBits); - DStatePtr->state = DInfo.nextState + lowBits; -} - -FORCE_INLINE_TEMPLATE void -ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, ZSTD_seqSymbol const DInfo) -{ - U32 const nbBits = DInfo.nbBits; - size_t const lowBits = BIT_readBits(bitD, nbBits); - DStatePtr->state = DInfo.nextState + lowBits; + DStatePtr->state = nextState + lowBits; } /* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum @@ -937,20 +927,36 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) { seq_t seq; - ZSTD_seqSymbol const llDInfo = seqState->stateLL.table[seqState->stateLL.state]; - ZSTD_seqSymbol const mlDInfo = seqState->stateML.table[seqState->stateML.state]; - ZSTD_seqSymbol const ofDInfo = seqState->stateOffb.table[seqState->stateOffb.state]; - U32 const llBase = llDInfo.baseValue; - U32 const mlBase = mlDInfo.baseValue; - U32 const ofBase = ofDInfo.baseValue; - BYTE const llBits = llDInfo.nbAdditionalBits; - BYTE const mlBits = mlDInfo.nbAdditionalBits; - BYTE const ofBits = ofDInfo.nbAdditionalBits; + const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state; + const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state; + const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state; + seq.matchLength = mlDInfo->baseValue; + seq.litLength = llDInfo->baseValue; + U32 const ofBase = ofDInfo->baseValue; + BYTE const llBits = llDInfo->nbAdditionalBits; + BYTE const mlBits = mlDInfo->nbAdditionalBits; + BYTE const ofBits = ofDInfo->nbAdditionalBits; BYTE const totalBits = llBits+mlBits+ofBits; + U16 const llNext = llDInfo->nextState; + U16 const mlNext = mlDInfo->nextState; + U16 const ofNext = ofDInfo->nextState; + U32 const llnbBits = llDInfo->nbBits; + U32 const mlnbBits = mlDInfo->nbBits; + U32 const ofnbBits = ofDInfo->nbBits; + /* + * As gcc has better branch and block analyzers, sometimes it is only + * valuable to mark likelyness for clang, it gives around 3-4% of + * performance. + */ + /* sequence */ { size_t offset; +#if defined(__clang__) + if (LIKELY(ofBits > 1)) { +#else if (ofBits > 1) { +#endif ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); assert(ofBits <= MaxOff); @@ -968,12 +974,10 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; } else { - U32 const ll0 = (llBase == 0); + U32 const ll0 = (llDInfo->baseValue == 0); if (LIKELY((ofBits == 0))) { - if (LIKELY(!ll0)) - offset = seqState->prevOffset[0]; - else { - offset = seqState->prevOffset[1]; + offset = seqState->prevOffset[ll0]; + if (UNLIKELY(ll0)) { seqState->prevOffset[1] = seqState->prevOffset[0]; seqState->prevOffset[0] = offset; } @@ -988,8 +992,11 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) seq.offset = offset; } - seq.matchLength = mlBase; +#if defined(__clang__) + if (UNLIKELY(mlBits > 0)) +#else if (mlBits > 0) +#endif seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) @@ -999,8 +1006,11 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); - seq.litLength = llBase; +#if defined(__clang__) + if (UNLIKELY(llBits > 0)) +#else if (llBits > 0) +#endif seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); if (MEM_32bits()) @@ -1009,31 +1019,10 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); - /* ANS state update - * gcc-9.0.0 does 2.5% worse with ZSTD_updateFseStateWithDInfo(). - * clang-9.2.0 does 7% worse with ZSTD_updateFseState(). - * Naturally it seems like ZSTD_updateFseStateWithDInfo() should be the - * better option, so it is the default for other compilers. But, if you - * measure that it is worse, please put up a pull request. - */ - { -#if defined(__GNUC__) && !defined(__clang__) - const int kUseUpdateFseState = 1; -#else - const int kUseUpdateFseState = 0; -#endif - if (kUseUpdateFseState) { - ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ - ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ - } else { - ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llDInfo); /* <= 9 bits */ - ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlDInfo); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofDInfo); /* <= 8 bits */ - } - } + ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ return seq; } From 444f4db9556d42f3b143130b32f6b9f51e6ea9d6 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Sat, 29 May 2021 20:55:37 +0100 Subject: [PATCH 031/274] Move declaration of 1 to an inlined cast --- lib/common/bitstream.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index 1a494ee85..48aad7f3a 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -338,8 +338,7 @@ MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 c * importance. */ #if defined(__x86_64__) || defined(_M_X86) - U64 const one = 1; - return (bitContainer >> (start & regMask)) & ((one << nbBits) - 1); + return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1); #else return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; #endif From 1e17184ad043fde95548dd7580fee62d7d6e5bdb Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Thu, 3 Jun 2021 11:12:27 -0400 Subject: [PATCH 032/274] Add documentation for --patch-from --- programs/README.md | 1 + programs/zstdcli.c | 1 + 2 files changed, 2 insertions(+) diff --git a/programs/README.md b/programs/README.md index 7fd710420..02a83ca3c 100644 --- a/programs/README.md +++ b/programs/README.md @@ -172,6 +172,7 @@ Advanced compression arguments : --long[=#]: enable long distance matching with given window log (default: 27) --fast[=#]: switch to very fast compression levels (default: 1) --adapt : dynamically adapt compression level to I/O conditions +--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine -T# : spawns # compression threads (default: 1, 0==# cores) -B# : select size of each job (default: 0==automatic) --single-thread : use a single thread for both I/O and compression (result slightly different than -T1) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 239aaf406..9e2133c4f 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -208,6 +208,7 @@ static void usage_advanced(const char* programName) DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1); DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n"); DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n"); + DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n"); # ifdef ZSTD_MULTITHREAD DISPLAYOUT( " -T# : spawns # compression threads (default: 1, 0==# cores) \n"); DISPLAYOUT( " -B# : select size of each job (default: 0==automatic) \n"); From 923e5ad3f5573cd68f792ebad49c24ecaa0c3ad0 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Mon, 7 Jun 2021 00:32:03 -0700 Subject: [PATCH 033/274] Fix entropy repeat mode bug --- lib/compress/zstd_compress.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6afecfa14..dafe3cbd5 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3332,6 +3332,7 @@ static size_t ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, */ static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, const ZSTD_CCtx* zc) { ZSTD_entropyCTablesMetadata_t entropyMetadata; + DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()"); FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore, &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, @@ -3510,9 +3511,6 @@ static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const return 0; } - if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) - zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; - if (cSeqsSize == 0) { cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock); FORWARD_IF_ERROR(cSize, "Nocompress block failed"); @@ -3529,6 +3527,10 @@ static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const cSize = ZSTD_blockHeaderSize + cSeqsSize; DEBUGLOG(4, "Writing out compressed block, size: %zu", cSize); } + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + return cSize; } @@ -3564,6 +3566,7 @@ static void ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx size_t midIdx = (startIdx + endIdx)/2; if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= MAX_NB_SPLITS) { + DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences"); return; } ZSTD_deriveSeqStoreChunk(&fullSeqStoreChunk, origSeqStore, startIdx, endIdx); From 88acf0ac6556631bd150b2339487eca0b3112a79 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 1 Jun 2021 05:59:01 +0300 Subject: [PATCH 034/274] Make regression test run on every PR --- .circleci/config.yml | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6a8c38642..035177edc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -84,21 +84,10 @@ workflows: commit: jobs: # Run the tests in parallel - - short-tests-0: - filters: - tags: - only: /.*/ - - short-tests-1: - filters: - tags: - only: /.*/ - # Create a branch called regression and set it to dev to force a - # regression test run - - regression-test: - filters: - branches: - only: - - regression + - short-tests-0 + - short-tests-1 + - regression-test + nightly: triggers: - schedule: @@ -110,7 +99,7 @@ workflows: - dev - master jobs: - # Run daily long regression tests + # Run daily regression tests - regression-test From 2ff5c7b59ffe75f948ffd399a17d9c1959f124a1 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Mon, 7 Jun 2021 00:44:23 -0700 Subject: [PATCH 035/274] Add no intrinsics fuzztest, rowhash compression size test, and S390X to travis --- .github/workflows/dev-long-tests.yml | 7 ++++++ .travis.yml | 12 ++++++++++ tests/fuzzer.c | 34 ++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dev-long-tests.yml b/.github/workflows/dev-long-tests.yml index bc7e51218..bc88c4a6a 100644 --- a/.github/workflows/dev-long-tests.yml +++ b/.github/workflows/dev-long-tests.yml @@ -27,6 +27,13 @@ jobs: - name: OS-X test run: make test # make -c lib all doesn't work because of the fact that it's not a tty + no-intrinsics-fuzztest: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: no intrinsics fuzztest + run: MOREFLAGS="-DZSTD_NO_INTRINSICS" make -C tests fuzztest + tsan-zstreamtest: runs-on: ubuntu-latest steps: diff --git a/.travis.yml b/.travis.yml index 32fedc887..7b202cb88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,18 @@ env: matrix: fast_finish: true include: + - name: S390X (big endian) + Fuzz test + dist: trusty + arch: s390x + script: + - FUZZER_FLAGS=--no-big-tests make -C tests fuzztest + + - name: S390X (big endian) + Fuzz test + no intrinsics + dist: trusty + arch: s390x + script: + - MOREFLAGS="-DZSTD_NO_INTRINSICS" FUZZER_FLAGS=--no-big-tests make -C tests fuzztest + - name: arm64 # ~2.5 mn os: linux arch: arm64 diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 1ea65210d..553209f4d 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1921,11 +1921,11 @@ static int basicUnitTests(U32 const seed, double compressibility) const void* const dict = (const char*)CNBuffer; const void* const contentStart = (const char*)dict + flatdictSize; /* These upper bounds are generally within a few bytes of the compressed size */ - size_t const target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770, - 3770, 3770, 3770, 3750, 3750, - 3742, 3670, 3670, 3660, 3660, - 3660, 3660, 3660, 3660, 3660, - 3660, 3660, 3660 }; + size_t target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770, + 3770, 3770, 3770, 3750, 3750, + 3742, 3670, 3670, 3660, 3660, + 3660, 3660, 3660, 3660, 3660, + 3660, 3660, 3660 }; size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940, 2950, 2950, 2925, 2900, 2891, 2910, 2910, 2910, 2770, 2760, @@ -1933,6 +1933,9 @@ static int basicUnitTests(U32 const seed, double compressibility) 2750, 2750, 2750 }; int l = 1; int const maxLevel = ZSTD_maxCLevel(); + /* clevels with strategies that support rowhash on small inputs */ + int rowLevel = 4; + int const rowLevelEnd = 8; DISPLAYLEVEL(3, "test%3i : flat-dictionary efficiency test : \n", testNb++); assert(maxLevel == 22); @@ -1964,6 +1967,27 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(4, "level %i with dictionary : max expected %u >= reached %u \n", l, (unsigned)target_wdict_cSize[l], (unsigned)wdict_cSize); } + /* Compression with ZSTD_compress2 and row match finder force enabled. + * Give some slack for force-enabled row matchfinder since we're on a small input (9KB) + */ + for ( ; rowLevel <= rowLevelEnd; ++rowLevel) target_nodict_cSize[rowLevel] += 5; + for (l=1 ; l <= maxLevel; l++) { + ZSTD_CCtx* const cctx = ZSTD_createCCtx(); + size_t nodict_cSize; + ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, l); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_useRowMatchFinder, ZSTD_urm_enableRowMatchFinder); + nodict_cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, + contentStart, contentSize); + if (nodict_cSize > target_nodict_cSize[l]) { + DISPLAYLEVEL(1, "error : compression with compress2 at level %i worse than expected (%u > %u) \n", + l, (unsigned)nodict_cSize, (unsigned)target_nodict_cSize[l]); + ZSTD_freeCCtx(cctx); + goto _output_error; + } + DISPLAYLEVEL(4, "level %i with compress2 : max expected %u >= reached %u \n", + l, (unsigned)target_nodict_cSize[l], (unsigned)nodict_cSize); + ZSTD_freeCCtx(cctx); + } /* Dict compression with DMS */ for ( l=1 ; l <= maxLevel; l++) { size_t wdict_cSize; From 6534c0000f73326f4a326dca9f0697f2b9d254c3 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Tue, 8 Jun 2021 20:45:57 +0100 Subject: [PATCH 036/274] Be C89 compliant and fix alignment for gcc11 --- lib/decompress/zstd_decompress_block.c | 175 +++++++++++++------------ 1 file changed, 88 insertions(+), 87 deletions(-) diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 6c40be416..40b2ae492 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -932,98 +932,99 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state; seq.matchLength = mlDInfo->baseValue; seq.litLength = llDInfo->baseValue; - U32 const ofBase = ofDInfo->baseValue; - BYTE const llBits = llDInfo->nbAdditionalBits; - BYTE const mlBits = mlDInfo->nbAdditionalBits; - BYTE const ofBits = ofDInfo->nbAdditionalBits; - BYTE const totalBits = llBits+mlBits+ofBits; + { U32 const ofBase = ofDInfo->baseValue; + BYTE const llBits = llDInfo->nbAdditionalBits; + BYTE const mlBits = mlDInfo->nbAdditionalBits; + BYTE const ofBits = ofDInfo->nbAdditionalBits; + BYTE const totalBits = llBits+mlBits+ofBits; - U16 const llNext = llDInfo->nextState; - U16 const mlNext = mlDInfo->nextState; - U16 const ofNext = ofDInfo->nextState; - U32 const llnbBits = llDInfo->nbBits; - U32 const mlnbBits = mlDInfo->nbBits; - U32 const ofnbBits = ofDInfo->nbBits; - /* - * As gcc has better branch and block analyzers, sometimes it is only - * valuable to mark likelyness for clang, it gives around 3-4% of - * performance. - */ + U16 const llNext = llDInfo->nextState; + U16 const mlNext = mlDInfo->nextState; + U16 const ofNext = ofDInfo->nextState; + U32 const llnbBits = llDInfo->nbBits; + U32 const mlnbBits = mlDInfo->nbBits; + U32 const ofnbBits = ofDInfo->nbBits; + /* + * As gcc has better branch and block analyzers, sometimes it is only + * valuable to mark likelyness for clang, it gives around 3-4% of + * performance. + */ - /* sequence */ - { size_t offset; -#if defined(__clang__) - if (LIKELY(ofBits > 1)) { -#else - if (ofBits > 1) { -#endif - ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); - ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); - assert(ofBits <= MaxOff); - if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { - U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed); - offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); - BIT_reloadDStream(&seqState->DStream); - if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); - assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */ - } else { - offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); - } - seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - } else { - U32 const ll0 = (llDInfo->baseValue == 0); - if (LIKELY((ofBits == 0))) { - offset = seqState->prevOffset[ll0]; - if (UNLIKELY(ll0)) { - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; + /* sequence */ + { size_t offset; + #if defined(__clang__) + if (LIKELY(ofBits > 1)) { + #else + if (ofBits > 1) { + #endif + ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); + ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); + assert(ofBits <= MaxOff); + if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { + U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed); + offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + BIT_reloadDStream(&seqState->DStream); + if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); + assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */ + } else { + offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); } + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; } else { - offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); - { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; - temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ - if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset = temp; - } } } - seq.offset = offset; + U32 const ll0 = (llDInfo->baseValue == 0); + if (LIKELY((ofBits == 0))) { + offset = seqState->prevOffset[ll0]; + if (UNLIKELY(ll0)) { + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } + } else { + offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); + { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } } } + seq.offset = offset; + } + + #if defined(__clang__) + if (UNLIKELY(mlBits > 0)) + #else + if (mlBits > 0) + #endif + seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); + + if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) + BIT_reloadDStream(&seqState->DStream); + if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ + ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); + + #if defined(__clang__) + if (UNLIKELY(llBits > 0)) + #else + if (llBits > 0) + #endif + seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); + + if (MEM_32bits()) + BIT_reloadDStream(&seqState->DStream); + + DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + + ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ } -#if defined(__clang__) - if (UNLIKELY(mlBits > 0)) -#else - if (mlBits > 0) -#endif - seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); - - if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) - BIT_reloadDStream(&seqState->DStream); - if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) - BIT_reloadDStream(&seqState->DStream); - /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ - ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); - -#if defined(__clang__) - if (UNLIKELY(llBits > 0)) -#else - if (llBits > 0) -#endif - seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); - - if (MEM_32bits()) - BIT_reloadDStream(&seqState->DStream); - - DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", - (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); - - ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ - ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ - if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ - ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ - return seq; } @@ -1155,7 +1156,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, __asm__("nop"); __asm__(".p2align 5"); __asm__("nop"); -# if __GNUC__ >= 9 +# if __GNUC__ >= 9 && __GNUC__ < 11 /* better for gcc-9 and gcc-10, worse for clang and gcc-8 */ __asm__(".p2align 3"); # else From 08a3ddbd28c362ef1f334c17894178d904436771 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Tue, 8 Jun 2021 20:54:21 +0100 Subject: [PATCH 037/274] Add comment for gcc-11 --- lib/decompress/zstd_decompress_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 40b2ae492..e5391d662 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -1157,7 +1157,7 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, __asm__(".p2align 5"); __asm__("nop"); # if __GNUC__ >= 9 && __GNUC__ < 11 - /* better for gcc-9 and gcc-10, worse for clang and gcc-8 */ + /* better for gcc-9 and gcc-10, worse for clang and gcc-8, gcc-11 */ __asm__(".p2align 3"); # else __asm__(".p2align 4"); From d2f31b662779f3c13871d54868e9d5839343856d Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Mon, 7 Jun 2021 11:50:22 -0400 Subject: [PATCH 038/274] Fix --progress flag to properly control progress display and default progress display on when using -v --- programs/fileio.c | 33 ++++++++++++++++----------------- tests/playTests.sh | 6 +++++- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 5693ac399..a67c0fbfb 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -2155,6 +2155,7 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput, ZSTD_inBuffer inBuff = { ress->srcBuffer, ress->srcBufferLoaded, 0 }; ZSTD_outBuffer outBuff= { ress->dstBuffer, ress->dstBufferSize, 0 }; size_t const readSizeHint = ZSTD_decompressStream(ress->dctx, &outBuff, &inBuff); + const int displayLevel = (!fCtx->hasStdoutOutput || g_display_prefs.progressSetting == FIO_ps_always) ? 1 : 2; if (ZSTD_isError(readSizeHint)) { DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n", srcFileName, ZSTD_getErrorName(readSizeHint)); @@ -2165,21 +2166,19 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput, /* Write block */ storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, prefs, storedSkips); frameSize += outBuff.pos; - if (!fCtx->hasStdoutOutput || g_display_prefs.progressSetting == FIO_ps_always) { - if (fCtx->nbFilesTotal > 1) { - size_t srcFileNameSize = strlen(srcFileName); - if (srcFileNameSize > 18) { - const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15; - DISPLAYUPDATE(2, "\rDecompress: %2u/%2u files. Current: ...%s : %u MB... ", - fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); - } else { - DISPLAYUPDATE(2, "\rDecompress: %2u/%2u files. Current: %s : %u MB... ", - fCtx->currFileIdx+1, fCtx->nbFilesTotal, srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); - } + if (fCtx->nbFilesTotal > 1) { + size_t srcFileNameSize = strlen(srcFileName); + if (srcFileNameSize > 18) { + const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15; + DISPLAYUPDATE(displayLevel, "\rDecompress: %2u/%2u files. Current: ...%s : %u MB... ", + fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); } else { - DISPLAYUPDATE(2, "\r%-20.20s : %u MB... ", - srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); + DISPLAYUPDATE(displayLevel, "\rDecompress: %2u/%2u files. Current: %s : %u MB... ", + fCtx->currFileIdx+1, fCtx->nbFilesTotal, srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); } + } else { + DISPLAYUPDATE(displayLevel, "\r%-20.20s : %u MB... ", + srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); } if (inBuff.pos > 0) { @@ -2513,10 +2512,10 @@ static int FIO_decompressFrames(FIO_ctx_t* const fCtx, fCtx->totalBytesOutput += (size_t)filesize; DISPLAYLEVEL(2, "\r%79s\r", ""); /* No status message in pipe mode (stdin - stdout) or multi-files mode */ - if (g_display_prefs.displayLevel >= 2) { - if (fCtx->nbFilesTotal <= 1 || g_display_prefs.displayLevel >= 3) { - DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize); - } + if ((g_display_prefs.displayLevel >= 2 && fCtx->nbFilesTotal <= 1) || + g_display_prefs.displayLevel >= 3 || + g_display_prefs.progressSetting == FIO_ps_always) { + DISPLAYLEVEL(1, "\r%-20s: %llu bytes \n", srcFileName, filesize); } return 0; diff --git a/tests/playTests.sh b/tests/playTests.sh index f57f61f3d..252939006 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -263,6 +263,10 @@ zstd -q -f tmpro println "test: --no-progress flag" zstd tmpro -c --no-progress | zstd -d -f -o "$INTOVOID" --no-progress zstd tmpro -cv --no-progress | zstd -dv -f -o "$INTOVOID" --no-progress +println "test: --progress flag" +zstd tmpro -c | zstd -d -f -o "$INTOVOID" --progress 2>&1 | grep -E "[A-Za-z0-9._ ]+: [0-9]+ bytes" +zstd tmpro -c | zstd -d -f -q -o "$INTOVOID" --progress 2>&1 | grep -E "[A-Za-z0-9._ ]+: [0-9]+ bytes" +zstd tmpro -c | zstd -d -f -v -o "$INTOVOID" 2>&1 | grep -E "[A-Za-z0-9._ ]+: [0-9]+ bytes" rm -f tmpro tmpro.zst println "test: overwrite input file (must fail)" zstd tmp -fo tmp && die "zstd compression overwrote the input file" @@ -1612,7 +1616,7 @@ roundTripTest -g600M -P50 "1 --single-thread --long --zstd=wlog=29,clog=28" if [ -n "$hasMT" ] then - println "\n===> zstdmt long round-trip tests " + println "\n===> zstdmt long round-trip tests " roundTripTest -g80000000 -P99 "19 -T2" " " roundTripTest -g5000000000 -P99 "1 -T2" " " roundTripTest -g500000000 -P97 "1 -T999" " " From dd4f6aa9e6db2964cc5ff8641be21334cab97a98 Mon Sep 17 00:00:00 2001 From: aqrit Date: Wed, 9 Jun 2021 01:50:25 -0400 Subject: [PATCH 039/274] Flatten ZSTD_row_getMatchMask (#2681) * Flatten ZSTD_row_getMatchMask * Remove the SIMD abstraction layer. * Add big endian support. * Align `hashTags` within `tagRow` to a 16-byte boundary. * Switch SSE2 to use aligned reads. * Optimize scalar path using SWAR. * Optimize neon path for `n == 32` * Work around minor clang issue for NEON (https://bugs.llvm.org/show_bug.cgi?id=49577) * replace memcpy with MEM_readST * silence alignment warnings * fix neon casts * Update zstd_lazy.c * unify simd preprocessor detection (#3) * remove duplicate asserts * tweak rotates * improve endian detection * add cast there is a fun little catch-22 with gcc: result from pmovmskb has to be cast to uint32_t to avoid a zero-extension but must be uint16_t to get gcc to generate a rotate instruction.. * more casts * fix casts better work-around for the (bogus) warning: unary minus on unsigned --- lib/common/compiler.h | 16 ++ lib/common/mem.h | 14 ++ lib/common/zstd_internal.h | 7 +- lib/compress/zstd_compress.c | 2 +- lib/compress/zstd_lazy.c | 325 +++++++++++------------------------ 5 files changed, 137 insertions(+), 227 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index a951d0ade..9e2a8fe70 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -197,6 +197,22 @@ #define STATIC_BMI2 0 #endif +/* compile time determination of SIMD support */ +#if !defined(ZSTD_NO_INTRINSICS) +# if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) +# define ZSTD_ARCH_X86_SSE2 +# endif +# if defined(__ARM_NEON) || defined(_M_ARM64) +# define ZSTD_ARCH_ARM_NEON +# endif +# +# if defined(ZSTD_ARCH_X86_SSE2) +# include +# elif defined(ZSTD_ARCH_ARM_NEON) +# include +# endif +#endif + /* compat. with non-clang compilers */ #ifndef __has_builtin # define __has_builtin(x) 0 diff --git a/lib/common/mem.h b/lib/common/mem.h index 9f3b81ab9..1c61b7e52 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -153,8 +153,22 @@ MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } MEM_STATIC unsigned MEM_isLittleEndian(void) { +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + return 1; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + return 0; +#elif defined(__clang__) && __LITTLE_ENDIAN__ + return 1; +#elif defined(__clang__) && __BIG_ENDIAN__ + return 0; +#elif defined(_MSC_VER) && (_M_AMD64 || _M_IX86) + return 1; +#elif defined(__DMC__) && defined(_M_IX86) + return 1; +#else const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; +#endif } #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 68252e987..3134a5abc 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -19,9 +19,6 @@ /*-************************************* * Dependencies ***************************************/ -#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) -#include -#endif #include "compiler.h" #include "mem.h" #include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ @@ -247,7 +244,7 @@ static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG; * Shared functions to include for inlining *********************************************/ static void ZSTD_copy8(void* dst, const void* src) { -#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) +#if defined(ZSTD_ARCH_ARM_NEON) vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src)); #else ZSTD_memcpy(dst, src, 8); @@ -256,7 +253,7 @@ static void ZSTD_copy8(void* dst, const void* src) { #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } static void ZSTD_copy16(void* dst, const void* src) { -#if !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) +#if defined(ZSTD_ARCH_ARM_NEON) vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src)); #else ZSTD_memcpy(dst, src, 16); diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6afecfa14..d7ae6d826 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -222,7 +222,7 @@ static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_useR /* Returns row matchfinder usage enum given an initial mode and cParams */ static ZSTD_useRowMatchFinderMode_e ZSTD_resolveRowMatchFinderMode(ZSTD_useRowMatchFinderMode_e mode, const ZSTD_compressionParameters* const cParams) { -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(_M_AMD64) || defined(__ARM_NEON)) +#if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON) int const kHasSIMD128 = 1; #else int const kHasSIMD128 = 0; diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index b772d19d1..4dfd9d9ed 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -865,7 +865,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( * (SIMD) Row-based matchfinder ***********************************/ /* Constants for row-based hash */ -#define ZSTD_ROW_HASH_TAG_OFFSET 1 /* byte offset of hashes in the match state's tagTable from the beginning of a row */ +#define ZSTD_ROW_HASH_TAG_OFFSET 16 /* byte offset of hashes in the match state's tagTable from the beginning of a row */ #define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ #define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) @@ -873,197 +873,6 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ -#if !defined(ZSTD_NO_INTRINSICS) && (defined(__SSE2__) || defined(_M_AMD64)) /* SIMD SSE version*/ - -#include -typedef __m128i ZSTD_Vec128; - -/* Returns a 128-bit container with 128-bits from src */ -static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) { - return _mm_loadu_si128((ZSTD_Vec128 const*)src); -} - -/* Returns a ZSTD_Vec128 with the byte "val" packed 16 times */ -static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { - return _mm_set1_epi8((char)val); -} - -/* Do byte-by-byte comparison result of x and y. Then collapse 128-bit resultant mask - * into a 32-bit mask that is the MSB of each byte. - * */ -static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { - return (ZSTD_VecMask)_mm_movemask_epi8(_mm_cmpeq_epi8(x, y)); -} - -typedef struct { - __m128i fst; - __m128i snd; -} ZSTD_Vec256; - -static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { - ZSTD_Vec256 v; - v.fst = ZSTD_Vec128_read(ptr); - v.snd = ZSTD_Vec128_read((ZSTD_Vec128 const*)ptr + 1); - return v; -} - -static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { - ZSTD_Vec256 v; - v.fst = ZSTD_Vec128_set8(val); - v.snd = ZSTD_Vec128_set8(val); - return v; -} - -static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { - ZSTD_VecMask fstMask; - ZSTD_VecMask sndMask; - fstMask = ZSTD_Vec128_cmpMask8(x.fst, y.fst); - sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); - return fstMask | (sndMask << 16); -} - -#elif !defined(ZSTD_NO_INTRINSICS) && defined(__ARM_NEON) /* SIMD ARM NEON Version */ - -#include -typedef uint8x16_t ZSTD_Vec128; - -static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) { - return vld1q_u8((const BYTE* const)src); -} - -static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { - return vdupq_n_u8(val); -} - -/* Mimics '_mm_movemask_epi8()' from SSE */ -static U32 ZSTD_vmovmaskq_u8(ZSTD_Vec128 val) { - /* Shift out everything but the MSB bits in each byte */ - uint16x8_t highBits = vreinterpretq_u16_u8(vshrq_n_u8(val, 7)); - /* Merge the even lanes together with vsra (right shift and add) */ - uint32x4_t paired16 = vreinterpretq_u32_u16(vsraq_n_u16(highBits, highBits, 7)); - uint64x2_t paired32 = vreinterpretq_u64_u32(vsraq_n_u32(paired16, paired16, 14)); - uint8x16_t paired64 = vreinterpretq_u8_u64(vsraq_n_u64(paired32, paired32, 28)); - /* Extract the low 8 bits from each lane, merge */ - return vgetq_lane_u8(paired64, 0) | ((U32)vgetq_lane_u8(paired64, 8) << 8); -} - -static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { - return (ZSTD_VecMask)ZSTD_vmovmaskq_u8(vceqq_u8(x, y)); -} - -typedef struct { - uint8x16_t fst; - uint8x16_t snd; -} ZSTD_Vec256; - -static ZSTD_Vec256 ZSTD_Vec256_read(const void* const ptr) { - ZSTD_Vec256 v; - v.fst = ZSTD_Vec128_read(ptr); - v.snd = ZSTD_Vec128_read((ZSTD_Vec128 const*)ptr + 1); - return v; -} - -static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { - ZSTD_Vec256 v; - v.fst = ZSTD_Vec128_set8(val); - v.snd = ZSTD_Vec128_set8(val); - return v; -} - -static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { - ZSTD_VecMask fstMask; - ZSTD_VecMask sndMask; - fstMask = ZSTD_Vec128_cmpMask8(x.fst, y.fst); - sndMask = ZSTD_Vec128_cmpMask8(x.snd, y.snd); - return fstMask | (sndMask << 16); -} - -#else /* Scalar fallback version */ - -#define VEC128_NB_SIZE_T (16 / sizeof(size_t)) -typedef struct { - size_t vec[VEC128_NB_SIZE_T]; -} ZSTD_Vec128; - -static ZSTD_Vec128 ZSTD_Vec128_read(const void* const src) { - ZSTD_Vec128 ret; - ZSTD_memcpy(ret.vec, src, VEC128_NB_SIZE_T*sizeof(size_t)); - return ret; -} - -static ZSTD_Vec128 ZSTD_Vec128_set8(BYTE val) { - ZSTD_Vec128 ret = { {0} }; - int startBit = sizeof(size_t) * 8 - 8; - for (;startBit >= 0; startBit -= 8) { - unsigned j = 0; - for (;j < VEC128_NB_SIZE_T; ++j) { - ret.vec[j] |= ((size_t)val << startBit); - } - } - return ret; -} - -/* Compare x to y, byte by byte, generating a "matches" bitfield */ -static ZSTD_VecMask ZSTD_Vec128_cmpMask8(ZSTD_Vec128 x, ZSTD_Vec128 y) { - ZSTD_VecMask res = 0; - unsigned i = 0; - unsigned l = 0; - for (; i < VEC128_NB_SIZE_T; ++i) { - const size_t cmp1 = x.vec[i]; - const size_t cmp2 = y.vec[i]; - unsigned j = 0; - for (; j < sizeof(size_t); ++j, ++l) { - if (((cmp1 >> j*8) & 0xFF) == ((cmp2 >> j*8) & 0xFF)) { - res |= ((U32)1 << (j+i*sizeof(size_t))); - } - } - } - return res; -} - -#define VEC256_NB_SIZE_T 2*VEC128_NB_SIZE_T -typedef struct { - size_t vec[VEC256_NB_SIZE_T]; -} ZSTD_Vec256; - -static ZSTD_Vec256 ZSTD_Vec256_read(const void* const src) { - ZSTD_Vec256 ret; - ZSTD_memcpy(ret.vec, src, VEC256_NB_SIZE_T*sizeof(size_t)); - return ret; -} - -static ZSTD_Vec256 ZSTD_Vec256_set8(BYTE val) { - ZSTD_Vec256 ret = { {0} }; - int startBit = sizeof(size_t) * 8 - 8; - for (;startBit >= 0; startBit -= 8) { - unsigned j = 0; - for (;j < VEC256_NB_SIZE_T; ++j) { - ret.vec[j] |= ((size_t)val << startBit); - } - } - return ret; -} - -/* Compare x to y, byte by byte, generating a "matches" bitfield */ -static ZSTD_VecMask ZSTD_Vec256_cmpMask8(ZSTD_Vec256 x, ZSTD_Vec256 y) { - ZSTD_VecMask res = 0; - unsigned i = 0; - unsigned l = 0; - for (; i < VEC256_NB_SIZE_T; ++i) { - const size_t cmp1 = x.vec[i]; - const size_t cmp2 = y.vec[i]; - unsigned j = 0; - for (; j < sizeof(size_t); ++j, ++l) { - if (((cmp1 >> j*8) & 0xFF) == ((cmp2 >> j*8) & 0xFF)) { - res |= ((U32)1 << (j+i*sizeof(size_t))); - } - } - } - return res; -} - -#endif /* !defined(ZSTD_NO_INTRINSICS) && defined(__SSE2__) */ - /* ZSTD_VecMask_next(): * Starting from the LSB, returns the idx of the next non-zero bit. * Basically counting the nb of trailing zeroes. @@ -1085,22 +894,22 @@ static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { # endif } -/* ZSTD_VecMask_rotateRight(): - * Rotates a bitfield to the right by "rotation" bits. - * If the rotation is greater than totalBits, the returned mask is 0. +/* ZSTD_rotateRight_U32(): + * Rotates a bitfield to the right by "count" bits. + * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts */ -FORCE_INLINE_TEMPLATE ZSTD_VecMask -ZSTD_VecMask_rotateRight(ZSTD_VecMask mask, U32 const rotation, U32 const totalBits) { - if (rotation == 0) - return mask; - switch (totalBits) { - default: - assert(0); - case 16: - return (mask >> rotation) | (U16)(mask << (16 - rotation)); - case 32: - return (mask >> rotation) | (U32)(mask << (32 - rotation)); - } +FORCE_INLINE_TEMPLATE +U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { + assert(count < 32); + count &= 0x1F; /* for fickle pattern recognition */ + return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); +} + +FORCE_INLINE_TEMPLATE +U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { + assert(count < 16); + count &= 0x0F; /* for fickle pattern recognition */ + return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); } /* ZSTD_row_nextIndex(): @@ -1226,24 +1035,98 @@ void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) { /* Returns a ZSTD_VecMask (U32) that has the nth bit set to 1 if the newly-computed "tag" matches * the hash at the nth position in a row of the tagTable. - */ + * Each row is a circular buffer beginning at the value of "head". So we must rotate the "matches" bitfield + * to match up with the actual layout of the entries within the hashTable */ FORCE_INLINE_TEMPLATE ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 head, const U32 rowEntries) { - ZSTD_VecMask matches = 0; + const BYTE* const src = tagRow + ZSTD_ROW_HASH_TAG_OFFSET; + assert((rowEntries == 16) || (rowEntries == 32)); +#if defined(ZSTD_ARCH_X86_SSE2) if (rowEntries == 16) { - ZSTD_Vec128 hashes = ZSTD_Vec128_read(tagRow + ZSTD_ROW_HASH_TAG_OFFSET); - ZSTD_Vec128 expandedTags = ZSTD_Vec128_set8(tag); - matches = ZSTD_Vec128_cmpMask8(hashes, expandedTags); - } else if (rowEntries == 32) { - ZSTD_Vec256 hashes = ZSTD_Vec256_read(tagRow + ZSTD_ROW_HASH_TAG_OFFSET); - ZSTD_Vec256 expandedTags = ZSTD_Vec256_set8(tag); - matches = ZSTD_Vec256_cmpMask8(hashes, expandedTags); - } else { - assert(0); + const __m128i chunk = _mm_loadu_si128((const __m128i*)(const void*)src); + const __m128i equalMask = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(tag)); + const U16 matches = (U16)_mm_movemask_epi8(equalMask); + return ZSTD_rotateRight_U16(matches, head); + } else { /* rowEntries == 32 */ + const __m128i chunk0 = _mm_loadu_si128((const __m128i*)(const void*)&src[0]); + const __m128i chunk1 = _mm_loadu_si128((const __m128i*)(const void*)&src[16]); + const __m128i equalMask0 = _mm_cmpeq_epi8(chunk0, _mm_set1_epi8(tag)); + const __m128i equalMask1 = _mm_cmpeq_epi8(chunk1, _mm_set1_epi8(tag)); + const U32 lo = (U32)_mm_movemask_epi8(equalMask0); + const U32 hi = (U32)_mm_movemask_epi8(equalMask1); + return ZSTD_rotateRight_U32((hi << 16) | lo, head); } - /* Each row is a circular buffer beginning at the value of "head". So we must rotate the "matches" bitfield - to match up with the actual layout of the entries within the hashTable */ - return ZSTD_VecMask_rotateRight(matches, head, rowEntries); +#else +# if defined(ZSTD_ARCH_ARM_NEON) + if (MEM_isLittleEndian()) { + if (rowEntries == 16) { + const uint8x16_t chunk = vld1q_u8(src); + const uint16x8_t equalMask = vreinterpretq_u16_u8(vceqq_u8(chunk, vdupq_n_u8(tag))); + const uint16x8_t t0 = vshlq_n_u16(equalMask, 7); + const uint32x4_t t1 = vreinterpretq_u32_u16(vsriq_n_u16(t0, t0, 14)); + const uint64x2_t t2 = vreinterpretq_u64_u32(vshrq_n_u32(t1, 14)); + const uint8x16_t t3 = vreinterpretq_u8_u64(vsraq_n_u64(t2, t2, 28)); + const U16 hi = (U16)vgetq_lane_u8(t3, 8); + const U16 lo = (U16)vgetq_lane_u8(t3, 0); + return ZSTD_rotateRight_U16((hi << 8) | lo, head); + } else { /* rowEntries == 32 */ + const uint16x8x2_t chunk = vld2q_u16((const U16*)(const void*)src); + const uint8x16_t chunk0 = vreinterpretq_u8_u16(chunk.val[0]); + const uint8x16_t chunk1 = vreinterpretq_u8_u16(chunk.val[1]); + const uint8x16_t equalMask0 = vceqq_u8(chunk0, vdupq_n_u8(tag)); + const uint8x16_t equalMask1 = vceqq_u8(chunk1, vdupq_n_u8(tag)); + const int8x8_t pack0 = vqmovn_s16(vreinterpretq_s16_u8(equalMask0)); + const int8x8_t pack1 = vqmovn_s16(vreinterpretq_s16_u8(equalMask1)); + const uint8x8_t t0 = vreinterpret_u8_s8(pack0); + const uint8x8_t t1 = vreinterpret_u8_s8(pack1); + const uint8x8_t t2 = vsri_n_u8(t1, t0, 2); + const uint8x8x2_t t3 = vuzp_u8(t2, t0); + const uint8x8_t t4 = vsri_n_u8(t3.val[1], t3.val[0], 4); + const U32 matches = vget_lane_u32(vreinterpret_u32_u8(t4), 0); + return ZSTD_rotateRight_U32(matches, head); + } + } +# endif + { /* SWAR */ + const size_t chunkSize = sizeof(size_t); + const size_t shiftAmount = ((chunkSize * 8) - chunkSize); + const size_t xFF = ~((size_t)0); + const size_t x01 = xFF / 0xFF; + const size_t x80 = x01 << 7; + const size_t splatChar = tag * x01; + size_t matches = 0; + int i = rowEntries - chunkSize; + assert((sizeof(size_t) == 4) || (sizeof(size_t) == 8)); + if (MEM_isLittleEndian()) { /* runtime check so have two loops */ + const size_t extractMagic = (xFF / 0x7F) >> chunkSize; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= (chunk * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } else { /* big endian: reverse bits during extraction */ + const size_t msb = xFF ^ (xFF >> 1); + const size_t extractMagic = (msb / 0x1FF) | msb; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= ((chunk >> 7) * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } + matches = ~matches; + if (rowEntries == 16) { + return ZSTD_rotateRight_U16((U16)matches, head); + } else { /* rowEntries == 32 */ + return ZSTD_rotateRight_U32((U32)matches, head); + } + } +#endif } /* The high-level approach of the SIMD row based match finder is as follows: From 912bb9fbf3375bb0ebf5ec9445eff43854eef20c Mon Sep 17 00:00:00 2001 From: Goutham Krishna Date: Wed, 9 Jun 2021 12:38:22 +0530 Subject: [PATCH 040/274] Update README for Travis CI Badge ### Updating Badge link to the newTravis CI link. - Update badge root to `api.travis-ci.com` (new) from `travis-ci.org` (old), which was migrated. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dcca7662d..b2ab80998 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ a list of known ports and bindings is provided on [Zstandard homepage](http://ww [![Build status][CirrusDevBadge]][CirrusLink] [![Fuzzing Status][OSSFuzzBadge]][OSSFuzzLink] -[travisDevBadge]: https://travis-ci.org/facebook/zstd.svg?branch=dev "Continuous Integration test suite" -[travisLink]: https://travis-ci.org/facebook/zstd +[travisDevBadge]: https://api.travis-ci.com/facebook/zstd.svg?branch=dev "Continuous Integration test suite" +[travisLink]: https://travis-ci.com/facebook/zstd [AppveyorDevBadge]: https://ci.appveyor.com/api/projects/status/xt38wbdxjk5mrbem/branch/dev?svg=true "Windows test suite" [AppveyorLink]: https://ci.appveyor.com/project/YannCollet/zstd-p0yf0 [CircleDevBadge]: https://circleci.com/gh/facebook/zstd/tree/dev.svg?style=shield "Short test suite" From 6583fa3f0ab8b7ab7c34888a07b20af852a2ef3c Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Wed, 9 Jun 2021 14:00:29 -0400 Subject: [PATCH 041/274] Add support for --long-param flag --- programs/zstdcli.c | 73 +++++++++++++++++++++++++++++++++++----------- tests/playTests.sh | 7 +++++ 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 9e2133c4f..28fc980a2 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -206,6 +206,7 @@ static void usage_advanced(const char* programName) DISPLAYOUT( "--ultra : enable levels beyond %i, up to %i (requires more memory) \n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel()); DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog); DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1); + DISPLAYOUT( "--long-param=#: specify compression level, accepts negative values as fast compression levels \n"); DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n"); DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n"); DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n"); @@ -354,6 +355,25 @@ static unsigned readU32FromChar(const char** stringPtr) { return result; } +#ifndef ZSTD_NOCOMPRESS +/*! readIntFromChar() : + * @return : signed integer value read from input in `char` format. + * allows and interprets K, KB, KiB, M, MB and MiB suffix. + * Will also modify `*stringPtr`, advancing it to position where it stopped reading. + * Note : function will exit() program if digit sequence overflows */ +static int readIntFromChar(const char** stringPtr) { + static const char errorMsg[] = "error: numeric value overflows 32-bit int"; + int sign = 1; + unsigned result; + if (**stringPtr=='-') { + (*stringPtr)++; + sign = -1; + } + if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); } + return (int) result * sign; +} +#endif + /*! readSizeTFromCharChecked() : * @return 0 if success, and store the result in *value. * allows and interprets K, KB, KiB, M, MB and MiB suffix. @@ -940,23 +960,6 @@ int main(int const argCount, const char* argv[]) if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; } #endif if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); continue; } - if (longCommandWArg(&argument, "--long")) { - unsigned ldmWindowLog = 0; - ldmFlag = 1; - /* Parse optional window log */ - if (*argument == '=') { - ++argument; - ldmWindowLog = readU32FromChar(&argument); - } else if (*argument != 0) { - /* Invalid character following --long */ - badusage(programName); - CLEAN_RETURN(1); - } - /* Only set windowLog if not already set by --zstd */ - if (compressionParams.windowLog == 0) - compressionParams.windowLog = ldmWindowLog; - continue; - } #ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */ if (longCommandWArg(&argument, "--fast")) { /* Parse optional acceleration factor */ @@ -981,8 +984,44 @@ int main(int const argCount, const char* argv[]) } continue; } + + if (longCommandWArg(&argument, "--long-param")) { + if (*argument == '=') { + int maxLevel = ZSTD_maxCLevel(); + int minLevel = ZSTD_minCLevel(); + int readLevel; + ++argument; + readLevel = readIntFromChar(&argument); + if (readLevel > maxLevel) readLevel = maxLevel; + if (readLevel < minLevel) readLevel = minLevel; + cLevel = readLevel; + } else { + /* --long-param requires an argument */ + badusage(programName); + CLEAN_RETURN(1); + } + continue; + } #endif + if (longCommandWArg(&argument, "--long")) { + unsigned ldmWindowLog = 0; + ldmFlag = 1; + /* Parse optional window log */ + if (*argument == '=') { + ++argument; + ldmWindowLog = readU32FromChar(&argument); + } else if (*argument != 0) { + /* Invalid character following --long */ + badusage(programName); + CLEAN_RETURN(1); + } + /* Only set windowLog if not already set by --zstd */ + if (compressionParams.windowLog == 0) + compressionParams.windowLog = ldmWindowLog; + continue; + } + if (longCommandWArg(&argument, "--filelist")) { const char* listName; NEXT_FIELD(listName); diff --git a/tests/playTests.sh b/tests/playTests.sh index 252939006..09dae1a29 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -191,6 +191,13 @@ zstd --fast=3 -f tmp # == -3 zstd --fast=200000 -f tmp # too low compression level, automatic fixed zstd --fast=5000000000 -f tmp && die "too large numeric value : must fail" zstd -c --fast=0 tmp > $INTOVOID && die "--fast must not accept value 0" +println "test : --long-param compression levels" +zstd --long-param=1 -f tmp +zstd --long-param=0 -f tmp +zstd --long-param=-1 -f tmp +zstd --long-param=-10000 -f tmp # too low, automatic fixed +zstd --long-param=10000 -f tmp # too high, automatic fixed +zstd --long-param -f tmp > $INTOVOID && die "--long-param must be given a value" println "test : too large numeric argument" zstd --fast=9999999999 -f tmp && die "should have refused numeric value" println "test : set compression level with environment variable ZSTD_CLEVEL" From 325952f878b692b6fb37dcba270ae1ee0ceede53 Mon Sep 17 00:00:00 2001 From: binhdvo Date: Wed, 9 Jun 2021 15:35:43 -0400 Subject: [PATCH 042/274] Revert "Add support for --long-param flag, fix #2104" --- programs/zstdcli.c | 73 +++++++++++----------------------------------- tests/playTests.sh | 7 ----- 2 files changed, 17 insertions(+), 63 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 28fc980a2..9e2133c4f 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -206,7 +206,6 @@ static void usage_advanced(const char* programName) DISPLAYOUT( "--ultra : enable levels beyond %i, up to %i (requires more memory) \n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel()); DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog); DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1); - DISPLAYOUT( "--long-param=#: specify compression level, accepts negative values as fast compression levels \n"); DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n"); DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n"); DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n"); @@ -355,25 +354,6 @@ static unsigned readU32FromChar(const char** stringPtr) { return result; } -#ifndef ZSTD_NOCOMPRESS -/*! readIntFromChar() : - * @return : signed integer value read from input in `char` format. - * allows and interprets K, KB, KiB, M, MB and MiB suffix. - * Will also modify `*stringPtr`, advancing it to position where it stopped reading. - * Note : function will exit() program if digit sequence overflows */ -static int readIntFromChar(const char** stringPtr) { - static const char errorMsg[] = "error: numeric value overflows 32-bit int"; - int sign = 1; - unsigned result; - if (**stringPtr=='-') { - (*stringPtr)++; - sign = -1; - } - if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); } - return (int) result * sign; -} -#endif - /*! readSizeTFromCharChecked() : * @return 0 if success, and store the result in *value. * allows and interprets K, KB, KiB, M, MB and MiB suffix. @@ -960,6 +940,23 @@ int main(int const argCount, const char* argv[]) if (longCommandWArg(&argument, "--trace")) { char const* traceFile; NEXT_FIELD(traceFile); TRACE_enable(traceFile); continue; } #endif if (longCommandWArg(&argument, "--patch-from")) { NEXT_FIELD(patchFromDictFileName); continue; } + if (longCommandWArg(&argument, "--long")) { + unsigned ldmWindowLog = 0; + ldmFlag = 1; + /* Parse optional window log */ + if (*argument == '=') { + ++argument; + ldmWindowLog = readU32FromChar(&argument); + } else if (*argument != 0) { + /* Invalid character following --long */ + badusage(programName); + CLEAN_RETURN(1); + } + /* Only set windowLog if not already set by --zstd */ + if (compressionParams.windowLog == 0) + compressionParams.windowLog = ldmWindowLog; + continue; + } #ifndef ZSTD_NOCOMPRESS /* linking ZSTD_minCLevel() requires compression support */ if (longCommandWArg(&argument, "--fast")) { /* Parse optional acceleration factor */ @@ -984,44 +981,8 @@ int main(int const argCount, const char* argv[]) } continue; } - - if (longCommandWArg(&argument, "--long-param")) { - if (*argument == '=') { - int maxLevel = ZSTD_maxCLevel(); - int minLevel = ZSTD_minCLevel(); - int readLevel; - ++argument; - readLevel = readIntFromChar(&argument); - if (readLevel > maxLevel) readLevel = maxLevel; - if (readLevel < minLevel) readLevel = minLevel; - cLevel = readLevel; - } else { - /* --long-param requires an argument */ - badusage(programName); - CLEAN_RETURN(1); - } - continue; - } #endif - if (longCommandWArg(&argument, "--long")) { - unsigned ldmWindowLog = 0; - ldmFlag = 1; - /* Parse optional window log */ - if (*argument == '=') { - ++argument; - ldmWindowLog = readU32FromChar(&argument); - } else if (*argument != 0) { - /* Invalid character following --long */ - badusage(programName); - CLEAN_RETURN(1); - } - /* Only set windowLog if not already set by --zstd */ - if (compressionParams.windowLog == 0) - compressionParams.windowLog = ldmWindowLog; - continue; - } - if (longCommandWArg(&argument, "--filelist")) { const char* listName; NEXT_FIELD(listName); diff --git a/tests/playTests.sh b/tests/playTests.sh index 09dae1a29..252939006 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -191,13 +191,6 @@ zstd --fast=3 -f tmp # == -3 zstd --fast=200000 -f tmp # too low compression level, automatic fixed zstd --fast=5000000000 -f tmp && die "too large numeric value : must fail" zstd -c --fast=0 tmp > $INTOVOID && die "--fast must not accept value 0" -println "test : --long-param compression levels" -zstd --long-param=1 -f tmp -zstd --long-param=0 -f tmp -zstd --long-param=-1 -f tmp -zstd --long-param=-10000 -f tmp # too low, automatic fixed -zstd --long-param=10000 -f tmp # too high, automatic fixed -zstd --long-param -f tmp > $INTOVOID && die "--long-param must be given a value" println "test : too large numeric argument" zstd --fast=9999999999 -f tmp && die "should have refused numeric value" println "test : set compression level with environment variable ZSTD_CLEVEL" From 26fab1d963b70b5673e7a7405735818f7b6e30bd Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 20:25:31 -0700 Subject: [PATCH 043/274] Make the CLI output the file sizes in human readable format --- programs/fileio.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index a67c0fbfb..9d3054b1c 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1527,6 +1527,26 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, return compressedfilesize; } +char* human_size(long size, char* str) { + if (size > 1125899906842624L) { + snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); + } else if (size > 1099511627776L) { + snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); + } else if (size > 1073741824L) { + snprintf(str, 7, "%.1fG", (float)size / 1073741824L); + } else if (size > 1048576L) { + snprintf(str, 7, "%.1fM", (float)size / 1048576L); + } else if (size > 1024) { + snprintf(str, 7, "%.1fK", (float)size / 1024); + } else if (size >= 0) { + snprintf(str, 7, "%dB", size); + } else { + str[0] = '\0'; + } + + return str; +} + /*! FIO_compressFilename_internal() : * same as FIO_compressFilename_extRess(), with `ress.desFile` already opened. * @return : 0 : compression completed correctly, @@ -1598,10 +1618,16 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); } else { - DISPLAYLEVEL(2,"%-20s :%6.2f%% (%6llu => %6llu bytes, %s) \n", + char input_size_str[8] = ""; + human_size((unsigned long long) readsize, input_size_str); + + char output_size_str[8] = ""; + human_size((unsigned long long) compressedfilesize, output_size_str); + + DISPLAYLEVEL(2,"%-20s :%6.2f%% (%s => %s, %s) \n", srcFileName, (double)compressedfilesize / (double)readsize * 100, - (unsigned long long)readsize, (unsigned long long) compressedfilesize, + input_size_str, output_size_str, dstFileName); } } From b70175e5ec51294115f311db3d77c104b557a14e Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 20:28:55 -0700 Subject: [PATCH 044/274] Put the human_size() function in util.c --- programs/fileio.c | 20 -------------------- programs/util.c | 21 +++++++++++++++++++++ programs/util.h | 2 ++ 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 9d3054b1c..b29295586 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1527,26 +1527,6 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, return compressedfilesize; } -char* human_size(long size, char* str) { - if (size > 1125899906842624L) { - snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); - } else if (size > 1099511627776L) { - snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); - } else if (size > 1073741824L) { - snprintf(str, 7, "%.1fG", (float)size / 1073741824L); - } else if (size > 1048576L) { - snprintf(str, 7, "%.1fM", (float)size / 1048576L); - } else if (size > 1024) { - snprintf(str, 7, "%.1fK", (float)size / 1024); - } else if (size >= 0) { - snprintf(str, 7, "%dB", size); - } else { - str[0] = '\0'; - } - - return str; -} - /*! FIO_compressFilename_internal() : * same as FIO_compressFilename_extRess(), with `ress.desFile` already opened. * @return : 0 : compression completed correctly, diff --git a/programs/util.c b/programs/util.c index 8d190c62c..d942d3732 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,6 +121,27 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ +char* human_size(long size, char* str) { + if (size > 1125899906842624L) { + snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); + } else if (size > 1099511627776L) { + snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); + } else if (size > 1073741824L) { + snprintf(str, 7, "%.1fG", (float)size / 1073741824L); + } else if (size > 1048576L) { + snprintf(str, 7, "%.1fM", (float)size / 1048576L); + } else if (size > 1024) { + snprintf(str, 7, "%.1fK", (float)size / 1024); + } else if (size >= 0) { + snprintf(str, 7, "%dB", size); + } else { + str[0] = '\0'; + } + + return str; +} + + int UTIL_stat(const char* filename, stat_t* statbuf) { #if defined(_MSC_VER) diff --git a/programs/util.h b/programs/util.h index 24cce4480..415b01f1b 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,6 +122,8 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif +char* human_size(long size, char* str); + /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. * Returns success (1) or failure (0). From b6b23dfe64e2ff52e52d2eeed7e68ebc70249178 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 21:44:40 -0700 Subject: [PATCH 045/274] Convert names to CamelCase --- programs/fileio.c | 10 +++++----- programs/util.c | 2 +- programs/util.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index b29295586..b5beb145c 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1598,16 +1598,16 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); } else { - char input_size_str[8] = ""; - human_size((unsigned long long) readsize, input_size_str); + char inputSizeStr[8] = ""; + humanSize((unsigned long long) readsize, inputSizeStr); - char output_size_str[8] = ""; - human_size((unsigned long long) compressedfilesize, output_size_str); + char outputSizeStr[8] = ""; + humanSize((unsigned long long) compressedfilesize, outputSizeStr); DISPLAYLEVEL(2,"%-20s :%6.2f%% (%s => %s, %s) \n", srcFileName, (double)compressedfilesize / (double)readsize * 100, - input_size_str, output_size_str, + inputSizeStr, outputSizeStr, dstFileName); } } diff --git a/programs/util.c b/programs/util.c index d942d3732..5aec11184 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,7 +121,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ -char* human_size(long size, char* str) { +char* humanSize(long size, char* str) { if (size > 1125899906842624L) { snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); } else if (size > 1099511627776L) { diff --git a/programs/util.h b/programs/util.h index 415b01f1b..aaaf2522c 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,7 +122,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif -char* human_size(long size, char* str); +char* humanSize(long size, char* str); /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. From eefdbcd93aa296df9a72ba75a53201bb10a3a2ae Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 22:02:32 -0700 Subject: [PATCH 046/274] Make the variable types match --- programs/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/util.c b/programs/util.c index 5aec11184..6d04b8fb7 100644 --- a/programs/util.c +++ b/programs/util.c @@ -133,7 +133,7 @@ char* humanSize(long size, char* str) { } else if (size > 1024) { snprintf(str, 7, "%.1fK", (float)size / 1024); } else if (size >= 0) { - snprintf(str, 7, "%dB", size); + snprintf(str, 7, "%dB", 0); } else { str[0] = '\0'; } From 4e0d9f1cc83a0795a2eb8401dc92369a899614c1 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 22:03:33 -0700 Subject: [PATCH 047/274] Move the variable declarations to the top --- programs/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index b5beb145c..b347da423 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1544,6 +1544,9 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, U64 readsize = 0; U64 compressedfilesize = 0; U64 const fileSize = UTIL_getFileSize(srcFileName); + char inputSizeStr[8] = ""; + char outputSizeStr[8] = ""; + DISPLAYLEVEL(5, "%s: %llu bytes \n", srcFileName, (unsigned long long)fileSize); /* compression format selection */ @@ -1598,10 +1601,7 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); } else { - char inputSizeStr[8] = ""; humanSize((unsigned long long) readsize, inputSizeStr); - - char outputSizeStr[8] = ""; humanSize((unsigned long long) compressedfilesize, outputSizeStr); DISPLAYLEVEL(2,"%-20s :%6.2f%% (%s => %s, %s) \n", From 894698d3b61583fb539f355584db576b7e0635c5 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 22:09:40 -0700 Subject: [PATCH 048/274] Use human_size() in the benchmark output also --- programs/benchzstd.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 49c03490d..954c9282d 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -388,6 +388,8 @@ BMK_benchMemAdvancedNoAlloc( # define NB_MARKS 4 const char* marks[NB_MARKS] = { " |", " /", " =", " \\" }; U32 markNb = 0; + char inputSizeStr[8] = ""; + char outputSizeStr[8] = ""; int compressionCompleted = (adv->mode == BMK_decodeOnly); int decompressionCompleted = (adv->mode == BMK_compressOnly); BMK_benchParams_t cbp, dbp; @@ -429,8 +431,10 @@ BMK_benchMemAdvancedNoAlloc( dctxprep.dictBuffer = dictBuffer; dctxprep.dictBufferSize = dictBufferSize; + humanSize((unsigned)srcSize, inputSizeStr); + DISPLAYLEVEL(2, "\r%70s\r", ""); /* blank line */ - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->\r", marks[markNb], displayName, (unsigned)srcSize); + DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> \r", marks[markNb], displayName, inputSizeStr); while (!(compressionCompleted && decompressionCompleted)) { if (!compressionCompleted) { @@ -451,9 +455,13 @@ BMK_benchMemAdvancedNoAlloc( } } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f),%6.*f MB/s\r", + + humanSize((unsigned)srcSize, inputSizeStr); + humanSize((unsigned)cSize, outputSizeStr); + + DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s\r", marks[markNb], displayName, - (unsigned)srcSize, (unsigned)cSize, + inputSizeStr, outputSizeStr, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); } @@ -474,9 +482,13 @@ BMK_benchMemAdvancedNoAlloc( } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", + + humanSize((unsigned)srcSize, inputSizeStr); + humanSize((unsigned)cSize, outputSizeStr); + + DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", marks[markNb], displayName, - (unsigned)srcSize, (unsigned)cSize, + inputSizeStr, outputSizeStr, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, (double)benchResult.dSpeed / MB_UNIT); From 77001f00fb30ee63f10c96b89b4d6ccfb00078b4 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Fri, 4 Jun 2021 22:21:00 -0700 Subject: [PATCH 049/274] Use human_size() on the "multiple files compressed" output also --- programs/fileio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index b347da423..7432348c0 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1841,6 +1841,8 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, { int status; int error = 0; + char inputSizeStr[8] = ""; + char outputSizeStr[8] = ""; cRess_t ress = FIO_createCResources(prefs, dictFileName, FIO_getLargestFileSize(inFileNamesTable, (unsigned)fCtx->nbFilesTotal), compressionLevel, comprParams); @@ -1896,10 +1898,13 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, } if (fCtx->nbFilesProcessed >= 1 && fCtx->nbFilesTotal > 1 && fCtx->totalBytesInput != 0) { + humanSize((unsigned long long) fCtx->totalBytesInput, inputSizeStr); + humanSize((unsigned long long) fCtx->totalBytesOutput, outputSizeStr); + DISPLAYLEVEL(2, "\r%79s\r", ""); - DISPLAYLEVEL(2, "%d files compressed : %.2f%% (%6zu => %6zu bytes)\n", fCtx->nbFilesProcessed, + DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%s => %s bytes)\n", fCtx->nbFilesProcessed, (double)fCtx->totalBytesOutput/((double)fCtx->totalBytesInput)*100, - fCtx->totalBytesInput, fCtx->totalBytesOutput); + inputSizeStr, outputSizeStr); } FIO_freeCResources(&ress); From 35576e63ce5f770b99306c5730244e310c0f0aed Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Sat, 5 Jun 2021 07:41:26 -0700 Subject: [PATCH 050/274] Convert tabs to spaces --- programs/benchzstd.c | 14 +++++++------- programs/fileio.c | 16 ++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 954c9282d..b4c73d73d 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -388,8 +388,8 @@ BMK_benchMemAdvancedNoAlloc( # define NB_MARKS 4 const char* marks[NB_MARKS] = { " |", " /", " =", " \\" }; U32 markNb = 0; - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; + char inputSizeStr[8] = ""; + char outputSizeStr[8] = ""; int compressionCompleted = (adv->mode == BMK_decodeOnly); int decompressionCompleted = (adv->mode == BMK_compressOnly); BMK_benchParams_t cbp, dbp; @@ -431,7 +431,7 @@ BMK_benchMemAdvancedNoAlloc( dctxprep.dictBuffer = dictBuffer; dctxprep.dictBufferSize = dictBufferSize; - humanSize((unsigned)srcSize, inputSizeStr); + humanSize((unsigned)srcSize, inputSizeStr); DISPLAYLEVEL(2, "\r%70s\r", ""); /* blank line */ DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> \r", marks[markNb], displayName, inputSizeStr); @@ -456,8 +456,8 @@ BMK_benchMemAdvancedNoAlloc( { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - humanSize((unsigned)srcSize, inputSizeStr); - humanSize((unsigned)cSize, outputSizeStr); + humanSize((unsigned)srcSize, inputSizeStr); + humanSize((unsigned)cSize, outputSizeStr); DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s\r", marks[markNb], displayName, @@ -483,8 +483,8 @@ BMK_benchMemAdvancedNoAlloc( { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - humanSize((unsigned)srcSize, inputSizeStr); - humanSize((unsigned)cSize, outputSizeStr); + humanSize((unsigned)srcSize, inputSizeStr); + humanSize((unsigned)cSize, outputSizeStr); DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", marks[markNb], displayName, diff --git a/programs/fileio.c b/programs/fileio.c index 7432348c0..cf65c2828 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1544,8 +1544,8 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, U64 readsize = 0; U64 compressedfilesize = 0; U64 const fileSize = UTIL_getFileSize(srcFileName); - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; + char inputSizeStr[8] = ""; + char outputSizeStr[8] = ""; DISPLAYLEVEL(5, "%s: %llu bytes \n", srcFileName, (unsigned long long)fileSize); @@ -1601,8 +1601,8 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); } else { - humanSize((unsigned long long) readsize, inputSizeStr); - humanSize((unsigned long long) compressedfilesize, outputSizeStr); + humanSize((unsigned long long) readsize, inputSizeStr); + humanSize((unsigned long long) compressedfilesize, outputSizeStr); DISPLAYLEVEL(2,"%-20s :%6.2f%% (%s => %s, %s) \n", srcFileName, @@ -1841,8 +1841,8 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, { int status; int error = 0; - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; + char inputSizeStr[8] = ""; + char outputSizeStr[8] = ""; cRess_t ress = FIO_createCResources(prefs, dictFileName, FIO_getLargestFileSize(inFileNamesTable, (unsigned)fCtx->nbFilesTotal), compressionLevel, comprParams); @@ -1898,8 +1898,8 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, } if (fCtx->nbFilesProcessed >= 1 && fCtx->nbFilesTotal > 1 && fCtx->totalBytesInput != 0) { - humanSize((unsigned long long) fCtx->totalBytesInput, inputSizeStr); - humanSize((unsigned long long) fCtx->totalBytesOutput, outputSizeStr); + humanSize((unsigned long long) fCtx->totalBytesInput, inputSizeStr); + humanSize((unsigned long long) fCtx->totalBytesOutput, outputSizeStr); DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%s => %s bytes)\n", fCtx->nbFilesProcessed, From e5fc830795f2966d0198bf3b6523e86984fbf4fa Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Sat, 5 Jun 2021 08:45:35 -0700 Subject: [PATCH 051/274] human_size() should use size_t --- programs/util.c | 6 +++--- programs/util.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/util.c b/programs/util.c index 6d04b8fb7..cdfda1ca0 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,7 +121,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ -char* humanSize(long size, char* str) { +char* humanSize(size_t size, char* str) { if (size > 1125899906842624L) { snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); } else if (size > 1099511627776L) { @@ -132,8 +132,8 @@ char* humanSize(long size, char* str) { snprintf(str, 7, "%.1fM", (float)size / 1048576L); } else if (size > 1024) { snprintf(str, 7, "%.1fK", (float)size / 1024); - } else if (size >= 0) { - snprintf(str, 7, "%dB", 0); + } else if (size <= 1024) { + snprintf(str, 7, "%luB", size); } else { str[0] = '\0'; } diff --git a/programs/util.h b/programs/util.h index aaaf2522c..8ac930d8c 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,7 +122,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif -char* humanSize(long size, char* str); +char* humanSize(size_t size, char* str); /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. From 1ef6f3d079b2415c6bdea61c944a1a0cea3a9a28 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Sat, 5 Jun 2021 10:06:40 -0700 Subject: [PATCH 052/274] Use unsigned long instead to help with some tests --- programs/util.c | 2 +- programs/util.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/util.c b/programs/util.c index cdfda1ca0..e7acc6cbb 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,7 +121,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ -char* humanSize(size_t size, char* str) { +char* humanSize(unsigned long size, char* str) { if (size > 1125899906842624L) { snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); } else if (size > 1099511627776L) { diff --git a/programs/util.h b/programs/util.h index 8ac930d8c..21e93d7d7 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,7 +122,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif -char* humanSize(size_t size, char* str); +char* humanSize(unsigned long size, char* str); /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. From 64385ef7cbb3388ceacb7611f29b2f0a03bdf477 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Sat, 5 Jun 2021 10:30:21 -0700 Subject: [PATCH 053/274] Update humanSize() to skip the big numbers (it requires 64 bit) --- programs/util.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/programs/util.c b/programs/util.c index e7acc6cbb..c2883ba7d 100644 --- a/programs/util.c +++ b/programs/util.c @@ -122,11 +122,15 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, ***************************************/ char* humanSize(unsigned long size, char* str) { + /* This only works on 64 bit platforms so I commented it out for now */ + /* if (size > 1125899906842624L) { snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); } else if (size > 1099511627776L) { snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); - } else if (size > 1073741824L) { + */ + + if (size > 1073741824L) { snprintf(str, 7, "%.1fG", (float)size / 1073741824L); } else if (size > 1048576L) { snprintf(str, 7, "%.1fM", (float)size / 1048576L); From 20b9b00b413c799bef54bfeb2a36256f11d65b06 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Sat, 5 Jun 2021 11:11:09 -0700 Subject: [PATCH 054/274] Try unsigned long long --- programs/util.c | 4 ++-- programs/util.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/util.c b/programs/util.c index c2883ba7d..1ca8eec19 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,7 +121,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ -char* humanSize(unsigned long size, char* str) { +char* humanSize(unsigned long long size, char* str) { /* This only works on 64 bit platforms so I commented it out for now */ /* if (size > 1125899906842624L) { @@ -137,7 +137,7 @@ char* humanSize(unsigned long size, char* str) { } else if (size > 1024) { snprintf(str, 7, "%.1fK", (float)size / 1024); } else if (size <= 1024) { - snprintf(str, 7, "%luB", size); + snprintf(str, 7, "%lluB", size); } else { str[0] = '\0'; } diff --git a/programs/util.h b/programs/util.h index 21e93d7d7..0eb64c013 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,7 +122,7 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif -char* humanSize(unsigned long size, char* str); +char* humanSize(unsigned long long size, char* str); /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. From 376a2730a8fbcefce94b33ed485a8b5ea606eb5e Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Sat, 5 Jun 2021 11:12:09 -0700 Subject: [PATCH 055/274] Try enabling the BIG strings now the unsigned long long is in effect --- programs/util.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/programs/util.c b/programs/util.c index 1ca8eec19..f99bf82c5 100644 --- a/programs/util.c +++ b/programs/util.c @@ -122,27 +122,23 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, ***************************************/ char* humanSize(unsigned long long size, char* str) { - /* This only works on 64 bit platforms so I commented it out for now */ - /* - if (size > 1125899906842624L) { - snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); - } else if (size > 1099511627776L) { - snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); - */ + if (size > 1125899906842624L) { + snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); + } else if (size > 1099511627776L) { + snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); + } else if (size > 1073741824L) { + snprintf(str, 7, "%.1fG", (float)size / 1073741824L); + } else if (size > 1048576L) { + snprintf(str, 7, "%.1fM", (float)size / 1048576L); + } else if (size > 1024) { + snprintf(str, 7, "%.1fK", (float)size / 1024); + } else if (size <= 1024) { + snprintf(str, 7, "%lluB", size); + } else { + str[0] = '\0'; + } - if (size > 1073741824L) { - snprintf(str, 7, "%.1fG", (float)size / 1073741824L); - } else if (size > 1048576L) { - snprintf(str, 7, "%.1fM", (float)size / 1048576L); - } else if (size > 1024) { - snprintf(str, 7, "%.1fK", (float)size / 1024); - } else if (size <= 1024) { - snprintf(str, 7, "%lluB", size); - } else { - str[0] = '\0'; - } - - return str; + return str; } From 1eb852854b48f7258b74d4e781e036db1b260607 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Mon, 7 Jun 2021 09:31:38 -0700 Subject: [PATCH 056/274] Some fixes to address things @felixhandte found --- programs/util.c | 10 +++++++--- programs/util.h | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/programs/util.c b/programs/util.c index f99bf82c5..934ec526d 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,8 +121,14 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ +/* + * Take a size in bytes and output a human readable string. Maximum + * buffer size is 8 but it's usually 7. Example: "123.4G" +*/ char* humanSize(unsigned long long size, char* str) { - if (size > 1125899906842624L) { + if (size > 1152921504606846976L) { + snprintf(str, 7, "%.1fE", (float)size / 1152921504606846976L); + } else if (size > 1125899906842624L) { snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); } else if (size > 1099511627776L) { snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); @@ -134,8 +140,6 @@ char* humanSize(unsigned long long size, char* str) { snprintf(str, 7, "%.1fK", (float)size / 1024); } else if (size <= 1024) { snprintf(str, 7, "%lluB", size); - } else { - str[0] = '\0'; } return str; diff --git a/programs/util.h b/programs/util.h index 0eb64c013..ba2ae13c8 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,6 +122,10 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif +/* + * Take a size in bytes and output a human readable string. Maximum + * buffer size is 8 but it's usually 7. Example: "123.4G" +*/ char* humanSize(unsigned long long size, char* str); /** From 8e0a9695d7a28087c14ca62ed15570021311a263 Mon Sep 17 00:00:00 2001 From: Scott Baker Date: Mon, 7 Jun 2021 13:53:55 -0700 Subject: [PATCH 057/274] Attempt to fix a failing test with help from @aqrit --- programs/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/util.c b/programs/util.c index 934ec526d..691613940 100644 --- a/programs/util.c +++ b/programs/util.c @@ -139,7 +139,7 @@ char* humanSize(unsigned long long size, char* str) { } else if (size > 1024) { snprintf(str, 7, "%.1fK", (float)size / 1024); } else if (size <= 1024) { - snprintf(str, 7, "%lluB", size); + snprintf(str, 7, "%uB", (unsigned)size); } return str; From bbb81c8801006d8a4bcc10d2605da2cb1eda1662 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 13:05:44 -0400 Subject: [PATCH 058/274] Avoid `snprintf()` in Preparing Human-Readable Sizes; Improve Formatting This produces the following formatting: Size | `zstd` | `ls -lh` ---------- | ------ | -------- 1 | 1 | 1 12 | 12 | 12 123 | 123 | 123 1234 | 1.21K | 1.3K 12345 | 12.1K | 13K 123456 | 121K | 121K 1234567 | 1.18M | 1.2M 12345678 | 11.8M | 12M 123456789 | 118M | 118M 1234567890 | 1.15G | 1.2G 999 | 999 | 999 1000 | 1000 | 1000 1001 | 1001 | 1001 1023 | 1023 | 1023 1024 | 1.000K | 1.0K 1025 | 1.00K | 1.1K 999999 | 977K | 977K 1000000 | 977K | 977K 1000001 | 977K | 977K 1023999 | 1000K | 1000K 1024000 | 1000K | 1000K 1024001 | 1000K | 1001K 1048575 | 1024K | 1.0M 1048576 | 1.000M | 1.0M 1048577 | 1.00M | 1.1M This was produced with the following invocation: ``` for N in 1 12 123 1234 12345 123456 1234567 12345678 123456789 1234567890 999 1000 1001 1023 1024 1025 999999 1000000 1000001 1023999 1024000 1024001 1048575 1048576 1048577; do head -c $N /dev/urandom > r$N done ./zstd -i1 -b1 -S r1 r12 r123 r1234 r12345 r123456 r1234567 r12345678 r123456789 r1234567890 r999 r1000 r1001 r1023 r1024 r1025 r999999 r1000000 r1000001 r1023999 r1024000 r1024001 r1048575 r1048576 r1048577 ``` --- programs/benchzstd.c | 28 +++++++++----------- programs/fileio.c | 24 ++++++++--------- programs/util.c | 62 ++++++++++++++++++++++++++------------------ programs/util.h | 18 +++++++++---- 4 files changed, 73 insertions(+), 59 deletions(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index b4c73d73d..db051781a 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -388,13 +388,13 @@ BMK_benchMemAdvancedNoAlloc( # define NB_MARKS 4 const char* marks[NB_MARKS] = { " |", " /", " =", " \\" }; U32 markNb = 0; - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; int compressionCompleted = (adv->mode == BMK_decodeOnly); int decompressionCompleted = (adv->mode == BMK_compressOnly); BMK_benchParams_t cbp, dbp; BMK_initCCtxArgs cctxprep; BMK_initDCtxArgs dctxprep; + UTIL_HumanReadableSize_t hr_isize; + UTIL_HumanReadableSize_t hr_osize; cbp.benchFn = local_defaultCompress; /* ZSTD_compress2 */ cbp.benchPayload = cctx; @@ -431,10 +431,10 @@ BMK_benchMemAdvancedNoAlloc( dctxprep.dictBuffer = dictBuffer; dctxprep.dictBufferSize = dictBufferSize; - humanSize((unsigned)srcSize, inputSizeStr); + hr_isize = UTIL_makeHumanReadableSize((U64) srcSize); DISPLAYLEVEL(2, "\r%70s\r", ""); /* blank line */ - DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> \r", marks[markNb], displayName, inputSizeStr); + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> \r", marks[markNb], displayName, hr_isize.precision, hr_isize.value, hr_isize.suffix); while (!(compressionCompleted && decompressionCompleted)) { if (!compressionCompleted) { @@ -455,13 +455,11 @@ BMK_benchMemAdvancedNoAlloc( } } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - - humanSize((unsigned)srcSize, inputSizeStr); - humanSize((unsigned)cSize, outputSizeStr); - - DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s\r", + hr_osize = UTIL_makeHumanReadableSize((U64) cSize); + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f),%6.*f MB/s\r", marks[markNb], displayName, - inputSizeStr, outputSizeStr, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); } @@ -482,13 +480,11 @@ BMK_benchMemAdvancedNoAlloc( } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - - humanSize((unsigned)srcSize, inputSizeStr); - humanSize((unsigned)cSize, outputSizeStr); - - DISPLAYLEVEL(2, "%2s-%-17.17s : %s -> %s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", + hr_osize = UTIL_makeHumanReadableSize((U64) cSize); + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", marks[markNb], displayName, - inputSizeStr, outputSizeStr, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, (double)benchResult.dSpeed / MB_UNIT); diff --git a/programs/fileio.c b/programs/fileio.c index cf65c2828..c83c4fffd 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1544,9 +1544,6 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, U64 readsize = 0; U64 compressedfilesize = 0; U64 const fileSize = UTIL_getFileSize(srcFileName); - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; - DISPLAYLEVEL(5, "%s: %llu bytes \n", srcFileName, (unsigned long long)fileSize); /* compression format selection */ @@ -1601,13 +1598,14 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, (unsigned long long)readsize, (unsigned long long) compressedfilesize, dstFileName); } else { - humanSize((unsigned long long) readsize, inputSizeStr); - humanSize((unsigned long long) compressedfilesize, outputSizeStr); + UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) readsize); + UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) compressedfilesize); - DISPLAYLEVEL(2,"%-20s :%6.2f%% (%s => %s, %s) \n", + DISPLAYLEVEL(2,"%-20s :%6.2f%% (%.*f%s => %.*f%s, %s) \n", srcFileName, (double)compressedfilesize / (double)readsize * 100, - inputSizeStr, outputSizeStr, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, dstFileName); } } @@ -1841,8 +1839,6 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, { int status; int error = 0; - char inputSizeStr[8] = ""; - char outputSizeStr[8] = ""; cRess_t ress = FIO_createCResources(prefs, dictFileName, FIO_getLargestFileSize(inFileNamesTable, (unsigned)fCtx->nbFilesTotal), compressionLevel, comprParams); @@ -1898,13 +1894,15 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, } if (fCtx->nbFilesProcessed >= 1 && fCtx->nbFilesTotal > 1 && fCtx->totalBytesInput != 0) { - humanSize((unsigned long long) fCtx->totalBytesInput, inputSizeStr); - humanSize((unsigned long long) fCtx->totalBytesOutput, outputSizeStr); + UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) fCtx->totalBytesInput); + UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) fCtx->totalBytesOutput); DISPLAYLEVEL(2, "\r%79s\r", ""); - DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%s => %s bytes)\n", fCtx->nbFilesProcessed, + DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%.*f%s => %.*f%s bytes)\n", + fCtx->nbFilesProcessed, (double)fCtx->totalBytesOutput/((double)fCtx->totalBytesInput)*100, - inputSizeStr, outputSizeStr); + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix); } FIO_freeCResources(&ress); diff --git a/programs/util.c b/programs/util.c index 691613940..347f5cc2f 100644 --- a/programs/util.c +++ b/programs/util.c @@ -121,31 +121,6 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, * Functions ***************************************/ -/* - * Take a size in bytes and output a human readable string. Maximum - * buffer size is 8 but it's usually 7. Example: "123.4G" -*/ -char* humanSize(unsigned long long size, char* str) { - if (size > 1152921504606846976L) { - snprintf(str, 7, "%.1fE", (float)size / 1152921504606846976L); - } else if (size > 1125899906842624L) { - snprintf(str, 7, "%.1fP", (float)size / 1125899906842624L); - } else if (size > 1099511627776L) { - snprintf(str, 7, "%.1fT", (float)size / 1099511627776L); - } else if (size > 1073741824L) { - snprintf(str, 7, "%.1fG", (float)size / 1073741824L); - } else if (size > 1048576L) { - snprintf(str, 7, "%.1fM", (float)size / 1048576L); - } else if (size > 1024) { - snprintf(str, 7, "%.1fK", (float)size / 1024); - } else if (size <= 1024) { - snprintf(str, 7, "%uB", (unsigned)size); - } - - return str; -} - - int UTIL_stat(const char* filename, stat_t* statbuf) { #if defined(_MSC_VER) @@ -328,6 +303,43 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) return (U64)statbuf->st_size; } +UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { + UTIL_HumanReadableSize_t hrs; + if (size >= (1L << 60)) { + hrs.value = (float)size / (1L << 60); + hrs.suffix = "E"; + } else if (size >= (1L << 50)) { + hrs.value = (float)size / (1L << 50); + hrs.suffix = "P"; + } else if (size >= (1L << 40)) { + hrs.value = (float)size / (1L << 40); + hrs.suffix = "T"; + } else if (size >= (1L << 30)) { + hrs.value = (float)size / (1L << 30); + hrs.suffix = "G"; + } else if (size >= (1L << 20)) { + hrs.value = (float)size / (1L << 20); + hrs.suffix = "M"; + } else if (size >= (1L << 10)) { + hrs.value = (float)size / (1L << 10); + hrs.suffix = "K"; + } else { + hrs.value = (float)size; + hrs.suffix = ""; + } + + if (hrs.value >= 100 || (U64)hrs.value == size) { + hrs.precision = 0; + } else if (hrs.value > 10) { + hrs.precision = 1; + } else if (hrs.value > 1) { + hrs.precision = 2; + } else { + hrs.precision = 3; + } + + return hrs; +} U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles) { diff --git a/programs/util.h b/programs/util.h index ba2ae13c8..63cd0c378 100644 --- a/programs/util.h +++ b/programs/util.h @@ -122,11 +122,6 @@ int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const #define STRDUP(s) strdup(s) #endif -/* - * Take a size in bytes and output a human readable string. Maximum - * buffer size is 8 but it's usually 7. Example: "123.4G" -*/ -char* humanSize(unsigned long long size, char* str); /** * Calls platform's equivalent of stat() on filename and writes info to statbuf. @@ -176,6 +171,19 @@ int UTIL_isFIFO(const char* infilename); U64 UTIL_getFileSize(const char* infilename); U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); +/** + * Take a size in bytes and prepare the components to pretty-print it in a + * scaled way. The components in the returned struct should be passed in + * precision, value, suffix order to a "%.*f%s" format string. + */ +typedef struct { + float value; + int precision; + const char* suffix; +} UTIL_HumanReadableSize_t; + +UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size); + int UTIL_compareStr(const void *p1, const void *p2); const char* UTIL_getFileExtension(const char* infilename); void UTIL_mirrorSourceFilesDirectories(const char** fileNamesTable, unsigned int nbFiles, const char *outDirName); From 9b67219b1e961574724f2c4fb9f2796430e7fccf Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 13:27:57 -0400 Subject: [PATCH 059/274] Fix Integer Constants; Fix Comparison --- programs/util.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/programs/util.c b/programs/util.c index 347f5cc2f..964d60ee2 100644 --- a/programs/util.c +++ b/programs/util.c @@ -305,23 +305,23 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { UTIL_HumanReadableSize_t hrs; - if (size >= (1L << 60)) { - hrs.value = (float)size / (1L << 60); + if (size >= (1ull << 60)) { + hrs.value = (float)size / (1ull << 60); hrs.suffix = "E"; - } else if (size >= (1L << 50)) { - hrs.value = (float)size / (1L << 50); + } else if (size >= (1ull << 50)) { + hrs.value = (float)size / (1ull << 50); hrs.suffix = "P"; - } else if (size >= (1L << 40)) { - hrs.value = (float)size / (1L << 40); + } else if (size >= (1ull << 40)) { + hrs.value = (float)size / (1ull << 40); hrs.suffix = "T"; - } else if (size >= (1L << 30)) { - hrs.value = (float)size / (1L << 30); + } else if (size >= (1ull << 30)) { + hrs.value = (float)size / (1ull << 30); hrs.suffix = "G"; - } else if (size >= (1L << 20)) { - hrs.value = (float)size / (1L << 20); + } else if (size >= (1ull << 20)) { + hrs.value = (float)size / (1ull << 20); hrs.suffix = "M"; - } else if (size >= (1L << 10)) { - hrs.value = (float)size / (1L << 10); + } else if (size >= (1ull << 10)) { + hrs.value = (float)size / (1ull << 10); hrs.suffix = "K"; } else { hrs.value = (float)size; @@ -330,7 +330,7 @@ UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { if (hrs.value >= 100 || (U64)hrs.value == size) { hrs.precision = 0; - } else if (hrs.value > 10) { + } else if (hrs.value >= 10) { hrs.precision = 1; } else if (hrs.value > 1) { hrs.precision = 2; From 464bfb022ef2d1f44778717b71979b86a3ffbea5 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 15:22:59 -0400 Subject: [PATCH 060/274] In Verbose Mode, Preserve Full Precision Where Possible --- programs/util.c | 76 ++++++++++++++++++++++++++++------------------ programs/util.h | 2 +- programs/zstdcli.c | 3 +- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/programs/util.c b/programs/util.c index 964d60ee2..c8f6d1886 100644 --- a/programs/util.c +++ b/programs/util.c @@ -305,37 +305,55 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { UTIL_HumanReadableSize_t hrs; - if (size >= (1ull << 60)) { - hrs.value = (float)size / (1ull << 60); - hrs.suffix = "E"; - } else if (size >= (1ull << 50)) { - hrs.value = (float)size / (1ull << 50); - hrs.suffix = "P"; - } else if (size >= (1ull << 40)) { - hrs.value = (float)size / (1ull << 40); - hrs.suffix = "T"; - } else if (size >= (1ull << 30)) { - hrs.value = (float)size / (1ull << 30); - hrs.suffix = "G"; - } else if (size >= (1ull << 20)) { - hrs.value = (float)size / (1ull << 20); - hrs.suffix = "M"; - } else if (size >= (1ull << 10)) { - hrs.value = (float)size / (1ull << 10); - hrs.suffix = "K"; - } else { - hrs.value = (float)size; - hrs.suffix = ""; - } - if (hrs.value >= 100 || (U64)hrs.value == size) { - hrs.precision = 0; - } else if (hrs.value >= 10) { - hrs.precision = 1; - } else if (hrs.value > 1) { - hrs.precision = 2; + if (g_utilDisplayLevel > 2) { + /* In verbose mode, do not scale sizes down, except in the case of + * values that exceed the integral precision of a double. */ + if (size >= (1ull << 53)) { + hrs.value = (double)size / (1ull << 20); + hrs.suffix = "M"; + /* At worst, a double representation of a maximal size will be + * accurate to better than tens of kilobytes. */ + hrs.precision = 2; + } else { + hrs.value = (double)size; + hrs.suffix = ""; + hrs.precision = 0; + } } else { - hrs.precision = 3; + /* In regular mode, scale sizes down and use suffixes. */ + if (size >= (1ull << 60)) { + hrs.value = (double)size / (1ull << 60); + hrs.suffix = "E"; + } else if (size >= (1ull << 50)) { + hrs.value = (double)size / (1ull << 50); + hrs.suffix = "P"; + } else if (size >= (1ull << 40)) { + hrs.value = (double)size / (1ull << 40); + hrs.suffix = "T"; + } else if (size >= (1ull << 30)) { + hrs.value = (double)size / (1ull << 30); + hrs.suffix = "G"; + } else if (size >= (1ull << 20)) { + hrs.value = (double)size / (1ull << 20); + hrs.suffix = "M"; + } else if (size >= (1ull << 10)) { + hrs.value = (double)size / (1ull << 10); + hrs.suffix = "K"; + } else { + hrs.value = (double)size; + hrs.suffix = ""; + } + + if (hrs.value >= 100 || (U64)hrs.value == size) { + hrs.precision = 0; + } else if (hrs.value >= 10) { + hrs.precision = 1; + } else if (hrs.value > 1) { + hrs.precision = 2; + } else { + hrs.precision = 3; + } } return hrs; diff --git a/programs/util.h b/programs/util.h index 63cd0c378..f146f3a08 100644 --- a/programs/util.h +++ b/programs/util.h @@ -177,7 +177,7 @@ U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); * precision, value, suffix order to a "%.*f%s" format string. */ typedef struct { - float value; + double value; int precision; const char* suffix; } UTIL_HumanReadableSize_t; diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 9e2133c4f..32cd5af86 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1146,8 +1146,9 @@ int main(int const argCount, const char* argv[]) (void)singleThread; (void)nbWorkers; #endif -#ifdef UTIL_HAS_CREATEFILELIST g_utilDisplayLevel = g_displayLevel; + +#ifdef UTIL_HAS_CREATEFILELIST if (!followLinks) { unsigned u, fileNamesNb; unsigned const nbFilenames = (unsigned)filenames->tableSize; From 93bb368d744ac56e4536b739e188aeadb2aaee8e Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 15:26:16 -0400 Subject: [PATCH 061/274] Change Suffix (e.g., "G" -> " GB") --- programs/fileio.c | 2 +- programs/util.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index c83c4fffd..d149c5a64 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1898,7 +1898,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) fCtx->totalBytesOutput); DISPLAYLEVEL(2, "\r%79s\r", ""); - DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%.*f%s => %.*f%s bytes)\n", + DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%.*f%s => %.*f%s)\n", fCtx->nbFilesProcessed, (double)fCtx->totalBytesOutput/((double)fCtx->totalBytesInput)*100, hr_isize.precision, hr_isize.value, hr_isize.suffix, diff --git a/programs/util.c b/programs/util.c index c8f6d1886..838da8304 100644 --- a/programs/util.c +++ b/programs/util.c @@ -311,38 +311,38 @@ UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { * values that exceed the integral precision of a double. */ if (size >= (1ull << 53)) { hrs.value = (double)size / (1ull << 20); - hrs.suffix = "M"; + hrs.suffix = " MB"; /* At worst, a double representation of a maximal size will be * accurate to better than tens of kilobytes. */ hrs.precision = 2; } else { hrs.value = (double)size; - hrs.suffix = ""; + hrs.suffix = " B"; hrs.precision = 0; } } else { /* In regular mode, scale sizes down and use suffixes. */ if (size >= (1ull << 60)) { hrs.value = (double)size / (1ull << 60); - hrs.suffix = "E"; + hrs.suffix = " EB"; } else if (size >= (1ull << 50)) { hrs.value = (double)size / (1ull << 50); - hrs.suffix = "P"; + hrs.suffix = " PB"; } else if (size >= (1ull << 40)) { hrs.value = (double)size / (1ull << 40); - hrs.suffix = "T"; + hrs.suffix = " TB"; } else if (size >= (1ull << 30)) { hrs.value = (double)size / (1ull << 30); - hrs.suffix = "G"; + hrs.suffix = " GB"; } else if (size >= (1ull << 20)) { hrs.value = (double)size / (1ull << 20); - hrs.suffix = "M"; + hrs.suffix = " MB"; } else if (size >= (1ull << 10)) { hrs.value = (double)size / (1ull << 10); - hrs.suffix = "K"; + hrs.suffix = " KB"; } else { hrs.value = (double)size; - hrs.suffix = ""; + hrs.suffix = " B"; } if (hrs.value >= 100 || (U64)hrs.value == size) { From 7e0058848ca45d1ff8c7e846955b0f15a4635073 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 15:28:12 -0400 Subject: [PATCH 062/274] Fix Whitespace --- programs/benchzstd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index db051781a..72793f07b 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -456,7 +456,7 @@ BMK_benchMemAdvancedNoAlloc( { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; hr_osize = UTIL_makeHumanReadableSize((U64) cSize); - DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f),%6.*f MB/s\r", + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f), %6.*f MB/s\r", marks[markNb], displayName, hr_isize.precision, hr_isize.value, hr_isize.suffix, hr_osize.precision, hr_osize.value, hr_osize.suffix, @@ -481,7 +481,7 @@ BMK_benchMemAdvancedNoAlloc( { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; hr_osize = UTIL_makeHumanReadableSize((U64) cSize); - DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f),%6.*f MB/s ,%6.1f MB/s \r", + DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f), %6.*f MB/s, %6.1f MB/s \r", marks[markNb], displayName, hr_isize.precision, hr_isize.value, hr_isize.suffix, hr_osize.precision, hr_osize.value, hr_osize.suffix, From bc46b6efe43d2cf521e14806b67ec26d4b8fb33e Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 16:04:10 -0400 Subject: [PATCH 063/274] Apply to Other Print Statement as Well --- programs/fileio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index d149c5a64..4073f030b 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1592,15 +1592,15 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, if (g_display_prefs.displayLevel >= 2 && !fCtx->hasStdoutOutput && (g_display_prefs.displayLevel >= 3 || fCtx->nbFilesTotal <= 1)) { + UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) readsize); + UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) compressedfilesize); if (readsize == 0) { - DISPLAYLEVEL(2,"%-20s : (%6llu => %6llu bytes, %s) \n", + DISPLAYLEVEL(2,"%-20s : (%.*f%s => %.*f%s, %s) \n", srcFileName, - (unsigned long long)readsize, (unsigned long long) compressedfilesize, + hr_isize.precision, hr_isize.value, hr_isize.suffix, + hr_osize.precision, hr_osize.value, hr_osize.suffix, dstFileName); } else { - UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) readsize); - UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) compressedfilesize); - DISPLAYLEVEL(2,"%-20s :%6.2f%% (%.*f%s => %.*f%s, %s) \n", srcFileName, (double)compressedfilesize / (double)readsize * 100, From 9c340ce014e70d413e7a01f0d0b77376a24db54d Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 9 Jun 2021 16:13:00 -0400 Subject: [PATCH 064/274] Require `-vv` to Enable Full Precision --- programs/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/util.c b/programs/util.c index 838da8304..2622ae825 100644 --- a/programs/util.c +++ b/programs/util.c @@ -306,7 +306,7 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { UTIL_HumanReadableSize_t hrs; - if (g_utilDisplayLevel > 2) { + if (g_utilDisplayLevel > 3) { /* In verbose mode, do not scale sizes down, except in the case of * values that exceed the integral precision of a double. */ if (size >= (1ull << 53)) { From 2af3687c507a2800eb900ea49665a2f67896e83f Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 10 Jun 2021 12:06:51 -0400 Subject: [PATCH 065/274] Switch to Binary Size Prefixes (e.g., "MB" -> "MiB") Suggested by @aqrit, a little more verbose, but hopefully addresses a real ambiguity. --- programs/util.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/programs/util.c b/programs/util.c index 2622ae825..96459b9d3 100644 --- a/programs/util.c +++ b/programs/util.c @@ -311,7 +311,7 @@ UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { * values that exceed the integral precision of a double. */ if (size >= (1ull << 53)) { hrs.value = (double)size / (1ull << 20); - hrs.suffix = " MB"; + hrs.suffix = " MiB"; /* At worst, a double representation of a maximal size will be * accurate to better than tens of kilobytes. */ hrs.precision = 2; @@ -324,22 +324,22 @@ UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { /* In regular mode, scale sizes down and use suffixes. */ if (size >= (1ull << 60)) { hrs.value = (double)size / (1ull << 60); - hrs.suffix = " EB"; + hrs.suffix = " EiB"; } else if (size >= (1ull << 50)) { hrs.value = (double)size / (1ull << 50); - hrs.suffix = " PB"; + hrs.suffix = " PiB"; } else if (size >= (1ull << 40)) { hrs.value = (double)size / (1ull << 40); - hrs.suffix = " TB"; + hrs.suffix = " TiB"; } else if (size >= (1ull << 30)) { hrs.value = (double)size / (1ull << 30); - hrs.suffix = " GB"; + hrs.suffix = " GiB"; } else if (size >= (1ull << 20)) { hrs.value = (double)size / (1ull << 20); - hrs.suffix = " MB"; + hrs.suffix = " MiB"; } else if (size >= (1ull << 10)) { hrs.value = (double)size / (1ull << 10); - hrs.suffix = " KB"; + hrs.suffix = " KiB"; } else { hrs.value = (double)size; hrs.suffix = " B"; From 87e94e3e39434d6c7175a0c9d67c2620cf37d721 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 10 Jun 2021 12:31:42 -0400 Subject: [PATCH 066/274] Convert Other Size Displays to Use Human-Readable Formatting --- programs/fileio.c | 80 +++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 4073f030b..4da1740d9 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1342,6 +1342,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, unsigned inputPresented = 0; unsigned inputBlocked = 0; unsigned lastJobID = 0; + UTIL_HumanReadableSize_t const file_hrs = UTIL_makeHumanReadableSize(fileSize); DISPLAYLEVEL(6, "compression using zstd format \n"); @@ -1352,6 +1353,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, /* unknown source size; use the declared stream size */ CHECK( ZSTD_CCtx_setPledgedSrcSize(ress.cctx, prefs->streamSrcSize) ); } + (void)srcFileName; /* Main compression loop */ @@ -1395,14 +1397,17 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, if (READY_FOR_UPDATE()) { ZSTD_frameProgression const zfp = ZSTD_getFrameProgression(ress.cctx); double const cShare = (double)zfp.produced / (double)(zfp.consumed + !zfp.consumed/*avoid div0*/) * 100; + UTIL_HumanReadableSize_t const buffered_hrs = UTIL_makeHumanReadableSize(zfp.ingested - zfp.consumed); + UTIL_HumanReadableSize_t const consumed_hrs = UTIL_makeHumanReadableSize(zfp.consumed); + UTIL_HumanReadableSize_t const produced_hrs = UTIL_makeHumanReadableSize(zfp.produced); /* display progress notifications */ if (g_display_prefs.displayLevel >= 3) { - DISPLAYUPDATE(3, "\r(L%i) Buffered :%4u MB - Consumed :%4u MB - Compressed :%4u MB => %.2f%% ", + DISPLAYUPDATE(3, "\r(L%i) Buffered :%6.*f%4s - Consumed :%6.*f%4s - Compressed :%6.*f%s => %.2f%% ", compressionLevel, - (unsigned)((zfp.ingested - zfp.consumed) >> 20), - (unsigned)(zfp.consumed >> 20), - (unsigned)(zfp.produced >> 20), + buffered_hrs.precision, buffered_hrs.value, buffered_hrs.suffix, + consumed_hrs.precision, consumed_hrs.value, consumed_hrs.suffix, + produced_hrs.precision, produced_hrs.value, produced_hrs.suffix, cShare ); } else if (g_display_prefs.displayLevel >= 2 || g_display_prefs.progressSetting == FIO_ps_always) { /* Require level 2 or forcibly displayed progress counter for summarized updates */ @@ -1419,10 +1424,10 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, fCtx->currFileIdx+1, fCtx->nbFilesTotal, (int)(18-srcFileNameSize), srcFileName); } } - DISPLAYLEVEL(1, "Read : %2u ", (unsigned)(zfp.consumed >> 20)); + DISPLAYLEVEL(1, "Read:%6.*f%4s ", consumed_hrs.precision, consumed_hrs.value, consumed_hrs.suffix); if (fileSize != UTIL_FILESIZE_UNKNOWN) - DISPLAYLEVEL(2, "/ %2u ", (unsigned)(fileSize >> 20)); - DISPLAYLEVEL(1, "MB ==> %2.f%%", cShare); + DISPLAYLEVEL(2, "/%6.*f%4s", file_hrs.precision, file_hrs.value, file_hrs.suffix); + DISPLAYLEVEL(1, " ==> %2.f%%", cShare); DELAY_NEXT_UPDATE(); } @@ -2165,6 +2170,7 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput, ZSTD_outBuffer outBuff= { ress->dstBuffer, ress->dstBufferSize, 0 }; size_t const readSizeHint = ZSTD_decompressStream(ress->dctx, &outBuff, &inBuff); const int displayLevel = (!fCtx->hasStdoutOutput || g_display_prefs.progressSetting == FIO_ps_always) ? 1 : 2; + UTIL_HumanReadableSize_t const hrs = UTIL_makeHumanReadableSize(alreadyDecoded+frameSize); if (ZSTD_isError(readSizeHint)) { DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n", srcFileName, ZSTD_getErrorName(readSizeHint)); @@ -2179,15 +2185,15 @@ FIO_decompressZstdFrame(FIO_ctx_t* const fCtx, dRess_t* ress, FILE* finput, size_t srcFileNameSize = strlen(srcFileName); if (srcFileNameSize > 18) { const char* truncatedSrcFileName = srcFileName + srcFileNameSize - 15; - DISPLAYUPDATE(displayLevel, "\rDecompress: %2u/%2u files. Current: ...%s : %u MB... ", - fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); + DISPLAYUPDATE(displayLevel, "\rDecompress: %2u/%2u files. Current: ...%s : %.*f%s... ", + fCtx->currFileIdx+1, fCtx->nbFilesTotal, truncatedSrcFileName, hrs.precision, hrs.value, hrs.suffix); } else { - DISPLAYUPDATE(displayLevel, "\rDecompress: %2u/%2u files. Current: %s : %u MB... ", - fCtx->currFileIdx+1, fCtx->nbFilesTotal, srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); + DISPLAYUPDATE(displayLevel, "\rDecompress: %2u/%2u files. Current: %s : %.*f%s... ", + fCtx->currFileIdx+1, fCtx->nbFilesTotal, srcFileName, hrs.precision, hrs.value, hrs.suffix); } } else { - DISPLAYUPDATE(displayLevel, "\r%-20.20s : %u MB... ", - srcFileName, (unsigned)((alreadyDecoded+frameSize)>>20) ); + DISPLAYUPDATE(displayLevel, "\r%-20.20s : %.*f%s... ", + srcFileName, hrs.precision, hrs.value, hrs.suffix); } if (inBuff.pos > 0) { @@ -2411,9 +2417,11 @@ FIO_decompressLz4Frame(dRess_t* ress, FILE* srcFile, /* Write Block */ if (decodedBytes) { + UTIL_HumanReadableSize_t hrs; storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, decodedBytes, prefs, storedSkips); filesize += decodedBytes; - DISPLAYUPDATE(2, "\rDecompressed : %u MB ", (unsigned)(filesize>>20)); + hrs = UTIL_makeHumanReadableSize(filesize); + DISPLAYUPDATE(2, "\rDecompressed : %.*f%s ", hrs.precision, hrs.value, hrs.suffix); } if (!nextToLoad) break; @@ -2981,25 +2989,24 @@ getFileInfo(fileInfo_t* info, const char* srcFileName) static void displayInfo(const char* inFileName, const fileInfo_t* info, int displayLevel) { - unsigned const unit = info->compressedSize < (1 MB) ? (1 KB) : (1 MB); - const char* const unitStr = info->compressedSize < (1 MB) ? "KB" : "MB"; - double const windowSizeUnit = (double)info->windowSize / unit; - double const compressedSizeUnit = (double)info->compressedSize / unit; - double const decompressedSizeUnit = (double)info->decompressedSize / unit; + UTIL_HumanReadableSize_t const window_hrs = UTIL_makeHumanReadableSize(info->windowSize); + UTIL_HumanReadableSize_t const compressed_hrs = UTIL_makeHumanReadableSize(info->compressedSize); + UTIL_HumanReadableSize_t const decompressed_hrs = UTIL_makeHumanReadableSize(info->decompressedSize); double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/(double)info->compressedSize; const char* const checkString = (info->usesCheck ? "XXH64" : "None"); if (displayLevel <= 2) { if (!info->decompUnavailable) { - DISPLAYOUT("%6d %5d %7.2f %2s %9.2f %2s %5.3f %5s %s\n", + DISPLAYOUT("%6d %5d %6.*f%4s %8.*f%4s %5.3f %5s %s\n", info->numSkippableFrames + info->numActualFrames, info->numSkippableFrames, - compressedSizeUnit, unitStr, decompressedSizeUnit, unitStr, + compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix, + decompressed_hrs.precision, decompressed_hrs.value, decompressed_hrs.suffix, ratio, checkString, inFileName); } else { - DISPLAYOUT("%6d %5d %7.2f %2s %5s %s\n", + DISPLAYOUT("%6d %5d %6.*f%4s %5s %s\n", info->numSkippableFrames + info->numActualFrames, info->numSkippableFrames, - compressedSizeUnit, unitStr, + compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix, checkString, inFileName); } } else { @@ -3007,15 +3014,15 @@ displayInfo(const char* inFileName, const fileInfo_t* info, int displayLevel) DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames); if (info->numSkippableFrames) DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAYOUT("Window Size: %.2f %2s (%llu B)\n", - windowSizeUnit, unitStr, + DISPLAYOUT("Window Size: %.*f%s (%llu B)\n", + window_hrs.precision, window_hrs.value, window_hrs.suffix, (unsigned long long)info->windowSize); - DISPLAYOUT("Compressed Size: %.2f %2s (%llu B)\n", - compressedSizeUnit, unitStr, + DISPLAYOUT("Compressed Size: %.*f%s (%llu B)\n", + compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix, (unsigned long long)info->compressedSize); if (!info->decompUnavailable) { - DISPLAYOUT("Decompressed Size: %.2f %2s (%llu B)\n", - decompressedSizeUnit, unitStr, + DISPLAYOUT("Decompressed Size: %.*f%s (%llu B)\n", + decompressed_hrs.precision, decompressed_hrs.value, decompressed_hrs.suffix, (unsigned long long)info->decompressedSize); DISPLAYOUT("Ratio: %.4f\n", ratio); } @@ -3103,24 +3110,23 @@ int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int dis error |= FIO_listFile(&total, filenameTable[u], displayLevel); } } if (numFiles > 1 && displayLevel <= 2) { /* display total */ - unsigned const unit = total.compressedSize < (1 MB) ? (1 KB) : (1 MB); - const char* const unitStr = total.compressedSize < (1 MB) ? "KB" : "MB"; - double const compressedSizeUnit = (double)total.compressedSize / unit; - double const decompressedSizeUnit = (double)total.decompressedSize / unit; + UTIL_HumanReadableSize_t const compressed_hrs = UTIL_makeHumanReadableSize(total.compressedSize); + UTIL_HumanReadableSize_t const decompressed_hrs = UTIL_makeHumanReadableSize(total.decompressedSize); double const ratio = (total.compressedSize == 0) ? 0 : ((double)total.decompressedSize)/(double)total.compressedSize; const char* const checkString = (total.usesCheck ? "XXH64" : ""); DISPLAYOUT("----------------------------------------------------------------- \n"); if (total.decompUnavailable) { - DISPLAYOUT("%6d %5d %7.2f %2s %5s %u files\n", + DISPLAYOUT("%6d %5d %6.*f%4s %5s %u files\n", total.numSkippableFrames + total.numActualFrames, total.numSkippableFrames, - compressedSizeUnit, unitStr, + compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix, checkString, (unsigned)total.nbFiles); } else { - DISPLAYOUT("%6d %5d %7.2f %2s %9.2f %2s %5.3f %5s %u files\n", + DISPLAYOUT("%6d %5d %6.*f%4s %8.*f%4s %5.3f %5s %u files\n", total.numSkippableFrames + total.numActualFrames, total.numSkippableFrames, - compressedSizeUnit, unitStr, decompressedSizeUnit, unitStr, + compressed_hrs.precision, compressed_hrs.value, compressed_hrs.suffix, + decompressed_hrs.precision, decompressed_hrs.value, decompressed_hrs.suffix, ratio, checkString, (unsigned)total.nbFiles); } } return error; From 94cf57bb134af9747a0f21b81c31aec67460c4db Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 10 Jun 2021 13:14:18 -0400 Subject: [PATCH 067/274] Update Tests to Reflect New Formatting --- tests/playTests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 252939006..54f2033cf 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1445,7 +1445,7 @@ datagen -g0 > tmp5 zstd tmp5 zstd -l tmp5.zst zstd -l tmp5* && die "-l must fail on non-zstd file" -zstd -lv tmp5.zst | grep "Decompressed Size: 0.00 KB (0 B)" # check that 0 size is present in header +zstd -lv tmp5.zst | grep "Decompressed Size: 0 B (0 B)" # check that 0 size is present in header zstd -lv tmp5* && die "-l must fail on non-zstd file" println "\n===> zstd --list/-l test with no content size field " @@ -1616,7 +1616,7 @@ roundTripTest -g600M -P50 "1 --single-thread --long --zstd=wlog=29,clog=28" if [ -n "$hasMT" ] then - println "\n===> zstdmt long round-trip tests " + println "\n===> zstdmt long round-trip tests " roundTripTest -g80000000 -P99 "19 -T2" " " roundTripTest -g5000000000 -P99 "1 -T2" " " roundTripTest -g500000000 -P97 "1 -T999" " " From 8c00807bbcee5fdeb1db126cec4529f09375dc2f Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 10 Jun 2021 13:28:38 -0400 Subject: [PATCH 068/274] Whitespace Fixes to Improve Cross-Line Alignment --- programs/fileio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 4da1740d9..da5412f27 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1403,7 +1403,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, /* display progress notifications */ if (g_display_prefs.displayLevel >= 3) { - DISPLAYUPDATE(3, "\r(L%i) Buffered :%6.*f%4s - Consumed :%6.*f%4s - Compressed :%6.*f%s => %.2f%% ", + DISPLAYUPDATE(3, "\r(L%i) Buffered :%6.*f%4s - Consumed :%6.*f%4s - Compressed :%6.*f%4s => %.2f%% ", compressionLevel, buffered_hrs.precision, buffered_hrs.value, buffered_hrs.suffix, consumed_hrs.precision, consumed_hrs.value, consumed_hrs.suffix, @@ -1600,13 +1600,13 @@ FIO_compressFilename_internal(FIO_ctx_t* const fCtx, UTIL_HumanReadableSize_t hr_isize = UTIL_makeHumanReadableSize((U64) readsize); UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) compressedfilesize); if (readsize == 0) { - DISPLAYLEVEL(2,"%-20s : (%.*f%s => %.*f%s, %s) \n", + DISPLAYLEVEL(2,"%-20s : (%6.*f%4s => %6.*f%4s, %s) \n", srcFileName, hr_isize.precision, hr_isize.value, hr_isize.suffix, hr_osize.precision, hr_osize.value, hr_osize.suffix, dstFileName); } else { - DISPLAYLEVEL(2,"%-20s :%6.2f%% (%.*f%s => %.*f%s, %s) \n", + DISPLAYLEVEL(2,"%-20s :%6.2f%% (%6.*f%4s => %6.*f%4s, %s) \n", srcFileName, (double)compressedfilesize / (double)readsize * 100, hr_isize.precision, hr_isize.value, hr_isize.suffix, @@ -1903,7 +1903,7 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx, UTIL_HumanReadableSize_t hr_osize = UTIL_makeHumanReadableSize((U64) fCtx->totalBytesOutput); DISPLAYLEVEL(2, "\r%79s\r", ""); - DISPLAYLEVEL(2, "%3d files compressed : %.2f%% (%.*f%s => %.*f%s)\n", + DISPLAYLEVEL(2, "%3d files compressed :%.2f%% (%6.*f%4s => %6.*f%4s)\n", fCtx->nbFilesProcessed, (double)fCtx->totalBytesOutput/((double)fCtx->totalBytesInput)*100, hr_isize.precision, hr_isize.value, hr_isize.suffix, @@ -2529,7 +2529,7 @@ static int FIO_decompressFrames(FIO_ctx_t* const fCtx, fCtx->totalBytesOutput += (size_t)filesize; DISPLAYLEVEL(2, "\r%79s\r", ""); /* No status message in pipe mode (stdin - stdout) or multi-files mode */ - if ((g_display_prefs.displayLevel >= 2 && fCtx->nbFilesTotal <= 1) || + if ((g_display_prefs.displayLevel >= 2 && fCtx->nbFilesTotal <= 1) || g_display_prefs.displayLevel >= 3 || g_display_prefs.progressSetting == FIO_ps_always) { DISPLAYLEVEL(1, "\r%-20s: %llu bytes \n", srcFileName, filesize); From e00412f6b595c517ddc9ab44e810454e156dfb77 Mon Sep 17 00:00:00 2001 From: koala <869829183@qq.com> Date: Fri, 11 Jun 2021 19:29:27 +0800 Subject: [PATCH 069/274] Z_PREFIX zError function When a project use zError function,linker can not find z_zError function --- zlibWrapper/zstd_zlibwrapper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c index ceb239379..adb231f06 100644 --- a/zlibWrapper/zstd_zlibwrapper.c +++ b/zlibWrapper/zstd_zlibwrapper.c @@ -1189,3 +1189,10 @@ ZEXTERN const z_crc_t FAR * ZEXPORT z_get_crc_table OF((void)) return get_crc_table(); } #endif + + /* Error function */ +ZEXTERN const char * ZEXPORT z_zError OF((int err)) +{ + /* Just use zlib Error function */ + return zError(err); +} From 6fad35c6a13919db9ab3b4f768f624220da50426 Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Wed, 9 Jun 2021 16:49:36 -0400 Subject: [PATCH 070/274] Add support for negative levels in --adapt=min and --adapt=max" --- programs/zstdcli.c | 21 +++++++++++++++++++-- tests/playTests.sh | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 9e2133c4f..c3a6ae0ba 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -354,6 +354,23 @@ static unsigned readU32FromChar(const char** stringPtr) { return result; } +/*! readIntFromChar() : + * @return : signed integer value read from input in `char` format. + * allows and interprets K, KB, KiB, M, MB and MiB suffix. + * Will also modify `*stringPtr`, advancing it to position where it stopped reading. + * Note : function will exit() program if digit sequence overflows */ +static int readIntFromChar(const char** stringPtr) { + static const char errorMsg[] = "error: numeric value overflows 32-bit int"; + int sign = 1; + unsigned result; + if (**stringPtr=='-') { + (*stringPtr)++; + sign = -1; + } + if (readU32FromCharChecked(stringPtr, &result)) { errorOut(errorMsg); } + return (int) result * sign; +} + /*! readSizeTFromCharChecked() : * @return 0 if success, and store the result in *value. * allows and interprets K, KB, KiB, M, MB and MiB suffix. @@ -547,8 +564,8 @@ static ZDICT_fastCover_params_t defaultFastCoverParams(void) static unsigned parseAdaptParameters(const char* stringPtr, int* adaptMinPtr, int* adaptMaxPtr) { for ( ; ;) { - if (longCommandWArg(&stringPtr, "min=")) { *adaptMinPtr = (int)readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } - if (longCommandWArg(&stringPtr, "max=")) { *adaptMaxPtr = (int)readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } + if (longCommandWArg(&stringPtr, "min=")) { *adaptMinPtr = readIntFromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } + if (longCommandWArg(&stringPtr, "max=")) { *adaptMaxPtr = readIntFromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } DISPLAYLEVEL(4, "invalid compression parameter \n"); return 0; } diff --git a/tests/playTests.sh b/tests/playTests.sh index 252939006..380e148f1 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1519,6 +1519,7 @@ then println "\n===> adaptive mode " roundTripTest -g270000000 " --adapt" roundTripTest -g27000000 " --adapt=min=1,max=4" + roundTripTest -g27000000 " --adapt=min=-2,max=-1" println "===> test: --adapt must fail on incoherent bounds " datagen > tmp zstd -f -vv --adapt=min=10,max=9 tmp && die "--adapt must fail on incoherent bounds" From 05b6773fbcce1075edbe498a821f9a41249cf384 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 14 Jun 2021 11:25:55 -0700 Subject: [PATCH 071/274] [fix] Add missing bounds checks during compression * The block splitter missed a bounds check, so when the buffer is too small it passes an erroneously large size to `ZSTD_entropyCompressSeqStore()`, which can then write the compressed data past the end of the buffer. This is a new regression in v1.5.0 when the block splitter is enabled. It is either enabled explicitly, or implicitly when using the optimal parser and `ZSTD_compress2()` or `ZSTD_compressStream*()`. * `HUF_writeCTable_wksp()` omits a bounds check when calling `HUF_compressWeights()`. If it is called with `dstCapacity == 0` it will pass an erroneously large size to `HUF_compressWeights()`, which can then write past the end of the buffer. This bug has been present for ages. However, I believe that zstd cannot trigger the bug, because it never calls `HUF_compress*()` with `dstCapacity == 0` because of [this check][1]. Credit to: Oss-Fuzz [1]: https://github.com/facebook/zstd/blob/89127e5ee2f3c1e141668fa6d4ee91245f05d132/lib/compress/zstd_compress_literals.c#L100 --- lib/compress/huf_compress.c | 1 + lib/compress/zstd_compress.c | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 485906e67..e9cb0bd5f 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -133,6 +133,7 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, wksp->huffWeight[n] = wksp->bitsToWeight[CTable[n].nbBits]; /* attempt weights compression by FSE */ + if (maxDstSize < 1) return ERROR(dstSize_tooSmall); { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) ); if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */ op[0] = (BYTE)hSize; diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 70f169357..9e814e31d 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3486,6 +3486,7 @@ static size_t ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, seqStore_t* const if (isPartition) ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart)); + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "Block header doesn't fit"); cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore, &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, &zc->appliedParams, From 9d9f7680f8cfa8eebbe6152b75044a7c969a5b3e Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Fri, 11 Jun 2021 12:11:58 -0400 Subject: [PATCH 072/274] Add API for fetching skippable frame content --- lib/decompress/zstd_decompress.c | 45 +++++++++++++++++++++++++++++++- lib/zstd.h | 20 ++++++++++++++ tests/fuzzer.c | 40 ++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 910bc034c..ee707ce6c 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -380,6 +380,19 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size) return 0; } +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + */ +unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } + return 0; +} + /** ZSTD_frameHeaderSize_internal() : * srcSize must be large enough to reach header size fields. * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. @@ -503,7 +516,6 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t src return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1); } - /** ZSTD_getFrameContentSize() : * compatible with legacy mode * @return : decompressed size of the single frame pointed to be `src` if known, otherwise @@ -544,6 +556,37 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize) } } +/*! ZSTD_readSkippableFrame() : + * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer. + * + * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, + * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested + * in the magicVariant. + * + * Returns an error if destination buffer is not large enough, or if the frame is not skippable. + * + * @return : number of bytes written or a ZSTD error. + */ +ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant, + const void* src, size_t srcSize) +{ + U32 const magicNumber = MEM_readLE32(src); + size_t skippableFrameSize = readSkippableFrameSize(src, srcSize); + size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE; + + /* check input validity */ + RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, ""); + RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, ""); + RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, ""); + + /* deliver payload */ + if (skippableContentSize > 0 && dst != NULL) + ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize); + if (magicVariant != NULL) + *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START; + return skippableContentSize; +} + /** ZSTD_findDecompressedSize() : * compatible with legacy mode * `srcSize` must be the exact length of some number of ZSTD compressed and/or diff --git a/lib/zstd.h b/lib/zstd.h index 4651e6c4d..054fb9a5a 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -1441,6 +1441,26 @@ ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size ZSTDLIB_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned magicVariant); +/*! ZSTD_readSkippableFrame() : + * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer. + * + * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, + * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested + * in the magicVariant. + * + * Returns an error if destination buffer is not large enough, or if the frame is not skippable. + * + * @return : number of bytes written or a ZSTD error. + */ +ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant, + const void* src, size_t srcSize); + +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + */ +ZSTDLIB_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size); + + /*************************************** * Memory management diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 553209f4d..960050f96 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1830,6 +1830,46 @@ static int basicUnitTests(U32 const seed, double compressibility) if (memcmp(decodedBuffer, CNBuffer, CNBuffSize / 2) != 0) goto _output_error; DISPLAYLEVEL(3, "OK \n"); + /* Simple API skippable frame test */ + DISPLAYLEVEL(3, "test%3i : read/write a skippable frame : ", testNb++); + { + U32 i; + unsigned readMagic; + unsigned long long receivedSize; + size_t skippableSize; + const U32 skipLen = 129 KB; + char* const skipBuff = (char*)malloc(skipLen); + assert(skipBuff != NULL); + for (i = 0; i < skipLen; i++) + skipBuff[i] = (BYTE) ((seed + i) % 256); + skippableSize = ZSTD_writeSkippableFrame((BYTE*)compressedBuffer, compressedBufferSize, + skipBuff, skipLen, seed % 15); + CHECK_Z(skippableSize); + CHECK_EQ(1, ZSTD_isSkippableFrame(compressedBuffer, skippableSize)); + receivedSize = ZSTD_readSkippableFrame(decodedBuffer, CNBuffSize, &readMagic, compressedBuffer, skippableSize); + CHECK_EQ(skippableSize, receivedSize + ZSTD_SKIPPABLEHEADERSIZE); + CHECK_EQ(seed % 15, readMagic); + if (memcmp(decodedBuffer, skipBuff, skipLen) != 0) goto _output_error; + + free(skipBuff); + } + DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3i : read/write an empty skippable frame : ", testNb++); + { + unsigned readMagic; + unsigned long long receivedSize; + size_t skippableSize; + skippableSize = ZSTD_writeSkippableFrame((BYTE*)compressedBuffer, compressedBufferSize, + CNBuffer, 0, seed % 15); + CHECK_EQ(ZSTD_SKIPPABLEHEADERSIZE, skippableSize); + CHECK_EQ(1, ZSTD_isSkippableFrame(compressedBuffer, skippableSize)); + receivedSize = ZSTD_readSkippableFrame(NULL, 0, &readMagic, compressedBuffer, skippableSize); + CHECK_EQ(skippableSize, receivedSize + ZSTD_SKIPPABLEHEADERSIZE); + CHECK_EQ(seed % 15, readMagic); + } + DISPLAYLEVEL(3, "OK \n"); + /* Dictionary and CCtx Duplication tests */ { ZSTD_CCtx* const ctxOrig = ZSTD_createCCtx(); ZSTD_CCtx* const ctxDuplicated = ZSTD_createCCtx(); From 6a46e38deba39f07287541e7be0bd98739d7009c Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Wed, 16 Jun 2021 09:38:43 -0400 Subject: [PATCH 073/274] Add option to use logical cores for default threads --- programs/util.c | 137 ++++++++++++++++++++++++++++++--------------- programs/util.h | 6 ++ programs/zstd.1.md | 3 + programs/zstdcli.c | 22 +++++++- tests/playTests.sh | 2 + 5 files changed, 123 insertions(+), 47 deletions(-) diff --git a/programs/util.c b/programs/util.c index 96459b9d3..81c10d0ca 100644 --- a/programs/util.c +++ b/programs/util.c @@ -1103,7 +1103,7 @@ FileNamesTable* UTIL_createFNT_fromROTable(const char** filenames, size_t nbFile /*-**************************************** -* count the number of physical cores +* count the number of cores ******************************************/ #if defined(_WIN32) || defined(WIN32) @@ -1112,10 +1112,26 @@ FileNamesTable* UTIL_createFNT_fromROTable(const char** filenames, size_t nbFile typedef BOOL(WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); -int UTIL_countPhysicalCores(void) +DWORD CountSetBits(ULONG_PTR bitMask) { - static int numPhysicalCores = 0; - if (numPhysicalCores != 0) return numPhysicalCores; + DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1; + DWORD bitSetCount = 0; + ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT; + DWORD i; + + for (i = 0; i <= LSHIFT; ++i) + { + bitSetCount += ((bitMask & bitTest)?1:0); + bitTest/=2; + } + + return bitSetCount; +} + +int UTIL_countCores(int logical) +{ + static int numCores = 0; + if (numCores != 0) return numCores; { LPFN_GLPI glpi; BOOL done = FALSE; @@ -1161,7 +1177,10 @@ int UTIL_countPhysicalCores(void) while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) { if (ptr->Relationship == RelationProcessorCore) { - numPhysicalCores++; + if (logical) + numCores += CountSetBits(ptr->ProcessorMask); + else + numCores++; } ptr++; @@ -1170,17 +1189,17 @@ int UTIL_countPhysicalCores(void) free(buffer); - return numPhysicalCores; + return numCores; } failed: /* try to fall back on GetSystemInfo */ { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); - numPhysicalCores = sysinfo.dwNumberOfProcessors; - if (numPhysicalCores == 0) numPhysicalCores = 1; /* just in case */ + numCores = sysinfo.dwNumberOfProcessors; + if (numCores == 0) numCores = 1; /* just in case */ } - return numPhysicalCores; + return numCores; } #elif defined(__APPLE__) @@ -1189,24 +1208,24 @@ failed: /* Use apple-provided syscall * see: man 3 sysctl */ -int UTIL_countPhysicalCores(void) +int UTIL_countCores(int logical) { - static S32 numPhysicalCores = 0; /* apple specifies int32_t */ - if (numPhysicalCores != 0) return numPhysicalCores; + static S32 numCores = 0; /* apple specifies int32_t */ + if (numCores != 0) return numCores; { size_t size = sizeof(S32); - int const ret = sysctlbyname("hw.physicalcpu", &numPhysicalCores, &size, NULL, 0); + int const ret = sysctlbyname(logical ? "hw.logicalcpu" : "hw.physicalcpu", &numCores, &size, NULL, 0); if (ret != 0) { if (errno == ENOENT) { /* entry not present, fall back on 1 */ - numPhysicalCores = 1; + numCores = 1; } else { - perror("zstd: can't get number of physical cpus"); + perror("zstd: can't get number of cpus"); exit(1); } } - return numPhysicalCores; + return numCores; } } @@ -1215,16 +1234,16 @@ int UTIL_countPhysicalCores(void) /* parse /proc/cpuinfo * siblings / cpu cores should give hyperthreading ratio * otherwise fall back on sysconf */ -int UTIL_countPhysicalCores(void) +int UTIL_countCores(int logical) { - static int numPhysicalCores = 0; + static int numCores = 0; - if (numPhysicalCores != 0) return numPhysicalCores; + if (numCores != 0) return numCores; - numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN); - if (numPhysicalCores == -1) { + numCores = (int)sysconf(_SC_NPROCESSORS_ONLN); + if (numCores == -1) { /* value not queryable, fall back on 1 */ - return numPhysicalCores = 1; + return numCores = 1; } /* try to determine if there's hyperthreading */ @@ -1238,7 +1257,7 @@ int UTIL_countPhysicalCores(void) if (cpuinfo == NULL) { /* fall back on the sysconf value */ - return numPhysicalCores; + return numCores; } /* assume the cpu cores/siblings values will be constant across all @@ -1271,13 +1290,13 @@ int UTIL_countPhysicalCores(void) ratio = siblings / cpu_cores; } - if (ratio && numPhysicalCores > ratio) { - numPhysicalCores = numPhysicalCores / ratio; + if (ratio && numCores > ratio && !logical) { + numCores = numCores / ratio; } failed: fclose(cpuinfo); - return numPhysicalCores; + return numCores; } } @@ -1288,52 +1307,70 @@ failed: /* Use physical core sysctl when available * see: man 4 smp, man 3 sysctl */ -int UTIL_countPhysicalCores(void) +int UTIL_countCores(int logical) { - static int numPhysicalCores = 0; /* freebsd sysctl is native int sized */ - if (numPhysicalCores != 0) return numPhysicalCores; + static int numCores = 0; /* freebsd sysctl is native int sized */ +#if __FreeBSD_version >= 1300008 + static int perCore = 1; +#endif + if (numCores != 0) return numCores; #if __FreeBSD_version >= 1300008 - { size_t size = sizeof(numPhysicalCores); - int ret = sysctlbyname("kern.smp.cores", &numPhysicalCores, &size, NULL, 0); - if (ret == 0) return numPhysicalCores; + { size_t size = sizeof(numCores); + int ret = sysctlbyname("kern.smp.cores", &numCores, &size, NULL, 0); + if (ret == 0) { + if (logical) { + ret = sysctlbyname("kern.smp.threads_per_core", &perCore, &size, NULL, 0); + /* default to physical cores if logical cannot be read */ + if (ret == 0) + numCores *= perCore; + } + + return numCores; + } if (errno != ENOENT) { - perror("zstd: can't get number of physical cpus"); + perror("zstd: can't get number of cpus"); exit(1); } /* sysctl not present, fall through to older sysconf method */ } +#else + /* suppress unused parameter warning */ + (void) logical; #endif - numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN); - if (numPhysicalCores == -1) { + numCores = (int)sysconf(_SC_NPROCESSORS_ONLN); + if (numCores == -1) { /* value not queryable, fall back on 1 */ - numPhysicalCores = 1; + numCores = 1; } - return numPhysicalCores; + return numCores; } #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__CYGWIN__) /* Use POSIX sysconf * see: man 3 sysconf */ -int UTIL_countPhysicalCores(void) +int UTIL_countCores(int logical) { - static int numPhysicalCores = 0; + /* suppress unused parameter warning */ + (void) logical; - if (numPhysicalCores != 0) return numPhysicalCores; + static int numCores = 0; - numPhysicalCores = (int)sysconf(_SC_NPROCESSORS_ONLN); - if (numPhysicalCores == -1) { + if (numCores != 0) return numCores; + + numCores = (int)sysconf(_SC_NPROCESSORS_ONLN); + if (numCores == -1) { /* value not queryable, fall back on 1 */ - return numPhysicalCores = 1; + return numCores = 1; } - return numPhysicalCores; + return numCores; } #else -int UTIL_countPhysicalCores(void) +int UTIL_countCores(int logical) { /* assume 1 */ return 1; @@ -1341,6 +1378,16 @@ int UTIL_countPhysicalCores(void) #endif +int UTIL_countPhysicalCores(void) +{ + return UTIL_countCores(0); +} + +int UTIL_countLogicalCores(void) +{ + return UTIL_countCores(1); +} + #if defined (__cplusplus) } #endif diff --git a/programs/util.h b/programs/util.h index f146f3a08..c1c963434 100644 --- a/programs/util.h +++ b/programs/util.h @@ -289,13 +289,19 @@ void UTIL_refFilename(FileNamesTable* fnt, const char* filename); FileNamesTable* UTIL_createExpandedFNT(const char* const* filenames, size_t nbFilenames, int followLinks); +#if defined(_WIN32) || defined(WIN32) +DWORD CountSetBits(ULONG_PTR bitMask); +#endif /*-**************************************** * System ******************************************/ +int UTIL_countCores(int logical); + int UTIL_countPhysicalCores(void); +int UTIL_countLogicalCores(void); #if defined (__cplusplus) } diff --git a/programs/zstd.1.md b/programs/zstd.1.md index ae5092866..066bcb83c 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -125,6 +125,9 @@ the last one takes effect. This mode is the only one available when multithread support is disabled. Single-thread mode features lower memory usage. Final compressed result is slightly different from `-T1`. +* `--auto-threads={physical,logical} (default: physical)`: + When using a default amount of threads via `-T0`, choose the default based on the number + of detected physical or logical cores. * `--adapt[=min=#,max=#]` : `zstd` will dynamically adapt compression level to perceived I/O conditions. Compression level adaptation can be observed live by using command `-v`. diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 5dba729a1..e496852f3 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -213,6 +213,7 @@ static void usage_advanced(const char* programName) DISPLAYOUT( " -T# : spawns # compression threads (default: 1, 0==# cores) \n"); DISPLAYOUT( " -B# : select size of each job (default: 0==automatic) \n"); DISPLAYOUT( "--single-thread : use a single thread for both I/O and compression (result slightly different than -T1) \n"); + DISPLAYOUT( "--auto-threads={physical,logical} (default: physical} : use either physical cores or logical cores as default when specifying -T0 \n"); DISPLAYOUT( "--rsyncable : compress using a rsync-friendly method (-B sets block size) \n"); # endif DISPLAYOUT( "--exclude-compressed: only compress files that are not already compressed \n"); @@ -761,6 +762,9 @@ int main(int const argCount, const char* argv[]) separateFiles = 0, setRealTimePrio = 0, singleThread = 0, +#ifdef ZSTD_MULTITHREAD + defaultLogicalCores = 0, +#endif showDefaultCParams = 0, ultra=0, contentSize=1; @@ -950,6 +954,15 @@ int main(int const argCount, const char* argv[]) if (longCommandWArg(&argument, "--target-compressed-block-size=")) { targetCBlockSize = readSizeTFromChar(&argument); continue; } if (longCommandWArg(&argument, "--size-hint=")) { srcSizeHint = readSizeTFromChar(&argument); continue; } if (longCommandWArg(&argument, "--output-dir-flat")) { NEXT_FIELD(outDirName); continue; } +#ifdef ZSTD_MULTITHREAD + if (longCommandWArg(&argument, "--auto-threads")) { + const char* threadDefault = NULL; + NEXT_FIELD(threadDefault); + if (strcmp(threadDefault, "logical") == 0) + defaultLogicalCores = 1; + continue; + } +#endif #ifdef UTIL_HAS_MIRRORFILELIST if (longCommandWArg(&argument, "--output-dir-mirror")) { NEXT_FIELD(outMirroredDirName); continue; } #endif @@ -1156,8 +1169,13 @@ int main(int const argCount, const char* argv[]) #ifdef ZSTD_MULTITHREAD if ((nbWorkers==0) && (!singleThread)) { /* automatically set # workers based on # of reported cpus */ - nbWorkers = UTIL_countPhysicalCores(); - DISPLAYLEVEL(3, "Note: %d physical core(s) detected \n", nbWorkers); + if (defaultLogicalCores) { + nbWorkers = UTIL_countLogicalCores(); + DISPLAYLEVEL(3, "Note: %d logical core(s) detected \n", nbWorkers); + } else { + nbWorkers = UTIL_countPhysicalCores(); + DISPLAYLEVEL(3, "Note: %d physical core(s) detected \n", nbWorkers); + } } #else (void)singleThread; (void)nbWorkers; diff --git a/tests/playTests.sh b/tests/playTests.sh index e3a8ebd20..6d202c715 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1351,6 +1351,8 @@ if [ -n "$hasMT" ] then println "\n===> zstdmt round-trip tests " roundTripTest -g4M "1 -T0" + roundTripTest -g4M "1 -T0 --auto-threads=physical" + roundTripTest -g4M "1 -T0 --auto-threads=logical" roundTripTest -g8M "3 -T2" roundTripTest -g8M "19 --long" roundTripTest -g8000K "2 --threads=2" From 8bdce1ff97fddd82e27389eb2a55fbd6a75c1a3f Mon Sep 17 00:00:00 2001 From: Usuario Date: Fri, 18 Jun 2021 10:07:39 -0400 Subject: [PATCH 074/274] lib/Makefile: Fix small typo in ZSTD_FORCE_DECOMPRESS_* build macros --- lib/Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 9109476bf..376a6690c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -43,7 +43,7 @@ ifneq ($(ZSTD_LIB_MINIFY), 0) ZSTD_LEGACY_SUPPORT ?= 0 ZSTD_LIB_DEPRECATED ?= 0 HUF_FORCE_DECOMPRESS_X1 ?= 1 - ZSTD_FORCE_DECOMPRESS_SHORT ?= 1 + ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 1 ZSTD_NO_INLINE ?= 1 ZSTD_STRIP_ERROR_STRINGS ?= 1 ifneq ($(HAVE_CC_OZ), 0) @@ -107,8 +107,8 @@ ZSTD_LEGACY_MULTITHREADED_API ?= 0 # Build size optimizations HUF_FORCE_DECOMPRESS_X1 ?= 0 HUF_FORCE_DECOMPRESS_X2 ?= 0 -ZSTD_FORCE_DECOMPRESS_SHORT ?= 0 -ZSTD_FORCE_DECOMPRESS_LONG ?= 0 +ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 0 +ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG ?= 0 ZSTD_NO_INLINE ?= 0 ZSTD_STRIP_ERROR_STRINGS ?= 0 @@ -146,12 +146,12 @@ ifneq ($(HUF_FORCE_DECOMPRESS_X2), 0) CFLAGS += -DHUF_FORCE_DECOMPRESS_X2 endif -ifneq ($(ZSTD_FORCE_DECOMPRESS_SHORT), 0) - CFLAGS += -DZSTD_FORCE_DECOMPRESS_SHORT +ifneq ($(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT), 0) + CFLAGS += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT endif -ifneq ($(ZSTD_FORCE_DECOMPRESS_LONG), 0) - CFLAGS += -DZSTD_FORCE_DECOMPRESS_LONG +ifneq ($(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG), 0) + CFLAGS += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG endif ifneq ($(ZSTD_NO_INLINE), 0) From 76466dfadf871babdaebcecb448cc00c08fbfd78 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 23 Jun 2021 11:21:14 -0400 Subject: [PATCH 075/274] Add simple API for converting ZSTD_Sequence into seqStore --- lib/compress/zstd_compress.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d7ae6d826..8ee46fd3f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3721,6 +3721,16 @@ static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, return cSize; } +/* ZSTD_convertBlockSequencesToSeqStore() + * Converts an array of ZSTD_Sequence* with the corresponding original src buffer into + * the seqStore of a cctx. + * + * Returns 0 on success, ZSTD_error on failure. + */ +static UNUSED_ATTR size_t ZSTD_convertBlockSequencesToSeqStore(ZSTD_CCtx* cctx, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize); + static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 frame) @@ -3757,12 +3767,6 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */, zc->bmi2); - if (zc->seqCollector.collectSequences) { - ZSTD_copyBlockSequences(zc); - return 0; - } - - if (frame && /* We don't want to emit our first block as a RLE even if it qualifies because * doing so will cause the decoder (cli only) to throw a "should consume all input error." @@ -5821,6 +5825,13 @@ static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZS return 0; } +static size_t ZSTD_convertBlockSequencesToSeqStore(ZSTD_CCtx* cctx, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize) { + ZSTD_sequencePosition dummySeqPos = {0, 0, 0}; + return ZSTD_copySequencesToSeqStoreExplicitBlockDelim(cctx, &dummySeqPos, inSeqs, inSeqsSize, src, srcSize); +} + /* Returns the number of bytes to move the current read position back by. Only non-zero * if we ended up splitting a sequence. Otherwise, it may return a ZSTD error if something * went wrong. From 139a2f1e0c14bd09e291f74d5f35961ec4bc73bf Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 24 Jun 2021 09:07:55 -0700 Subject: [PATCH 076/274] remove invalid test `--mt` is no longer supported by `zstreamtest` (relevant API entry point has been removed from `libzstd`). fix #2701 --- build/meson/tests/meson.build | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build/meson/tests/meson.build b/build/meson/tests/meson.build index 1b233630a..4d6cd1d75 100644 --- a/build/meson/tests/meson.build +++ b/build/meson/tests/meson.build @@ -186,10 +186,6 @@ test('test-zstream-1', zstreamtest, args: ['-v', ZSTREAM_TESTTIME] + FUZZER_FLAGS, timeout: 240) -test('test-zstream-2', - zstreamtest, - args: ['-mt', '-t1', ZSTREAM_TESTTIME] + FUZZER_FLAGS, - timeout: 120) test('test-zstream-3', zstreamtest, args: ['--newapi', '-t1', ZSTREAM_TESTTIME] + FUZZER_FLAGS, From 2c2c9e7dfdcb8eee5a2b8611647698559d657477 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Tue, 29 Jun 2021 09:06:47 +0100 Subject: [PATCH 077/274] Add possible improvements for gcc-11 --- lib/decompress/zstd_decompress_block.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index e5391d662..9acf2f746 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -977,10 +977,8 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) U32 const ll0 = (llDInfo->baseValue == 0); if (LIKELY((ofBits == 0))) { offset = seqState->prevOffset[ll0]; - if (UNLIKELY(ll0)) { - seqState->prevOffset[1] = seqState->prevOffset[0]; - seqState->prevOffset[0] = offset; - } + seqState->prevOffset[1] = seqState->prevOffset[!ll0]; + seqState->prevOffset[0] = offset; } else { offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; From e855b78be6a9e2dff5fd81183c244835dc42170c Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Tue, 29 Jun 2021 17:57:53 +0100 Subject: [PATCH 078/274] Include what you use in zstd_ldm_geartab --- lib/compress/zstd_ldm_geartab.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/compress/zstd_ldm_geartab.h b/lib/compress/zstd_ldm_geartab.h index e5c24d856..647f865be 100644 --- a/lib/compress/zstd_ldm_geartab.h +++ b/lib/compress/zstd_ldm_geartab.h @@ -11,7 +11,10 @@ #ifndef ZSTD_LDM_GEARTAB_H #define ZSTD_LDM_GEARTAB_H -static U64 ZSTD_ldm_gearTab[256] = { +#include "../common/compiler.h" /* UNUSED_ATTR */ +#include "../common/mem.h" /* U64 */ + +static UNUSED_ATTR const U64 ZSTD_ldm_gearTab[256] = { 0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc, 0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05, 0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e, From dc5b693f1ef6f2aa297c615fe3567ad39030bf46 Mon Sep 17 00:00:00 2001 From: Binh Vo Date: Mon, 28 Jun 2021 10:06:20 -0400 Subject: [PATCH 079/274] Proactively skip huffman compression based on sampling where non-compressibility is suspected --- lib/common/huf.h | 10 ++++---- lib/compress/huf_compress.c | 34 +++++++++++++++++++++------ lib/compress/zstd_compress.c | 7 +++++- lib/compress/zstd_compress_literals.c | 7 +++--- lib/compress/zstd_compress_literals.h | 4 +++- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 3d47ced03..1f27ab46d 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -206,12 +206,13 @@ typedef enum { * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. * If it uses hufTable it does not modify hufTable or repeat. * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. - * If preferRepeat then the old table will always be used if valid. */ + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ size_t HUF_compress4X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible); /** HUF_buildCTable_wksp() : * Same as HUF_buildCTable(), but using externally allocated scratch buffer. @@ -311,12 +312,13 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. * If it uses hufTable it does not modify hufTable or repeat. * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. - * If preferRepeat then the old table will always be used if valid. */ + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ size_t HUF_compress1X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2); + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible); size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ #ifndef HUF_FORCE_DECOMPRESS_X1 diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index e9cb0bd5f..183ae4a47 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -758,6 +758,9 @@ typedef struct { } wksps; } HUF_compress_tables_t; +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096 +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */ + /* HUF_compress_internal() : * `workSpace_align4` must be aligned on 4-bytes boundaries, * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */ @@ -768,7 +771,7 @@ HUF_compress_internal (void* dst, size_t dstSize, HUF_nbStreams_e nbStreams, void* workSpace_align4, size_t wkspSize, HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat, - const int bmi2) + const int bmi2, unsigned suspectUncompressible) { HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4; BYTE* const ostart = (BYTE*)dst; @@ -795,6 +798,21 @@ HUF_compress_internal (void* dst, size_t dstSize, nbStreams, oldHufTable, bmi2); } + /* If uncompressible data is suspected, do a smaller sampling first */ + DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2); + if (suspectUncompressible && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) { + size_t largestTotal = 0; + { unsigned maxSymbolValueBegin = maxSymbolValue; + CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestBegin; + } + { unsigned maxSymbolValueEnd = maxSymbolValue; + CHECK_V_F(largestEnd, HIST_count_simple (table->count, &maxSymbolValueEnd, (const BYTE*)src + srcSize - SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestEnd; + } + if (largestTotal <= ((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + /* Scan input and build symbol stats */ { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) ); if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ @@ -860,19 +878,20 @@ size_t HUF_compress1X_wksp (void* dst, size_t dstSize, return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, HUF_singleStream, workSpace, wkspSize, - NULL, NULL, 0, 0 /*bmi2*/); + NULL, NULL, 0, 0 /*bmi2*/, 0); } size_t HUF_compress1X_repeat (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void* workSpace, size_t wkspSize, - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2) + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, + int bmi2, unsigned suspectUncompressible) { return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, HUF_singleStream, workSpace, wkspSize, hufTable, - repeat, preferRepeat, bmi2); + repeat, preferRepeat, bmi2, suspectUncompressible); } /* HUF_compress4X_repeat(): @@ -886,22 +905,23 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize, return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, HUF_fourStreams, workSpace, wkspSize, - NULL, NULL, 0, 0 /*bmi2*/); + NULL, NULL, 0, 0 /*bmi2*/, 0); } /* HUF_compress4X_repeat(): * compress input using 4 streams. + * consider skipping quickly * re-use an existing huffman compression table */ size_t HUF_compress4X_repeat (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void* workSpace, size_t wkspSize, - HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2) + HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible) { return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, HUF_fourStreams, workSpace, wkspSize, - hufTable, repeat, preferRepeat, bmi2); + hufTable, repeat, preferRepeat, bmi2, suspectUncompressible); } #ifndef ZSTD_NO_UNUSED_FUNCTIONS diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 2838d31c6..d6bbca7d1 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2557,6 +2557,7 @@ ZSTD_buildSequencesStatistics(seqStore_t* seqStorePtr, size_t nbSeq, * compresses both literals and sequences * Returns compressed size of block, or a zstd error. */ +#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20 MEM_STATIC size_t ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr, const ZSTD_entropyCTables_t* prevEntropy, @@ -2591,6 +2592,10 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr, /* Compress literals */ { const BYTE* const literals = seqStorePtr->litStart; + size_t const numSequences = seqStorePtr->sequences - seqStorePtr->sequencesStart; + size_t const numLiterals = seqStorePtr->lit - seqStorePtr->litStart; + /* Base suspicion of uncompressibility on ratio of literals to sequences */ + unsigned const suspectUncompressible = (numSequences == 0) || (numLiterals / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO); size_t const litSize = (size_t)(seqStorePtr->lit - literals); size_t const cSize = ZSTD_compressLiterals( &prevEntropy->huf, &nextEntropy->huf, @@ -2599,7 +2604,7 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr, op, dstCapacity, literals, litSize, entropyWorkspace, entropyWkspSize, - bmi2); + bmi2, suspectUncompressible); FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed"); assert(cSize <= dstCapacity); op += cSize; diff --git a/lib/compress/zstd_compress_literals.c b/lib/compress/zstd_compress_literals.c index 008337bb1..52b0a8059 100644 --- a/lib/compress/zstd_compress_literals.c +++ b/lib/compress/zstd_compress_literals.c @@ -73,7 +73,8 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, void* dst, size_t dstCapacity, const void* src, size_t srcSize, void* entropyWorkspace, size_t entropyWorkspaceSize, - const int bmi2) + const int bmi2, + unsigned suspectUncompressible) { size_t const minGain = ZSTD_minGain(srcSize, strategy); size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); @@ -105,11 +106,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, HUF_compress1X_repeat( ostart+lhSize, dstCapacity-lhSize, src, srcSize, HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize, - (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) : + (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2, suspectUncompressible) : HUF_compress4X_repeat( ostart+lhSize, dstCapacity-lhSize, src, srcSize, HUF_SYMBOLVALUE_MAX, HUF_TABLELOG_DEFAULT, entropyWorkspace, entropyWorkspaceSize, - (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2); + (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2, suspectUncompressible); if (repeat != HUF_repeat_none) { /* reused the existing table */ DEBUGLOG(5, "Reusing previous huffman table"); diff --git a/lib/compress/zstd_compress_literals.h b/lib/compress/zstd_compress_literals.h index 9904c0cd3..9775fb97c 100644 --- a/lib/compress/zstd_compress_literals.h +++ b/lib/compress/zstd_compress_literals.h @@ -18,12 +18,14 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize); +/* If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf, ZSTD_hufCTables_t* nextHuf, ZSTD_strategy strategy, int disableLiteralCompression, void* dst, size_t dstCapacity, const void* src, size_t srcSize, void* entropyWorkspace, size_t entropyWorkspaceSize, - const int bmi2); + const int bmi2, + unsigned suspectUncompressible); #endif /* ZSTD_COMPRESS_LITERALS_H */ From f5f6cc2e483a3af49a98a063d014b2e2e7e9606c Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 30 Jun 2021 13:09:00 -0400 Subject: [PATCH 080/274] Remove folder when done with test --- tests/playTests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index f57f61f3d..3aa90f692 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -325,6 +325,7 @@ zstd --long --rm -r precompressedFilterTestDir # Files should get compressed again without the --exclude-compressed flag. test -f precompressedFilterTestDir/input.5.zst.zst test -f precompressedFilterTestDir/input.6.zst.zst +rm -rf precompressedFilterTestDir println "Test completed" From e1f85dbca3a0ed5ef06c8396912a0914db8dea6a Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Fri, 9 Jul 2021 13:21:15 -0700 Subject: [PATCH 081/274] pzstd: fix linking for static builds --- build/cmake/contrib/pzstd/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build/cmake/contrib/pzstd/CMakeLists.txt b/build/cmake/contrib/pzstd/CMakeLists.txt index 5c30a91b1..27af86c88 100644 --- a/build/cmake/contrib/pzstd/CMakeLists.txt +++ b/build/cmake/contrib/pzstd/CMakeLists.txt @@ -21,10 +21,16 @@ add_executable(pzstd ${PROGRAMS_DIR}/util.c ${PZSTD_DIR}/main.cpp ${PZSTD_DIR}/O set_property(TARGET pzstd APPEND PROPERTY COMPILE_DEFINITIONS "NDEBUG") set_property(TARGET pzstd APPEND PROPERTY COMPILE_OPTIONS "-Wno-shadow") +if (ZSTD_BUILD_SHARED) + set(ZSTD_LIB libzstd_shared) +else() + set(ZSTD_LIB libzstd_static) +endif() + set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) if (CMAKE_USE_PTHREADS_INIT) - target_link_libraries(pzstd libzstd_shared ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(pzstd ${ZSTD_LIB} ${CMAKE_THREAD_LIBS_INIT}) else() message(SEND_ERROR "ZSTD currently does not support thread libraries other than pthreads") endif() From d4ad02c7210b4b2936cee45b426db9e8e78a7bc4 Mon Sep 17 00:00:00 2001 From: makise-homura Date: Sat, 10 Jul 2021 03:57:06 +0300 Subject: [PATCH 082/274] Add support for MCST LCC compiler --- lib/common/compiler.h | 9 ++++++++- programs/zstdcli.c | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 9e2a8fe70..cae0061a1 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -79,6 +79,13 @@ # define UNUSED_ATTR #endif +/* CONST_ARGC tells the compiler correct const argc specificator for -Wmain. */ +#if !defined(__LCC__) +# define CONST_ARGC const +#else +# define CONST_ARGC +#endif + /* force no inlining */ #ifdef _MSC_VER # define FORCE_NOINLINE static __declspec(noinline) @@ -151,7 +158,7 @@ /* vectorization * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */ -#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) +#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5) # define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) # else diff --git a/programs/zstdcli.c b/programs/zstdcli.c index e496852f3..845610dc3 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -741,7 +741,7 @@ typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom # define MAXCLEVEL ZSTD_maxCLevel() #endif -int main(int const argCount, const char* argv[]) +int main(int CONST_ARGC argCount, const char* argv[]) { int argNb, followLinks = 0, From a5f518ae273ff0000bfd4c50689663f690f95d24 Mon Sep 17 00:00:00 2001 From: makise-homura Date: Wed, 14 Jul 2021 19:55:47 +0300 Subject: [PATCH 083/274] Change zstdcli's main() declaration due to -Wmain on some compilers --- lib/common/compiler.h | 7 ------- programs/zstdcli.c | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index cae0061a1..a01c30cc1 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -79,13 +79,6 @@ # define UNUSED_ATTR #endif -/* CONST_ARGC tells the compiler correct const argc specificator for -Wmain. */ -#if !defined(__LCC__) -# define CONST_ARGC const -#else -# define CONST_ARGC -#endif - /* force no inlining */ #ifdef _MSC_VER # define FORCE_NOINLINE static __declspec(noinline) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 845610dc3..9178a4bef 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -741,7 +741,7 @@ typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom # define MAXCLEVEL ZSTD_maxCLevel() #endif -int main(int CONST_ARGC argCount, const char* argv[]) +int main(int argCount, const char* argv[]) { int argNb, followLinks = 0, From 3cd085cec3cc805f19e52ec98bfe60e7f1543672 Mon Sep 17 00:00:00 2001 From: makise-homura Date: Wed, 14 Jul 2021 20:00:44 +0300 Subject: [PATCH 084/274] Clarify no-tree-vectorize usage for ICC and LCC --- lib/common/compiler.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index a01c30cc1..012ff0221 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -150,7 +150,8 @@ } /* vectorization - * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */ + * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax, + * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */ #if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__) # if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5) # define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) From ba044bd6f12b22b3339731d6dc5a12476a24d1cc Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 15 Jul 2021 12:14:44 -0700 Subject: [PATCH 085/274] [bug-fix] Fix a determinism bug with the DUBT The DUBT can be non-deterministic if an index is equal to `ZSTD_DUBT_UNSORTED_MARK`. Ensure that never happens by starting the indices at 2. This bug was found by the OSS-Fuzz determinism fuzzer. With this change the fuzzer test passes. And I've confirmed that this is the root cause, not just hiding the problem. Aside: This took me a long time to figure out, because I thought I had tried this first thing. But, apparantly I messed it up, because when I was going through it again with @felixhandte, I was pointing out that it wasn't the case, but it turns out it was. Credit to: OSS-Fuzz --- lib/compress/zstd_compress_internal.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 3b04fd09f..5c79485e7 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -199,6 +199,8 @@ typedef struct { */ } ZSTD_window_t; +#define ZSTD_WINDOW_START_INDEX 2 + typedef struct ZSTD_matchState_t ZSTD_matchState_t; #define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */ @@ -884,9 +886,9 @@ MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window) MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window) { - return window.dictLimit == 1 && - window.lowLimit == 1 && - (window.nextSrc - window.base) == 1; + return window.dictLimit == ZSTD_WINDOW_START_INDEX && + window.lowLimit == ZSTD_WINDOW_START_INDEX && + (window.nextSrc - window.base) == ZSTD_WINDOW_START_INDEX; } /** @@ -1149,11 +1151,12 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window, MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) { ZSTD_memset(window, 0, sizeof(*window)); - window->base = (BYTE const*)""; - window->dictBase = (BYTE const*)""; - window->dictLimit = 1; /* start from 1, so that 1st position is valid */ - window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */ - window->nextSrc = window->base + 1; /* see issue #1241 */ + window->base = (BYTE const*)" "; + window->dictBase = (BYTE const*)" "; + ZSTD_STATIC_ASSERT(ZSTD_DUBT_UNSORTED_MARK < ZSTD_WINDOW_START_INDEX); /* Start above ZSTD_DUBT_UNSORTED_MARK */ + window->dictLimit = ZSTD_WINDOW_START_INDEX; /* start from >0, so that 1st position is valid */ + window->lowLimit = ZSTD_WINDOW_START_INDEX; /* it ensures first and later CCtx usages compress the same */ + window->nextSrc = window->base + ZSTD_WINDOW_START_INDEX; /* see issue #1241 */ window->nbOverflowCorrections = 0; } From da58821ff2741bde6f78df87f859a3e791515197 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 22 Jul 2021 12:37:35 -0400 Subject: [PATCH 086/274] Fix DDSS Load This PR fixes an incorrect comparison in figuring out `minChain` in `ZSTD_dedicatedDictSearch_lazy_loadDictionary()`. This incorrect comparison had been masked by the fact that `idx` was always 1, until @terrelln changed that in #2726. Credit-to: OSS-Fuzz --- lib/compress/zstd_lazy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 4dfd9d9ed..e1f5a4f0d 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -450,7 +450,7 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B U32* const chainTable = ms->chainTable; U32 const chainSize = 1 << ms->cParams.chainLog; U32 idx = ms->nextToUpdate; - U32 const minChain = chainSize < target ? target - chainSize : idx; + U32 const minChain = chainSize < target - idx ? target - chainSize : idx; U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG; U32 const cacheSize = bucketSize - 1; U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize; From 46f27105626e0e35a2f277d20469066ffe050c81 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 12 Jul 2021 11:57:01 -0700 Subject: [PATCH 087/274] [HUF] Improve Huffman encoding speed Improve Huffman encoding speed by 20% for gcc and 10% for clang. | Compiler | Benchmark | Config | Dataset | Ratio | Speed MB/s (dev) | Speed MB/s (huf-cspeed) | Speed MB/s (huf-cspeed - dev) | |----------|-------------------|---------|-------------|-------|------------------|-------------------------|-------------------------------| | gcc | compress | level_1 | enwik7 | 2.43 | 253.70 | 258.72 | 2.0% | | gcc | compress | level_1 | silesia | 2.88 | 341.90 | 348.15 | 1.8% | | gcc | compress_literals | level_1 | enwik7 | 1.49 | 761.83 | 912.76 | 19.8% | | gcc | compress_literals | level_1 | silesia | 1.28 | 754.83 | 902.37 | 19.5% | | gcc | compress_literals | level_7 | enwik7 | 1.29 | 502.81 | 552.79 | 9.9% | | gcc | compress_literals | level_7 | silesia | 1.11 | 675.97 | 776.44 | 14.9% | | clang | compress | level_1 | enwik7 | 2.43 | 277.54 | 280.98 | 1.2% | | clang | compress | level_1 | silesia | 2.88 | 369.98 | 375.46 | 1.5% | | clang | compress_literals | level_1 | enwik7 | 1.49 | 828.83 | 918.41 | 10.8% | | clang | compress_literals | level_1 | silesia | 1.28 | 815.81 | 905.41 | 11.0% | | clang | compress_literals | level_7 | enwik7 | 1.29 | 533.13 | 553.30 | 3.8% | | clang | compress_literals | level_7 | silesia | 1.11 | 714.52 | 775.38 | 8.5% | --- lib/common/huf.h | 27 +- lib/compress/huf_compress.c | 435 ++++++++++++++++++++++---- lib/compress/zstd_compress_internal.h | 2 +- lib/compress/zstd_opt.c | 2 +- tests/decodecorpus.c | 4 +- 5 files changed, 382 insertions(+), 88 deletions(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 1f27ab46d..39e6c2d04 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -89,9 +89,9 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, /** HUF_compress4X_wksp() : * Same as HUF_compress2(), but uses externally allocated `workSpace`. - * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */ -#define HUF_WORKSPACE_SIZE ((6 << 10) + 256) -#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) + * `workspace` must be at least as large as HUF_WORKSPACE_SIZE */ +#define HUF_WORKSPACE_SIZE ((8 << 10) + 256) +#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, @@ -136,15 +136,11 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, /* static allocation of HUF's Compression Table */ /* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */ -struct HUF_CElt_s { - U16 val; - BYTE nbBits; -}; /* typedef'd to HUF_CElt */ -typedef struct HUF_CElt_s HUF_CElt; /* consider it an incomplete type */ -#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */ -#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32)) +typedef size_t HUF_CElt; /* consider it an incomplete type */ +#define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */ +#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t)) #define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ - HUF_CElt name[HUF_CTABLE_SIZE_U32(maxSymbolValue)] /* no final ; */ + HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */ /* static allocation of HUF's DTable */ typedef U32 HUF_DTable; @@ -250,11 +246,10 @@ size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, * Loading a CTable saved with HUF_writeCTable() */ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights); -/** HUF_getNbBits() : +/** HUF_getNbBitsFromCTable() : * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX - * Note 1 : is not inlined, as HUF_CElt definition is private - * Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */ -U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue); + * Note 1 : is not inlined, as HUF_CElt definition is private */ +U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue); /* * HUF_decompress() does the following: @@ -306,7 +301,7 @@ size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* c /* ====================== */ size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); -size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ +size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U64 U64 */ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); /** HUF_compress1X_repeat() : * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 183ae4a47..7c23c0c75 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -53,6 +53,28 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS /* ******************************************************* * HUF : Huffman block compression *********************************************************/ +#define HUF_WORKSPACE_MAX_ALIGNMENT 8 + +static void* HUF_alignUpWorkspace(void* workspace, size_t* workspaceSizePtr, size_t align) +{ + size_t const mask = align - 1; + size_t const rem = (size_t)workspace & mask; + size_t const add = (align - rem) & mask; + BYTE* const aligned = (BYTE*)workspace + add; + assert((align & (align - 1)) == 0); /* pow 2 */ + assert(align <= HUF_WORKSPACE_MAX_ALIGNMENT); + if (*workspaceSizePtr >= add) { + assert(add < align); + assert(((size_t)aligned & mask) == 0); + *workspaceSizePtr -= add; + return aligned; + } else { + *workspaceSizePtr = 0; + return NULL; + } +} + + /* HUF_compressWeights() : * Same as FSE_compress(), but dedicated to huff0's weights compression. * The use case needs much less stack memory. @@ -75,7 +97,7 @@ static size_t HUF_compressWeights(void* dst, size_t dstSize, const void* weightT unsigned maxSymbolValue = HUF_TABLELOG_MAX; U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; - HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)workspace; + HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, sizeof(U32)); if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC); @@ -106,6 +128,40 @@ static size_t HUF_compressWeights(void* dst, size_t dstSize, const void* weightT return (size_t)(op-ostart); } +static size_t HUF_getNbBits(HUF_CElt elt) +{ + return elt & 0xFF; +} + +static size_t HUF_getNbBitsFast(HUF_CElt elt) +{ + return elt; +} + +static size_t HUF_getValue(HUF_CElt elt) +{ + return elt & ~0xFF; +} + +static size_t HUF_getValueFast(HUF_CElt elt) +{ + return elt; +} + +static void HUF_setNbBits(HUF_CElt* elt, size_t nbBits) +{ + assert(nbBits <= HUF_TABLELOG_ABSOLUTEMAX); + *elt = nbBits; +} + +static void HUF_setValue(HUF_CElt* elt, size_t value) +{ + size_t const nbBits = HUF_getNbBits(*elt); + if (nbBits > 0) { + assert((value >> nbBits) == 0); + *elt |= value << (sizeof(HUF_CElt) * 8 - nbBits); + } +} typedef struct { HUF_CompressWeightsWksp wksp; @@ -117,9 +173,10 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize) { + HUF_CElt const* const ct = CTable + 1; BYTE* op = (BYTE*)dst; U32 n; - HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)workspace; + HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, sizeof(U32)); /* check conditions */ if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); @@ -130,7 +187,7 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, for (n=1; nbitsToWeight[n] = (BYTE)(huffLog + 1 - n); for (n=0; nhuffWeight[n] = wksp->bitsToWeight[CTable[n].nbBits]; + wksp->huffWeight[n] = wksp->bitsToWeight[HUF_getNbBits(ct[n])]; /* attempt weights compression by FSE */ if (maxDstSize < 1) return ERROR(dstSize_tooSmall); @@ -167,6 +224,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ U32 tableLog = 0; U32 nbSymbols = 0; + HUF_CElt* const ct = CTable + 1; /* get symbol weights */ CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); @@ -176,6 +234,8 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall); + CTable[0] = tableLog; + /* Prepare base value per rank */ { U32 n, nextRankStart = 0; for (n=1; n<=tableLog; n++) { @@ -187,13 +247,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void /* fill nbBits */ { U32 n; for (n=0; nn=tableLog+1 */ U16 valPerRank[HUF_TABLELOG_MAX+2] = {0}; - { U32 n; for (n=0; n>= 1; } } /* assign value within rank, symbol order */ - { U32 n; for (n=0; n>= 1; } } for (n=0; nhuffNodeTbl; nodeElt* const huffNode = huffNode0+1; int nonNullRank; /* safety checks */ - if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) return ERROR(workSpace_tooSmall); if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; @@ -537,91 +598,327 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbo maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits); if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */ - HUF_buildCTableFromTree(tree, huffNode, nonNullRank, maxSymbolValue, maxNbBits); + HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits); return maxNbBits; } size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) { + HUF_CElt const* ct = CTable + 1; size_t nbBits = 0; int s; for (s = 0; s <= (int)maxSymbolValue; ++s) { - nbBits += CTable[s].nbBits * count[s]; + nbBits += HUF_getNbBits(ct[s]) * count[s]; } return nbBits >> 3; } int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) { + HUF_CElt const* ct = CTable + 1; int bad = 0; int s; for (s = 0; s <= (int)maxSymbolValue; ++s) { - bad |= (count[s] != 0) & (CTable[s].nbBits == 0); + bad |= (count[s] != 0) & (HUF_getNbBits(ct[s]) == 0); } return !bad; } size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); } -FORCE_INLINE_TEMPLATE void -HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable) +/** HUF_CStream_t: + * Huffman uses its own BIT_CStream_t implementation. + * There are three major differences from BIT_CStream_t: + * 1. HUF_addBits() takes a HUF_CElt (size_t) which is + * the pair (nbBits, value) in the format: + * format: + * - Bits [0, 4) = nbBits + * - Bits [4, 64 - nbBits) = 0 + * - Bits [64 - nbBits, 64) = value + * 2. The bitContainer is built from the upper bits and + * right shifted. E.g. to add a new value of N bits + * you right shift the bitContainer by N, then or in + * the new value into the N upper bits. + * 3. The bitstream has two bit containers. You can add + * bits to the second container and merge them into + * the first container. + */ + +#define HUF_BITS_IN_CONTAINER (sizeof(size_t) * 8) + +typedef struct { + size_t bitContainer[2]; + size_t bitPos[2]; + + BYTE* startPtr; + BYTE* ptr; + BYTE* endPtr; +} HUF_CStream_t; + +/**! HUF_initCStream(): + * Initializes the bistream. + * @returns 0 or an error code. + */ +static size_t HUF_initCStream(HUF_CStream_t* bitC, + void* startPtr, size_t dstCapacity) { - BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits); + ZSTD_memset(bitC, 0, sizeof(*bitC)); + bitC->startPtr = (BYTE*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer[0]); + if (dstCapacity <= sizeof(bitC->bitContainer[0])) return ERROR(dstSize_tooSmall); + return 0; } -#define HUF_FLUSHBITS(s) BIT_flushBits(s) +/*! HUF_addBits(): + * Adds the symbol stored in HUF_CElt elt to the bitstream. + * + * @param elt The element we're adding. This is a (nbBits, value) pair. + * See the HUF_CStream_t docs for the format. + * @param idx Insert into the bistream at this idx. + * @param kFast This is a template parameter. If the bitstream is guaranteed + * to have at least 4 unused bits after this call it may be 1, + * otherwise it must be 0. HUF_addBits() is faster when fast is set. + */ +FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int idx, int kFast) +{ + assert(idx <= 1); + assert(HUF_getNbBits(elt) <= HUF_TABLELOG_ABSOLUTEMAX); + /* This is efficient on x86-64 with BMI2 because shrx + * only reads the low 6 bits of the register. The compiler + * knows this and elides the mask. When fast is set, + * every operation can use the same value loaded from elt. + */ + bitC->bitContainer[idx] >>= HUF_getNbBits(elt); + bitC->bitContainer[idx] |= kFast ? HUF_getValueFast(elt) : HUF_getValue(elt); + /* We only read the low 8 bits of bitC->bitPos[idx] so it + * doesn't matter that the high bits have noise from the value. + */ + bitC->bitPos[idx] += HUF_getNbBitsFast(elt); + assert((bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + /* The last 4-bits of elt are dirty if fast is set, + * so we must not be overwriting bits that have already been + * inserted into the bit container. + */ +#if DEBUGLEVEL >= 1 + { + size_t const nbBits = HUF_getNbBits(elt); + size_t const dirtyBits = nbBits == 0 ? 0 : BIT_highbit32((U32)nbBits) + 1; + /* Middle bits are 0. */ + assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0); + /* We didn't overwrite any bits in the bit container. */ + assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + } +#endif +} -#define HUF_FLUSHBITS_1(stream) \ - if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream) +FORCE_INLINE_TEMPLATE void HUF_zeroIndex1(HUF_CStream_t* bitC) +{ + bitC->bitContainer[1] = 0; + bitC->bitPos[1] = 0; +} + +/*! HUF_mergeIndex1() : + * Merges the bit container @ index 1 into the bit container @ index 0 + * and zeros the bit container @ index 1. + */ +FORCE_INLINE_TEMPLATE void HUF_mergeIndex1(HUF_CStream_t* bitC) +{ + assert((bitC->bitPos[1] & 0xFF) < HUF_BITS_IN_CONTAINER); + bitC->bitContainer[0] >>= (bitC->bitPos[1] & 0xFF); + bitC->bitContainer[0] |= bitC->bitContainer[1]; + bitC->bitPos[0] += bitC->bitPos[1]; + assert((bitC->bitPos[0] & 0xFF) <= HUF_BITS_IN_CONTAINER); +} + +/*! HUF_flushBits() : +* Flushes the bits in the bit container @ index 0. +* +* @post bitPos will be < 8. +* @param kFast If kFast is set then we must know a-priori that +* the bit container will not overflow. +*/ +FORCE_INLINE_TEMPLATE void HUF_flushBits(HUF_CStream_t* bitC, int kFast) +{ + /* The upper bits of bitPos are noisy, so we must mask by 0xFF. */ + size_t const nbBits = bitC->bitPos[0] & 0xFF; + size_t const nbBytes = nbBits >> 3; + /* The top nbBits bits of bitContainer are the ones we need. */ + size_t const bitContainer = bitC->bitContainer[0] >> (HUF_BITS_IN_CONTAINER - nbBits); + /* Mask bitPos to account for the bytes we consumed. */ + bitC->bitPos[0] &= 7; + assert(nbBits > 0); + assert(nbBits <= sizeof(bitC->bitContainer[0]) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitContainer); + bitC->ptr += nbBytes; + assert(!kFast || bitC->ptr <= bitC->endPtr); + if (!kFast && bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + /* bitContainer doesn't need to be modified because the leftover + * bits are already the top bitPos bits. And we don't care about + * noise in the lower values. + */ +} + +/*! HUF_endMark() + * @returns The Huffman stream end mark: A 1-bit value = 1. + */ +static HUF_CElt HUF_endMark(void) +{ + HUF_CElt endMark; + HUF_setNbBits(&endMark, 1); + HUF_setValue(&endMark, 1); + return endMark; +} + +/*! HUF_closeCStream() : + * @return Size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +static size_t HUF_closeCStream(HUF_CStream_t* bitC) +{ + HUF_addBits(bitC, HUF_endMark(), /* idx */ 0, /* kFast */ 0); + HUF_flushBits(bitC, /* kFast */ 0); + { + size_t const nbBits = bitC->bitPos[0] & 0xFF; + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (bitC->ptr - bitC->startPtr) + (nbBits > 0); + } +} + +FORCE_INLINE_TEMPLATE void +HUF_encodeSymbol(HUF_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable, int idx, int fast) +{ + HUF_addBits(bitCPtr, CTable[symbol], idx, fast); +} + +FORCE_INLINE_TEMPLATE void +HUF_compress1X_usingCTable_internal_body_loop(HUF_CStream_t* bitC, + const BYTE* ip, size_t srcSize, + const HUF_CElt* ct, + int kUnroll, int kFastFlush, int kLastFast) +{ + /* Join to kUnroll */ + int n = (int)srcSize; + int rem = n % kUnroll; + if (rem > 0) { + for (; rem > 0; --rem) { + HUF_encodeSymbol(bitC, ip[--n], ct, 0, /* fast */ 0); + } + HUF_flushBits(bitC, kFastFlush); + } + assert(n % kUnroll == 0); + + /* Join to 2 * kUnroll */ + if (n % (2 * kUnroll)) { + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, 0, 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, 0, kLastFast); + HUF_flushBits(bitC, kFastFlush); + n -= kUnroll; + } + assert(n % (2 * kUnroll) == 0); + + for (; n>0; n-= 2 * kUnroll) { + /* Encode kUnroll symbols into the bitstream @ index 0. */ + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, /* idx */ 0, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, /* idx */ 0, /* fast */ kLastFast); + HUF_flushBits(bitC, kFastFlush); + /* Encode kUnroll symbols into the bitstream @ index 1. + * This allows us to start filling the bit container + * without any data dependencies. + */ + HUF_zeroIndex1(bitC); + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - kUnroll - u], ct, /* idx */ 1, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll - kUnroll], ct, /* idx */ 1, /* fast */ kLastFast); + /* Merge bitstream @ index 1 into the bitstream @ index 0 */ + HUF_mergeIndex1(bitC); + HUF_flushBits(bitC, kFastFlush); + } + assert(n == 0); + +} + +/** + * Returns a tight upper bound on the output space needed by Huffman + * with 8 bytes buffer to handle over-writes. If the output is at least + * this large we don't need to do bounds checks during Huffman encoding. + */ +static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog) +{ + return ((srcSize * tableLog) >> 3) + 8; +} -#define HUF_FLUSHBITS_2(stream) \ - if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream) FORCE_INLINE_TEMPLATE size_t HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable) { + U32 const tableLog = (U32)CTable[0]; + HUF_CElt const* ct = CTable + 1; const BYTE* ip = (const BYTE*) src; BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; BYTE* op = ostart; - size_t n; - BIT_CStream_t bitC; + HUF_CStream_t bitC; /* init */ if (dstSize < 8) return 0; /* not enough space to compress */ - { size_t const initErr = BIT_initCStream(&bitC, op, (size_t)(oend-op)); + { size_t const initErr = HUF_initCStream(&bitC, op, (size_t)(oend-op)); if (HUF_isError(initErr)) return 0; } - n = srcSize & ~3; /* join to mod 4 */ - switch (srcSize & 3) - { - case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable); - HUF_FLUSHBITS_2(&bitC); - /* fall-through */ - case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable); - HUF_FLUSHBITS_1(&bitC); - /* fall-through */ - case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable); - HUF_FLUSHBITS(&bitC); - /* fall-through */ - case 0 : /* fall-through */ - default: break; + if (dstSize < HUF_tightCompressBound(srcSize, (size_t)tableLog) || tableLog > 11) + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ MEM_32bits() ? 2 : 4, /* kFast */ 0, /* kLastFast */ 0); + else { + if (MEM_32bits()) { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: + case 9: + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 7: + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } else { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 9: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 6, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 7, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 7: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 6: + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } } + assert(bitC.ptr <= bitC.endPtr); - for (; n>0; n-=4) { /* note : n&3==0 at this stage */ - HUF_encodeSymbol(&bitC, ip[n- 1], CTable); - HUF_FLUSHBITS_1(&bitC); - HUF_encodeSymbol(&bitC, ip[n- 2], CTable); - HUF_FLUSHBITS_2(&bitC); - HUF_encodeSymbol(&bitC, ip[n- 3], CTable); - HUF_FLUSHBITS_1(&bitC); - HUF_encodeSymbol(&bitC, ip[n- 4], CTable); - HUF_FLUSHBITS(&bitC); - } - - return BIT_closeCStream(&bitC); + return HUF_closeCStream(&bitC); } #if DYNAMIC_BMI2 @@ -671,7 +968,6 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0); } - static size_t HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, const void* src, size_t srcSize, @@ -751,10 +1047,11 @@ static size_t HUF_compressCTable_internal( typedef struct { unsigned count[HUF_SYMBOLVALUE_MAX + 1]; - HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1]; + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(HUF_SYMBOLVALUE_MAX)]; union { HUF_buildCTable_wksp_tables buildCTable_wksp; HUF_WriteCTableWksp writeCTable_wksp; + U32 hist_wksp[HIST_WKSP_SIZE_U32]; } wksps; } HUF_compress_tables_t; @@ -763,26 +1060,25 @@ typedef struct { /* HUF_compress_internal() : * `workSpace_align4` must be aligned on 4-bytes boundaries, - * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U32 unsigned */ + * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */ static size_t HUF_compress_internal (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, HUF_nbStreams_e nbStreams, - void* workSpace_align4, size_t wkspSize, + void* workSpace, size_t wkspSize, HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat, const int bmi2, unsigned suspectUncompressible) { - HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace_align4; + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, sizeof(size_t)); BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; BYTE* op = ostart; - HUF_STATIC_ASSERT(sizeof(*table) <= HUF_WORKSPACE_SIZE); - assert(((size_t)workSpace_align4 & 3) == 0); /* must be aligned on 4-bytes boundaries */ + HUF_STATIC_ASSERT(sizeof(*table) + HUF_WORKSPACE_MAX_ALIGNMENT <= HUF_WORKSPACE_SIZE); /* checks & inits */ - if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall); + if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall); if (!srcSize) return 0; /* Uncompressed */ if (!dstSize) return 0; /* cannot fit anything within dst budget */ if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */ @@ -814,7 +1110,7 @@ HUF_compress_internal (void* dst, size_t dstSize, } /* Scan input and build symbol stats */ - { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace_align4, wkspSize) ); + { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->wksps.hist_wksp, sizeof(table->wksps.hist_wksp)) ); if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */ } @@ -839,9 +1135,12 @@ HUF_compress_internal (void* dst, size_t dstSize, &table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp)); CHECK_F(maxBits); huffLog = (U32)maxBits; - /* Zero unused symbols in CTable, so we can check it for validity */ - ZSTD_memset(table->CTable + (maxSymbolValue + 1), 0, - sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt))); + } + /* Zero unused symbols in CTable, so we can check it for validity */ + { + size_t const ctableSize = HUF_CTABLE_SIZE_ST(maxSymbolValue); + size_t const unusedSize = sizeof(table->CTable) - ctableSize * sizeof(HUF_CElt); + ZSTD_memset(table->CTable + ctableSize, 0, unusedSize); } /* Write table description header */ @@ -939,7 +1238,7 @@ size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog) { - unsigned workSpace[HUF_WORKSPACE_SIZE_U32]; + U64 workSpace[HUF_WORKSPACE_SIZE_U64]; return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace)); } @@ -947,7 +1246,7 @@ size_t HUF_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog) { - unsigned workSpace[HUF_WORKSPACE_SIZE_U32]; + U64 workSpace[HUF_WORKSPACE_SIZE_U64]; return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace)); } diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 3b04fd09f..65420857a 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -63,7 +63,7 @@ typedef struct { } ZSTD_localDict; typedef struct { - HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)]; + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(255)]; HUF_repeat repeatMode; } ZSTD_hufCTables_t; diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index a880fadad..19999470e 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -126,7 +126,7 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, optPtr->litSum = 0; for (lit=0; lit<=MaxLit; lit++) { U32 const scaleLog = 11; /* scale to 2K */ - U32 const bitCost = HUF_getNbBits(optPtr->symbolCosts->huf.CTable, lit); + U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit); assert(bitCost <= scaleLog); optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; optPtr->litSum += optPtr->litFreq[lit]; diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index fa6a2d6ed..4f4db8575 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -185,7 +185,7 @@ BYTE SEQUENCE_LLCODE[ZSTD_BLOCKSIZE_MAX]; BYTE SEQUENCE_MLCODE[ZSTD_BLOCKSIZE_MAX]; BYTE SEQUENCE_OFCODE[ZSTD_BLOCKSIZE_MAX]; -unsigned WKSP[HUF_WORKSPACE_SIZE_U32]; +U64 WKSP[HUF_WORKSPACE_SIZE_U64]; typedef struct { size_t contentSize; /* 0 means unknown (unless contentSize == windowSize == 0) */ @@ -199,7 +199,7 @@ typedef struct { int hufInit; /* the distribution used in the previous block for repeat mode */ BYTE hufDist[DISTSIZE]; - HUF_CElt hufTable [256]; + HUF_CElt hufTable [HUF_CTABLE_SIZE_ST(255)]; int fseInit; FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; From 43aad811db139204c70b896cd62c360ae09f09e2 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 29 Jul 2021 08:49:36 -0700 Subject: [PATCH 088/274] Add VS2019 test, migrate minimal decompressor macros to GHActions --- .github/workflows/dev-short-tests.yml | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 0092775b1..1f676c46b 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -151,6 +151,23 @@ jobs: make gcc8install CC=gcc-8 CFLAGS="-Werror" make -j all + visual-2019: + runs-on: windows-latest + strategy: + matrix: + platform: [x64, Win32] + configuration: [Debug, Release] + steps: + - uses: actions/checkout@v2 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + run: > + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v142 + /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} + visual-2015: # only GH actions windows-2016 contains VS 2015 runs-on: windows-2016 @@ -168,6 +185,21 @@ jobs: msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} + minimal-decompressor-macros: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: minimal decompressor macros + run: | + make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" + make clean && make check ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" + make clean && make -j all MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X1 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT" + make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X1 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT" + make clean && make -j all MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" + make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" + make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + # For reference : icc tests # icc tests are currently failing on Github Actions, likely to issues during installation stage # To be fixed later From 5ec7897a26d0fbe54c20ff0c761f98218e1314bd Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 29 Jul 2021 09:05:51 -0700 Subject: [PATCH 089/274] Fix static analyzer warnings --- lib/compress/zstd_compress.c | 1 + lib/compress/zstd_lazy.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d6bbca7d1..fa49df6ab 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3646,6 +3646,7 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s repcodes_t cRep; ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); + ZSTD_memset(&nextSeqStore, 0, sizeof(seqStore_t)); DEBUGLOG(4, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 4dfd9d9ed..957c88be9 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1176,9 +1176,10 @@ size_t ZSTD_RowFindBestMatch_generic ( /* DMS/DDS variables that may be referenced laster */ const ZSTD_matchState_t* const dms = ms->dictMatchState; - size_t ddsIdx; - U32 ddsExtraAttempts; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ - U32 dmsTag; + /* Initialize the following variables to satisfy static analyzer */ + size_t ddsIdx = 0; + U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ + U32 dmsTag = 0; U32* dmsRow = NULL; BYTE* dmsTagRow = NULL; From d8a07972687004a5446cd612404de8a1c5584188 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 2 Aug 2021 21:02:31 -0700 Subject: [PATCH 090/274] [fuzz] Add Huffman round trip fuzzer * Add a Huffman round trip fuzzer * Fix two minor bugs in Huffman that aren't exposed in zstd - Incorrect weight comparison (weights are allowed to be equal to table log). - HUF_compress1X_usingCTable_internal() can return compressed size >= source size, so the assert that `cSize <= 65535` isn't correct, and it needs to be checked instead. --- lib/common/entropy_common.c | 2 +- lib/common/huf.h | 2 + lib/compress/huf_compress.c | 25 ++++--- tests/fuzz/.gitignore | 1 + tests/fuzz/Makefile | 6 +- tests/fuzz/fuzz.py | 1 + tests/fuzz/huf_round_trip.c | 132 ++++++++++++++++++++++++++++++++++++ 7 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 tests/fuzz/huf_round_trip.c diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index 41cd69566..6ba1f2209 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -299,7 +299,7 @@ HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); weightTotal = 0; { U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected); + if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected); rankStats[huffWeight[n]]++; weightTotal += (1 << huffWeight[n]) >> 1; } } diff --git a/lib/common/huf.h b/lib/common/huf.h index 39e6c2d04..2f2bf4b7f 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -190,6 +190,7 @@ size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSym size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog); size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize); size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); +size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2); size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); @@ -303,6 +304,7 @@ size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* c size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog); size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U64 U64 */ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable); +size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2); /** HUF_compress1X_repeat() : * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. * If it uses hufTable it does not modify hufTable or repeat. diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 7c23c0c75..8529a4b0b 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -965,7 +965,12 @@ HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable) { - return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0); + return HUF_compress1X_usingCTable_bmi2(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0); +} + +size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2) +{ + return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2); } static size_t @@ -986,8 +991,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, assert(op <= oend); { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) ); - if (cSize==0) return 0; - assert(cSize <= 65535); + if (cSize == 0 || cSize > 65535) return 0; MEM_writeLE16(ostart, (U16)cSize); op += cSize; } @@ -995,8 +999,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, ip += segmentSize; assert(op <= oend); { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) ); - if (cSize==0) return 0; - assert(cSize <= 65535); + if (cSize == 0 || cSize > 65535) return 0; MEM_writeLE16(ostart+2, (U16)cSize); op += cSize; } @@ -1004,8 +1007,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, ip += segmentSize; assert(op <= oend); { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, bmi2) ); - if (cSize==0) return 0; - assert(cSize <= 65535); + if (cSize == 0 || cSize > 65535) return 0; MEM_writeLE16(ostart+4, (U16)cSize); op += cSize; } @@ -1014,7 +1016,7 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, assert(op <= oend); assert(ip <= iend); { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, bmi2) ); - if (cSize==0) return 0; + if (cSize == 0 || cSize > 65535) return 0; op += cSize; } @@ -1023,7 +1025,12 @@ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable) { - return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0); + return HUF_compress4X_usingCTable_bmi2(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0); +} + +size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2) +{ + return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, bmi2); } typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e; diff --git a/tests/fuzz/.gitignore b/tests/fuzz/.gitignore index 93d935a85..02c2f10be 100644 --- a/tests/fuzz/.gitignore +++ b/tests/fuzz/.gitignore @@ -17,6 +17,7 @@ decompress_dstSize_tooSmall fse_read_ncount sequence_compression_api seekable_roundtrip +huf_round_trip fuzz-*.log rt_lib_* d_lib_* diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index ccb574b79..5c54ccd77 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -103,7 +103,8 @@ FUZZ_TARGETS := \ decompress_dstSize_tooSmall \ fse_read_ncount \ sequence_compression_api \ - seekable_roundtrip + seekable_roundtrip \ + huf_round_trip all: libregression.a $(FUZZ_TARGETS) @@ -200,6 +201,9 @@ sequence_compression_api: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_sequenc seekable_roundtrip: $(FUZZ_HEADERS) $(SEEKABLE_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) $(SEEKABLE_OBJS) rt_fuzz_seekable_roundtrip.o $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) $(SEEKABLE_OBJS) rt_fuzz_seekable_roundtrip.o $(LIB_FUZZING_ENGINE) -o $@ +huf_round_trip: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_huf_round_trip.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_huf_round_trip.o $(LIB_FUZZING_ENGINE) -o $@ + libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h $(PRGDIR)/util.c d_fuzz_regression_driver.o $(AR) $(FUZZ_ARFLAGS) $@ d_fuzz_regression_driver.o diff --git a/tests/fuzz/fuzz.py b/tests/fuzz/fuzz.py index d8dfa7782..057a47ecb 100755 --- a/tests/fuzz/fuzz.py +++ b/tests/fuzz/fuzz.py @@ -63,6 +63,7 @@ TARGET_INFO = { 'fse_read_ncount': TargetInfo(InputType.RAW_DATA), 'sequence_compression_api': TargetInfo(InputType.RAW_DATA), 'seekable_roundtrip': TargetInfo(InputType.RAW_DATA), + 'huf_round_trip': TargetInfo(InputType.RAW_DATA), } TARGETS = list(TARGET_INFO.keys()) ALL_TARGETS = TARGETS + ['all'] diff --git a/tests/fuzz/huf_round_trip.c b/tests/fuzz/huf_round_trip.c new file mode 100644 index 000000000..0e26ca9b5 --- /dev/null +++ b/tests/fuzz/huf_round_trip.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/** + * This fuzz target performs a zstd round-trip test (compress & decompress), + * compares the result with the original, and calls abort() on corruption. + */ + +#define HUF_STATIC_LINKING_ONLY + +#include +#include +#include +#include +#include "common/cpu.h" +#include "compress/hist.h" +#include "common/huf.h" +#include "fuzz_helpers.h" +#include "fuzz_data_producer.h" + +static size_t adjustTableLog(size_t tableLog, size_t maxSymbol) +{ + size_t const alphabetSize = maxSymbol + 1; + size_t minTableLog = BIT_highbit32(alphabetSize) + 1; + if ((alphabetSize & (alphabetSize - 1)) != 0) { + ++minTableLog; + } + assert(minTableLog <= 9); + if (tableLog < minTableLog) + return minTableLog; + else + return tableLog; +} + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + /* Select random parameters: #streams, X1 or X2 decoding, bmi2 */ + int const streams = FUZZ_dataProducer_int32Range(producer, 0, 1); + int const symbols = FUZZ_dataProducer_int32Range(producer, 0, 1); + int const bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()) && FUZZ_dataProducer_int32Range(producer, 0, 1); + /* Select a random cBufSize - it may be too small */ + size_t const cBufSize = FUZZ_dataProducer_uint32Range(producer, 0, 4 * size); + /* Select a random tableLog - we'll adjust it up later */ + size_t tableLog = FUZZ_dataProducer_uint32Range(producer, 1, 12); + size_t const kMaxSize = 256 * 1024; + size = FUZZ_dataProducer_remainingBytes(producer); + if (size > kMaxSize) + size = kMaxSize; + + if (size <= 1) { + FUZZ_dataProducer_free(producer); + return 0; + } + + uint32_t maxSymbol = 255; + + U32 count[256]; + size_t const mostFrequent = HIST_count(count, &maxSymbol, src, size); + FUZZ_ZASSERT(mostFrequent); + if (mostFrequent == size) { + /* RLE */ + FUZZ_dataProducer_free(producer); + return 0; + + } + FUZZ_ASSERT(maxSymbol <= 255); + tableLog = adjustTableLog(tableLog, maxSymbol); + + size_t const wkspSize = HUF_WORKSPACE_SIZE; + void* wksp = FUZZ_malloc(wkspSize); + void* rBuf = FUZZ_malloc(size); + void* cBuf = FUZZ_malloc(cBufSize); + HUF_CElt* ct = (HUF_CElt*)FUZZ_malloc(HUF_CTABLE_SIZE(maxSymbol)); + HUF_DTable* dt = (HUF_DTable*)FUZZ_malloc(HUF_DTABLE_SIZE(tableLog) * sizeof(HUF_DTable)); + dt[0] = tableLog * 0x01000001; + + tableLog = HUF_optimalTableLog(tableLog, size, maxSymbol); + FUZZ_ASSERT(tableLog <= 12); + tableLog = HUF_buildCTable_wksp(ct, count, maxSymbol, tableLog, wksp, wkspSize); + FUZZ_ZASSERT(tableLog); + size_t const tableSize = HUF_writeCTable_wksp(cBuf, cBufSize, ct, maxSymbol, tableLog, wksp, wkspSize); + if (ERR_isError(tableSize)) { + /* Errors on uncompressible data or cBufSize too small */ + goto _out; + } + FUZZ_ZASSERT(tableSize); + if (symbols == 0) { + FUZZ_ZASSERT(HUF_readDTableX1_wksp_bmi2(dt, cBuf, tableSize, wksp, wkspSize, bmi2)); + } else { + size_t const ret = HUF_readDTableX2_wksp(dt, cBuf, tableSize, wksp, wkspSize); + if (ERR_getErrorCode(ret) == ZSTD_error_tableLog_tooLarge) { + FUZZ_ZASSERT(HUF_readDTableX1_wksp_bmi2(dt, cBuf, tableSize, wksp, wkspSize, bmi2)); + } else { + FUZZ_ZASSERT(ret); + } + } + + size_t cSize; + size_t rSize; + if (streams == 0) { + cSize = HUF_compress1X_usingCTable_bmi2(cBuf, cBufSize, src, size, ct, bmi2); + FUZZ_ZASSERT(cSize); + if (cSize != 0) + rSize = HUF_decompress1X_usingDTable_bmi2(rBuf, size, cBuf, cSize, dt, bmi2); + } else { + cSize = HUF_compress4X_usingCTable_bmi2(cBuf, cBufSize, src, size, ct, bmi2); + FUZZ_ZASSERT(cSize); + if (cSize != 0) + rSize = HUF_decompress4X_usingDTable_bmi2(rBuf, size, cBuf, cSize, dt, bmi2); + } + if (cSize != 0) { + FUZZ_ZASSERT(rSize); + FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size"); + FUZZ_ASSERT_MSG(!FUZZ_memcmp(src, rBuf, size), "Corruption!"); + } +_out: + free(rBuf); + free(cBuf); + free(ct); + free(dt); + free(wksp); + FUZZ_dataProducer_free(producer); + return 0; +} From ead41bcb4ef413f32c733846d2c1a3db0ffcd581 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Tue, 3 Aug 2021 17:20:12 -0400 Subject: [PATCH 091/274] Add Test to Verify mtime is Copied to Destination --- tests/playTests.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index ce585f226..d108d5d8e 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -124,6 +124,13 @@ case "$UNAME" in Darwin | FreeBSD | OpenBSD | NetBSD) MTIME="stat -f %m" ;; esac +assertSameMTime() { + MT1=$($MTIME "$1") + MT2=$($MTIME "$2") + echo MTIME $MT1 $MT2 + [ "$MT1" = "$MT2" ] || die "mtime on $1 doesn't match mtime on $2 ($MT1 != $MT2)" +} + GET_PERMS="stat -c %a" case "$UNAME" in Darwin | FreeBSD | OpenBSD | NetBSD) GET_PERMS="stat -f %Lp" ;; @@ -588,6 +595,18 @@ if [ -n "$READFROMBLOCKDEVICE" ] ; then rm -f tmp.img tmp.img.zst tmp.img.copy fi +println "\n===> zstd created file timestamp tests" +datagen > tmp +sleep 1 # could also use touch -t but I don't know how portable that is. +println "test : copy mtime in file -> file compression " +zstd -f tmp -o tmp.zst +assertSameMTime tmp tmp.zst +sleep 1 # could also use touch -t but I don't know how portable that is. +println "test : copy mtime in file -> file decompression " +zstd -f -d tmp.zst -o tmp.out +assertSameMTime tmp.zst tmp.out +rm -f tmp + println "\n===> compress multiple files into an output directory, --output-dir-flat" println henlo > tmp1 mkdir tmpInputTestDir From aa1957477b07af1dba32335b0ac352fe368f06a4 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Thu, 8 Jul 2021 15:48:57 -0400 Subject: [PATCH 092/274] Improve Huffman sorting algorithm --- lib/common/huf.h | 2 +- lib/compress/huf_compress.c | 150 ++++++++++-- tests/regression/results.csv | 426 +++++++++++++++++------------------ 3 files changed, 343 insertions(+), 235 deletions(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 2f2bf4b7f..a3ae06e4d 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -90,7 +90,7 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, /** HUF_compress4X_wksp() : * Same as HUF_compress2(), but uses externally allocated `workSpace`. * `workspace` must be at least as large as HUF_WORKSPACE_SIZE */ -#define HUF_WORKSPACE_SIZE ((8 << 10) + 256) +#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */) #define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const void* src, size_t srcSize, diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 8529a4b0b..67b7ef956 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -428,22 +428,122 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits) } typedef struct { - U32 base; - U32 curr; + U16 base; + U16 curr; } rankPos; typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32]; -#define RANK_POSITION_TABLE_SIZE 32 +/* Number of buckets available for HUF_sort() */ +#define RANK_POSITION_TABLE_SIZE 128 typedef struct { huffNodeTable huffNodeTbl; rankPos rankPosition[RANK_POSITION_TABLE_SIZE]; } HUF_buildCTable_wksp_tables; +/* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing. + * Strategy is to use as many buckets as possible for representing distinct + * counts while using the remainder to represent all counts up to HUF_BLOCKSIZE_MAX + * using log2 bucketing. + * + * To satisfy this requirement for 128 buckets, we can do the following: + * Let buckets 0-114 represent distinct counts of [0, 114] + * Let buckets 115 to 126 represent counts of [115, HUF_BLOCKSIZE_MAX]. (the final bucket 127 must remain empty) + * + * Note that we don't actually need 17 buckets (assuming 2^17 maxcount) for log2 bucketing since + * the first few buckets in the log2 bucketing representation are already covered by the distinct count bucketing. + */ +#define RANK_POSITION_LOG_BUCKETS_BEGIN (RANK_POSITION_TABLE_SIZE - 1) - BIT_highbit32(HUF_BLOCKSIZE_MAX) - 1 +#define RANK_POSITION_DISTINCT_COUNT_CUTOFF RANK_POSITION_LOG_BUCKETS_BEGIN + BIT_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) + +/* Return the appropriate bucket index for a given count. See definition of + * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy. + */ +static U32 HUF_getIndex(U32 const count) { + return (count < RANK_POSITION_DISTINCT_COUNT_CUTOFF) + ? count + : BIT_highbit32(count) + RANK_POSITION_LOG_BUCKETS_BEGIN; +} + +/* Helper swap function for HUF_quickSortPartition() */ +static void HUF_swapNodes(nodeElt* a, nodeElt* b) { + nodeElt tmp = *a; + *a = *b; + *b = tmp; +} + +/* Returns 0 if the huffNode array is not sorted by descending count */ +UNUSED_ATTR +static int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) { + U32 i; + for (i = 1; i < maxSymbolValue1; ++i) { + if (huffNode[i].count > huffNode[i-1].count) { + return 0; + } + } + return 1; +} + +/* Insertion sort by descending order */ +HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high) { + int i; + int const size = high-low+1; + huffNode += low; + for (i = 1; i < size; ++i) { + nodeElt const key = huffNode[i]; + int j = i - 1; + while (j >= 0 && huffNode[j].count < key.count) { + huffNode[j + 1] = huffNode[j]; + j--; + } + huffNode[j + 1] = key; + } +} + +/* Pivot helper function for quicksort. */ +static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) { + /* Simply select rightmost element as pivot. "Better" selectors like + * median-of-three don't experimentally appear to have any benefit. + */ + U32 const pivot = arr[high].count; + int i = low - 1; + int j = low; + for ( ; j < high; j++) { + if (arr[j].count > pivot) { + i++; + HUF_swapNodes(&arr[i], &arr[j]); + } + } + HUF_swapNodes(&arr[i + 1], &arr[high]); + return i + 1; +} + +/* Classic quicksort by descending with partially iterative calls + * to reduce worst case callstack size. + */ +static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) { + int const kInsertionSortThreshold = 8; + if (high - low < kInsertionSortThreshold) { + HUF_insertionSort(arr, low, high); + return; + } + while (low < high) { + int const idx = HUF_quickSortPartition(arr, low, high); + if (idx - low < high - idx) { + HUF_simpleQuickSort(arr, low, idx - 1); + low = idx + 1; + } else { + HUF_simpleQuickSort(arr, idx + 1, high); + high = idx - 1; + } + } +} + /** * HUF_sort(): * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order. + * This is a typical bucket sorting strategy that uses either quicksort or insertion sort to sort each bucket. * * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled. * Must have (maxSymbolValue + 1) entries. @@ -451,44 +551,52 @@ typedef struct { * @param[in] maxSymbolValue Maximum symbol value. * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries. */ -static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue, rankPos* rankPosition) -{ - int n; - int const maxSymbolValue1 = (int)maxSymbolValue + 1; +static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[]) { + U32 n; + U32 const maxSymbolValue1 = maxSymbolValue+1; /* Compute base and set curr to base. - * For symbol s let lowerRank = BIT_highbit32(count[n]+1) and rank = lowerRank + 1. - * Then 2^lowerRank <= count[n]+1 <= 2^rank. + * For symbol s let lowerRank = HUF_getIndex(count[n]) and rank = lowerRank + 1. + * See HUF_getIndex to see bucketing strategy. * We attribute each symbol to lowerRank's base value, because we want to know where * each rank begins in the output, so for rank R we want to count ranks R+1 and above. */ ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE); for (n = 0; n < maxSymbolValue1; ++n) { - U32 lowerRank = BIT_highbit32(count[n] + 1); + U32 lowerRank = HUF_getIndex(count[n]); + assert(lowerRank < RANK_POSITION_TABLE_SIZE - 1); rankPosition[lowerRank].base++; } + assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0); + /* Set up the rankPosition table */ for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) { rankPosition[n-1].base += rankPosition[n].base; rankPosition[n-1].curr = rankPosition[n-1].base; } - /* Sort */ + + /* Insert each symbol into their appropriate bucket, setting up rankPosition table. */ for (n = 0; n < maxSymbolValue1; ++n) { U32 const c = count[n]; - U32 const r = BIT_highbit32(c+1) + 1; - U32 pos = rankPosition[r].curr++; - /* Insert into the correct position in the rank. - * We have at most 256 symbols, so this insertion should be fine. - */ - while ((pos > rankPosition[r].base) && (c > huffNode[pos-1].count)) { - huffNode[pos] = huffNode[pos-1]; - pos--; - } + U32 const r = HUF_getIndex(c) + 1; + U32 const pos = rankPosition[r].curr++; + assert(pos < maxSymbolValue1); huffNode[pos].count = c; huffNode[pos].byte = (BYTE)n; } -} + /* Sort each bucket. */ + for (n = RANK_POSITION_DISTINCT_COUNT_CUTOFF; n < RANK_POSITION_TABLE_SIZE - 1; ++n) { + U32 const bucketSize = rankPosition[n].curr-rankPosition[n].base; + U32 const bucketStartIdx = rankPosition[n].base; + if (bucketSize > 1) { + assert(bucketStartIdx < maxSymbolValue1); + HUF_simpleQuickSort(huffNode + bucketStartIdx, 0, bucketSize-1); + } + } + + assert(HUF_isSorted(huffNode, maxSymbolValue1)); +} /** HUF_buildCTable_wksp() : * Same as HUF_buildCTable(), but using externally allocated scratch buffer. diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 0734a539f..855401acb 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -2,19 +2,19 @@ Data, Config, Method, silesia.tar, level -5, compress simple, 6738593 silesia.tar, level -3, compress simple, 6446372 silesia.tar, level -1, compress simple, 6186042 -silesia.tar, level 0, compress simple, 4861425 +silesia.tar, level 0, compress simple, 4861423 silesia.tar, level 1, compress simple, 5334885 -silesia.tar, level 3, compress simple, 4861425 -silesia.tar, level 4, compress simple, 4799630 +silesia.tar, level 3, compress simple, 4861423 +silesia.tar, level 4, compress simple, 4799632 silesia.tar, level 5, compress simple, 4719256 -silesia.tar, level 6, compress simple, 4677721 -silesia.tar, level 7, compress simple, 4613541 +silesia.tar, level 6, compress simple, 4677724 +silesia.tar, level 7, compress simple, 4613545 silesia.tar, level 9, compress simple, 4555426 -silesia.tar, level 13, compress simple, 4491764 +silesia.tar, level 13, compress simple, 4491768 silesia.tar, level 16, compress simple, 4356834 -silesia.tar, level 19, compress simple, 4264392 -silesia.tar, uncompressed literals, compress simple, 4861425 -silesia.tar, uncompressed literals optimal, compress simple, 4264392 +silesia.tar, level 19, compress simple, 4264388 +silesia.tar, uncompressed literals, compress simple, 4861423 +silesia.tar, uncompressed literals optimal, compress simple, 4264388 silesia.tar, huffman literals, compress simple, 6186042 github.tar, level -5, compress simple, 46856 github.tar, level -3, compress simple, 43754 @@ -36,28 +36,28 @@ github.tar, huffman literals, compress silesia, level -5, compress cctx, 6737607 silesia, level -3, compress cctx, 6444677 silesia, level -1, compress cctx, 6178460 -silesia, level 0, compress cctx, 4849552 -silesia, level 1, compress cctx, 5313204 -silesia, level 3, compress cctx, 4849552 -silesia, level 4, compress cctx, 4786970 -silesia, level 5, compress cctx, 4707794 +silesia, level 0, compress cctx, 4849551 +silesia, level 1, compress cctx, 5313202 +silesia, level 3, compress cctx, 4849551 +silesia, level 4, compress cctx, 4786969 +silesia, level 5, compress cctx, 4707790 silesia, level 6, compress cctx, 4666383 silesia, level 7, compress cctx, 4603381 -silesia, level 9, compress cctx, 4546001 -silesia, level 13, compress cctx, 4482135 +silesia, level 9, compress cctx, 4546005 +silesia, level 13, compress cctx, 4482131 silesia, level 16, compress cctx, 4360251 -silesia, level 19, compress cctx, 4283237 -silesia, long distance mode, compress cctx, 4849552 -silesia, multithreaded, compress cctx, 4849552 -silesia, multithreaded long distance mode, compress cctx, 4849552 +silesia, level 19, compress cctx, 4283236 +silesia, long distance mode, compress cctx, 4849551 +silesia, multithreaded, compress cctx, 4849551 +silesia, multithreaded long distance mode, compress cctx, 4849551 silesia, small window log, compress cctx, 7084179 silesia, small hash log, compress cctx, 6526141 -silesia, small chain log, compress cctx, 4912197 -silesia, explicit params, compress cctx, 4794479 -silesia, uncompressed literals, compress cctx, 4849552 -silesia, uncompressed literals optimal, compress cctx, 4283237 +silesia, small chain log, compress cctx, 4912199 +silesia, explicit params, compress cctx, 4794480 +silesia, uncompressed literals, compress cctx, 4849551 +silesia, uncompressed literals optimal, compress cctx, 4283236 silesia, huffman literals, compress cctx, 6178460 -silesia, multithreaded with advanced params, compress cctx, 4849552 +silesia, multithreaded with advanced params, compress cctx, 4849551 github, level -5, compress cctx, 205285 github, level -5 with dict, compress cctx, 47294 github, level -3, compress cctx, 190643 @@ -100,50 +100,50 @@ github, multithreaded with advanced params, compress silesia, level -5, zstdcli, 6737655 silesia, level -3, zstdcli, 6444725 silesia, level -1, zstdcli, 6178508 -silesia, level 0, zstdcli, 4849600 -silesia, level 1, zstdcli, 5313252 -silesia, level 3, zstdcli, 4849600 -silesia, level 4, zstdcli, 4787018 -silesia, level 5, zstdcli, 4707842 +silesia, level 0, zstdcli, 4849599 +silesia, level 1, zstdcli, 5313250 +silesia, level 3, zstdcli, 4849599 +silesia, level 4, zstdcli, 4787017 +silesia, level 5, zstdcli, 4707838 silesia, level 6, zstdcli, 4666431 silesia, level 7, zstdcli, 4603429 -silesia, level 9, zstdcli, 4546049 -silesia, level 13, zstdcli, 4482183 +silesia, level 9, zstdcli, 4546053 +silesia, level 13, zstdcli, 4482179 silesia, level 16, zstdcli, 4360299 -silesia, level 19, zstdcli, 4283285 -silesia, long distance mode, zstdcli, 4840806 -silesia, multithreaded, zstdcli, 4849600 -silesia, multithreaded long distance mode, zstdcli, 4840806 +silesia, level 19, zstdcli, 4283284 +silesia, long distance mode, zstdcli, 4840807 +silesia, multithreaded, zstdcli, 4849599 +silesia, multithreaded long distance mode, zstdcli, 4840807 silesia, small window log, zstdcli, 7095967 silesia, small hash log, zstdcli, 6526189 -silesia, small chain log, zstdcli, 4912245 +silesia, small chain log, zstdcli, 4912247 silesia, explicit params, zstdcli, 4795856 silesia, uncompressed literals, zstdcli, 5128030 silesia, uncompressed literals optimal, zstdcli, 4317944 -silesia, huffman literals, zstdcli, 5326316 +silesia, huffman literals, zstdcli, 5326317 silesia, multithreaded with advanced params, zstdcli, 5128030 silesia.tar, level -5, zstdcli, 6738934 silesia.tar, level -3, zstdcli, 6448419 silesia.tar, level -1, zstdcli, 6186912 -silesia.tar, level 0, zstdcli, 4861512 +silesia.tar, level 0, zstdcli, 4861511 silesia.tar, level 1, zstdcli, 5336318 -silesia.tar, level 3, zstdcli, 4861512 +silesia.tar, level 3, zstdcli, 4861511 silesia.tar, level 4, zstdcli, 4800529 silesia.tar, level 5, zstdcli, 4720121 -silesia.tar, level 6, zstdcli, 4678661 -silesia.tar, level 7, zstdcli, 4614424 +silesia.tar, level 6, zstdcli, 4678663 +silesia.tar, level 7, zstdcli, 4614426 silesia.tar, level 9, zstdcli, 4556062 -silesia.tar, level 13, zstdcli, 4491768 +silesia.tar, level 13, zstdcli, 4491772 silesia.tar, level 16, zstdcli, 4356838 -silesia.tar, level 19, zstdcli, 4264396 -silesia.tar, no source size, zstdcli, 4861508 -silesia.tar, long distance mode, zstdcli, 4853226 -silesia.tar, multithreaded, zstdcli, 4861512 -silesia.tar, multithreaded long distance mode, zstdcli, 4853226 +silesia.tar, level 19, zstdcli, 4264392 +silesia.tar, no source size, zstdcli, 4861507 +silesia.tar, long distance mode, zstdcli, 4853225 +silesia.tar, multithreaded, zstdcli, 4861511 +silesia.tar, multithreaded long distance mode, zstdcli, 4853225 silesia.tar, small window log, zstdcli, 7101576 -silesia.tar, small hash log, zstdcli, 6529290 -silesia.tar, small chain log, zstdcli, 4917022 -silesia.tar, explicit params, zstdcli, 4821274 +silesia.tar, small hash log, zstdcli, 6529286 +silesia.tar, small chain log, zstdcli, 4917020 +silesia.tar, explicit params, zstdcli, 4821277 silesia.tar, uncompressed literals, zstdcli, 5129559 silesia.tar, uncompressed literals optimal, zstdcli, 4307404 silesia.tar, huffman literals, zstdcli, 5347610 @@ -231,63 +231,63 @@ github.tar, multithreaded with advanced params, zstdcli, silesia, level -5, advanced one pass, 6737607 silesia, level -3, advanced one pass, 6444677 silesia, level -1, advanced one pass, 6178460 -silesia, level 0, advanced one pass, 4849552 -silesia, level 1, advanced one pass, 5313204 -silesia, level 3, advanced one pass, 4849552 -silesia, level 4, advanced one pass, 4786970 -silesia, level 5 row 1, advanced one pass, 4710236 -silesia, level 5 row 2, advanced one pass, 4707794 -silesia, level 5, advanced one pass, 4707794 +silesia, level 0, advanced one pass, 4849551 +silesia, level 1, advanced one pass, 5313202 +silesia, level 3, advanced one pass, 4849551 +silesia, level 4, advanced one pass, 4786969 +silesia, level 5 row 1, advanced one pass, 4710233 +silesia, level 5 row 2, advanced one pass, 4707790 +silesia, level 5, advanced one pass, 4707790 silesia, level 6, advanced one pass, 4666383 -silesia, level 7 row 1, advanced one pass, 4596296 +silesia, level 7 row 1, advanced one pass, 4596297 silesia, level 7 row 2, advanced one pass, 4603381 silesia, level 7, advanced one pass, 4603381 -silesia, level 9, advanced one pass, 4546001 +silesia, level 9, advanced one pass, 4546005 silesia, level 12 row 1, advanced one pass, 4519288 -silesia, level 12 row 2, advanced one pass, 4521397 -silesia, level 13, advanced one pass, 4482135 +silesia, level 12 row 2, advanced one pass, 4521406 +silesia, level 13, advanced one pass, 4482131 silesia, level 16, advanced one pass, 4360251 -silesia, level 19, advanced one pass, 4283237 -silesia, no source size, advanced one pass, 4849552 +silesia, level 19, advanced one pass, 4283236 +silesia, no source size, advanced one pass, 4849551 silesia, long distance mode, advanced one pass, 4840738 -silesia, multithreaded, advanced one pass, 4849552 -silesia, multithreaded long distance mode, advanced one pass, 4840758 +silesia, multithreaded, advanced one pass, 4849551 +silesia, multithreaded long distance mode, advanced one pass, 4840759 silesia, small window log, advanced one pass, 7095919 silesia, small hash log, advanced one pass, 6526141 -silesia, small chain log, advanced one pass, 4912197 +silesia, small chain log, advanced one pass, 4912199 silesia, explicit params, advanced one pass, 4795856 silesia, uncompressed literals, advanced one pass, 5127982 silesia, uncompressed literals optimal, advanced one pass, 4317896 -silesia, huffman literals, advanced one pass, 5326268 +silesia, huffman literals, advanced one pass, 5326269 silesia, multithreaded with advanced params, advanced one pass, 5127982 silesia.tar, level -5, advanced one pass, 6738593 silesia.tar, level -3, advanced one pass, 6446372 silesia.tar, level -1, advanced one pass, 6186042 -silesia.tar, level 0, advanced one pass, 4861425 +silesia.tar, level 0, advanced one pass, 4861423 silesia.tar, level 1, advanced one pass, 5334885 -silesia.tar, level 3, advanced one pass, 4861425 -silesia.tar, level 4, advanced one pass, 4799630 +silesia.tar, level 3, advanced one pass, 4861423 +silesia.tar, level 4, advanced one pass, 4799632 silesia.tar, level 5 row 1, advanced one pass, 4722324 silesia.tar, level 5 row 2, advanced one pass, 4719256 silesia.tar, level 5, advanced one pass, 4719256 -silesia.tar, level 6, advanced one pass, 4677721 -silesia.tar, level 7 row 1, advanced one pass, 4606715 -silesia.tar, level 7 row 2, advanced one pass, 4613541 -silesia.tar, level 7, advanced one pass, 4613541 +silesia.tar, level 6, advanced one pass, 4677724 +silesia.tar, level 7 row 1, advanced one pass, 4606716 +silesia.tar, level 7 row 2, advanced one pass, 4613545 +silesia.tar, level 7, advanced one pass, 4613545 silesia.tar, level 9, advanced one pass, 4555426 -silesia.tar, level 12 row 1, advanced one pass, 4529459 -silesia.tar, level 12 row 2, advanced one pass, 4530256 -silesia.tar, level 13, advanced one pass, 4491764 +silesia.tar, level 12 row 1, advanced one pass, 4529458 +silesia.tar, level 12 row 2, advanced one pass, 4530257 +silesia.tar, level 13, advanced one pass, 4491768 silesia.tar, level 16, advanced one pass, 4356834 -silesia.tar, level 19, advanced one pass, 4264392 -silesia.tar, no source size, advanced one pass, 4861425 -silesia.tar, long distance mode, advanced one pass, 4847754 -silesia.tar, multithreaded, advanced one pass, 4861508 -silesia.tar, multithreaded long distance mode, advanced one pass, 4853222 +silesia.tar, level 19, advanced one pass, 4264388 +silesia.tar, no source size, advanced one pass, 4861423 +silesia.tar, long distance mode, advanced one pass, 4847753 +silesia.tar, multithreaded, advanced one pass, 4861507 +silesia.tar, multithreaded long distance mode, advanced one pass, 4853221 silesia.tar, small window log, advanced one pass, 7101530 -silesia.tar, small hash log, advanced one pass, 6529232 -silesia.tar, small chain log, advanced one pass, 4917041 -silesia.tar, explicit params, advanced one pass, 4807380 +silesia.tar, small hash log, advanced one pass, 6529228 +silesia.tar, small chain log, advanced one pass, 4917039 +silesia.tar, explicit params, advanced one pass, 4807383 silesia.tar, uncompressed literals, advanced one pass, 5129458 silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 silesia.tar, huffman literals, advanced one pass, 5347335 @@ -525,63 +525,63 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced one pass small out, 6737607 silesia, level -3, advanced one pass small out, 6444677 silesia, level -1, advanced one pass small out, 6178460 -silesia, level 0, advanced one pass small out, 4849552 -silesia, level 1, advanced one pass small out, 5313204 -silesia, level 3, advanced one pass small out, 4849552 -silesia, level 4, advanced one pass small out, 4786970 -silesia, level 5 row 1, advanced one pass small out, 4710236 -silesia, level 5 row 2, advanced one pass small out, 4707794 -silesia, level 5, advanced one pass small out, 4707794 +silesia, level 0, advanced one pass small out, 4849551 +silesia, level 1, advanced one pass small out, 5313202 +silesia, level 3, advanced one pass small out, 4849551 +silesia, level 4, advanced one pass small out, 4786969 +silesia, level 5 row 1, advanced one pass small out, 4710233 +silesia, level 5 row 2, advanced one pass small out, 4707790 +silesia, level 5, advanced one pass small out, 4707790 silesia, level 6, advanced one pass small out, 4666383 -silesia, level 7 row 1, advanced one pass small out, 4596296 +silesia, level 7 row 1, advanced one pass small out, 4596297 silesia, level 7 row 2, advanced one pass small out, 4603381 silesia, level 7, advanced one pass small out, 4603381 -silesia, level 9, advanced one pass small out, 4546001 +silesia, level 9, advanced one pass small out, 4546005 silesia, level 12 row 1, advanced one pass small out, 4519288 -silesia, level 12 row 2, advanced one pass small out, 4521397 -silesia, level 13, advanced one pass small out, 4482135 +silesia, level 12 row 2, advanced one pass small out, 4521406 +silesia, level 13, advanced one pass small out, 4482131 silesia, level 16, advanced one pass small out, 4360251 -silesia, level 19, advanced one pass small out, 4283237 -silesia, no source size, advanced one pass small out, 4849552 +silesia, level 19, advanced one pass small out, 4283236 +silesia, no source size, advanced one pass small out, 4849551 silesia, long distance mode, advanced one pass small out, 4840738 -silesia, multithreaded, advanced one pass small out, 4849552 -silesia, multithreaded long distance mode, advanced one pass small out, 4840758 +silesia, multithreaded, advanced one pass small out, 4849551 +silesia, multithreaded long distance mode, advanced one pass small out, 4840759 silesia, small window log, advanced one pass small out, 7095919 silesia, small hash log, advanced one pass small out, 6526141 -silesia, small chain log, advanced one pass small out, 4912197 +silesia, small chain log, advanced one pass small out, 4912199 silesia, explicit params, advanced one pass small out, 4795856 silesia, uncompressed literals, advanced one pass small out, 5127982 silesia, uncompressed literals optimal, advanced one pass small out, 4317896 -silesia, huffman literals, advanced one pass small out, 5326268 +silesia, huffman literals, advanced one pass small out, 5326269 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 silesia.tar, level -5, advanced one pass small out, 6738593 silesia.tar, level -3, advanced one pass small out, 6446372 silesia.tar, level -1, advanced one pass small out, 6186042 -silesia.tar, level 0, advanced one pass small out, 4861425 +silesia.tar, level 0, advanced one pass small out, 4861423 silesia.tar, level 1, advanced one pass small out, 5334885 -silesia.tar, level 3, advanced one pass small out, 4861425 -silesia.tar, level 4, advanced one pass small out, 4799630 +silesia.tar, level 3, advanced one pass small out, 4861423 +silesia.tar, level 4, advanced one pass small out, 4799632 silesia.tar, level 5 row 1, advanced one pass small out, 4722324 silesia.tar, level 5 row 2, advanced one pass small out, 4719256 silesia.tar, level 5, advanced one pass small out, 4719256 -silesia.tar, level 6, advanced one pass small out, 4677721 -silesia.tar, level 7 row 1, advanced one pass small out, 4606715 -silesia.tar, level 7 row 2, advanced one pass small out, 4613541 -silesia.tar, level 7, advanced one pass small out, 4613541 +silesia.tar, level 6, advanced one pass small out, 4677724 +silesia.tar, level 7 row 1, advanced one pass small out, 4606716 +silesia.tar, level 7 row 2, advanced one pass small out, 4613545 +silesia.tar, level 7, advanced one pass small out, 4613545 silesia.tar, level 9, advanced one pass small out, 4555426 -silesia.tar, level 12 row 1, advanced one pass small out, 4529459 -silesia.tar, level 12 row 2, advanced one pass small out, 4530256 -silesia.tar, level 13, advanced one pass small out, 4491764 +silesia.tar, level 12 row 1, advanced one pass small out, 4529458 +silesia.tar, level 12 row 2, advanced one pass small out, 4530257 +silesia.tar, level 13, advanced one pass small out, 4491768 silesia.tar, level 16, advanced one pass small out, 4356834 -silesia.tar, level 19, advanced one pass small out, 4264392 -silesia.tar, no source size, advanced one pass small out, 4861425 -silesia.tar, long distance mode, advanced one pass small out, 4847754 -silesia.tar, multithreaded, advanced one pass small out, 4861508 -silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853222 +silesia.tar, level 19, advanced one pass small out, 4264388 +silesia.tar, no source size, advanced one pass small out, 4861423 +silesia.tar, long distance mode, advanced one pass small out, 4847753 +silesia.tar, multithreaded, advanced one pass small out, 4861507 +silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853221 silesia.tar, small window log, advanced one pass small out, 7101530 -silesia.tar, small hash log, advanced one pass small out, 6529232 -silesia.tar, small chain log, advanced one pass small out, 4917041 -silesia.tar, explicit params, advanced one pass small out, 4807380 +silesia.tar, small hash log, advanced one pass small out, 6529228 +silesia.tar, small chain log, advanced one pass small out, 4917039 +silesia.tar, explicit params, advanced one pass small out, 4807383 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 silesia.tar, huffman literals, advanced one pass small out, 5347335 @@ -819,63 +819,63 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced streaming, 6882505 silesia, level -3, advanced streaming, 6568376 silesia, level -1, advanced streaming, 6183403 -silesia, level 0, advanced streaming, 4849552 -silesia, level 1, advanced streaming, 5314162 -silesia, level 3, advanced streaming, 4849552 -silesia, level 4, advanced streaming, 4786970 -silesia, level 5 row 1, advanced streaming, 4710236 -silesia, level 5 row 2, advanced streaming, 4707794 -silesia, level 5, advanced streaming, 4707794 +silesia, level 0, advanced streaming, 4849551 +silesia, level 1, advanced streaming, 5314161 +silesia, level 3, advanced streaming, 4849551 +silesia, level 4, advanced streaming, 4786969 +silesia, level 5 row 1, advanced streaming, 4710233 +silesia, level 5 row 2, advanced streaming, 4707790 +silesia, level 5, advanced streaming, 4707790 silesia, level 6, advanced streaming, 4666383 -silesia, level 7 row 1, advanced streaming, 4596296 +silesia, level 7 row 1, advanced streaming, 4596297 silesia, level 7 row 2, advanced streaming, 4603381 silesia, level 7, advanced streaming, 4603381 -silesia, level 9, advanced streaming, 4546001 +silesia, level 9, advanced streaming, 4546005 silesia, level 12 row 1, advanced streaming, 4519288 -silesia, level 12 row 2, advanced streaming, 4521397 -silesia, level 13, advanced streaming, 4482135 +silesia, level 12 row 2, advanced streaming, 4521406 +silesia, level 13, advanced streaming, 4482131 silesia, level 16, advanced streaming, 4360251 -silesia, level 19, advanced streaming, 4283237 -silesia, no source size, advanced streaming, 4849516 +silesia, level 19, advanced streaming, 4283236 +silesia, no source size, advanced streaming, 4849515 silesia, long distance mode, advanced streaming, 4840738 -silesia, multithreaded, advanced streaming, 4849552 -silesia, multithreaded long distance mode, advanced streaming, 4840758 +silesia, multithreaded, advanced streaming, 4849551 +silesia, multithreaded long distance mode, advanced streaming, 4840759 silesia, small window log, advanced streaming, 7112062 silesia, small hash log, advanced streaming, 6526141 -silesia, small chain log, advanced streaming, 4912197 +silesia, small chain log, advanced streaming, 4912199 silesia, explicit params, advanced streaming, 4795884 silesia, uncompressed literals, advanced streaming, 5127982 silesia, uncompressed literals optimal, advanced streaming, 4317896 -silesia, huffman literals, advanced streaming, 5331168 +silesia, huffman literals, advanced streaming, 5331171 silesia, multithreaded with advanced params, advanced streaming, 5127982 silesia.tar, level -5, advanced streaming, 6982759 silesia.tar, level -3, advanced streaming, 6641283 silesia.tar, level -1, advanced streaming, 6190795 -silesia.tar, level 0, advanced streaming, 4861427 -silesia.tar, level 1, advanced streaming, 5336939 -silesia.tar, level 3, advanced streaming, 4861427 -silesia.tar, level 4, advanced streaming, 4799630 +silesia.tar, level 0, advanced streaming, 4861425 +silesia.tar, level 1, advanced streaming, 5336941 +silesia.tar, level 3, advanced streaming, 4861425 +silesia.tar, level 4, advanced streaming, 4799632 silesia.tar, level 5 row 1, advanced streaming, 4722329 silesia.tar, level 5 row 2, advanced streaming, 4719261 silesia.tar, level 5, advanced streaming, 4719261 -silesia.tar, level 6, advanced streaming, 4677729 -silesia.tar, level 7 row 1, advanced streaming, 4606715 -silesia.tar, level 7 row 2, advanced streaming, 4613544 -silesia.tar, level 7, advanced streaming, 4613544 +silesia.tar, level 6, advanced streaming, 4677732 +silesia.tar, level 7 row 1, advanced streaming, 4606717 +silesia.tar, level 7 row 2, advanced streaming, 4613548 +silesia.tar, level 7, advanced streaming, 4613548 silesia.tar, level 9, advanced streaming, 4555432 -silesia.tar, level 12 row 1, advanced streaming, 4529459 -silesia.tar, level 12 row 2, advanced streaming, 4530258 -silesia.tar, level 13, advanced streaming, 4491765 +silesia.tar, level 12 row 1, advanced streaming, 4529458 +silesia.tar, level 12 row 2, advanced streaming, 4530259 +silesia.tar, level 13, advanced streaming, 4491769 silesia.tar, level 16, advanced streaming, 4356834 -silesia.tar, level 19, advanced streaming, 4264392 -silesia.tar, no source size, advanced streaming, 4861423 -silesia.tar, long distance mode, advanced streaming, 4847754 -silesia.tar, multithreaded, advanced streaming, 4861508 -silesia.tar, multithreaded long distance mode, advanced streaming, 4853222 +silesia.tar, level 19, advanced streaming, 4264388 +silesia.tar, no source size, advanced streaming, 4861421 +silesia.tar, long distance mode, advanced streaming, 4847753 +silesia.tar, multithreaded, advanced streaming, 4861507 +silesia.tar, multithreaded long distance mode, advanced streaming, 4853221 silesia.tar, small window log, advanced streaming, 7118769 -silesia.tar, small hash log, advanced streaming, 6529235 -silesia.tar, small chain log, advanced streaming, 4917021 -silesia.tar, explicit params, advanced streaming, 4807399 +silesia.tar, small hash log, advanced streaming, 6529231 +silesia.tar, small chain log, advanced streaming, 4917019 +silesia.tar, explicit params, advanced streaming, 4807403 silesia.tar, uncompressed literals, advanced streaming, 5129461 silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 silesia.tar, huffman literals, advanced streaming, 5352360 @@ -1113,38 +1113,38 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, old streaming, 6882505 silesia, level -3, old streaming, 6568376 silesia, level -1, old streaming, 6183403 -silesia, level 0, old streaming, 4849552 -silesia, level 1, old streaming, 5314162 -silesia, level 3, old streaming, 4849552 -silesia, level 4, old streaming, 4786970 -silesia, level 5, old streaming, 4707794 +silesia, level 0, old streaming, 4849551 +silesia, level 1, old streaming, 5314161 +silesia, level 3, old streaming, 4849551 +silesia, level 4, old streaming, 4786969 +silesia, level 5, old streaming, 4707790 silesia, level 6, old streaming, 4666383 silesia, level 7, old streaming, 4603381 -silesia, level 9, old streaming, 4546001 -silesia, level 13, old streaming, 4482135 +silesia, level 9, old streaming, 4546005 +silesia, level 13, old streaming, 4482131 silesia, level 16, old streaming, 4360251 -silesia, level 19, old streaming, 4283237 -silesia, no source size, old streaming, 4849516 -silesia, uncompressed literals, old streaming, 4849552 -silesia, uncompressed literals optimal, old streaming, 4283237 +silesia, level 19, old streaming, 4283236 +silesia, no source size, old streaming, 4849515 +silesia, uncompressed literals, old streaming, 4849551 +silesia, uncompressed literals optimal, old streaming, 4283236 silesia, huffman literals, old streaming, 6183403 silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -3, old streaming, 6641283 silesia.tar, level -1, old streaming, 6190795 -silesia.tar, level 0, old streaming, 4861427 -silesia.tar, level 1, old streaming, 5336939 -silesia.tar, level 3, old streaming, 4861427 -silesia.tar, level 4, old streaming, 4799630 +silesia.tar, level 0, old streaming, 4861425 +silesia.tar, level 1, old streaming, 5336941 +silesia.tar, level 3, old streaming, 4861425 +silesia.tar, level 4, old streaming, 4799632 silesia.tar, level 5, old streaming, 4719261 -silesia.tar, level 6, old streaming, 4677729 -silesia.tar, level 7, old streaming, 4613544 +silesia.tar, level 6, old streaming, 4677732 +silesia.tar, level 7, old streaming, 4613548 silesia.tar, level 9, old streaming, 4555432 -silesia.tar, level 13, old streaming, 4491765 +silesia.tar, level 13, old streaming, 4491769 silesia.tar, level 16, old streaming, 4356834 -silesia.tar, level 19, old streaming, 4264392 -silesia.tar, no source size, old streaming, 4861423 -silesia.tar, uncompressed literals, old streaming, 4861427 -silesia.tar, uncompressed literals optimal, old streaming, 4264392 +silesia.tar, level 19, old streaming, 4264388 +silesia.tar, no source size, old streaming, 4861421 +silesia.tar, uncompressed literals, old streaming, 4861425 +silesia.tar, uncompressed literals optimal, old streaming, 4264388 silesia.tar, huffman literals, old streaming, 6190795 github, level -5, old streaming, 205285 github, level -5 with dict, old streaming, 46718 @@ -1215,55 +1215,55 @@ github.tar, huffman literals, old stre silesia, level -5, old streaming advanced, 6882505 silesia, level -3, old streaming advanced, 6568376 silesia, level -1, old streaming advanced, 6183403 -silesia, level 0, old streaming advanced, 4849552 -silesia, level 1, old streaming advanced, 5314162 -silesia, level 3, old streaming advanced, 4849552 -silesia, level 4, old streaming advanced, 4786970 -silesia, level 5, old streaming advanced, 4707794 +silesia, level 0, old streaming advanced, 4849551 +silesia, level 1, old streaming advanced, 5314161 +silesia, level 3, old streaming advanced, 4849551 +silesia, level 4, old streaming advanced, 4786969 +silesia, level 5, old streaming advanced, 4707790 silesia, level 6, old streaming advanced, 4666383 silesia, level 7, old streaming advanced, 4603381 -silesia, level 9, old streaming advanced, 4546001 -silesia, level 13, old streaming advanced, 4482135 +silesia, level 9, old streaming advanced, 4546005 +silesia, level 13, old streaming advanced, 4482131 silesia, level 16, old streaming advanced, 4360251 -silesia, level 19, old streaming advanced, 4283237 -silesia, no source size, old streaming advanced, 4849516 -silesia, long distance mode, old streaming advanced, 4849552 -silesia, multithreaded, old streaming advanced, 4849552 -silesia, multithreaded long distance mode, old streaming advanced, 4849552 +silesia, level 19, old streaming advanced, 4283236 +silesia, no source size, old streaming advanced, 4849515 +silesia, long distance mode, old streaming advanced, 4849551 +silesia, multithreaded, old streaming advanced, 4849551 +silesia, multithreaded long distance mode, old streaming advanced, 4849551 silesia, small window log, old streaming advanced, 7112062 silesia, small hash log, old streaming advanced, 6526141 -silesia, small chain log, old streaming advanced, 4912197 +silesia, small chain log, old streaming advanced, 4912199 silesia, explicit params, old streaming advanced, 4795884 -silesia, uncompressed literals, old streaming advanced, 4849552 -silesia, uncompressed literals optimal, old streaming advanced, 4283237 +silesia, uncompressed literals, old streaming advanced, 4849551 +silesia, uncompressed literals optimal, old streaming advanced, 4283236 silesia, huffman literals, old streaming advanced, 6183403 -silesia, multithreaded with advanced params, old streaming advanced, 4849552 +silesia, multithreaded with advanced params, old streaming advanced, 4849551 silesia.tar, level -5, old streaming advanced, 6982759 silesia.tar, level -3, old streaming advanced, 6641283 silesia.tar, level -1, old streaming advanced, 6190795 -silesia.tar, level 0, old streaming advanced, 4861427 -silesia.tar, level 1, old streaming advanced, 5336939 -silesia.tar, level 3, old streaming advanced, 4861427 -silesia.tar, level 4, old streaming advanced, 4799630 +silesia.tar, level 0, old streaming advanced, 4861425 +silesia.tar, level 1, old streaming advanced, 5336941 +silesia.tar, level 3, old streaming advanced, 4861425 +silesia.tar, level 4, old streaming advanced, 4799632 silesia.tar, level 5, old streaming advanced, 4719261 -silesia.tar, level 6, old streaming advanced, 4677729 -silesia.tar, level 7, old streaming advanced, 4613544 +silesia.tar, level 6, old streaming advanced, 4677732 +silesia.tar, level 7, old streaming advanced, 4613548 silesia.tar, level 9, old streaming advanced, 4555432 -silesia.tar, level 13, old streaming advanced, 4491765 +silesia.tar, level 13, old streaming advanced, 4491769 silesia.tar, level 16, old streaming advanced, 4356834 -silesia.tar, level 19, old streaming advanced, 4264392 -silesia.tar, no source size, old streaming advanced, 4861423 -silesia.tar, long distance mode, old streaming advanced, 4861427 -silesia.tar, multithreaded, old streaming advanced, 4861427 -silesia.tar, multithreaded long distance mode, old streaming advanced, 4861427 +silesia.tar, level 19, old streaming advanced, 4264388 +silesia.tar, no source size, old streaming advanced, 4861421 +silesia.tar, long distance mode, old streaming advanced, 4861425 +silesia.tar, multithreaded, old streaming advanced, 4861425 +silesia.tar, multithreaded long distance mode, old streaming advanced, 4861425 silesia.tar, small window log, old streaming advanced, 7118772 -silesia.tar, small hash log, old streaming advanced, 6529235 -silesia.tar, small chain log, old streaming advanced, 4917021 -silesia.tar, explicit params, old streaming advanced, 4807399 -silesia.tar, uncompressed literals, old streaming advanced, 4861427 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4264392 +silesia.tar, small hash log, old streaming advanced, 6529231 +silesia.tar, small chain log, old streaming advanced, 4917019 +silesia.tar, explicit params, old streaming advanced, 4807403 +silesia.tar, uncompressed literals, old streaming advanced, 4861425 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4264388 silesia.tar, huffman literals, old streaming advanced, 6190795 -silesia.tar, multithreaded with advanced params, old streaming advanced, 4861427 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 github, level -5, old streaming advanced, 216734 github, level -5 with dict, old streaming advanced, 49562 github, level -3, old streaming advanced, 192160 From a719edbbc3f8f978ed41f1152b29cb51150cfd07 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 4 Aug 2021 14:49:00 -0400 Subject: [PATCH 093/274] Pull `utime()` Call into Helper --- programs/util.c | 43 ++++++++++++++++++++++++------------------- programs/util.h | 8 ++++++++ 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/programs/util.c b/programs/util.c index 81c10d0ca..b29177818 100644 --- a/programs/util.c +++ b/programs/util.c @@ -159,6 +159,29 @@ int UTIL_chmod(char const* filename, const stat_t* statbuf, mode_t permissions) return chmod(filename, permissions); } +/* set access and modification times */ +int UTIL_utime(const char* filename, const stat_t *statbuf) +{ + int ret; + /* We check that st_mtime is a macro here in order to give us confidence + * that struct stat has a struct timespec st_mtim member. We need this + * check because there are some platforms that claim to be POSIX 2008 + * compliant but which do not have st_mtim... */ +#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime) + /* (atime, mtime) */ + struct timespec timebuf[2] = { {0, UTIME_NOW} }; + timebuf[1] = statbuf->st_mtim; + ret = utimensat(AT_FDCWD, filename, timebuf, 0); +#else + struct utimbuf timebuf; + timebuf.actime = time(NULL); + timebuf.modtime = statbuf->st_mtime; + ret = utime(filename, &timebuf); +#endif + errno = 0; + return ret; +} + int UTIL_setFileStat(const char *filename, const stat_t *statbuf) { int res = 0; @@ -168,25 +191,7 @@ int UTIL_setFileStat(const char *filename, const stat_t *statbuf) return -1; /* set access and modification times */ - /* We check that st_mtime is a macro here in order to give us confidence - * that struct stat has a struct timespec st_mtim member. We need this - * check because there are some platforms that claim to be POSIX 2008 - * compliant but which do not have st_mtim... */ -#if (PLATFORM_POSIX_VERSION >= 200809L) && defined(st_mtime) - { - /* (atime, mtime) */ - struct timespec timebuf[2] = { {0, UTIME_NOW} }; - timebuf[1] = statbuf->st_mtim; - res += utimensat(AT_FDCWD, filename, timebuf, 0); - } -#else - { - struct utimbuf timebuf; - timebuf.actime = time(NULL); - timebuf.modtime = statbuf->st_mtime; - res += utime(filename, &timebuf); - } -#endif + res += UTIL_utime(filename, statbuf); #if !defined(_WIN32) res += chown(filename, statbuf->st_uid, statbuf->st_gid); /* Copy ownership */ diff --git a/programs/util.h b/programs/util.h index c1c963434..7632b9a0a 100644 --- a/programs/util.h +++ b/programs/util.h @@ -136,6 +136,14 @@ int UTIL_stat(const char* filename, stat_t* statbuf); */ int UTIL_setFileStat(const char* filename, const stat_t* statbuf); +/** + * Set atime to now and mtime to the st_mtim in statbuf. + * + * Directly wraps utime() or utimensat(). Returns -1 on error. + * Does not validate filename is valid. + */ +int UTIL_utime(const char* filename, const stat_t *statbuf); + /* * These helpers operate on a pre-populated stat_t, i.e., the result of * calling one of the above functions. From 9cd6c1ff4d56fc74a2cbdfd9bcc82a64e0fe4bb7 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 4 Aug 2021 14:49:56 -0400 Subject: [PATCH 094/274] Update mtime and atime for Written Files --- programs/fileio.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/programs/fileio.c b/programs/fileio.c index da5412f27..b786b7e4d 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1647,6 +1647,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx, int closeDstFile = 0; int result; stat_t statbuf; + int transferMTime = 0; assert(ress.srcFile != NULL); if (ress.dstFile == NULL) { int dstFilePermissions = DEFAULT_FILE_PERMISSIONS; @@ -1654,6 +1655,7 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx, && UTIL_stat(srcFileName, &statbuf) && UTIL_isRegularFileStat(&statbuf) ) { dstFilePermissions = statbuf.st_mode; + transferMTime = 1; } closeDstFile = 1; @@ -1680,6 +1682,9 @@ static int FIO_compressFilename_dstFile(FIO_ctx_t* const fCtx, DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; } + if (transferMTime) { + UTIL_utime(dstFileName, &statbuf); + } if ( (result != 0) /* operation failure */ && strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */ ) { @@ -2553,6 +2558,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx, int result; stat_t statbuf; int releaseDstFile = 0; + int transferMTime = 0; if ((ress.dstFile == NULL) && (prefs->testMode==0)) { int dstFilePermissions = DEFAULT_FILE_PERMISSIONS; @@ -2560,6 +2566,7 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx, && UTIL_stat(srcFileName, &statbuf) && UTIL_isRegularFileStat(&statbuf) ) { dstFilePermissions = statbuf.st_mode; + transferMTime = 1; } releaseDstFile = 1; @@ -2585,6 +2592,10 @@ static int FIO_decompressDstFile(FIO_ctx_t* const fCtx, result = 1; } + if (transferMTime) { + UTIL_utime(dstFileName, &statbuf); + } + if ( (result != 0) /* operation failure */ && strcmp(dstFileName, stdoutmark) /* special case : don't remove() stdout */ ) { From a8f4612eab1a61da5cbadccacee43a440e8f34c0 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 4 Aug 2021 15:53:37 -0400 Subject: [PATCH 095/274] Remove sleep()s in Test; Replace with Artificial mtime This behavior of `touch` is standardized in POSIX, so it should be available. --- tests/playTests.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index d108d5d8e..d83001fee 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -597,11 +597,10 @@ fi println "\n===> zstd created file timestamp tests" datagen > tmp -sleep 1 # could also use touch -t but I don't know how portable that is. +touch -m -t 200001010000.00 tmp println "test : copy mtime in file -> file compression " zstd -f tmp -o tmp.zst assertSameMTime tmp tmp.zst -sleep 1 # could also use touch -t but I don't know how portable that is. println "test : copy mtime in file -> file decompression " zstd -f -d tmp.zst -o tmp.out assertSameMTime tmp.zst tmp.out From 31820e032c5c35b589275462724bf6d2fd4102d6 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Thu, 3 Jun 2021 10:38:23 +0300 Subject: [PATCH 096/274] Rebalance clevels for lazy --- lib/compress/zstd_compress.c | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index fa49df6ab..245256b15 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -6187,14 +6187,14 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ - { 21, 18, 19, 2, 5, 2, ZSTD_greedy }, /* level 5 */ - { 21, 19, 19, 3, 5, 4, ZSTD_greedy }, /* level 6 */ - { 21, 19, 19, 3, 5, 8, ZSTD_lazy }, /* level 7 */ - { 21, 19, 19, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */ - { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ - { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ - { 22, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */ - { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */ + { 21, 18, 19, 4, 5, 2, ZSTD_greedy }, /* level 5 */ + { 21, 19, 20, 5, 5, 4, ZSTD_greedy }, /* level 6 */ + { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ + { 21, 19, 20, 5, 5, 16, ZSTD_lazy }, /* level 8 */ + { 21, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 22, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ + { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 11 */ + { 22, 21, 22, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ { 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 13 */ { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ @@ -6212,13 +6212,13 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ - { 18, 16, 17, 2, 5, 2, ZSTD_greedy }, /* level 4.*/ - { 18, 18, 18, 3, 5, 2, ZSTD_greedy }, /* level 5.*/ - { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ - { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ - { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ - { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ - { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ + { 18, 18, 18, 4, 5, 2, ZSTD_greedy }, /* level 5.*/ + { 18, 18, 19, 5, 5, 4, ZSTD_greedy }, /* level 6.*/ + { 18, 18, 19, 3, 4, 4, ZSTD_lazy }, /* level 7 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy }, /* level 8 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 10 */ { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ @@ -6239,12 +6239,12 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ - { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ - { 17, 17, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ - { 17, 17, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ - { 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ - { 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ - { 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 17, 16, 17, 4, 4, 2, ZSTD_greedy }, /* level 5 */ + { 17, 16, 17, 5, 4, 4, ZSTD_greedy }, /* level 6 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy }, /* level 7 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy }, /* level 8 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 10 */ { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ From e411040ea18bbda6e1aae1daf5936db88627b53e Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Thu, 3 Jun 2021 10:54:31 +0300 Subject: [PATCH 097/274] Add 64 row entry support for lazy --- lib/compress/zstd_compress.c | 28 +- lib/compress/zstd_lazy.c | 111 +++++-- tests/regression/levels.h | 10 +- tests/regression/results.csv | 546 ++++++++++++++++++++++++++--------- 4 files changed, 507 insertions(+), 188 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 245256b15..9910265fe 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1785,8 +1785,8 @@ 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 = cParams->searchLog < 5 ? 4 : 5; - assert(cParams->hashLog > rowLog); + U32 const rowLog = MAX(MIN(cParams->searchLog, 6), 4); + assert(cParams->hashLog >= rowLog); ms->rowHashLog = cParams->hashLog - rowLog; } } @@ -6213,12 +6213,12 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ - { 18, 18, 18, 4, 5, 2, ZSTD_greedy }, /* level 5.*/ - { 18, 18, 19, 5, 5, 4, ZSTD_greedy }, /* level 6.*/ - { 18, 18, 19, 3, 4, 4, ZSTD_lazy }, /* level 7 */ - { 18, 18, 19, 4, 4, 8, ZSTD_lazy }, /* level 8 */ - { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 9 */ - { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/ + { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ + { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ @@ -6239,12 +6239,12 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ - { 17, 16, 17, 4, 4, 2, ZSTD_greedy }, /* level 5 */ - { 17, 16, 17, 5, 4, 4, ZSTD_greedy }, /* level 6 */ - { 17, 16, 17, 4, 4, 8, ZSTD_lazy }, /* level 7 */ - { 17, 16, 17, 5, 4, 8, ZSTD_lazy }, /* level 8 */ - { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 9 */ - { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ + { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ + { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 7009fd2e7..18e1331fe 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -865,39 +865,48 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( * (SIMD) Row-based matchfinder ***********************************/ /* Constants for row-based hash */ -#define ZSTD_ROW_HASH_TAG_OFFSET 16 /* byte offset of hashes in the match state's tagTable from the beginning of a row */ -#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ +#define ZSTD_ROW_HASH_TAG_OFFSET 16 /* byte offset of hashes in the match state's tagTable from the beginning of a row */ +#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ #define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) +#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ #define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1) -typedef U32 ZSTD_VecMask; /* Clarifies when we are interacting with a U32 representing a mask of matches */ +typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 representing a mask of matches */ /* ZSTD_VecMask_next(): * Starting from the LSB, returns the idx of the next non-zero bit. * Basically counting the nb of trailing zeroes. */ static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { -# if defined(_MSC_VER) /* Visual */ + assert(val != 0); +# if defined(_MSC_VER) && defined(_WIN64) unsigned long r=0; - return _BitScanForward(&r, val) ? (U32)r : 0; -# elif defined(__GNUC__) && (__GNUC__ >= 3) - return (U32)__builtin_ctz(val); + return _BitScanForward64(&r, val) ? (U64)r : 0; /* _BitScanForward64 not defined outside of x86/64 */ +# elif (defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))) + return (U32)__builtin_ctzll(val); # else - /* Software ctz version: http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */ - static const U32 multiplyDeBruijnBitPosition[32] = - { - 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 - }; - return multiplyDeBruijnBitPosition[((U32)((val & -(int)val) * 0x077CB531U)) >> 27]; + /* Software ctz version: http://aggregate.org/MAGIC/#Trailing%20Zero%20Count + * and: https://stackoverflow.com/questions/2709430/count-number-of-bits-in-a-64-bit-long-big-integer + */ + val = ~val & (val - 1ULL); /* Lowest set bit mask */ + val = val - ((val >> 1) & 0x5555555555555555); + val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL); + return (U32)((((val + (val >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56); # endif } -/* ZSTD_rotateRight_U32(): +/* ZSTD_rotateRight_*(): * Rotates a bitfield to the right by "count" bits. * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts */ +FORCE_INLINE_TEMPLATE +U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { + assert(count < 64); + count &= 0x3F; /* for fickle pattern recognition */ + return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); +} + FORCE_INLINE_TEMPLATE U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { assert(count < 32); @@ -935,13 +944,17 @@ MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) { */ FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, U16 const* tagTable, U32 const relRow, U32 const rowLog) { PREFETCH_L1(hashTable + relRow); - if (rowLog == 5) { + if (rowLog >= 5) { PREFETCH_L1(hashTable + relRow + 16); + /* Note: prefetching more of the hash table does not appear to be beneficial for 128-entry rows */ } PREFETCH_L1(tagTable + relRow); - assert(rowLog == 4 || rowLog == 5); + if (rowLog == 6) { + PREFETCH_L1(tagTable + relRow + 32); + } + assert(rowLog == 4 || rowLog == 5 || rowLog == 6); assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */ - assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on a multiple of 32 or 64 bytes */ + assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on correct multiple of bytes (32,64,128) */ } /* ZSTD_row_fillHashCache(): @@ -1025,7 +1038,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 = ms->cParams.searchLog < 5 ? 4 : 5; + const U32 rowLog = MAX(MIN(ms->cParams.searchLog, 6), 4); const U32 rowMask = (1u << rowLog) - 1; const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */); @@ -1040,14 +1053,15 @@ void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) { FORCE_INLINE_TEMPLATE ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, const U32 head, const U32 rowEntries) { const BYTE* const src = tagRow + ZSTD_ROW_HASH_TAG_OFFSET; - assert((rowEntries == 16) || (rowEntries == 32)); + assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64); + assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES); #if defined(ZSTD_ARCH_X86_SSE2) if (rowEntries == 16) { const __m128i chunk = _mm_loadu_si128((const __m128i*)(const void*)src); const __m128i equalMask = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(tag)); const U16 matches = (U16)_mm_movemask_epi8(equalMask); return ZSTD_rotateRight_U16(matches, head); - } else { /* rowEntries == 32 */ + } else if (rowEntries == 32) { const __m128i chunk0 = _mm_loadu_si128((const __m128i*)(const void*)&src[0]); const __m128i chunk1 = _mm_loadu_si128((const __m128i*)(const void*)&src[16]); const __m128i equalMask0 = _mm_cmpeq_epi8(chunk0, _mm_set1_epi8(tag)); @@ -1055,6 +1069,21 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con const U32 lo = (U32)_mm_movemask_epi8(equalMask0); const U32 hi = (U32)_mm_movemask_epi8(equalMask1); return ZSTD_rotateRight_U32((hi << 16) | lo, head); + } else { /* rowEntries == 64 */ + const __m128i chunk0 = _mm_loadu_si128((const __m128i*)(const void*)&src[0]); + const __m128i chunk1 = _mm_loadu_si128((const __m128i*)(const void*)&src[16]); + const __m128i chunk2 = _mm_loadu_si128((const __m128i*)(const void*)&src[32]); + const __m128i chunk3 = _mm_loadu_si128((const __m128i*)(const void*)&src[48]); + const __m128i comparisonMask = _mm_set1_epi8(tag); + const __m128i equalMask0 = _mm_cmpeq_epi8(chunk0, comparisonMask); + const __m128i equalMask1 = _mm_cmpeq_epi8(chunk1, comparisonMask); + const __m128i equalMask2 = _mm_cmpeq_epi8(chunk2, comparisonMask); + const __m128i equalMask3 = _mm_cmpeq_epi8(chunk3, comparisonMask); + const U64 mask0 = (U64)_mm_movemask_epi8(equalMask0); + const U64 mask1 = (U64)_mm_movemask_epi8(equalMask1); + const U64 mask2 = (U64)_mm_movemask_epi8(equalMask2); + const U64 mask3 = (U64)_mm_movemask_epi8(equalMask3); + return ZSTD_rotateRight_U64((mask3 << 48) | (mask2 << 32) | (mask1 << 16) | mask0, head); } #else # if defined(ZSTD_ARCH_ARM_NEON) @@ -1069,7 +1098,7 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con const U16 hi = (U16)vgetq_lane_u8(t3, 8); const U16 lo = (U16)vgetq_lane_u8(t3, 0); return ZSTD_rotateRight_U16((hi << 8) | lo, head); - } else { /* rowEntries == 32 */ + } else if (rowEntries == 32) { const uint16x8x2_t chunk = vld2q_u16((const U16*)(const void*)src); const uint8x16_t chunk0 = vreinterpretq_u8_u16(chunk.val[0]); const uint8x16_t chunk1 = vreinterpretq_u8_u16(chunk.val[1]); @@ -1084,6 +1113,21 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con const uint8x8_t t4 = vsri_n_u8(t3.val[1], t3.val[0], 4); const U32 matches = vget_lane_u32(vreinterpret_u32_u8(t4), 0); return ZSTD_rotateRight_U32(matches, head); + } else { /* rowEntries == 64 */ + const uint8x16x4_t chunk = vld4q_u8(src); + const uint8x16_t dup = vdupq_n_u8(tag); + const uint8x16_t cmp0 = vceqq_u8(chunk.val[0], dup); + const uint8x16_t cmp1 = vceqq_u8(chunk.val[1], dup); + const uint8x16_t cmp2 = vceqq_u8(chunk.val[2], dup); + const uint8x16_t cmp3 = vceqq_u8(chunk.val[3], dup); + + const uint8x16_t t0 = vsriq_n_u8(cmp1, cmp0, 1); + const uint8x16_t t1 = vsriq_n_u8(cmp3, cmp2, 1); + const uint8x16_t t2 = vsriq_n_u8(t1, t0, 2); + const uint8x16_t t3 = vsriq_n_u8(t2, t2, 4); + const uint8x8_t t4 = vshrn_n_u16(vreinterpretq_u16_u8(t3), 4); + const U64 matches = vget_lane_u64(vreinterpret_u64_u8(t4), 0); + return ZSTD_rotateRight_U64(matches, head); } } # endif @@ -1094,7 +1138,7 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con const size_t x01 = xFF / 0xFF; const size_t x80 = x01 << 7; const size_t splatChar = tag * x01; - size_t matches = 0; + ZSTD_VecMask matches = 0; int i = rowEntries - chunkSize; assert((sizeof(size_t) == 4) || (sizeof(size_t) == 8)); if (MEM_isLittleEndian()) { /* runtime check so have two loops */ @@ -1122,8 +1166,10 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con matches = ~matches; if (rowEntries == 16) { return ZSTD_rotateRight_U16((U16)matches, head); - } else { /* rowEntries == 32 */ + } else if (rowEntries == 32) { return ZSTD_rotateRight_U32((U32)matches, head); + } else { + return ZSTD_rotateRight_U64((U64)matches, head); } } #endif @@ -1176,6 +1222,7 @@ size_t ZSTD_RowFindBestMatch_generic ( /* DMS/DDS variables that may be referenced laster */ const ZSTD_matchState_t* const dms = ms->dictMatchState; + /* Initialize the following variables to satisfy static analyzer */ size_t ddsIdx = 0; U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ @@ -1213,7 +1260,7 @@ size_t ZSTD_RowFindBestMatch_generic ( U32* const row = hashTable + relRow; BYTE* tagRow = (BYTE*)(tagTable + relRow); U32 const head = *tagRow & rowMask; - U32 matchBuffer[32 /* maximum nb entries per row */]; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; size_t numMatches = 0; size_t currMatch = 0; ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, head, rowEntries); @@ -1281,7 +1328,7 @@ size_t ZSTD_RowFindBestMatch_generic ( const U32 dmsIndexDelta = dictLimit - dmsSize; { U32 const head = *dmsTagRow & rowMask; - U32 matchBuffer[32 /* maximum nb row entries */]; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; size_t numMatches = 0; size_t currMatch = 0; ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, head, rowEntries); @@ -1340,12 +1387,13 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectRowLog ( const BYTE* ip, const BYTE* const iLimit, size_t* offsetPtr) { - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5); + const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); switch(cappedSearchLog) { default : case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 4); case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 5); + case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 6); } } @@ -1354,12 +1402,13 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dictMatchState_selectRowLog( const BYTE* ip, const BYTE* const iLimit, size_t* offsetPtr) { - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5); + const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); switch(cappedSearchLog) { default : case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 4); case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 5); + case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 6); } } @@ -1368,12 +1417,13 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRow const BYTE* ip, const BYTE* const iLimit, size_t* offsetPtr) { - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5); + const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); switch(cappedSearchLog) { default : case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 4); case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 5); + case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 6); } } @@ -1382,12 +1432,13 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_extDict_selectRowLog ( const BYTE* ip, const BYTE* const iLimit, size_t* offsetPtr) { - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 5); + const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); switch(cappedSearchLog) { default : case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 4); case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 5); + case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 6); } } diff --git a/tests/regression/levels.h b/tests/regression/levels.h index 3b211f8c2..5a933c133 100644 --- a/tests/regression/levels.h +++ b/tests/regression/levels.h @@ -35,21 +35,23 @@ LEVEL(1) LEVEL(3) LEVEL(4) /* ROW_LEVEL triggers the row hash (force enabled and disabled) with different - * dictionary strategies, and 16/32 row entries based on the level/searchLog. + * dictionary strategies, and 16/32/64 row entries based on the level/searchLog. * 1 == disabled, 2 == enabled. */ ROW_LEVEL(5, 1) -ROW_LEVEL(5, 2) +ROW_LEVEL(5, 2) /* 16-entry rows */ LEVEL(5) LEVEL(6) ROW_LEVEL(7, 1) -ROW_LEVEL(7, 2) +ROW_LEVEL(7, 2) /* 16-entry rows */ LEVEL(7) LEVEL(9) +ROW_LEVEL(11, 1) +ROW_LEVEL(11, 2) /* 32-entry rows */ ROW_LEVEL(12, 1) -ROW_LEVEL(12, 2) +ROW_LEVEL(12, 2) /* 64-entry rows */ LEVEL(13) LEVEL(16) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 855401acb..579f4ecc5 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -4,6 +4,7 @@ silesia.tar, level -3, compress silesia.tar, level -1, compress simple, 6186042 silesia.tar, level 0, compress simple, 4861423 silesia.tar, level 1, compress simple, 5334885 +<<<<<<< HEAD silesia.tar, level 3, compress simple, 4861423 silesia.tar, level 4, compress simple, 4799632 silesia.tar, level 5, compress simple, 4719256 @@ -11,6 +12,15 @@ silesia.tar, level 6, compress silesia.tar, level 7, compress simple, 4613545 silesia.tar, level 9, compress simple, 4555426 silesia.tar, level 13, compress simple, 4491768 +======= +silesia.tar, level 3, compress simple, 4861425 +silesia.tar, level 4, compress simple, 4799630 +silesia.tar, level 5, compress simple, 4650203 +silesia.tar, level 6, compress simple, 4616811 +silesia.tar, level 7, compress simple, 4576830 +silesia.tar, level 9, compress simple, 4552585 +silesia.tar, level 13, compress simple, 4491764 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, compress simple, 4356834 silesia.tar, level 19, compress simple, 4264388 silesia.tar, uncompressed literals, compress simple, 4861423 @@ -23,10 +33,10 @@ github.tar, level 0, compress github.tar, level 1, compress simple, 39265 github.tar, level 3, compress simple, 38441 github.tar, level 4, compress simple, 38467 -github.tar, level 5, compress simple, 39693 -github.tar, level 6, compress simple, 39621 -github.tar, level 7, compress simple, 39213 -github.tar, level 9, compress simple, 36758 +github.tar, level 5, compress simple, 38376 +github.tar, level 6, compress simple, 38610 +github.tar, level 7, compress simple, 38073 +github.tar, level 9, compress simple, 36767 github.tar, level 13, compress simple, 35621 github.tar, level 16, compress simple, 40255 github.tar, level 19, compress simple, 32837 @@ -36,6 +46,7 @@ github.tar, huffman literals, compress silesia, level -5, compress cctx, 6737607 silesia, level -3, compress cctx, 6444677 silesia, level -1, compress cctx, 6178460 +<<<<<<< HEAD silesia, level 0, compress cctx, 4849551 silesia, level 1, compress cctx, 5313202 silesia, level 3, compress cctx, 4849551 @@ -45,6 +56,17 @@ silesia, level 6, compress silesia, level 7, compress cctx, 4603381 silesia, level 9, compress cctx, 4546005 silesia, level 13, compress cctx, 4482131 +======= +silesia, level 0, compress cctx, 4849552 +silesia, level 1, compress cctx, 5313204 +silesia, level 3, compress cctx, 4849552 +silesia, level 4, compress cctx, 4786970 +silesia, level 5, compress cctx, 4638959 +silesia, level 6, compress cctx, 4605369 +silesia, level 7, compress cctx, 4567207 +silesia, level 9, compress cctx, 4543310 +silesia, level 13, compress cctx, 4482135 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, compress cctx, 4360251 silesia, level 19, compress cctx, 4283236 silesia, long distance mode, compress cctx, 4849551 @@ -100,6 +122,7 @@ github, multithreaded with advanced params, compress silesia, level -5, zstdcli, 6737655 silesia, level -3, zstdcli, 6444725 silesia, level -1, zstdcli, 6178508 +<<<<<<< HEAD silesia, level 0, zstdcli, 4849599 silesia, level 1, zstdcli, 5313250 silesia, level 3, zstdcli, 4849599 @@ -109,6 +132,17 @@ silesia, level 6, zstdcli, silesia, level 7, zstdcli, 4603429 silesia, level 9, zstdcli, 4546053 silesia, level 13, zstdcli, 4482179 +======= +silesia, level 0, zstdcli, 4849600 +silesia, level 1, zstdcli, 5313252 +silesia, level 3, zstdcli, 4849600 +silesia, level 4, zstdcli, 4787018 +silesia, level 5, zstdcli, 4639007 +silesia, level 6, zstdcli, 4605417 +silesia, level 7, zstdcli, 4567255 +silesia, level 9, zstdcli, 4543358 +silesia, level 13, zstdcli, 4482183 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, zstdcli, 4360299 silesia, level 19, zstdcli, 4283284 silesia, long distance mode, zstdcli, 4840807 @@ -129,11 +163,19 @@ silesia.tar, level 0, zstdcli, silesia.tar, level 1, zstdcli, 5336318 silesia.tar, level 3, zstdcli, 4861511 silesia.tar, level 4, zstdcli, 4800529 +<<<<<<< HEAD silesia.tar, level 5, zstdcli, 4720121 silesia.tar, level 6, zstdcli, 4678663 silesia.tar, level 7, zstdcli, 4614426 silesia.tar, level 9, zstdcli, 4556062 silesia.tar, level 13, zstdcli, 4491772 +======= +silesia.tar, level 5, zstdcli, 4651160 +silesia.tar, level 6, zstdcli, 4618403 +silesia.tar, level 7, zstdcli, 4578883 +silesia.tar, level 9, zstdcli, 4553500 +silesia.tar, level 13, zstdcli, 4491768 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, zstdcli, 4356838 silesia.tar, level 19, zstdcli, 4264392 silesia.tar, no source size, zstdcli, 4861507 @@ -165,11 +207,11 @@ github, level 4 with dict, zstdcli, github, level 5, zstdcli, 137121 github, level 5 with dict, zstdcli, 40728 github, level 6, zstdcli, 137122 -github, level 6 with dict, zstdcli, 40630 +github, level 6 with dict, zstdcli, 40636 github, level 7, zstdcli, 137122 -github, level 7 with dict, zstdcli, 40747 +github, level 7 with dict, zstdcli, 40745 github, level 9, zstdcli, 137122 -github, level 9 with dict, zstdcli, 41338 +github, level 9 with dict, zstdcli, 41393 github, level 13, zstdcli, 136064 github, level 13 with dict, zstdcli, 41743 github, level 16, zstdcli, 136064 @@ -201,14 +243,14 @@ github.tar, level 3, zstdcli, github.tar, level 3 with dict, zstdcli, 37999 github.tar, level 4, zstdcli, 38471 github.tar, level 4 with dict, zstdcli, 37952 -github.tar, level 5, zstdcli, 39697 +github.tar, level 5, zstdcli, 38380 github.tar, level 5 with dict, zstdcli, 39032 -github.tar, level 6, zstdcli, 39625 +github.tar, level 6, zstdcli, 38614 github.tar, level 6 with dict, zstdcli, 38614 -github.tar, level 7, zstdcli, 39217 -github.tar, level 7 with dict, zstdcli, 37871 -github.tar, level 9, zstdcli, 36762 -github.tar, level 9 with dict, zstdcli, 36641 +github.tar, level 7, zstdcli, 38077 +github.tar, level 7 with dict, zstdcli, 37873 +github.tar, level 9, zstdcli, 36771 +github.tar, level 9 with dict, zstdcli, 36623 github.tar, level 13, zstdcli, 35625 github.tar, level 13 with dict, zstdcli, 38730 github.tar, level 16, zstdcli, 40259 @@ -231,6 +273,7 @@ github.tar, multithreaded with advanced params, zstdcli, silesia, level -5, advanced one pass, 6737607 silesia, level -3, advanced one pass, 6444677 silesia, level -1, advanced one pass, 6178460 +<<<<<<< HEAD silesia, level 0, advanced one pass, 4849551 silesia, level 1, advanced one pass, 5313202 silesia, level 3, advanced one pass, 4849551 @@ -246,6 +289,25 @@ silesia, level 9, advanced silesia, level 12 row 1, advanced one pass, 4519288 silesia, level 12 row 2, advanced one pass, 4521406 silesia, level 13, advanced one pass, 4482131 +======= +silesia, level 0, advanced one pass, 4849552 +silesia, level 1, advanced one pass, 5313204 +silesia, level 3, advanced one pass, 4849552 +silesia, level 4, advanced one pass, 4786970 +silesia, level 5 row 1, advanced one pass, 4640752 +silesia, level 5 row 2, advanced one pass, 4638959 +silesia, level 5, advanced one pass, 4638959 +silesia, level 6, advanced one pass, 4605369 +silesia, level 7 row 1, advanced one pass, 4564867 +silesia, level 7 row 2, advanced one pass, 4567207 +silesia, level 7, advanced one pass, 4567207 +silesia, level 9, advanced one pass, 4543310 +silesia, level 11 row 1, advanced one pass, 4519288 +silesia, level 11 row 2, advanced one pass, 4521397 +silesia, level 12 row 1, advanced one pass, 4503116 +silesia, level 12 row 2, advanced one pass, 4505151 +silesia, level 13, advanced one pass, 4482135 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, advanced one pass, 4360251 silesia, level 19, advanced one pass, 4283236 silesia, no source size, advanced one pass, 4849551 @@ -265,6 +327,7 @@ silesia.tar, level -3, advanced silesia.tar, level -1, advanced one pass, 6186042 silesia.tar, level 0, advanced one pass, 4861423 silesia.tar, level 1, advanced one pass, 5334885 +<<<<<<< HEAD silesia.tar, level 3, advanced one pass, 4861423 silesia.tar, level 4, advanced one pass, 4799632 silesia.tar, level 5 row 1, advanced one pass, 4722324 @@ -278,6 +341,23 @@ silesia.tar, level 9, advanced silesia.tar, level 12 row 1, advanced one pass, 4529458 silesia.tar, level 12 row 2, advanced one pass, 4530257 silesia.tar, level 13, advanced one pass, 4491768 +======= +silesia.tar, level 3, advanced one pass, 4861425 +silesia.tar, level 4, advanced one pass, 4799630 +silesia.tar, level 5 row 1, advanced one pass, 4652860 +silesia.tar, level 5 row 2, advanced one pass, 4650203 +silesia.tar, level 5, advanced one pass, 4650203 +silesia.tar, level 6, advanced one pass, 4616811 +silesia.tar, level 7 row 1, advanced one pass, 4575392 +silesia.tar, level 7 row 2, advanced one pass, 4576830 +silesia.tar, level 7, advanced one pass, 4576830 +silesia.tar, level 9, advanced one pass, 4552585 +silesia.tar, level 11 row 1, advanced one pass, 4529459 +silesia.tar, level 11 row 2, advanced one pass, 4530256 +silesia.tar, level 12 row 1, advanced one pass, 4513605 +silesia.tar, level 12 row 2, advanced one pass, 4514567 +silesia.tar, level 13, advanced one pass, 4491764 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, advanced one pass, 4356834 silesia.tar, level 19, advanced one pass, 4264388 silesia.tar, no source size, advanced one pass, 4861423 @@ -341,31 +421,41 @@ github, level 5 with dict load, advanced github, level 6, advanced one pass, 135122 github, level 6 with dict, advanced one pass, 38671 github, level 6 with dict dms, advanced one pass, 38671 -github, level 6 with dict dds, advanced one pass, 38630 +github, level 6 with dict dds, advanced one pass, 38636 github, level 6 with dict copy, advanced one pass, 38669 github, level 6 with dict load, advanced one pass, 40695 github, level 7 row 1, advanced one pass, 135122 -github, level 7 row 1 with dict dms, advanced one pass, 38771 -github, level 7 row 1 with dict dds, advanced one pass, 38771 -github, level 7 row 1 with dict copy, advanced one pass, 38745 +github, level 7 row 1 with dict dms, advanced one pass, 38860 +github, level 7 row 1 with dict dds, advanced one pass, 38766 +github, level 7 row 1 with dict copy, advanced one pass, 38834 github, level 7 row 1 with dict load, advanced one pass, 40695 github, level 7 row 2, advanced one pass, 134584 github, level 7 row 2 with dict dms, advanced one pass, 38758 -github, level 7 row 2 with dict dds, advanced one pass, 38747 +github, level 7 row 2 with dict dds, advanced one pass, 38745 github, level 7 row 2 with dict copy, advanced one pass, 38755 -github, level 7 row 2 with dict load, advanced one pass, 41030 +github, level 7 row 2 with dict load, advanced one pass, 43154 github, level 7, advanced one pass, 135122 github, level 7 with dict, advanced one pass, 38758 github, level 7 with dict dms, advanced one pass, 38758 -github, level 7 with dict dds, advanced one pass, 38747 +github, level 7 with dict dds, advanced one pass, 38745 github, level 7 with dict copy, advanced one pass, 38755 github, level 7 with dict load, advanced one pass, 40695 github, level 9, advanced one pass, 135122 github, level 9 with dict, advanced one pass, 39437 github, level 9 with dict dms, advanced one pass, 39437 -github, level 9 with dict dds, advanced one pass, 39338 +github, level 9 with dict dds, advanced one pass, 39393 github, level 9 with dict copy, advanced one pass, 39398 github, level 9 with dict load, advanced one pass, 41710 +github, level 11 row 1, advanced one pass, 135119 +github, level 11 row 1 with dict dms, advanced one pass, 39671 +github, level 11 row 1 with dict dds, advanced one pass, 39671 +github, level 11 row 1 with dict copy, advanced one pass, 39651 +github, level 11 row 1 with dict load, advanced one pass, 41360 +github, level 11 row 2, advanced one pass, 135119 +github, level 11 row 2 with dict dms, advanced one pass, 39671 +github, level 11 row 2 with dict dds, advanced one pass, 39671 +github, level 11 row 2 with dict copy, advanced one pass, 39651 +github, level 11 row 2 with dict load, advanced one pass, 41360 github, level 12 row 1, advanced one pass, 134180 github, level 12 row 1 with dict dms, advanced one pass, 39677 github, level 12 row 1 with dict dds, advanced one pass, 39677 @@ -437,60 +527,70 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass, 37954 github.tar, level 4 with dict copy, advanced one pass, 37948 github.tar, level 4 with dict load, advanced one pass, 37927 -github.tar, level 5 row 1, advanced one pass, 39788 +github.tar, level 5 row 1, advanced one pass, 38534 github.tar, level 5 row 1 with dict dms, advanced one pass, 39365 github.tar, level 5 row 1 with dict dds, advanced one pass, 39233 github.tar, level 5 row 1 with dict copy, advanced one pass, 39715 -github.tar, level 5 row 1 with dict load, advanced one pass, 39209 -github.tar, level 5 row 2, advanced one pass, 39693 +github.tar, level 5 row 1 with dict load, advanced one pass, 38019 +github.tar, level 5 row 2, advanced one pass, 38376 github.tar, level 5 row 2 with dict dms, advanced one pass, 39024 github.tar, level 5 row 2 with dict dds, advanced one pass, 39028 github.tar, level 5 row 2 with dict copy, advanced one pass, 39040 -github.tar, level 5 row 2 with dict load, advanced one pass, 39037 -github.tar, level 5, advanced one pass, 39693 +github.tar, level 5 row 2 with dict load, advanced one pass, 37600 +github.tar, level 5, advanced one pass, 38376 github.tar, level 5 with dict, advanced one pass, 39040 github.tar, level 5 with dict dms, advanced one pass, 39024 github.tar, level 5 with dict dds, advanced one pass, 39028 github.tar, level 5 with dict copy, advanced one pass, 39040 -github.tar, level 5 with dict load, advanced one pass, 39037 -github.tar, level 6, advanced one pass, 39621 +github.tar, level 5 with dict load, advanced one pass, 37600 +github.tar, level 6, advanced one pass, 38610 github.tar, level 6 with dict, advanced one pass, 38622 github.tar, level 6 with dict dms, advanced one pass, 38608 github.tar, level 6 with dict dds, advanced one pass, 38610 github.tar, level 6 with dict copy, advanced one pass, 38622 -github.tar, level 6 with dict load, advanced one pass, 38962 -github.tar, level 7 row 1, advanced one pass, 39206 -github.tar, level 7 row 1 with dict dms, advanced one pass, 37954 -github.tar, level 7 row 1 with dict dds, advanced one pass, 37954 -github.tar, level 7 row 1 with dict copy, advanced one pass, 38071 -github.tar, level 7 row 1 with dict load, advanced one pass, 38584 -github.tar, level 7 row 2, advanced one pass, 39213 +github.tar, level 6 with dict load, advanced one pass, 37829 +github.tar, level 7 row 1, advanced one pass, 38077 +github.tar, level 7 row 1 with dict dms, advanced one pass, 38012 +github.tar, level 7 row 1 with dict dds, advanced one pass, 38014 +github.tar, level 7 row 1 with dict copy, advanced one pass, 38101 +github.tar, level 7 row 1 with dict load, advanced one pass, 37402 +github.tar, level 7 row 2, advanced one pass, 38073 github.tar, level 7 row 2 with dict dms, advanced one pass, 37848 -github.tar, level 7 row 2 with dict dds, advanced one pass, 37867 +github.tar, level 7 row 2 with dict dds, advanced one pass, 37869 github.tar, level 7 row 2 with dict copy, advanced one pass, 37848 -github.tar, level 7 row 2 with dict load, advanced one pass, 38582 -github.tar, level 7, advanced one pass, 39213 +github.tar, level 7 row 2 with dict load, advanced one pass, 37371 +github.tar, level 7, advanced one pass, 38073 github.tar, level 7 with dict, advanced one pass, 37848 github.tar, level 7 with dict dms, advanced one pass, 37848 -github.tar, level 7 with dict dds, advanced one pass, 37867 +github.tar, level 7 with dict dds, advanced one pass, 37869 github.tar, level 7 with dict copy, advanced one pass, 37848 -github.tar, level 7 with dict load, advanced one pass, 38582 -github.tar, level 9, advanced one pass, 36758 +github.tar, level 7 with dict load, advanced one pass, 37371 +github.tar, level 9, advanced one pass, 36767 github.tar, level 9 with dict, advanced one pass, 36457 github.tar, level 9 with dict dms, advanced one pass, 36549 -github.tar, level 9 with dict dds, advanced one pass, 36637 +github.tar, level 9 with dict dds, advanced one pass, 36619 github.tar, level 9 with dict copy, advanced one pass, 36457 -github.tar, level 9 with dict load, advanced one pass, 36350 -github.tar, level 12 row 1, advanced one pass, 36435 +github.tar, level 9 with dict load, advanced one pass, 36352 +github.tar, level 11 row 1, advanced one pass, 36435 +github.tar, level 11 row 1 with dict dms, advanced one pass, 36963 +github.tar, level 11 row 1 with dict dds, advanced one pass, 36963 +github.tar, level 11 row 1 with dict copy, advanced one pass, 36557 +github.tar, level 11 row 1 with dict load, advanced one pass, 36419 +github.tar, level 11 row 2, advanced one pass, 36435 +github.tar, level 11 row 2 with dict dms, advanced one pass, 36963 +github.tar, level 11 row 2 with dict dds, advanced one pass, 36963 +github.tar, level 11 row 2 with dict copy, advanced one pass, 36557 +github.tar, level 11 row 2 with dict load, advanced one pass, 36424 +github.tar, level 12 row 1, advanced one pass, 36110 github.tar, level 12 row 1 with dict dms, advanced one pass, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass, 36419 -github.tar, level 12 row 2, advanced one pass, 36435 +github.tar, level 12 row 1 with dict load, advanced one pass, 36459 +github.tar, level 12 row 2, advanced one pass, 36105 github.tar, level 12 row 2 with dict dms, advanced one pass, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass, 36424 +github.tar, level 12 row 2 with dict load, advanced one pass, 36460 github.tar, level 13, advanced one pass, 35621 github.tar, level 13 with dict, advanced one pass, 38726 github.tar, level 13 with dict dms, advanced one pass, 38903 @@ -525,6 +625,7 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced one pass small out, 6737607 silesia, level -3, advanced one pass small out, 6444677 silesia, level -1, advanced one pass small out, 6178460 +<<<<<<< HEAD silesia, level 0, advanced one pass small out, 4849551 silesia, level 1, advanced one pass small out, 5313202 silesia, level 3, advanced one pass small out, 4849551 @@ -540,6 +641,25 @@ silesia, level 9, advanced silesia, level 12 row 1, advanced one pass small out, 4519288 silesia, level 12 row 2, advanced one pass small out, 4521406 silesia, level 13, advanced one pass small out, 4482131 +======= +silesia, level 0, advanced one pass small out, 4849552 +silesia, level 1, advanced one pass small out, 5313204 +silesia, level 3, advanced one pass small out, 4849552 +silesia, level 4, advanced one pass small out, 4786970 +silesia, level 5 row 1, advanced one pass small out, 4640752 +silesia, level 5 row 2, advanced one pass small out, 4638959 +silesia, level 5, advanced one pass small out, 4638959 +silesia, level 6, advanced one pass small out, 4605369 +silesia, level 7 row 1, advanced one pass small out, 4564867 +silesia, level 7 row 2, advanced one pass small out, 4567207 +silesia, level 7, advanced one pass small out, 4567207 +silesia, level 9, advanced one pass small out, 4543310 +silesia, level 11 row 1, advanced one pass small out, 4519288 +silesia, level 11 row 2, advanced one pass small out, 4521397 +silesia, level 12 row 1, advanced one pass small out, 4503116 +silesia, level 12 row 2, advanced one pass small out, 4505151 +silesia, level 13, advanced one pass small out, 4482135 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, advanced one pass small out, 4360251 silesia, level 19, advanced one pass small out, 4283236 silesia, no source size, advanced one pass small out, 4849551 @@ -559,6 +679,7 @@ silesia.tar, level -3, advanced silesia.tar, level -1, advanced one pass small out, 6186042 silesia.tar, level 0, advanced one pass small out, 4861423 silesia.tar, level 1, advanced one pass small out, 5334885 +<<<<<<< HEAD silesia.tar, level 3, advanced one pass small out, 4861423 silesia.tar, level 4, advanced one pass small out, 4799632 silesia.tar, level 5 row 1, advanced one pass small out, 4722324 @@ -572,6 +693,23 @@ silesia.tar, level 9, advanced silesia.tar, level 12 row 1, advanced one pass small out, 4529458 silesia.tar, level 12 row 2, advanced one pass small out, 4530257 silesia.tar, level 13, advanced one pass small out, 4491768 +======= +silesia.tar, level 3, advanced one pass small out, 4861425 +silesia.tar, level 4, advanced one pass small out, 4799630 +silesia.tar, level 5 row 1, advanced one pass small out, 4652860 +silesia.tar, level 5 row 2, advanced one pass small out, 4650203 +silesia.tar, level 5, advanced one pass small out, 4650203 +silesia.tar, level 6, advanced one pass small out, 4616811 +silesia.tar, level 7 row 1, advanced one pass small out, 4575392 +silesia.tar, level 7 row 2, advanced one pass small out, 4576830 +silesia.tar, level 7, advanced one pass small out, 4576830 +silesia.tar, level 9, advanced one pass small out, 4552585 +silesia.tar, level 11 row 1, advanced one pass small out, 4529459 +silesia.tar, level 11 row 2, advanced one pass small out, 4530256 +silesia.tar, level 12 row 1, advanced one pass small out, 4513605 +silesia.tar, level 12 row 2, advanced one pass small out, 4514567 +silesia.tar, level 13, advanced one pass small out, 4491764 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, advanced one pass small out, 4356834 silesia.tar, level 19, advanced one pass small out, 4264388 silesia.tar, no source size, advanced one pass small out, 4861423 @@ -635,31 +773,41 @@ github, level 5 with dict load, advanced github, level 6, advanced one pass small out, 135122 github, level 6 with dict, advanced one pass small out, 38671 github, level 6 with dict dms, advanced one pass small out, 38671 -github, level 6 with dict dds, advanced one pass small out, 38630 +github, level 6 with dict dds, advanced one pass small out, 38636 github, level 6 with dict copy, advanced one pass small out, 38669 github, level 6 with dict load, advanced one pass small out, 40695 github, level 7 row 1, advanced one pass small out, 135122 -github, level 7 row 1 with dict dms, advanced one pass small out, 38771 -github, level 7 row 1 with dict dds, advanced one pass small out, 38771 -github, level 7 row 1 with dict copy, advanced one pass small out, 38745 +github, level 7 row 1 with dict dms, advanced one pass small out, 38860 +github, level 7 row 1 with dict dds, advanced one pass small out, 38766 +github, level 7 row 1 with dict copy, advanced one pass small out, 38834 github, level 7 row 1 with dict load, advanced one pass small out, 40695 github, level 7 row 2, advanced one pass small out, 134584 github, level 7 row 2 with dict dms, advanced one pass small out, 38758 -github, level 7 row 2 with dict dds, advanced one pass small out, 38747 +github, level 7 row 2 with dict dds, advanced one pass small out, 38745 github, level 7 row 2 with dict copy, advanced one pass small out, 38755 -github, level 7 row 2 with dict load, advanced one pass small out, 41030 +github, level 7 row 2 with dict load, advanced one pass small out, 43154 github, level 7, advanced one pass small out, 135122 github, level 7 with dict, advanced one pass small out, 38758 github, level 7 with dict dms, advanced one pass small out, 38758 -github, level 7 with dict dds, advanced one pass small out, 38747 +github, level 7 with dict dds, advanced one pass small out, 38745 github, level 7 with dict copy, advanced one pass small out, 38755 github, level 7 with dict load, advanced one pass small out, 40695 github, level 9, advanced one pass small out, 135122 github, level 9 with dict, advanced one pass small out, 39437 github, level 9 with dict dms, advanced one pass small out, 39437 -github, level 9 with dict dds, advanced one pass small out, 39338 +github, level 9 with dict dds, advanced one pass small out, 39393 github, level 9 with dict copy, advanced one pass small out, 39398 github, level 9 with dict load, advanced one pass small out, 41710 +github, level 11 row 1, advanced one pass small out, 135119 +github, level 11 row 1 with dict dms, advanced one pass small out, 39671 +github, level 11 row 1 with dict dds, advanced one pass small out, 39671 +github, level 11 row 1 with dict copy, advanced one pass small out, 39651 +github, level 11 row 1 with dict load, advanced one pass small out, 41360 +github, level 11 row 2, advanced one pass small out, 135119 +github, level 11 row 2 with dict dms, advanced one pass small out, 39671 +github, level 11 row 2 with dict dds, advanced one pass small out, 39671 +github, level 11 row 2 with dict copy, advanced one pass small out, 39651 +github, level 11 row 2 with dict load, advanced one pass small out, 41360 github, level 12 row 1, advanced one pass small out, 134180 github, level 12 row 1 with dict dms, advanced one pass small out, 39677 github, level 12 row 1 with dict dds, advanced one pass small out, 39677 @@ -731,60 +879,70 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass small out, 37954 github.tar, level 4 with dict copy, advanced one pass small out, 37948 github.tar, level 4 with dict load, advanced one pass small out, 37927 -github.tar, level 5 row 1, advanced one pass small out, 39788 +github.tar, level 5 row 1, advanced one pass small out, 38534 github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39365 github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39233 github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39715 -github.tar, level 5 row 1 with dict load, advanced one pass small out, 39209 -github.tar, level 5 row 2, advanced one pass small out, 39693 +github.tar, level 5 row 1 with dict load, advanced one pass small out, 38019 +github.tar, level 5 row 2, advanced one pass small out, 38376 github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39024 github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39028 github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39040 -github.tar, level 5 row 2 with dict load, advanced one pass small out, 39037 -github.tar, level 5, advanced one pass small out, 39693 +github.tar, level 5 row 2 with dict load, advanced one pass small out, 37600 +github.tar, level 5, advanced one pass small out, 38376 github.tar, level 5 with dict, advanced one pass small out, 39040 github.tar, level 5 with dict dms, advanced one pass small out, 39024 github.tar, level 5 with dict dds, advanced one pass small out, 39028 github.tar, level 5 with dict copy, advanced one pass small out, 39040 -github.tar, level 5 with dict load, advanced one pass small out, 39037 -github.tar, level 6, advanced one pass small out, 39621 +github.tar, level 5 with dict load, advanced one pass small out, 37600 +github.tar, level 6, advanced one pass small out, 38610 github.tar, level 6 with dict, advanced one pass small out, 38622 github.tar, level 6 with dict dms, advanced one pass small out, 38608 github.tar, level 6 with dict dds, advanced one pass small out, 38610 github.tar, level 6 with dict copy, advanced one pass small out, 38622 -github.tar, level 6 with dict load, advanced one pass small out, 38962 -github.tar, level 7 row 1, advanced one pass small out, 39206 -github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37954 -github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37954 -github.tar, level 7 row 1 with dict copy, advanced one pass small out, 38071 -github.tar, level 7 row 1 with dict load, advanced one pass small out, 38584 -github.tar, level 7 row 2, advanced one pass small out, 39213 +github.tar, level 6 with dict load, advanced one pass small out, 37829 +github.tar, level 7 row 1, advanced one pass small out, 38077 +github.tar, level 7 row 1 with dict dms, advanced one pass small out, 38012 +github.tar, level 7 row 1 with dict dds, advanced one pass small out, 38014 +github.tar, level 7 row 1 with dict copy, advanced one pass small out, 38101 +github.tar, level 7 row 1 with dict load, advanced one pass small out, 37402 +github.tar, level 7 row 2, advanced one pass small out, 38073 github.tar, level 7 row 2 with dict dms, advanced one pass small out, 37848 -github.tar, level 7 row 2 with dict dds, advanced one pass small out, 37867 +github.tar, level 7 row 2 with dict dds, advanced one pass small out, 37869 github.tar, level 7 row 2 with dict copy, advanced one pass small out, 37848 -github.tar, level 7 row 2 with dict load, advanced one pass small out, 38582 -github.tar, level 7, advanced one pass small out, 39213 +github.tar, level 7 row 2 with dict load, advanced one pass small out, 37371 +github.tar, level 7, advanced one pass small out, 38073 github.tar, level 7 with dict, advanced one pass small out, 37848 github.tar, level 7 with dict dms, advanced one pass small out, 37848 -github.tar, level 7 with dict dds, advanced one pass small out, 37867 +github.tar, level 7 with dict dds, advanced one pass small out, 37869 github.tar, level 7 with dict copy, advanced one pass small out, 37848 -github.tar, level 7 with dict load, advanced one pass small out, 38582 -github.tar, level 9, advanced one pass small out, 36758 +github.tar, level 7 with dict load, advanced one pass small out, 37371 +github.tar, level 9, advanced one pass small out, 36767 github.tar, level 9 with dict, advanced one pass small out, 36457 github.tar, level 9 with dict dms, advanced one pass small out, 36549 -github.tar, level 9 with dict dds, advanced one pass small out, 36637 +github.tar, level 9 with dict dds, advanced one pass small out, 36619 github.tar, level 9 with dict copy, advanced one pass small out, 36457 -github.tar, level 9 with dict load, advanced one pass small out, 36350 -github.tar, level 12 row 1, advanced one pass small out, 36435 +github.tar, level 9 with dict load, advanced one pass small out, 36352 +github.tar, level 11 row 1, advanced one pass small out, 36435 +github.tar, level 11 row 1 with dict dms, advanced one pass small out, 36963 +github.tar, level 11 row 1 with dict dds, advanced one pass small out, 36963 +github.tar, level 11 row 1 with dict copy, advanced one pass small out, 36557 +github.tar, level 11 row 1 with dict load, advanced one pass small out, 36419 +github.tar, level 11 row 2, advanced one pass small out, 36435 +github.tar, level 11 row 2 with dict dms, advanced one pass small out, 36963 +github.tar, level 11 row 2 with dict dds, advanced one pass small out, 36963 +github.tar, level 11 row 2 with dict copy, advanced one pass small out, 36557 +github.tar, level 11 row 2 with dict load, advanced one pass small out, 36424 +github.tar, level 12 row 1, advanced one pass small out, 36110 github.tar, level 12 row 1 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass small out, 36419 -github.tar, level 12 row 2, advanced one pass small out, 36435 +github.tar, level 12 row 1 with dict load, advanced one pass small out, 36459 +github.tar, level 12 row 2, advanced one pass small out, 36105 github.tar, level 12 row 2 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass small out, 36424 +github.tar, level 12 row 2 with dict load, advanced one pass small out, 36460 github.tar, level 13, advanced one pass small out, 35621 github.tar, level 13 with dict, advanced one pass small out, 38726 github.tar, level 13 with dict dms, advanced one pass small out, 38903 @@ -819,6 +977,7 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced streaming, 6882505 silesia, level -3, advanced streaming, 6568376 silesia, level -1, advanced streaming, 6183403 +<<<<<<< HEAD silesia, level 0, advanced streaming, 4849551 silesia, level 1, advanced streaming, 5314161 silesia, level 3, advanced streaming, 4849551 @@ -834,6 +993,25 @@ silesia, level 9, advanced silesia, level 12 row 1, advanced streaming, 4519288 silesia, level 12 row 2, advanced streaming, 4521406 silesia, level 13, advanced streaming, 4482131 +======= +silesia, level 0, advanced streaming, 4849552 +silesia, level 1, advanced streaming, 5314162 +silesia, level 3, advanced streaming, 4849552 +silesia, level 4, advanced streaming, 4786970 +silesia, level 5 row 1, advanced streaming, 4640752 +silesia, level 5 row 2, advanced streaming, 4638959 +silesia, level 5, advanced streaming, 4638959 +silesia, level 6, advanced streaming, 4605369 +silesia, level 7 row 1, advanced streaming, 4564867 +silesia, level 7 row 2, advanced streaming, 4567207 +silesia, level 7, advanced streaming, 4567207 +silesia, level 9, advanced streaming, 4543310 +silesia, level 11 row 1, advanced streaming, 4519288 +silesia, level 11 row 2, advanced streaming, 4521397 +silesia, level 12 row 1, advanced streaming, 4503116 +silesia, level 12 row 2, advanced streaming, 4505151 +silesia, level 13, advanced streaming, 4482135 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, advanced streaming, 4360251 silesia, level 19, advanced streaming, 4283236 silesia, no source size, advanced streaming, 4849515 @@ -851,6 +1029,7 @@ silesia, multithreaded with advanced params, advanced silesia.tar, level -5, advanced streaming, 6982759 silesia.tar, level -3, advanced streaming, 6641283 silesia.tar, level -1, advanced streaming, 6190795 +<<<<<<< HEAD silesia.tar, level 0, advanced streaming, 4861425 silesia.tar, level 1, advanced streaming, 5336941 silesia.tar, level 3, advanced streaming, 4861425 @@ -866,6 +1045,25 @@ silesia.tar, level 9, advanced silesia.tar, level 12 row 1, advanced streaming, 4529458 silesia.tar, level 12 row 2, advanced streaming, 4530259 silesia.tar, level 13, advanced streaming, 4491769 +======= +silesia.tar, level 0, advanced streaming, 4861427 +silesia.tar, level 1, advanced streaming, 5336939 +silesia.tar, level 3, advanced streaming, 4861427 +silesia.tar, level 4, advanced streaming, 4799630 +silesia.tar, level 5 row 1, advanced streaming, 4652864 +silesia.tar, level 5 row 2, advanced streaming, 4650208 +silesia.tar, level 5, advanced streaming, 4650208 +silesia.tar, level 6, advanced streaming, 4616816 +silesia.tar, level 7 row 1, advanced streaming, 4575393 +silesia.tar, level 7 row 2, advanced streaming, 4576832 +silesia.tar, level 7, advanced streaming, 4576832 +silesia.tar, level 9, advanced streaming, 4552591 +silesia.tar, level 11 row 1, advanced streaming, 4529459 +silesia.tar, level 11 row 2, advanced streaming, 4530258 +silesia.tar, level 12 row 1, advanced streaming, 4513605 +silesia.tar, level 12 row 2, advanced streaming, 4514567 +silesia.tar, level 13, advanced streaming, 4491765 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, advanced streaming, 4356834 silesia.tar, level 19, advanced streaming, 4264388 silesia.tar, no source size, advanced streaming, 4861421 @@ -929,31 +1127,41 @@ github, level 5 with dict load, advanced github, level 6, advanced streaming, 135122 github, level 6 with dict, advanced streaming, 38671 github, level 6 with dict dms, advanced streaming, 38671 -github, level 6 with dict dds, advanced streaming, 38630 +github, level 6 with dict dds, advanced streaming, 38636 github, level 6 with dict copy, advanced streaming, 38669 github, level 6 with dict load, advanced streaming, 40695 github, level 7 row 1, advanced streaming, 135122 -github, level 7 row 1 with dict dms, advanced streaming, 38771 -github, level 7 row 1 with dict dds, advanced streaming, 38771 -github, level 7 row 1 with dict copy, advanced streaming, 38745 +github, level 7 row 1 with dict dms, advanced streaming, 38860 +github, level 7 row 1 with dict dds, advanced streaming, 38766 +github, level 7 row 1 with dict copy, advanced streaming, 38834 github, level 7 row 1 with dict load, advanced streaming, 40695 github, level 7 row 2, advanced streaming, 134584 github, level 7 row 2 with dict dms, advanced streaming, 38758 -github, level 7 row 2 with dict dds, advanced streaming, 38747 +github, level 7 row 2 with dict dds, advanced streaming, 38745 github, level 7 row 2 with dict copy, advanced streaming, 38755 -github, level 7 row 2 with dict load, advanced streaming, 41030 +github, level 7 row 2 with dict load, advanced streaming, 43154 github, level 7, advanced streaming, 135122 github, level 7 with dict, advanced streaming, 38758 github, level 7 with dict dms, advanced streaming, 38758 -github, level 7 with dict dds, advanced streaming, 38747 +github, level 7 with dict dds, advanced streaming, 38745 github, level 7 with dict copy, advanced streaming, 38755 github, level 7 with dict load, advanced streaming, 40695 github, level 9, advanced streaming, 135122 github, level 9 with dict, advanced streaming, 39437 github, level 9 with dict dms, advanced streaming, 39437 -github, level 9 with dict dds, advanced streaming, 39338 +github, level 9 with dict dds, advanced streaming, 39393 github, level 9 with dict copy, advanced streaming, 39398 github, level 9 with dict load, advanced streaming, 41710 +github, level 11 row 1, advanced streaming, 135119 +github, level 11 row 1 with dict dms, advanced streaming, 39671 +github, level 11 row 1 with dict dds, advanced streaming, 39671 +github, level 11 row 1 with dict copy, advanced streaming, 39651 +github, level 11 row 1 with dict load, advanced streaming, 41360 +github, level 11 row 2, advanced streaming, 135119 +github, level 11 row 2 with dict dms, advanced streaming, 39671 +github, level 11 row 2 with dict dds, advanced streaming, 39671 +github, level 11 row 2 with dict copy, advanced streaming, 39651 +github, level 11 row 2 with dict load, advanced streaming, 41360 github, level 12 row 1, advanced streaming, 134180 github, level 12 row 1 with dict dms, advanced streaming, 39677 github, level 12 row 1 with dict dds, advanced streaming, 39677 @@ -1025,60 +1233,70 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced streaming, 37954 github.tar, level 4 with dict copy, advanced streaming, 37948 github.tar, level 4 with dict load, advanced streaming, 37927 -github.tar, level 5 row 1, advanced streaming, 39788 +github.tar, level 5 row 1, advanced streaming, 38534 github.tar, level 5 row 1 with dict dms, advanced streaming, 39365 github.tar, level 5 row 1 with dict dds, advanced streaming, 39233 github.tar, level 5 row 1 with dict copy, advanced streaming, 39715 -github.tar, level 5 row 1 with dict load, advanced streaming, 39209 -github.tar, level 5 row 2, advanced streaming, 39693 +github.tar, level 5 row 1 with dict load, advanced streaming, 38019 +github.tar, level 5 row 2, advanced streaming, 38376 github.tar, level 5 row 2 with dict dms, advanced streaming, 39024 github.tar, level 5 row 2 with dict dds, advanced streaming, 39028 github.tar, level 5 row 2 with dict copy, advanced streaming, 39040 -github.tar, level 5 row 2 with dict load, advanced streaming, 39037 -github.tar, level 5, advanced streaming, 39693 +github.tar, level 5 row 2 with dict load, advanced streaming, 37600 +github.tar, level 5, advanced streaming, 38376 github.tar, level 5 with dict, advanced streaming, 39040 github.tar, level 5 with dict dms, advanced streaming, 39024 github.tar, level 5 with dict dds, advanced streaming, 39028 github.tar, level 5 with dict copy, advanced streaming, 39040 -github.tar, level 5 with dict load, advanced streaming, 39037 -github.tar, level 6, advanced streaming, 39621 +github.tar, level 5 with dict load, advanced streaming, 37600 +github.tar, level 6, advanced streaming, 38610 github.tar, level 6 with dict, advanced streaming, 38622 github.tar, level 6 with dict dms, advanced streaming, 38608 github.tar, level 6 with dict dds, advanced streaming, 38610 github.tar, level 6 with dict copy, advanced streaming, 38622 -github.tar, level 6 with dict load, advanced streaming, 38962 -github.tar, level 7 row 1, advanced streaming, 39206 -github.tar, level 7 row 1 with dict dms, advanced streaming, 37954 -github.tar, level 7 row 1 with dict dds, advanced streaming, 37954 -github.tar, level 7 row 1 with dict copy, advanced streaming, 38071 -github.tar, level 7 row 1 with dict load, advanced streaming, 38584 -github.tar, level 7 row 2, advanced streaming, 39213 +github.tar, level 6 with dict load, advanced streaming, 37829 +github.tar, level 7 row 1, advanced streaming, 38077 +github.tar, level 7 row 1 with dict dms, advanced streaming, 38012 +github.tar, level 7 row 1 with dict dds, advanced streaming, 38014 +github.tar, level 7 row 1 with dict copy, advanced streaming, 38101 +github.tar, level 7 row 1 with dict load, advanced streaming, 37402 +github.tar, level 7 row 2, advanced streaming, 38073 github.tar, level 7 row 2 with dict dms, advanced streaming, 37848 -github.tar, level 7 row 2 with dict dds, advanced streaming, 37867 +github.tar, level 7 row 2 with dict dds, advanced streaming, 37869 github.tar, level 7 row 2 with dict copy, advanced streaming, 37848 -github.tar, level 7 row 2 with dict load, advanced streaming, 38582 -github.tar, level 7, advanced streaming, 39213 +github.tar, level 7 row 2 with dict load, advanced streaming, 37371 +github.tar, level 7, advanced streaming, 38073 github.tar, level 7 with dict, advanced streaming, 37848 github.tar, level 7 with dict dms, advanced streaming, 37848 -github.tar, level 7 with dict dds, advanced streaming, 37867 +github.tar, level 7 with dict dds, advanced streaming, 37869 github.tar, level 7 with dict copy, advanced streaming, 37848 -github.tar, level 7 with dict load, advanced streaming, 38582 -github.tar, level 9, advanced streaming, 36758 +github.tar, level 7 with dict load, advanced streaming, 37371 +github.tar, level 9, advanced streaming, 36767 github.tar, level 9 with dict, advanced streaming, 36457 github.tar, level 9 with dict dms, advanced streaming, 36549 -github.tar, level 9 with dict dds, advanced streaming, 36637 +github.tar, level 9 with dict dds, advanced streaming, 36619 github.tar, level 9 with dict copy, advanced streaming, 36457 -github.tar, level 9 with dict load, advanced streaming, 36350 -github.tar, level 12 row 1, advanced streaming, 36435 +github.tar, level 9 with dict load, advanced streaming, 36352 +github.tar, level 11 row 1, advanced streaming, 36435 +github.tar, level 11 row 1 with dict dms, advanced streaming, 36963 +github.tar, level 11 row 1 with dict dds, advanced streaming, 36963 +github.tar, level 11 row 1 with dict copy, advanced streaming, 36557 +github.tar, level 11 row 1 with dict load, advanced streaming, 36419 +github.tar, level 11 row 2, advanced streaming, 36435 +github.tar, level 11 row 2 with dict dms, advanced streaming, 36963 +github.tar, level 11 row 2 with dict dds, advanced streaming, 36963 +github.tar, level 11 row 2 with dict copy, advanced streaming, 36557 +github.tar, level 11 row 2 with dict load, advanced streaming, 36424 +github.tar, level 12 row 1, advanced streaming, 36110 github.tar, level 12 row 1 with dict dms, advanced streaming, 36986 github.tar, level 12 row 1 with dict dds, advanced streaming, 36986 github.tar, level 12 row 1 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 1 with dict load, advanced streaming, 36419 -github.tar, level 12 row 2, advanced streaming, 36435 +github.tar, level 12 row 1 with dict load, advanced streaming, 36459 +github.tar, level 12 row 2, advanced streaming, 36105 github.tar, level 12 row 2 with dict dms, advanced streaming, 36986 github.tar, level 12 row 2 with dict dds, advanced streaming, 36986 github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 2 with dict load, advanced streaming, 36424 +github.tar, level 12 row 2 with dict load, advanced streaming, 36460 github.tar, level 13, advanced streaming, 35621 github.tar, level 13 with dict, advanced streaming, 38726 github.tar, level 13 with dict dms, advanced streaming, 38903 @@ -1113,6 +1331,7 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, old streaming, 6882505 silesia, level -3, old streaming, 6568376 silesia, level -1, old streaming, 6183403 +<<<<<<< HEAD silesia, level 0, old streaming, 4849551 silesia, level 1, old streaming, 5314161 silesia, level 3, old streaming, 4849551 @@ -1122,6 +1341,17 @@ silesia, level 6, old stre silesia, level 7, old streaming, 4603381 silesia, level 9, old streaming, 4546005 silesia, level 13, old streaming, 4482131 +======= +silesia, level 0, old streaming, 4849552 +silesia, level 1, old streaming, 5314162 +silesia, level 3, old streaming, 4849552 +silesia, level 4, old streaming, 4786970 +silesia, level 5, old streaming, 4638959 +silesia, level 6, old streaming, 4605369 +silesia, level 7, old streaming, 4567207 +silesia, level 9, old streaming, 4543310 +silesia, level 13, old streaming, 4482135 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, old streaming, 4360251 silesia, level 19, old streaming, 4283236 silesia, no source size, old streaming, 4849515 @@ -1131,6 +1361,7 @@ silesia, huffman literals, old stre silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -3, old streaming, 6641283 silesia.tar, level -1, old streaming, 6190795 +<<<<<<< HEAD silesia.tar, level 0, old streaming, 4861425 silesia.tar, level 1, old streaming, 5336941 silesia.tar, level 3, old streaming, 4861425 @@ -1140,6 +1371,17 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming, 4613548 silesia.tar, level 9, old streaming, 4555432 silesia.tar, level 13, old streaming, 4491769 +======= +silesia.tar, level 0, old streaming, 4861427 +silesia.tar, level 1, old streaming, 5336939 +silesia.tar, level 3, old streaming, 4861427 +silesia.tar, level 4, old streaming, 4799630 +silesia.tar, level 5, old streaming, 4650208 +silesia.tar, level 6, old streaming, 4616816 +silesia.tar, level 7, old streaming, 4576832 +silesia.tar, level 9, old streaming, 4552591 +silesia.tar, level 13, old streaming, 4491765 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, old streaming, 4356834 silesia.tar, level 19, old streaming, 4264388 silesia.tar, no source size, old streaming, 4861421 @@ -1193,13 +1435,13 @@ github.tar, level 3, old stre github.tar, level 3 with dict, old streaming, 37995 github.tar, level 4, old streaming, 38467 github.tar, level 4 with dict, old streaming, 37948 -github.tar, level 5, old streaming, 39693 +github.tar, level 5, old streaming, 38376 github.tar, level 5 with dict, old streaming, 39040 -github.tar, level 6, old streaming, 39621 +github.tar, level 6, old streaming, 38610 github.tar, level 6 with dict, old streaming, 38622 -github.tar, level 7, old streaming, 39213 +github.tar, level 7, old streaming, 38073 github.tar, level 7 with dict, old streaming, 37848 -github.tar, level 9, old streaming, 36758 +github.tar, level 9, old streaming, 36767 github.tar, level 9 with dict, old streaming, 36457 github.tar, level 13, old streaming, 35621 github.tar, level 13 with dict, old streaming, 38726 @@ -1215,6 +1457,7 @@ github.tar, huffman literals, old stre silesia, level -5, old streaming advanced, 6882505 silesia, level -3, old streaming advanced, 6568376 silesia, level -1, old streaming advanced, 6183403 +<<<<<<< HEAD silesia, level 0, old streaming advanced, 4849551 silesia, level 1, old streaming advanced, 5314161 silesia, level 3, old streaming advanced, 4849551 @@ -1224,6 +1467,17 @@ silesia, level 6, old stre silesia, level 7, old streaming advanced, 4603381 silesia, level 9, old streaming advanced, 4546005 silesia, level 13, old streaming advanced, 4482131 +======= +silesia, level 0, old streaming advanced, 4849552 +silesia, level 1, old streaming advanced, 5314162 +silesia, level 3, old streaming advanced, 4849552 +silesia, level 4, old streaming advanced, 4786970 +silesia, level 5, old streaming advanced, 4638959 +silesia, level 6, old streaming advanced, 4605369 +silesia, level 7, old streaming advanced, 4567207 +silesia, level 9, old streaming advanced, 4543310 +silesia, level 13, old streaming advanced, 4482135 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia, level 16, old streaming advanced, 4360251 silesia, level 19, old streaming advanced, 4283236 silesia, no source size, old streaming advanced, 4849515 @@ -1241,6 +1495,7 @@ silesia, multithreaded with advanced params, old stre silesia.tar, level -5, old streaming advanced, 6982759 silesia.tar, level -3, old streaming advanced, 6641283 silesia.tar, level -1, old streaming advanced, 6190795 +<<<<<<< HEAD silesia.tar, level 0, old streaming advanced, 4861425 silesia.tar, level 1, old streaming advanced, 5336941 silesia.tar, level 3, old streaming advanced, 4861425 @@ -1250,6 +1505,17 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming advanced, 4613548 silesia.tar, level 9, old streaming advanced, 4555432 silesia.tar, level 13, old streaming advanced, 4491769 +======= +silesia.tar, level 0, old streaming advanced, 4861427 +silesia.tar, level 1, old streaming advanced, 5336939 +silesia.tar, level 3, old streaming advanced, 4861427 +silesia.tar, level 4, old streaming advanced, 4799630 +silesia.tar, level 5, old streaming advanced, 4650208 +silesia.tar, level 6, old streaming advanced, 4616816 +silesia.tar, level 7, old streaming advanced, 4576832 +silesia.tar, level 9, old streaming advanced, 4552591 +silesia.tar, level 13, old streaming advanced, 4491765 +>>>>>>> 546c2250 (Add 64 row entry support for lazy) silesia.tar, level 16, old streaming advanced, 4356834 silesia.tar, level 19, old streaming advanced, 4264388 silesia.tar, no source size, old streaming advanced, 4861421 @@ -1278,12 +1544,12 @@ github, level 3, old stre github, level 3 with dict, old streaming advanced, 41113 github, level 4, old streaming advanced, 141104 github, level 4 with dict, old streaming advanced, 41084 -github, level 5, old streaming advanced, 139399 -github, level 5 with dict, old streaming advanced, 38633 +github, level 5, old streaming advanced, 139402 +github, level 5 with dict, old streaming advanced, 38805 github, level 6, old streaming advanced, 139402 -github, level 6 with dict, old streaming advanced, 38723 +github, level 6 with dict, old streaming advanced, 39363 github, level 7, old streaming advanced, 138676 -github, level 7 with dict, old streaming advanced, 38744 +github, level 7 with dict, old streaming advanced, 38924 github, level 9, old streaming advanced, 138676 github, level 9 with dict, old streaming advanced, 38981 github, level 13, old streaming advanced, 138676 @@ -1319,13 +1585,13 @@ github.tar, level 3, old stre github.tar, level 3 with dict, old streaming advanced, 38013 github.tar, level 4, old streaming advanced, 38467 github.tar, level 4 with dict, old streaming advanced, 38063 -github.tar, level 5, old streaming advanced, 39693 -github.tar, level 5 with dict, old streaming advanced, 39049 -github.tar, level 6, old streaming advanced, 39621 -github.tar, level 6 with dict, old streaming advanced, 38959 -github.tar, level 7, old streaming advanced, 39213 -github.tar, level 7 with dict, old streaming advanced, 38573 -github.tar, level 9, old streaming advanced, 36758 +github.tar, level 5, old streaming advanced, 38376 +github.tar, level 5 with dict, old streaming advanced, 37677 +github.tar, level 6, old streaming advanced, 38610 +github.tar, level 6 with dict, old streaming advanced, 37786 +github.tar, level 7, old streaming advanced, 38073 +github.tar, level 7 with dict, old streaming advanced, 37322 +github.tar, level 9, old streaming advanced, 36767 github.tar, level 9 with dict, old streaming advanced, 36233 github.tar, level 13, old streaming advanced, 35621 github.tar, level 13 with dict, old streaming advanced, 36035 @@ -1368,10 +1634,10 @@ github.tar, level 0 with dict, old stre github.tar, level 1 with dict, old streaming cdict, 38766 github.tar, level 3 with dict, old streaming cdict, 37956 github.tar, level 4 with dict, old streaming cdict, 37927 -github.tar, level 5 with dict, old streaming cdict, 39037 -github.tar, level 6 with dict, old streaming cdict, 38962 -github.tar, level 7 with dict, old streaming cdict, 38582 -github.tar, level 9 with dict, old streaming cdict, 36350 +github.tar, level 5 with dict, old streaming cdict, 37600 +github.tar, level 6 with dict, old streaming cdict, 37829 +github.tar, level 7 with dict, old streaming cdict, 37371 +github.tar, level 9 with dict, old streaming cdict, 36352 github.tar, level 13 with dict, old streaming cdict, 36372 github.tar, level 16 with dict, old streaming cdict, 39353 github.tar, level 19 with dict, old streaming cdict, 32676 @@ -1383,9 +1649,9 @@ github, level 0 with dict, old stre github, level 1 with dict, old streaming advanced cdict, 42430 github, level 3 with dict, old streaming advanced cdict, 41113 github, level 4 with dict, old streaming advanced cdict, 41084 -github, level 5 with dict, old streaming advanced cdict, 38633 -github, level 6 with dict, old streaming advanced cdict, 38723 -github, level 7 with dict, old streaming advanced cdict, 38744 +github, level 5 with dict, old streaming advanced cdict, 38805 +github, level 6 with dict, old streaming advanced cdict, 39363 +github, level 7 with dict, old streaming advanced cdict, 38924 github, level 9 with dict, old streaming advanced cdict, 38981 github, level 13 with dict, old streaming advanced cdict, 39731 github, level 16 with dict, old streaming advanced cdict, 40789 @@ -1398,9 +1664,9 @@ github.tar, level 0 with dict, old stre github.tar, level 1 with dict, old streaming advanced cdict, 39002 github.tar, level 3 with dict, old streaming advanced cdict, 38013 github.tar, level 4 with dict, old streaming advanced cdict, 38063 -github.tar, level 5 with dict, old streaming advanced cdict, 39049 -github.tar, level 6 with dict, old streaming advanced cdict, 38959 -github.tar, level 7 with dict, old streaming advanced cdict, 38573 +github.tar, level 5 with dict, old streaming advanced cdict, 37677 +github.tar, level 6 with dict, old streaming advanced cdict, 37786 +github.tar, level 7 with dict, old streaming advanced cdict, 37322 github.tar, level 9 with dict, old streaming advanced cdict, 36233 github.tar, level 13 with dict, old streaming advanced cdict, 36035 github.tar, level 16 with dict, old streaming advanced cdict, 38736 From 539b3aab9be79d2b8b0537633ed51ca4214ed40f Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 29 Jul 2021 08:35:36 -0700 Subject: [PATCH 098/274] Optimize 32-bit VecMask_next() --- lib/compress/zstd_lazy.c | 14 +- tests/regression/results.csv | 390 +++++++++-------------------------- 2 files changed, 110 insertions(+), 294 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 18e1331fe..70319d575 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -882,9 +882,19 @@ static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { assert(val != 0); # if defined(_MSC_VER) && defined(_WIN64) unsigned long r=0; - return _BitScanForward64(&r, val) ? (U64)r : 0; /* _BitScanForward64 not defined outside of x86/64 */ + return _BitScanForward64(&r, val) ? (U32)r : 0; /* _BitScanForward64 not defined outside of x86/64 */ # elif (defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))) - return (U32)__builtin_ctzll(val); + if (sizeof(size_t) == 4) { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (leastSignificantWord == 0) { + return 32 + (U32)__builtin_ctz(mostSignificantWord); + } else { + return (U32)__builtin_ctz(leastSignificantWord); + } + } else { + return (U32)__builtin_ctzll(val); + } # else /* Software ctz version: http://aggregate.org/MAGIC/#Trailing%20Zero%20Count * and: https://stackoverflow.com/questions/2709430/count-number-of-bits-in-a-64-bit-long-big-integer diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 579f4ecc5..bcecafae7 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -4,23 +4,13 @@ silesia.tar, level -3, compress silesia.tar, level -1, compress simple, 6186042 silesia.tar, level 0, compress simple, 4861423 silesia.tar, level 1, compress simple, 5334885 -<<<<<<< HEAD silesia.tar, level 3, compress simple, 4861423 silesia.tar, level 4, compress simple, 4799632 -silesia.tar, level 5, compress simple, 4719256 -silesia.tar, level 6, compress simple, 4677724 -silesia.tar, level 7, compress simple, 4613545 -silesia.tar, level 9, compress simple, 4555426 -silesia.tar, level 13, compress simple, 4491768 -======= -silesia.tar, level 3, compress simple, 4861425 -silesia.tar, level 4, compress simple, 4799630 -silesia.tar, level 5, compress simple, 4650203 +silesia.tar, level 5, compress simple, 4650202 silesia.tar, level 6, compress simple, 4616811 -silesia.tar, level 7, compress simple, 4576830 -silesia.tar, level 9, compress simple, 4552585 -silesia.tar, level 13, compress simple, 4491764 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 7, compress simple, 4576828 +silesia.tar, level 9, compress simple, 4552584 +silesia.tar, level 13, compress simple, 4491768 silesia.tar, level 16, compress simple, 4356834 silesia.tar, level 19, compress simple, 4264388 silesia.tar, uncompressed literals, compress simple, 4861423 @@ -46,27 +36,15 @@ github.tar, huffman literals, compress silesia, level -5, compress cctx, 6737607 silesia, level -3, compress cctx, 6444677 silesia, level -1, compress cctx, 6178460 -<<<<<<< HEAD silesia, level 0, compress cctx, 4849551 silesia, level 1, compress cctx, 5313202 silesia, level 3, compress cctx, 4849551 silesia, level 4, compress cctx, 4786969 -silesia, level 5, compress cctx, 4707790 -silesia, level 6, compress cctx, 4666383 -silesia, level 7, compress cctx, 4603381 -silesia, level 9, compress cctx, 4546005 -silesia, level 13, compress cctx, 4482131 -======= -silesia, level 0, compress cctx, 4849552 -silesia, level 1, compress cctx, 5313204 -silesia, level 3, compress cctx, 4849552 -silesia, level 4, compress cctx, 4786970 -silesia, level 5, compress cctx, 4638959 +silesia, level 5, compress cctx, 4638960 silesia, level 6, compress cctx, 4605369 -silesia, level 7, compress cctx, 4567207 -silesia, level 9, compress cctx, 4543310 -silesia, level 13, compress cctx, 4482135 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 7, compress cctx, 4567203 +silesia, level 9, compress cctx, 4543311 +silesia, level 13, compress cctx, 4482131 silesia, level 16, compress cctx, 4360251 silesia, level 19, compress cctx, 4283236 silesia, long distance mode, compress cctx, 4849551 @@ -122,27 +100,15 @@ github, multithreaded with advanced params, compress silesia, level -5, zstdcli, 6737655 silesia, level -3, zstdcli, 6444725 silesia, level -1, zstdcli, 6178508 -<<<<<<< HEAD silesia, level 0, zstdcli, 4849599 silesia, level 1, zstdcli, 5313250 silesia, level 3, zstdcli, 4849599 silesia, level 4, zstdcli, 4787017 -silesia, level 5, zstdcli, 4707838 -silesia, level 6, zstdcli, 4666431 -silesia, level 7, zstdcli, 4603429 -silesia, level 9, zstdcli, 4546053 -silesia, level 13, zstdcli, 4482179 -======= -silesia, level 0, zstdcli, 4849600 -silesia, level 1, zstdcli, 5313252 -silesia, level 3, zstdcli, 4849600 -silesia, level 4, zstdcli, 4787018 -silesia, level 5, zstdcli, 4639007 +silesia, level 5, zstdcli, 4639008 silesia, level 6, zstdcli, 4605417 -silesia, level 7, zstdcli, 4567255 -silesia, level 9, zstdcli, 4543358 -silesia, level 13, zstdcli, 4482183 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 7, zstdcli, 4567251 +silesia, level 9, zstdcli, 4543359 +silesia, level 13, zstdcli, 4482179 silesia, level 16, zstdcli, 4360299 silesia, level 19, zstdcli, 4283284 silesia, long distance mode, zstdcli, 4840807 @@ -163,19 +129,11 @@ silesia.tar, level 0, zstdcli, silesia.tar, level 1, zstdcli, 5336318 silesia.tar, level 3, zstdcli, 4861511 silesia.tar, level 4, zstdcli, 4800529 -<<<<<<< HEAD -silesia.tar, level 5, zstdcli, 4720121 -silesia.tar, level 6, zstdcli, 4678663 -silesia.tar, level 7, zstdcli, 4614426 -silesia.tar, level 9, zstdcli, 4556062 -silesia.tar, level 13, zstdcli, 4491772 -======= -silesia.tar, level 5, zstdcli, 4651160 -silesia.tar, level 6, zstdcli, 4618403 +silesia.tar, level 5, zstdcli, 4651159 +silesia.tar, level 6, zstdcli, 4618402 silesia.tar, level 7, zstdcli, 4578883 -silesia.tar, level 9, zstdcli, 4553500 -silesia.tar, level 13, zstdcli, 4491768 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 9, zstdcli, 4553498 +silesia.tar, level 13, zstdcli, 4491772 silesia.tar, level 16, zstdcli, 4356838 silesia.tar, level 19, zstdcli, 4264392 silesia.tar, no source size, zstdcli, 4861507 @@ -273,41 +231,23 @@ github.tar, multithreaded with advanced params, zstdcli, silesia, level -5, advanced one pass, 6737607 silesia, level -3, advanced one pass, 6444677 silesia, level -1, advanced one pass, 6178460 -<<<<<<< HEAD silesia, level 0, advanced one pass, 4849551 silesia, level 1, advanced one pass, 5313202 silesia, level 3, advanced one pass, 4849551 silesia, level 4, advanced one pass, 4786969 -silesia, level 5 row 1, advanced one pass, 4710233 -silesia, level 5 row 2, advanced one pass, 4707790 -silesia, level 5, advanced one pass, 4707790 -silesia, level 6, advanced one pass, 4666383 -silesia, level 7 row 1, advanced one pass, 4596297 -silesia, level 7 row 2, advanced one pass, 4603381 -silesia, level 7, advanced one pass, 4603381 -silesia, level 9, advanced one pass, 4546005 -silesia, level 12 row 1, advanced one pass, 4519288 -silesia, level 12 row 2, advanced one pass, 4521406 -silesia, level 13, advanced one pass, 4482131 -======= -silesia, level 0, advanced one pass, 4849552 -silesia, level 1, advanced one pass, 5313204 -silesia, level 3, advanced one pass, 4849552 -silesia, level 4, advanced one pass, 4786970 -silesia, level 5 row 1, advanced one pass, 4640752 -silesia, level 5 row 2, advanced one pass, 4638959 -silesia, level 5, advanced one pass, 4638959 +silesia, level 5 row 1, advanced one pass, 4640753 +silesia, level 5 row 2, advanced one pass, 4638960 +silesia, level 5, advanced one pass, 4638960 silesia, level 6, advanced one pass, 4605369 -silesia, level 7 row 1, advanced one pass, 4564867 -silesia, level 7 row 2, advanced one pass, 4567207 -silesia, level 7, advanced one pass, 4567207 -silesia, level 9, advanced one pass, 4543310 +silesia, level 7 row 1, advanced one pass, 4564870 +silesia, level 7 row 2, advanced one pass, 4567203 +silesia, level 7, advanced one pass, 4567203 +silesia, level 9, advanced one pass, 4543311 silesia, level 11 row 1, advanced one pass, 4519288 -silesia, level 11 row 2, advanced one pass, 4521397 -silesia, level 12 row 1, advanced one pass, 4503116 -silesia, level 12 row 2, advanced one pass, 4505151 -silesia, level 13, advanced one pass, 4482135 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 11 row 2, advanced one pass, 4521406 +silesia, level 12 row 1, advanced one pass, 4503117 +silesia, level 12 row 2, advanced one pass, 4505152 +silesia, level 13, advanced one pass, 4482131 silesia, level 16, advanced one pass, 4360251 silesia, level 19, advanced one pass, 4283236 silesia, no source size, advanced one pass, 4849551 @@ -327,37 +267,21 @@ silesia.tar, level -3, advanced silesia.tar, level -1, advanced one pass, 6186042 silesia.tar, level 0, advanced one pass, 4861423 silesia.tar, level 1, advanced one pass, 5334885 -<<<<<<< HEAD silesia.tar, level 3, advanced one pass, 4861423 silesia.tar, level 4, advanced one pass, 4799632 -silesia.tar, level 5 row 1, advanced one pass, 4722324 -silesia.tar, level 5 row 2, advanced one pass, 4719256 -silesia.tar, level 5, advanced one pass, 4719256 -silesia.tar, level 6, advanced one pass, 4677724 -silesia.tar, level 7 row 1, advanced one pass, 4606716 -silesia.tar, level 7 row 2, advanced one pass, 4613545 -silesia.tar, level 7, advanced one pass, 4613545 -silesia.tar, level 9, advanced one pass, 4555426 -silesia.tar, level 12 row 1, advanced one pass, 4529458 -silesia.tar, level 12 row 2, advanced one pass, 4530257 -silesia.tar, level 13, advanced one pass, 4491768 -======= -silesia.tar, level 3, advanced one pass, 4861425 -silesia.tar, level 4, advanced one pass, 4799630 -silesia.tar, level 5 row 1, advanced one pass, 4652860 -silesia.tar, level 5 row 2, advanced one pass, 4650203 -silesia.tar, level 5, advanced one pass, 4650203 +silesia.tar, level 5 row 1, advanced one pass, 4652862 +silesia.tar, level 5 row 2, advanced one pass, 4650202 +silesia.tar, level 5, advanced one pass, 4650202 silesia.tar, level 6, advanced one pass, 4616811 silesia.tar, level 7 row 1, advanced one pass, 4575392 -silesia.tar, level 7 row 2, advanced one pass, 4576830 -silesia.tar, level 7, advanced one pass, 4576830 -silesia.tar, level 9, advanced one pass, 4552585 -silesia.tar, level 11 row 1, advanced one pass, 4529459 -silesia.tar, level 11 row 2, advanced one pass, 4530256 -silesia.tar, level 12 row 1, advanced one pass, 4513605 -silesia.tar, level 12 row 2, advanced one pass, 4514567 -silesia.tar, level 13, advanced one pass, 4491764 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 7 row 2, advanced one pass, 4576828 +silesia.tar, level 7, advanced one pass, 4576828 +silesia.tar, level 9, advanced one pass, 4552584 +silesia.tar, level 11 row 1, advanced one pass, 4529458 +silesia.tar, level 11 row 2, advanced one pass, 4530257 +silesia.tar, level 12 row 1, advanced one pass, 4513603 +silesia.tar, level 12 row 2, advanced one pass, 4514568 +silesia.tar, level 13, advanced one pass, 4491768 silesia.tar, level 16, advanced one pass, 4356834 silesia.tar, level 19, advanced one pass, 4264388 silesia.tar, no source size, advanced one pass, 4861423 @@ -625,41 +549,23 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced one pass small out, 6737607 silesia, level -3, advanced one pass small out, 6444677 silesia, level -1, advanced one pass small out, 6178460 -<<<<<<< HEAD silesia, level 0, advanced one pass small out, 4849551 silesia, level 1, advanced one pass small out, 5313202 silesia, level 3, advanced one pass small out, 4849551 silesia, level 4, advanced one pass small out, 4786969 -silesia, level 5 row 1, advanced one pass small out, 4710233 -silesia, level 5 row 2, advanced one pass small out, 4707790 -silesia, level 5, advanced one pass small out, 4707790 -silesia, level 6, advanced one pass small out, 4666383 -silesia, level 7 row 1, advanced one pass small out, 4596297 -silesia, level 7 row 2, advanced one pass small out, 4603381 -silesia, level 7, advanced one pass small out, 4603381 -silesia, level 9, advanced one pass small out, 4546005 -silesia, level 12 row 1, advanced one pass small out, 4519288 -silesia, level 12 row 2, advanced one pass small out, 4521406 -silesia, level 13, advanced one pass small out, 4482131 -======= -silesia, level 0, advanced one pass small out, 4849552 -silesia, level 1, advanced one pass small out, 5313204 -silesia, level 3, advanced one pass small out, 4849552 -silesia, level 4, advanced one pass small out, 4786970 -silesia, level 5 row 1, advanced one pass small out, 4640752 -silesia, level 5 row 2, advanced one pass small out, 4638959 -silesia, level 5, advanced one pass small out, 4638959 +silesia, level 5 row 1, advanced one pass small out, 4640753 +silesia, level 5 row 2, advanced one pass small out, 4638960 +silesia, level 5, advanced one pass small out, 4638960 silesia, level 6, advanced one pass small out, 4605369 -silesia, level 7 row 1, advanced one pass small out, 4564867 -silesia, level 7 row 2, advanced one pass small out, 4567207 -silesia, level 7, advanced one pass small out, 4567207 -silesia, level 9, advanced one pass small out, 4543310 +silesia, level 7 row 1, advanced one pass small out, 4564870 +silesia, level 7 row 2, advanced one pass small out, 4567203 +silesia, level 7, advanced one pass small out, 4567203 +silesia, level 9, advanced one pass small out, 4543311 silesia, level 11 row 1, advanced one pass small out, 4519288 -silesia, level 11 row 2, advanced one pass small out, 4521397 -silesia, level 12 row 1, advanced one pass small out, 4503116 -silesia, level 12 row 2, advanced one pass small out, 4505151 -silesia, level 13, advanced one pass small out, 4482135 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 11 row 2, advanced one pass small out, 4521406 +silesia, level 12 row 1, advanced one pass small out, 4503117 +silesia, level 12 row 2, advanced one pass small out, 4505152 +silesia, level 13, advanced one pass small out, 4482131 silesia, level 16, advanced one pass small out, 4360251 silesia, level 19, advanced one pass small out, 4283236 silesia, no source size, advanced one pass small out, 4849551 @@ -679,37 +585,21 @@ silesia.tar, level -3, advanced silesia.tar, level -1, advanced one pass small out, 6186042 silesia.tar, level 0, advanced one pass small out, 4861423 silesia.tar, level 1, advanced one pass small out, 5334885 -<<<<<<< HEAD silesia.tar, level 3, advanced one pass small out, 4861423 silesia.tar, level 4, advanced one pass small out, 4799632 -silesia.tar, level 5 row 1, advanced one pass small out, 4722324 -silesia.tar, level 5 row 2, advanced one pass small out, 4719256 -silesia.tar, level 5, advanced one pass small out, 4719256 -silesia.tar, level 6, advanced one pass small out, 4677724 -silesia.tar, level 7 row 1, advanced one pass small out, 4606716 -silesia.tar, level 7 row 2, advanced one pass small out, 4613545 -silesia.tar, level 7, advanced one pass small out, 4613545 -silesia.tar, level 9, advanced one pass small out, 4555426 -silesia.tar, level 12 row 1, advanced one pass small out, 4529458 -silesia.tar, level 12 row 2, advanced one pass small out, 4530257 -silesia.tar, level 13, advanced one pass small out, 4491768 -======= -silesia.tar, level 3, advanced one pass small out, 4861425 -silesia.tar, level 4, advanced one pass small out, 4799630 -silesia.tar, level 5 row 1, advanced one pass small out, 4652860 -silesia.tar, level 5 row 2, advanced one pass small out, 4650203 -silesia.tar, level 5, advanced one pass small out, 4650203 +silesia.tar, level 5 row 1, advanced one pass small out, 4652862 +silesia.tar, level 5 row 2, advanced one pass small out, 4650202 +silesia.tar, level 5, advanced one pass small out, 4650202 silesia.tar, level 6, advanced one pass small out, 4616811 silesia.tar, level 7 row 1, advanced one pass small out, 4575392 -silesia.tar, level 7 row 2, advanced one pass small out, 4576830 -silesia.tar, level 7, advanced one pass small out, 4576830 -silesia.tar, level 9, advanced one pass small out, 4552585 -silesia.tar, level 11 row 1, advanced one pass small out, 4529459 -silesia.tar, level 11 row 2, advanced one pass small out, 4530256 -silesia.tar, level 12 row 1, advanced one pass small out, 4513605 -silesia.tar, level 12 row 2, advanced one pass small out, 4514567 -silesia.tar, level 13, advanced one pass small out, 4491764 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 7 row 2, advanced one pass small out, 4576828 +silesia.tar, level 7, advanced one pass small out, 4576828 +silesia.tar, level 9, advanced one pass small out, 4552584 +silesia.tar, level 11 row 1, advanced one pass small out, 4529458 +silesia.tar, level 11 row 2, advanced one pass small out, 4530257 +silesia.tar, level 12 row 1, advanced one pass small out, 4513603 +silesia.tar, level 12 row 2, advanced one pass small out, 4514568 +silesia.tar, level 13, advanced one pass small out, 4491768 silesia.tar, level 16, advanced one pass small out, 4356834 silesia.tar, level 19, advanced one pass small out, 4264388 silesia.tar, no source size, advanced one pass small out, 4861423 @@ -977,41 +867,23 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced streaming, 6882505 silesia, level -3, advanced streaming, 6568376 silesia, level -1, advanced streaming, 6183403 -<<<<<<< HEAD silesia, level 0, advanced streaming, 4849551 silesia, level 1, advanced streaming, 5314161 silesia, level 3, advanced streaming, 4849551 silesia, level 4, advanced streaming, 4786969 -silesia, level 5 row 1, advanced streaming, 4710233 -silesia, level 5 row 2, advanced streaming, 4707790 -silesia, level 5, advanced streaming, 4707790 -silesia, level 6, advanced streaming, 4666383 -silesia, level 7 row 1, advanced streaming, 4596297 -silesia, level 7 row 2, advanced streaming, 4603381 -silesia, level 7, advanced streaming, 4603381 -silesia, level 9, advanced streaming, 4546005 -silesia, level 12 row 1, advanced streaming, 4519288 -silesia, level 12 row 2, advanced streaming, 4521406 -silesia, level 13, advanced streaming, 4482131 -======= -silesia, level 0, advanced streaming, 4849552 -silesia, level 1, advanced streaming, 5314162 -silesia, level 3, advanced streaming, 4849552 -silesia, level 4, advanced streaming, 4786970 -silesia, level 5 row 1, advanced streaming, 4640752 -silesia, level 5 row 2, advanced streaming, 4638959 -silesia, level 5, advanced streaming, 4638959 +silesia, level 5 row 1, advanced streaming, 4640753 +silesia, level 5 row 2, advanced streaming, 4638960 +silesia, level 5, advanced streaming, 4638960 silesia, level 6, advanced streaming, 4605369 -silesia, level 7 row 1, advanced streaming, 4564867 -silesia, level 7 row 2, advanced streaming, 4567207 -silesia, level 7, advanced streaming, 4567207 -silesia, level 9, advanced streaming, 4543310 +silesia, level 7 row 1, advanced streaming, 4564870 +silesia, level 7 row 2, advanced streaming, 4567203 +silesia, level 7, advanced streaming, 4567203 +silesia, level 9, advanced streaming, 4543311 silesia, level 11 row 1, advanced streaming, 4519288 -silesia, level 11 row 2, advanced streaming, 4521397 -silesia, level 12 row 1, advanced streaming, 4503116 -silesia, level 12 row 2, advanced streaming, 4505151 -silesia, level 13, advanced streaming, 4482135 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 11 row 2, advanced streaming, 4521406 +silesia, level 12 row 1, advanced streaming, 4503117 +silesia, level 12 row 2, advanced streaming, 4505152 +silesia, level 13, advanced streaming, 4482131 silesia, level 16, advanced streaming, 4360251 silesia, level 19, advanced streaming, 4283236 silesia, no source size, advanced streaming, 4849515 @@ -1029,41 +901,23 @@ silesia, multithreaded with advanced params, advanced silesia.tar, level -5, advanced streaming, 6982759 silesia.tar, level -3, advanced streaming, 6641283 silesia.tar, level -1, advanced streaming, 6190795 -<<<<<<< HEAD silesia.tar, level 0, advanced streaming, 4861425 silesia.tar, level 1, advanced streaming, 5336941 silesia.tar, level 3, advanced streaming, 4861425 silesia.tar, level 4, advanced streaming, 4799632 -silesia.tar, level 5 row 1, advanced streaming, 4722329 -silesia.tar, level 5 row 2, advanced streaming, 4719261 -silesia.tar, level 5, advanced streaming, 4719261 -silesia.tar, level 6, advanced streaming, 4677732 -silesia.tar, level 7 row 1, advanced streaming, 4606717 -silesia.tar, level 7 row 2, advanced streaming, 4613548 -silesia.tar, level 7, advanced streaming, 4613548 -silesia.tar, level 9, advanced streaming, 4555432 -silesia.tar, level 12 row 1, advanced streaming, 4529458 -silesia.tar, level 12 row 2, advanced streaming, 4530259 -silesia.tar, level 13, advanced streaming, 4491769 -======= -silesia.tar, level 0, advanced streaming, 4861427 -silesia.tar, level 1, advanced streaming, 5336939 -silesia.tar, level 3, advanced streaming, 4861427 -silesia.tar, level 4, advanced streaming, 4799630 -silesia.tar, level 5 row 1, advanced streaming, 4652864 -silesia.tar, level 5 row 2, advanced streaming, 4650208 -silesia.tar, level 5, advanced streaming, 4650208 +silesia.tar, level 5 row 1, advanced streaming, 4652866 +silesia.tar, level 5 row 2, advanced streaming, 4650207 +silesia.tar, level 5, advanced streaming, 4650207 silesia.tar, level 6, advanced streaming, 4616816 silesia.tar, level 7 row 1, advanced streaming, 4575393 -silesia.tar, level 7 row 2, advanced streaming, 4576832 -silesia.tar, level 7, advanced streaming, 4576832 -silesia.tar, level 9, advanced streaming, 4552591 -silesia.tar, level 11 row 1, advanced streaming, 4529459 -silesia.tar, level 11 row 2, advanced streaming, 4530258 -silesia.tar, level 12 row 1, advanced streaming, 4513605 -silesia.tar, level 12 row 2, advanced streaming, 4514567 -silesia.tar, level 13, advanced streaming, 4491765 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 7 row 2, advanced streaming, 4576830 +silesia.tar, level 7, advanced streaming, 4576830 +silesia.tar, level 9, advanced streaming, 4552590 +silesia.tar, level 11 row 1, advanced streaming, 4529458 +silesia.tar, level 11 row 2, advanced streaming, 4530259 +silesia.tar, level 12 row 1, advanced streaming, 4513603 +silesia.tar, level 12 row 2, advanced streaming, 4514569 +silesia.tar, level 13, advanced streaming, 4491769 silesia.tar, level 16, advanced streaming, 4356834 silesia.tar, level 19, advanced streaming, 4264388 silesia.tar, no source size, advanced streaming, 4861421 @@ -1331,27 +1185,15 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, old streaming, 6882505 silesia, level -3, old streaming, 6568376 silesia, level -1, old streaming, 6183403 -<<<<<<< HEAD silesia, level 0, old streaming, 4849551 silesia, level 1, old streaming, 5314161 silesia, level 3, old streaming, 4849551 silesia, level 4, old streaming, 4786969 -silesia, level 5, old streaming, 4707790 -silesia, level 6, old streaming, 4666383 -silesia, level 7, old streaming, 4603381 -silesia, level 9, old streaming, 4546005 -silesia, level 13, old streaming, 4482131 -======= -silesia, level 0, old streaming, 4849552 -silesia, level 1, old streaming, 5314162 -silesia, level 3, old streaming, 4849552 -silesia, level 4, old streaming, 4786970 -silesia, level 5, old streaming, 4638959 +silesia, level 5, old streaming, 4638960 silesia, level 6, old streaming, 4605369 -silesia, level 7, old streaming, 4567207 -silesia, level 9, old streaming, 4543310 -silesia, level 13, old streaming, 4482135 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 7, old streaming, 4567203 +silesia, level 9, old streaming, 4543311 +silesia, level 13, old streaming, 4482131 silesia, level 16, old streaming, 4360251 silesia, level 19, old streaming, 4283236 silesia, no source size, old streaming, 4849515 @@ -1361,27 +1203,15 @@ silesia, huffman literals, old stre silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -3, old streaming, 6641283 silesia.tar, level -1, old streaming, 6190795 -<<<<<<< HEAD silesia.tar, level 0, old streaming, 4861425 silesia.tar, level 1, old streaming, 5336941 silesia.tar, level 3, old streaming, 4861425 silesia.tar, level 4, old streaming, 4799632 -silesia.tar, level 5, old streaming, 4719261 -silesia.tar, level 6, old streaming, 4677732 -silesia.tar, level 7, old streaming, 4613548 -silesia.tar, level 9, old streaming, 4555432 -silesia.tar, level 13, old streaming, 4491769 -======= -silesia.tar, level 0, old streaming, 4861427 -silesia.tar, level 1, old streaming, 5336939 -silesia.tar, level 3, old streaming, 4861427 -silesia.tar, level 4, old streaming, 4799630 -silesia.tar, level 5, old streaming, 4650208 +silesia.tar, level 5, old streaming, 4650207 silesia.tar, level 6, old streaming, 4616816 -silesia.tar, level 7, old streaming, 4576832 -silesia.tar, level 9, old streaming, 4552591 -silesia.tar, level 13, old streaming, 4491765 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 7, old streaming, 4576830 +silesia.tar, level 9, old streaming, 4552590 +silesia.tar, level 13, old streaming, 4491769 silesia.tar, level 16, old streaming, 4356834 silesia.tar, level 19, old streaming, 4264388 silesia.tar, no source size, old streaming, 4861421 @@ -1457,27 +1287,15 @@ github.tar, huffman literals, old stre silesia, level -5, old streaming advanced, 6882505 silesia, level -3, old streaming advanced, 6568376 silesia, level -1, old streaming advanced, 6183403 -<<<<<<< HEAD silesia, level 0, old streaming advanced, 4849551 silesia, level 1, old streaming advanced, 5314161 silesia, level 3, old streaming advanced, 4849551 silesia, level 4, old streaming advanced, 4786969 -silesia, level 5, old streaming advanced, 4707790 -silesia, level 6, old streaming advanced, 4666383 -silesia, level 7, old streaming advanced, 4603381 -silesia, level 9, old streaming advanced, 4546005 -silesia, level 13, old streaming advanced, 4482131 -======= -silesia, level 0, old streaming advanced, 4849552 -silesia, level 1, old streaming advanced, 5314162 -silesia, level 3, old streaming advanced, 4849552 -silesia, level 4, old streaming advanced, 4786970 -silesia, level 5, old streaming advanced, 4638959 +silesia, level 5, old streaming advanced, 4638960 silesia, level 6, old streaming advanced, 4605369 -silesia, level 7, old streaming advanced, 4567207 -silesia, level 9, old streaming advanced, 4543310 -silesia, level 13, old streaming advanced, 4482135 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia, level 7, old streaming advanced, 4567203 +silesia, level 9, old streaming advanced, 4543311 +silesia, level 13, old streaming advanced, 4482131 silesia, level 16, old streaming advanced, 4360251 silesia, level 19, old streaming advanced, 4283236 silesia, no source size, old streaming advanced, 4849515 @@ -1495,27 +1313,15 @@ silesia, multithreaded with advanced params, old stre silesia.tar, level -5, old streaming advanced, 6982759 silesia.tar, level -3, old streaming advanced, 6641283 silesia.tar, level -1, old streaming advanced, 6190795 -<<<<<<< HEAD silesia.tar, level 0, old streaming advanced, 4861425 silesia.tar, level 1, old streaming advanced, 5336941 silesia.tar, level 3, old streaming advanced, 4861425 silesia.tar, level 4, old streaming advanced, 4799632 -silesia.tar, level 5, old streaming advanced, 4719261 -silesia.tar, level 6, old streaming advanced, 4677732 -silesia.tar, level 7, old streaming advanced, 4613548 -silesia.tar, level 9, old streaming advanced, 4555432 -silesia.tar, level 13, old streaming advanced, 4491769 -======= -silesia.tar, level 0, old streaming advanced, 4861427 -silesia.tar, level 1, old streaming advanced, 5336939 -silesia.tar, level 3, old streaming advanced, 4861427 -silesia.tar, level 4, old streaming advanced, 4799630 -silesia.tar, level 5, old streaming advanced, 4650208 +silesia.tar, level 5, old streaming advanced, 4650207 silesia.tar, level 6, old streaming advanced, 4616816 -silesia.tar, level 7, old streaming advanced, 4576832 -silesia.tar, level 9, old streaming advanced, 4552591 -silesia.tar, level 13, old streaming advanced, 4491765 ->>>>>>> 546c2250 (Add 64 row entry support for lazy) +silesia.tar, level 7, old streaming advanced, 4576830 +silesia.tar, level 9, old streaming advanced, 4552590 +silesia.tar, level 13, old streaming advanced, 4491769 silesia.tar, level 16, old streaming advanced, 4356834 silesia.tar, level 19, old streaming advanced, 4264388 silesia.tar, no source size, old streaming advanced, 4861421 From ee3355df30752456481541d6e120f60fd1f81e8f Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Mon, 9 Aug 2021 20:03:57 -0400 Subject: [PATCH 099/274] meson: link tests with a convenience library of sources used by multiple binaries This saves repeatedly compiling them, resulting in 16 fewer compile steps, in exchange for one `ar` step. --- build/meson/tests/meson.build | 50 +++++++++++++++-------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/build/meson/tests/meson.build b/build/meson/tests/meson.build index 4d6cd1d75..0c4c3535a 100644 --- a/build/meson/tests/meson.build +++ b/build/meson/tests/meson.build @@ -29,58 +29,54 @@ ZSTDRTTEST = ['--test-large-data'] test_includes = [ include_directories(join_paths(zstd_rootdir, 'programs')) ] -datagen_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'tests/datagencli.c')] +testcommon_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'programs/timefn.c'), + join_paths(zstd_rootdir, 'programs/benchfn.c'), + join_paths(zstd_rootdir, 'programs/benchzstd.c')] +testcommon = static_library('testcommon', + testcommon_sources) + +datagen_sources = [join_paths(zstd_rootdir, 'tests/datagencli.c')] datagen = executable('datagen', datagen_sources, c_args: [ '-DNDEBUG' ], include_directories: test_includes, dependencies: libzstd_dep, + link_with: testcommon, install: false) -fullbench_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'programs/benchfn.c'), - join_paths(zstd_rootdir, 'programs/benchzstd.c'), - join_paths(zstd_rootdir, 'tests/fullbench.c')] +fullbench_sources = [join_paths(zstd_rootdir, 'tests/fullbench.c')] fullbench = executable('fullbench', fullbench_sources, include_directories: test_includes, dependencies: libzstd_dep, + link_with: testcommon, install: false) -fuzzer_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'tests/fuzzer.c')] +fuzzer_sources = [join_paths(zstd_rootdir, 'tests/fuzzer.c')] fuzzer = executable('fuzzer', fuzzer_sources, include_directories: test_includes, dependencies: [ libzstd_dep, thread_dep ], + link_with: testcommon, install: false) -zstreamtest_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'tests/seqgen.c'), +zstreamtest_sources = [join_paths(zstd_rootdir, 'tests/seqgen.c'), join_paths(zstd_rootdir, 'tests/zstreamtest.c')] zstreamtest = executable('zstreamtest', zstreamtest_sources, include_directories: test_includes, dependencies: libzstd_dep, + link_with: testcommon, install: false) -paramgrill_sources = [join_paths(zstd_rootdir, 'programs/benchfn.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'programs/benchzstd.c'), - join_paths(zstd_rootdir, 'programs/datagen.c'), - join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'tests/paramgrill.c')] +paramgrill_sources = [join_paths(zstd_rootdir, 'tests/paramgrill.c')] paramgrill = executable('paramgrill', paramgrill_sources, include_directories: test_includes, dependencies: [ libzstd_dep, libm_dep ], + link_with: testcommon, install: false) roundTripCrash_sources = [join_paths(zstd_rootdir, 'tests/roundTripCrash.c')] @@ -111,18 +107,15 @@ if 0 < legacy_level and legacy_level <= 4 install: false) endif -decodecorpus_sources = [join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'tests/decodecorpus.c')] +decodecorpus_sources = [join_paths(zstd_rootdir, 'tests/decodecorpus.c')] decodecorpus = executable('decodecorpus', decodecorpus_sources, include_directories: test_includes, dependencies: [ libzstd_dep, libm_dep ], + link_with: testcommon, install: false) -poolTests_sources = [join_paths(zstd_rootdir, 'programs/util.c'), - join_paths(zstd_rootdir, 'programs/timefn.c'), - join_paths(zstd_rootdir, 'tests/poolTests.c'), +poolTests_sources = [join_paths(zstd_rootdir, 'tests/poolTests.c'), join_paths(zstd_rootdir, 'lib/common/pool.c'), join_paths(zstd_rootdir, 'lib/common/threading.c'), join_paths(zstd_rootdir, 'lib/common/zstd_common.c'), @@ -131,6 +124,7 @@ poolTests = executable('poolTests', poolTests_sources, include_directories: test_includes, dependencies: [ libzstd_dep, thread_dep ], + link_with: testcommon, install: false) checkTag_sources = [join_paths(zstd_rootdir, 'tests/checkTag.c')] From d95a3f50973592184f956cf937cc1aedca4e464c Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Sun, 8 Aug 2021 21:11:20 -0400 Subject: [PATCH 100/274] meson: fix warnings in build files meson prefers that project-level options for Wall/Wextra/pedantic be used, rather than hardcoding raw flags in add_project_arguments. If you do the latter anyway, it raises a meson warning. Set the default options for the project to use all this. Also move the -Werror comment to the project default options with appropriate format, but leave it commented out since it does not work. --- build/meson/contrib/pzstd/meson.build | 2 +- build/meson/meson.build | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/build/meson/contrib/pzstd/meson.build b/build/meson/contrib/pzstd/meson.build index dcf2136db..2c47999fa 100644 --- a/build/meson/contrib/pzstd/meson.build +++ b/build/meson/contrib/pzstd/meson.build @@ -18,7 +18,7 @@ pzstd_sources = [join_paths(zstd_rootdir, 'programs/util.c'), join_paths(zstd_rootdir, 'contrib/pzstd/SkippableFrame.cpp')] pzstd = executable('pzstd', pzstd_sources, - cpp_args: [ '-DNDEBUG', '-Wno-shadow', '-pedantic', '-Wno-deprecated-declarations' ], + cpp_args: [ '-DNDEBUG', '-Wno-shadow', '-Wno-deprecated-declarations' ], include_directories: pzstd_includes, dependencies: [ libzstd_dep, thread_dep ], install: true) diff --git a/build/meson/meson.build b/build/meson/meson.build index 2a425b2fa..b74932c41 100644 --- a/build/meson/meson.build +++ b/build/meson/meson.build @@ -14,7 +14,11 @@ project('zstd', default_options : [ 'c_std=gnu99', 'cpp_std=c++11', - 'buildtype=release' + 'buildtype=release', + 'warning_level=3', + # -Wdocumentation does not actually pass, nor do the test binaries, + # so this isn't safe + #'werror=true' ], version: 'DUMMY', meson_version: '>=0.47.0') @@ -106,10 +110,8 @@ use_lz4 = lz4_dep.found() add_project_arguments('-DXXH_NAMESPACE=ZSTD_', language: ['c']) if [compiler_gcc, compiler_clang].contains(cc_id) - common_warning_flags = [ '-Wextra', '-Wundef', '-Wshadow', '-Wcast-align', '-Wcast-qual' ] + common_warning_flags = [ '-Wundef', '-Wshadow', '-Wcast-align', '-Wcast-qual' ] if cc_id == compiler_clang - # Should use Meson's own --werror build option - #common_warning_flags += '-Werror' common_warning_flags += ['-Wconversion', '-Wno-sign-conversion', '-Wdocumentation'] endif cc_compile_flags = cc.get_supported_arguments(common_warning_flags + ['-Wstrict-prototypes']) From 9748608aeb6a68ca622268eb8ba07e9003079e8f Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Sun, 8 Aug 2021 21:43:59 -0400 Subject: [PATCH 101/274] meson: set the symbol visibility of the shared library to hidden This matches the Makefile build. Due to one private xxhash symbol in use by the program, it recompiles a private copy of xxhash. Due to the test binaries making extensive (?) use of private symbols, it doesn't even attempt to link to shared libzstd, and instead, all of the original object files are added to libtestcommon itself for private linkage. This, too, matches the Makefile build. Ref. #2261 --- build/meson/lib/meson.build | 1 + build/meson/meson.build | 2 +- build/meson/programs/meson.build | 4 +++- build/meson/tests/meson.build | 32 ++++++++++++++++---------------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/build/meson/lib/meson.build b/build/meson/lib/meson.build index 5cc9fee86..5da538729 100644 --- a/build/meson/lib/meson.build +++ b/build/meson/lib/meson.build @@ -108,6 +108,7 @@ libzstd = library('zstd', libzstd_sources, include_directories: libzstd_includes, c_args: libzstd_c_args, + gnu_symbol_visibility: 'hidden', dependencies: libzstd_deps, install: true, version: zstd_libversion) diff --git a/build/meson/meson.build b/build/meson/meson.build index b74932c41..0c29a7621 100644 --- a/build/meson/meson.build +++ b/build/meson/meson.build @@ -21,7 +21,7 @@ project('zstd', #'werror=true' ], version: 'DUMMY', - meson_version: '>=0.47.0') + meson_version: '>=0.48.0') cc = meson.get_compiler('c') cxx = meson.get_compiler('cpp') diff --git a/build/meson/programs/meson.build b/build/meson/programs/meson.build index d255627cd..4181030c2 100644 --- a/build/meson/programs/meson.build +++ b/build/meson/programs/meson.build @@ -18,7 +18,9 @@ zstd_programs_sources = [join_paths(zstd_rootdir, 'programs/zstdcli.c'), join_paths(zstd_rootdir, 'programs/benchzstd.c'), join_paths(zstd_rootdir, 'programs/datagen.c'), join_paths(zstd_rootdir, 'programs/dibio.c'), - join_paths(zstd_rootdir, 'programs/zstdcli_trace.c')] + join_paths(zstd_rootdir, 'programs/zstdcli_trace.c'), + # needed due to use of private symbol + -fvisibility=hidden + join_paths(zstd_rootdir, 'lib/common/xxhash.c')] zstd_c_args = libzstd_debug_cflags if use_multi_thread diff --git a/build/meson/tests/meson.build b/build/meson/tests/meson.build index 0c4c3535a..14f45982a 100644 --- a/build/meson/tests/meson.build +++ b/build/meson/tests/meson.build @@ -34,32 +34,36 @@ testcommon_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), join_paths(zstd_rootdir, 'programs/timefn.c'), join_paths(zstd_rootdir, 'programs/benchfn.c'), join_paths(zstd_rootdir, 'programs/benchzstd.c')] + testcommon = static_library('testcommon', - testcommon_sources) + testcommon_sources, + # needed due to use of private symbol + -fvisibility=hidden + objects: libzstd.extract_all_objects(recursive: false)) + +testcommon_dep = declare_dependency(link_with: testcommon, + dependencies: libzstd_deps, + include_directories: libzstd_includes) datagen_sources = [join_paths(zstd_rootdir, 'tests/datagencli.c')] datagen = executable('datagen', datagen_sources, c_args: [ '-DNDEBUG' ], include_directories: test_includes, - dependencies: libzstd_dep, - link_with: testcommon, + dependencies: testcommon_dep, install: false) fullbench_sources = [join_paths(zstd_rootdir, 'tests/fullbench.c')] fullbench = executable('fullbench', fullbench_sources, include_directories: test_includes, - dependencies: libzstd_dep, - link_with: testcommon, + dependencies: testcommon_dep, install: false) fuzzer_sources = [join_paths(zstd_rootdir, 'tests/fuzzer.c')] fuzzer = executable('fuzzer', fuzzer_sources, include_directories: test_includes, - dependencies: [ libzstd_dep, thread_dep ], - link_with: testcommon, + dependencies: [ testcommon_dep, thread_dep ], install: false) zstreamtest_sources = [join_paths(zstd_rootdir, 'tests/seqgen.c'), @@ -67,22 +71,20 @@ zstreamtest_sources = [join_paths(zstd_rootdir, 'tests/seqgen.c'), zstreamtest = executable('zstreamtest', zstreamtest_sources, include_directories: test_includes, - dependencies: libzstd_dep, - link_with: testcommon, + dependencies: testcommon_dep, install: false) paramgrill_sources = [join_paths(zstd_rootdir, 'tests/paramgrill.c')] paramgrill = executable('paramgrill', paramgrill_sources, include_directories: test_includes, - dependencies: [ libzstd_dep, libm_dep ], - link_with: testcommon, + dependencies: [ testcommon_dep, libm_dep ], install: false) roundTripCrash_sources = [join_paths(zstd_rootdir, 'tests/roundTripCrash.c')] roundTripCrash = executable('roundTripCrash', roundTripCrash_sources, - dependencies: [ libzstd_dep ], + dependencies: [ testcommon_dep ], install: false) longmatch_sources = [join_paths(zstd_rootdir, 'tests/longmatch.c')] @@ -111,8 +113,7 @@ decodecorpus_sources = [join_paths(zstd_rootdir, 'tests/decodecorpus.c')] decodecorpus = executable('decodecorpus', decodecorpus_sources, include_directories: test_includes, - dependencies: [ libzstd_dep, libm_dep ], - link_with: testcommon, + dependencies: [ testcommon_dep, libm_dep ], install: false) poolTests_sources = [join_paths(zstd_rootdir, 'tests/poolTests.c'), @@ -123,8 +124,7 @@ poolTests_sources = [join_paths(zstd_rootdir, 'tests/poolTests.c'), poolTests = executable('poolTests', poolTests_sources, include_directories: test_includes, - dependencies: [ libzstd_dep, thread_dep ], - link_with: testcommon, + dependencies: [ testcommon_dep, thread_dep ], install: false) checkTag_sources = [join_paths(zstd_rootdir, 'tests/checkTag.c')] From 399849e236bdaa1215cf90e41606e222be23735c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Tue, 3 Aug 2021 12:39:44 +0200 Subject: [PATCH 102/274] Makefile: add AIX support For lib, AIX linker doesn't allow --soname. --- Makefile | 2 +- lib/Makefile | 8 ++++++-- programs/Makefile | 2 +- tests/Makefile | 3 +-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c1908f0a1..2c24261e3 100644 --- a/Makefile +++ b/Makefile @@ -148,7 +148,7 @@ clean: #------------------------------------------------------------------------------ # make install is validated only for Linux, macOS, Hurd and some BSD targets #------------------------------------------------------------------------------ -ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT Haiku)) +ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD DragonFly NetBSD MSYS_NT Haiku AIX)) HOST_OS = POSIX diff --git a/lib/Makefile b/lib/Makefile index 376a6690c..33908e9f6 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -212,7 +212,11 @@ ifeq ($(UNAME), Darwin) SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT) SONAME_FLAGS = -install_name $(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) else - SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) + ifeq ($(UNAME), AIX) + SONAME_FLAGS = + else + SONAME_FLAGS = -Wl,-soname=libzstd.$(SHARED_EXT).$(LIBVER_MAJOR) + endif SHARED_EXT = so SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR) SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) @@ -374,7 +378,7 @@ clean: #----------------------------------------------------------------------------- # make install is validated only for below listed environments #----------------------------------------------------------------------------- -ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku)) +ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX)) all: libzstd.pc diff --git a/programs/Makefile b/programs/Makefile index 599fb02fa..e4223d92f 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -411,7 +411,7 @@ include $(wildcard $(DEPFILES)) #----------------------------------------------------------------------------- # make install is validated only for Linux, macOS, BSD, Hurd and Solaris targets #----------------------------------------------------------------------------- -ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku)) +ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX)) HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) EGREP_OPTIONS ?= diff --git a/tests/Makefile b/tests/Makefile index 85553007d..44d224ea0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -244,7 +244,7 @@ clean: # valgrind tests are validated only for some posix platforms #---------------------------------------------------------------------------------- UNAME := $(shell uname) -ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS)) +ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS AIX)) HOST_OS = POSIX valgrindTest: VALGRIND = valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 @@ -263,7 +263,6 @@ valgrindTest: zstd datagen fuzzer fullbench endif - ifneq (,$(filter MINGW% MSYS%,$(UNAME))) HOST_OS = MSYS endif From 6ef6cd79995cd0f4e50a989210729b59d017b735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Mon, 2 Aug 2021 16:02:39 +0200 Subject: [PATCH 103/274] test: avoid /dev/full on AIX --- tests/playTests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index d83001fee..26c2ddaa7 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -810,7 +810,7 @@ rm -f ./*.tmp ./*.zstd println "frame concatenation tests completed" -if [ "$isWindows" = false ] && [ "$UNAME" != 'SunOS' ] && [ "$UNAME" != "OpenBSD" ] ; then +if [ "$isWindows" = false ] && [ "$UNAME" != 'SunOS' ] && [ "$UNAME" != "OpenBSD" ] && [ "$UNAME" != "AIX" ]; then println "\n**** flush write error test **** " println "println foo | zstd > /dev/full" From da095ed8991cdb2932042e208c4453fc681ce10a Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 6 Jul 2021 10:08:15 -0400 Subject: [PATCH 104/274] Improve branch misses on FSE symbol spreading --- lib/common/fse.h | 2 +- lib/compress/fse_compress.c | 53 ++++++++++++++++++++++++++++++++----- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/common/fse.h b/lib/common/fse.h index 19dd4febc..df8280ccd 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -337,7 +337,7 @@ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`. */ -#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (maxSymbolValue + 2 + (1ull << (tableLog - 2))) +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2) #define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)) size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index b4297ec88..52e0bdf2c 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -75,9 +75,11 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ; FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); U32 const step = FSE_TABLESTEP(tableSize); + U32 const maxSV1 = maxSymbolValue+1; - U32* cumul = (U32*)workSpace; - FSE_FUNCTION_TYPE* tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSymbolValue + 2)); + U16* cumul = (U16*)workSpace; /* size = maxSV1 */ + FSE_FUNCTION_TYPE* tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */ + BYTE* spread = tableSymbol + tableSize; /* size = tableSize */ U32 highThreshold = tableSize-1; @@ -98,20 +100,59 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, /* symbol start positions */ { U32 u; cumul[0] = 0; - for (u=1; u <= maxSymbolValue+1; u++) { + for (u=1; u <= maxSV1; u++) { if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ cumul[u] = cumul[u-1] + 1; tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); } else { cumul[u] = cumul[u-1] + normalizedCounter[u-1]; } } - cumul[maxSymbolValue+1] = tableSize+1; + cumul[maxSV1] = (U16)(tableSize+1); } /* Spread symbols */ - { U32 position = 0; + if (highThreshold == tableSize - 1) { + /* Case for no low prob count symbols. Lay down 8 bytes at a time + * to reduce branch misses since we are operating on a small block + */ + { + U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s Date: Fri, 20 Aug 2021 09:52:42 -0700 Subject: [PATCH 105/274] make ZSTD_HASHLOG3_MAX private This is an implementation detail, it doesn't belong to public space (zstd.h). --- lib/compress/zstd_compress.c | 16 ++++++++++++++-- lib/zstd.h | 5 +---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 9910265fe..2f02d512c 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -42,6 +42,18 @@ # define ZSTD_COMPRESS_HEAPMODE 0 #endif +/*! + * ZSTD_HASHLOG3_MAX : + * Maximum size of the hash table dedicated to find 3-bytes matches, + * in log format, aka 17 => 1 << 17 == 128Ki positions. + * This structure is only used in zstd_opt. + * Since allocation is centralized for all strategies, it has to be known here. + * The actual (selected) size of the hash table is then stored in ZSTD_matchState_t.hashLog3, + * so that zstd_opt.c doesn't need to know about this constant. + */ +#ifndef ZSTD_HASHLOG3_MAX +# define ZSTD_HASHLOG3_MAX 17 +#endif /*-************************************* * Helper functions @@ -3732,9 +3744,9 @@ static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, } /* ZSTD_convertBlockSequencesToSeqStore() - * Converts an array of ZSTD_Sequence* with the corresponding original src buffer into + * Converts an array of ZSTD_Sequence* with the corresponding original src buffer into * the seqStore of a cctx. - * + * * Returns 0 on success, ZSTD_error on failure. */ static UNUSED_ATTR size_t ZSTD_convertBlockSequencesToSeqStore(ZSTD_CCtx* cctx, diff --git a/lib/zstd.h b/lib/zstd.h index 054fb9a5a..ebe2e04b5 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -1157,9 +1157,6 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); #define ZSTD_SRCSIZEHINT_MIN 0 #define ZSTD_SRCSIZEHINT_MAX INT_MAX -/* internal */ -#define ZSTD_HASHLOG3_MAX 17 - /* --- Advanced types --- */ @@ -2225,7 +2222,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, * This function is DEPRECATED, and equivalent to: * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); * ZSTD_CCtx_refCDict(zcs, cdict); - * + * * note : cdict will just be referenced, and must outlive compression session * This prototype will generate compilation warnings. */ From dce48f53dfc88b971d1e592dbfdb1f6b77970485 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 23 Aug 2021 19:10:16 -0400 Subject: [PATCH 106/274] Fix benchzstd error message --- programs/benchzstd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 72793f07b..32ce60593 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -805,6 +805,10 @@ BMK_benchOutcome_t BMK_benchFilesAdvanced( RETURN_ERROR(15, BMK_benchOutcome_t, "Invalid Compression Level"); } + if (totalSizeToLoad == UTIL_FILESIZE_UNKNOWN) { + RETURN_ERROR(9, BMK_benchOutcome_t, "Error loading files"); + } + fileSizes = (size_t*)calloc(nbFiles, sizeof(size_t)); if (!fileSizes) RETURN_ERROR(12, BMK_benchOutcome_t, "not enough memory for fileSizes"); From ef6953984954dbb5dd333d277a5700ff35df6781 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 11:53:56 -0700 Subject: [PATCH 107/274] transferred inter-versions compatibility tests to GA --- .github/workflows/dev-short-tests.yml | 14 +++++++++++--- .travis.yml | 19 ++++--------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 1f676c46b..bd3e16da9 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -2,7 +2,7 @@ name: dev-short-tests # Faster tests: mostly build tests, along with some other # misc tests -concurrency: +concurrency: group: fast-${{ github.ref }} cancel-in-progress: true @@ -140,7 +140,7 @@ jobs: sudo apt-get -qqq update make libc6install CFLAGS="-Werror -m32" make -j all32 - + gcc-8-make: runs-on: ubuntu-latest steps: @@ -184,7 +184,7 @@ jobs: run: > msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} - + minimal-decompressor-macros: runs-on: ubuntu-latest steps: @@ -200,6 +200,14 @@ jobs: make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + versions-compatibility: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Versions Compatibility Test + run: | + make -C tests versionsTest + # For reference : icc tests # icc tests are currently failing on Github Actions, likely to issues during installation stage # To be fixed later diff --git a/.travis.yml b/.travis.yml index 7b202cb88..85fbf78b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,31 +43,19 @@ matrix: arch: arm64 script: - make check - + - name: arm64fuzz os: linux arch: arm64 script: - make -C tests fuzztest - - # TODO: migrate to GH actions once warnings are fixed - - name: Minimal Decompressor Macros # ~5mn - script: - - make clean && make -j all ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" - - make clean && make check ZSTD_LIB_MINIFY=1 MOREFLAGS="-Werror" - - make clean && make -j all MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X1 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT" - - make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X1 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT" - - make clean && make -j all MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" - - make clean && make check MOREFLAGS="-Werror -DHUF_FORCE_DECOMPRESS_X2 -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG" - - make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" - - make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" # TODO: migrate to GH actions once newest clang staticanalyze warnings are fixed - name: static analyzer scanbuild # ~26mn dist: trusty # note : it's important to pin down a version of static analyzer, since different versions report different false positives script: - make staticAnalyze - + # GH actions can't run this command on OS-X, non-tty issues - name: OS-X make all lib os: osx @@ -115,7 +103,8 @@ matrix: script: - make arminstall - make aarch64fuzz - + + # To be removed once confirmed transferred to GA - name: Versions Compatibility Test # 11.5mn script: - make -C tests versionsTest From 7f37b8a547e960e58dd3c247925a66dcb0412f77 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 14:48:11 -0700 Subject: [PATCH 108/274] accelerate versionsCompatibilityTest by allowing parallel build of units, and reducing optimization levels. Parallel build is only effective on "recent" versions of `zstd`, as previously, the list of units was passed as a list of source files, which is something neither `make` nor `gcc` can parallelize. So its impact is mildly effective (-20%). Reducing optimization level to `-O1` makes compilation much faster. It also makes runtime slower, but in this test, compilation time dominates run time. The savings are very significant (-50%). On my test system, it reduces the length of this test from 13mn to 5mn. --- tests/test-zstd-versions.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/test-zstd-versions.py b/tests/test-zstd-versions.py index c86af7ddf..cc1693a26 100755 --- a/tests/test-zstd-versions.py +++ b/tests/test-zstd-versions.py @@ -23,6 +23,7 @@ from subprocess import Popen, PIPE repo_url = 'https://github.com/facebook/zstd.git' tmp_dir_name = 'tests/versionsTest' make_cmd = 'make' +make_args = ['-j','CFLAGS=-O1'] git_cmd = 'git' test_dat_src = 'README.md' test_dat = 'test_dat' @@ -56,8 +57,11 @@ def proc(cmd_args, pipe=True, dummy=False): return subproc.communicate() -def make(args, pipe=True): - return proc([make_cmd] + args, pipe) +def make(targets, pipe=True): + cmd = [make_cmd] + make_args + targets + cmd_str = str(cmd) + print('compilation command : ' + cmd_str) + return proc(cmd, pipe) def git(args, pipe=True): @@ -223,20 +227,25 @@ if __name__ == '__main__': dst_zstd = '{}/zstd.{}'.format(tmp_dir, tag) # /path/to/zstd/tests/versionsTest/zstd. if not os.path.isfile(dst_zstd) or tag == head: if tag != head: + print('-----------------------------------------------') + print('compiling ' + tag) + print('-----------------------------------------------') r_dir = '{}/{}'.format(tmp_dir, tag) # /path/to/zstd/tests/versionsTest/ os.makedirs(r_dir, exist_ok=True) os.chdir(clone_dir) git(['--work-tree=' + r_dir, 'checkout', tag, '--', '.'], False) if tag == 'v0.5.0': os.chdir(r_dir + '/dictBuilder') # /path/to/zstd/tests/versionsTest/v0.5.0/dictBuilder - make(['clean', 'dictBuilder'], False) + make(['clean'], False) # separate 'clean' target to allow parallel build + make(['dictBuilder'], False) shutil.copy2('dictBuilder', '{}/dictBuilder.{}'.format(tmp_dir, tag)) os.chdir(r_dir + '/programs') # /path/to/zstd/tests/versionsTest//programs - make(['clean', 'zstd'], False) + make(['clean'], False) # separate 'clean' target to allow parallel build + make(['zstd'], False) else: os.chdir(programs_dir) make(['zstd'], False) - shutil.copy2('zstd', dst_zstd) + shutil.copy2('zstd', dst_zstd) # remove any remaining *.zst and *.dec from previous test os.chdir(tmp_dir) From 72bd2a83a01c70938f4d55337ecc2c3211694a2a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 15:26:31 -0700 Subject: [PATCH 109/274] reduce length of scanbuild static analyzer test This was ~30mn, by far the longest run on travisCI. That's because it re-analyzes multiple times the same files (library files notably). It also performs actions that make no sense for the static analyzer purpose, such as building the single-file library. Reduced time spent in this test by reducing its scope : just build the CLI, and obviously the library along it. These are the only ones that really deserve to be analyzed. Unfortunately, it still results in a number of false positives when using newer versions of scanbuild (each version of scanbuild generates a different list of false positives). These will have to be fixed before transfering to Github Actions. --- .travis.yml | 7 ++++--- Makefile | 2 +- tests/test-zstd-versions.py | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85fbf78b8..1acbfecf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,7 +51,7 @@ matrix: - make -C tests fuzztest # TODO: migrate to GH actions once newest clang staticanalyze warnings are fixed - - name: static analyzer scanbuild # ~26mn + - name: static analyzer scanbuild # ~8mn dist: trusty # note : it's important to pin down a version of static analyzer, since different versions report different false positives script: - make staticAnalyze @@ -104,8 +104,9 @@ matrix: - make arminstall - make aarch64fuzz - # To be removed once confirmed transferred to GA - - name: Versions Compatibility Test # 11.5mn + # This test currently fails on GA specifically, for no obvious reason + # (it works fine on travisCI, and on local test platforms). + - name: Versions Compatibility Test # ~6mn script: - make -C tests versionsTest diff --git a/Makefile b/Makefile index c1908f0a1..b9265e7f8 100644 --- a/Makefile +++ b/Makefile @@ -416,5 +416,5 @@ bmi32build: clean staticAnalyze: SCANBUILD ?= scan-build staticAnalyze: $(CC) -v - CC=$(CC) CPPFLAGS=-g $(SCANBUILD) --status-bugs -v $(MAKE) allzstd examples contrib + CC=$(CC) CPPFLAGS=-g $(SCANBUILD) --status-bugs -v $(MAKE) zstd endif diff --git a/tests/test-zstd-versions.py b/tests/test-zstd-versions.py index cc1693a26..baca251f5 100755 --- a/tests/test-zstd-versions.py +++ b/tests/test-zstd-versions.py @@ -244,6 +244,9 @@ if __name__ == '__main__': make(['zstd'], False) else: os.chdir(programs_dir) + print('-----------------------------------------------') + print('compiling head') + print('-----------------------------------------------') make(['zstd'], False) shutil.copy2('zstd', dst_zstd) @@ -260,7 +263,9 @@ if __name__ == '__main__': print('cp ' + dict_files + ' ' + dict_source_path) execute('cp ' + dict_files + ' ' + dict_source_path, param_shell=True) + print('-----------------------------------------------') print('Compress test.dat by all released zstd') + print('-----------------------------------------------') error_code = 0 for tag in tags: From b341aa2f95e0ec363a593452faa58b6e6ac1f587 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 15:47:04 -0700 Subject: [PATCH 110/274] remove versions-compatibility test from GA since it fails on Github Actions specifically. The test is run on TravisCI for the time being. Its duration has been reduced to ~6mn anyway. --- .github/workflows/dev-short-tests.yml | 18 +++++++++++------- .travis.yml | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index bd3e16da9..85c966d36 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -200,13 +200,17 @@ jobs: make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" - versions-compatibility: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Versions Compatibility Test - run: | - make -C tests versionsTest +# This test currently fails on Github Actions specifically. +# No clear reason, as the same test works fine locally and on travisCI. +# This will have to be fixed before transfering the test to GA. +# versions-compatibility: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v2 +# - name: Versions Compatibility Test +# run: | +# make -C tests versionsTest + # For reference : icc tests # icc tests are currently failing on Github Actions, likely to issues during installation stage diff --git a/.travis.yml b/.travis.yml index 1acbfecf1..1e963246c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ matrix: script: - make -C tests fuzztest - # TODO: migrate to GH actions once newest clang staticanalyze warnings are fixed + # TODO: migrate to GH Actions once newest clang staticanalyze warnings are fixed - name: static analyzer scanbuild # ~8mn dist: trusty # note : it's important to pin down a version of static analyzer, since different versions report different false positives script: From 1c97ec73d7efc412ae32bee4f88cbcd39ba3f146 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 16:28:41 -0700 Subject: [PATCH 111/274] added qemu tests running zstd library on emulated targets --- .github/workflows/dev-long-tests.yml | 8 +++- .github/workflows/dev-short-tests.yml | 59 +++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dev-long-tests.yml b/.github/workflows/dev-long-tests.yml index bc88c4a6a..0f0c36e33 100644 --- a/.github/workflows/dev-long-tests.yml +++ b/.github/workflows/dev-long-tests.yml @@ -1,7 +1,7 @@ name: dev-long-tests # Tests longer than 10mn -concurrency: +concurrency: group: long-${{ github.ref }} cancel-in-progress: true @@ -10,6 +10,7 @@ on: branches: [ dev, release, actionsTest ] jobs: + # lasts ~24mn make-test: runs-on: ubuntu-latest env: @@ -20,6 +21,7 @@ jobs: - name: make test run: make test + # lasts ~26mn make-test-osx: runs-on: macos-latest steps: @@ -41,6 +43,7 @@ jobs: - name: thread sanitizer zstreamtest run: CC=clang ZSTREAM_TESTTIME=-T3mn make tsan-test-zstream + # lasts ~15mn tsan-fuzztest: runs-on: ubuntu-latest steps: @@ -48,6 +51,7 @@ jobs: - name: thread sanitizer fuzztest run: CC=clang make tsan-fuzztest + # lasts ~23mn gcc-8-asan-ubsan-testzstd: runs-on: ubuntu-latest steps: @@ -113,6 +117,7 @@ jobs: sudo apt-get install clang CC=clang FUZZER_FLAGS="--long-tests" make clean msan-fuzztest + # lasts ~24mn clang-msan-testzstd: runs-on: ubuntu-latest steps: @@ -145,6 +150,7 @@ jobs: make clean make -C tests test-fuzzer-stackmode + # lasts ~20mn oss-fuzz: runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 1f676c46b..a5b1b122c 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -2,7 +2,7 @@ name: dev-short-tests # Faster tests: mostly build tests, along with some other # misc tests -concurrency: +concurrency: group: fast-${{ github.ref }} cancel-in-progress: true @@ -140,7 +140,7 @@ jobs: sudo apt-get -qqq update make libc6install CFLAGS="-Werror -m32" make -j all32 - + gcc-8-make: runs-on: ubuntu-latest steps: @@ -184,7 +184,7 @@ jobs: run: > msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v140 /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} - + minimal-decompressor-macros: runs-on: ubuntu-latest steps: @@ -200,6 +200,59 @@ jobs: make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + + qemu-consistency: + name: QEMU ${{ matrix.name }} + runs-on: ubuntu-latest + strategy: + fail-fast: false # 'false' means Don't stop matrix workflows even if some matrix failed. + matrix: + include: [ + { name: ARM, xcc_pkg: gcc-arm-linux-gnueabi, xcc: arm-linux-gnueabi-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-arm-static }, + { name: ARM64, xcc_pkg: gcc-aarch64-linux-gnu, xcc: aarch64-linux-gnu-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-aarch64-static }, + { name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static }, + { name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static }, + { name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static }, + ] + env: # Set environment variables + XCC: ${{ matrix.xcc }} + XEMU: ${{ matrix.xemu }} + steps: + - uses: actions/checkout@v2 # https://github.com/actions/checkout + - name: apt update & install + run: | + sudo apt-get update + sudo apt-get install gcc-multilib g++-multilib qemu-utils qemu-user-static + sudo apt-get install ${{ matrix.xcc_pkg }} ${{ matrix.xemu_pkg }} + - name: Environment info + run: | + echo && which $XCC + echo && $XCC --version + echo && $XCC -v # Show built-in specs + echo && which $XEMU + echo && $XEMU --version + - name: ARM + if: ${{ matrix.name == 'ARM' }} + run: | + LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + - name: ARM64 + if: ${{ matrix.name == 'ARM64' }} + run: | + LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + - name: PPC64LE + if: ${{ matrix.name == 'PPC64LE' }} + run: | + LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + - name: S390X + if: ${{ matrix.name == 'S390X' }} + run: | + LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + - name: MIPS + if: ${{ matrix.name == 'MIPS' }} + run: | + LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + + # For reference : icc tests # icc tests are currently failing on Github Actions, likely to issues during installation stage # To be fixed later From 18191c85c96e942e02f3eae6c255d7a7b5c34367 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 16:43:32 -0700 Subject: [PATCH 112/274] adding optional QEMU_SYS --- .github/workflows/dev-short-tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index a5b1b122c..eca24be1c 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -234,23 +234,23 @@ jobs: - name: ARM if: ${{ matrix.name == 'ARM' }} run: | - LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: ARM64 if: ${{ matrix.name == 'ARM64' }} run: | - LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: PPC64LE if: ${{ matrix.name == 'PPC64LE' }} run: | - LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: S390X if: ${{ matrix.name == 'S390X' }} run: | - LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: MIPS if: ${{ matrix.name == 'MIPS' }} run: | - LDFLAGS="-static" CC=$XCC RUN_ENV=$XEMU make clean check + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check # For reference : icc tests From f21977c5e6af6897435dce5645e538c2e36a14ea Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 17:20:12 -0700 Subject: [PATCH 113/274] fix playTests.sh when EXE_PREFIX not null --- programs/Makefile | 6 +++--- tests/playTests.sh | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index 599fb02fa..ad05dbe1d 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -156,7 +156,7 @@ endif # zlib detection NO_ZLIB_MSG := ==> no zlib, building zstd without .gz support -HAVE_ZLIB := $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_zlib.c && $(CC) $(FLAGS) -o have_zlib$(EXT) have_zlib.c -lz 2> $(VOID) && rm have_zlib$(EXT) && echo 1 || echo 0; rm have_zlib.c) +HAVE_ZLIB ?= $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_zlib.c && $(CC) $(FLAGS) -o have_zlib$(EXT) have_zlib.c -lz 2> $(VOID) && rm have_zlib$(EXT) && echo 1 || echo 0; rm have_zlib.c) ifeq ($(HAVE_ZLIB), 1) ZLIB_MSG := ==> building zstd with .gz compression support ZLIBCPP = -DZSTD_GZCOMPRESS -DZSTD_GZDECOMPRESS @@ -167,7 +167,7 @@ endif # lzma detection NO_LZMA_MSG := ==> no liblzma, building zstd without .xz/.lzma support -HAVE_LZMA := $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_lzma.c && $(CC) $(FLAGS) -o have_lzma$(EXT) have_lzma.c -llzma 2> $(VOID) && rm have_lzma$(EXT) && echo 1 || echo 0; rm have_lzma.c) +HAVE_LZMA ?= $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_lzma.c && $(CC) $(FLAGS) -o have_lzma$(EXT) have_lzma.c -llzma 2> $(VOID) && rm have_lzma$(EXT) && echo 1 || echo 0; rm have_lzma.c) ifeq ($(HAVE_LZMA), 1) LZMA_MSG := ==> building zstd with .xz/.lzma compression support LZMACPP = -DZSTD_LZMACOMPRESS -DZSTD_LZMADECOMPRESS @@ -178,7 +178,7 @@ endif # lz4 detection NO_LZ4_MSG := ==> no liblz4, building zstd without .lz4 support -HAVE_LZ4 := $(shell printf '$(NUM_SYMBOL)include \n$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_lz4.c && $(CC) $(FLAGS) -o have_lz4$(EXT) have_lz4.c -llz4 2> $(VOID) && rm have_lz4$(EXT) && echo 1 || echo 0; rm have_lz4.c) +HAVE_LZ4 ?= $(shell printf '$(NUM_SYMBOL)include \n$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_lz4.c && $(CC) $(FLAGS) -o have_lz4$(EXT) have_lz4.c -llz4 2> $(VOID) && rm have_lz4$(EXT) && echo 1 || echo 0; rm have_lz4.c) ifeq ($(HAVE_LZ4), 1) LZ4_MSG := ==> building zstd with .lz4 compression support LZ4CPP = -DZSTD_LZ4COMPRESS -DZSTD_LZ4DECOMPRESS diff --git a/tests/playTests.sh b/tests/playTests.sh index d83001fee..774655aa9 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -166,7 +166,8 @@ if [ -z "${DATAGEN_BIN}" ]; then DATAGEN_BIN="$TESTDIR/datagen" fi -ZSTD_BIN="$EXE_PREFIX$ZSTD_BIN" +# Why was this line here ? Generates a strange ZSTD_BIN when EXE_PREFIX is non empty +# ZSTD_BIN="$EXE_PREFIX$ZSTD_BIN" # assertions [ -n "$ZSTD_BIN" ] || die "zstd not found at $ZSTD_BIN! \n Please define ZSTD_BIN pointing to the zstd binary. You might also consider rebuilding zstd follwing the instructions in README.md" From 74b4171fb834c3dbab8e5939d3d7abd46d25b60b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 19:05:04 -0700 Subject: [PATCH 114/274] fix alignment condition in FSE_buildCTable 2-bytes alignment is enough for 16-bit fields --- lib/compress/fse_compress.c | 47 +++++++++++--------------- lib/compress/zstd_compress_sequences.c | 7 ++-- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index 52e0bdf2c..16948245e 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -78,12 +78,11 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, U32 const maxSV1 = maxSymbolValue+1; U16* cumul = (U16*)workSpace; /* size = maxSV1 */ - FSE_FUNCTION_TYPE* tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */ - BYTE* spread = tableSymbol + tableSize; /* size = tableSize */ + FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */ U32 highThreshold = tableSize-1; - if ((size_t)workSpace & 3) return ERROR(GENERIC); /* Must be 4 byte aligned */ + assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */ if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge); /* CTable header */ tableU16[-2] = (U16) tableLog; @@ -105,7 +104,9 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, cumul[u] = cumul[u-1] + 1; tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); } else { - cumul[u] = cumul[u-1] + normalizedCounter[u-1]; + assert(normalizedCounter[u-1] >= 0); + cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1]; + assert(cumul[u] >= cumul[u-1]); /* no overflow */ } } cumul[maxSV1] = (U16)(tableSize+1); } @@ -115,8 +116,8 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, /* Case for no low prob count symbols. Lay down 8 bytes at a time * to reduce branch misses since we are operating on a small block */ - { - U64 const add = 0x0101010101010101ull; + BYTE* const spread = tableSymbol + tableSize; /* size = tableSize */ + { U64 const add = 0x0101010101010101ull; size_t pos = 0; U64 sv = 0; U32 s; @@ -127,15 +128,15 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, for (i = 8; i < n; i += 8) { MEM_write64(spread + pos + i, sv); } - pos += n; + assert(n>=0); + pos += (size_t)n; } } /* Spread symbols across the table. Lack of lowprob symbols means that * we don't need variable sized inner loop, so we can unroll the loop and * reduce branch misses. */ - { - size_t position = 0; + { size_t position = 0; size_t s; size_t const unroll = 2; /* Experimentally determined optimal unroll */ assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ @@ -147,7 +148,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, } position = (position + (unroll * step)) & tableMask; } - assert(position == 0); + assert(position == 0); /* Must have initialized all positions */ } } else { U32 position = 0; @@ -161,7 +162,6 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, while (position > highThreshold) position = (position + step) & tableMask; /* Low proba area */ } } - assert(position==0); /* Must have initialized all positions */ } @@ -185,16 +185,17 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, case -1: case 1: symbolTT[s].deltaNbBits = (tableLog << 16) - (1< 1); + { U32 const maxBitsOut = tableLog - BIT_highbit32 ((U32)normalizedCounter[s]-1); + U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut; symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; - symbolTT[s].deltaFindState = total - normalizedCounter[s]; - total += normalizedCounter[s]; + symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]); + total += (unsigned)normalizedCounter[s]; } } } } #if 0 /* debug : symbol costs */ @@ -205,26 +206,16 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, symbol, normalizedCounter[symbol], FSE_getMaxNbBits(symbolTT, symbol), (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256); - } - } + } } #endif return 0; } -#ifndef ZSTD_NO_UNUSED_FUNCTIONS -size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) -{ - FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */ - return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol)); -} -#endif - #ifndef FSE_COMMONDEFS_ONLY - /*-************************************************************** * FSE NCount encoding ****************************************************************/ diff --git a/lib/compress/zstd_compress_sequences.c b/lib/compress/zstd_compress_sequences.c index 611eabdcb..44e1728ff 100644 --- a/lib/compress/zstd_compress_sequences.c +++ b/lib/compress/zstd_compress_sequences.c @@ -275,10 +275,11 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity, assert(nbSeq_1 > 1); assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp)); (void)entropyWorkspaceSize; - FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), ""); - { size_t const NCountSize = FSE_writeNCount(op, oend - op, wksp->norm, max, tableLog); /* overflow protected */ + FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "FSE_normalizeCount failed"); + assert(oend >= op); + { size_t const NCountSize = FSE_writeNCount(op, (size_t)(oend - op), wksp->norm, max, tableLog); /* overflow protected */ FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed"); - FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), ""); + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "FSE_buildCTable_wksp failed"); return NCountSize; } } From 1e5c90cb5b9f562ed9d23abb793c1f13d6aacdd0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 20:54:18 -0700 Subject: [PATCH 115/274] remove qemu tests that are being transfered to GA in #2758. This represents a saving of ~25mn of cpu time on TravisCI. --- .travis.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e963246c..6a1295b4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,12 +69,6 @@ matrix: - make arminstall - make armbuild - - name: Qemu PPC + Fuzz Test # ~13mn - dist: trusty # it seems ppc cross-compilation fails on "current" - script: - - make ppcinstall - - make ppcfuzz - # check release number (release/new tag only) - name: Tag-Specific Test if: tag =~ ^v[0-9]\.[0-9] @@ -91,19 +85,6 @@ matrix: - cat /proc/cpuinfo - make -C tests fuzztest - - name: Qemu PPC64 + Fuzz test # ~13mn, presumed Big-Endian (?) - dist: trusty # note : PPC64 cross-compilation for Qemu tests seems broken on Xenial - script: - - make ppcinstall - - make ppc64fuzz - - # note : we already have aarch64 tests on hardware - - name: Qemu aarch64 + Fuzz Test (on Xenial) # ~14mn - dist: xenial - script: - - make arminstall - - make aarch64fuzz - # This test currently fails on GA specifically, for no obvious reason # (it works fine on travisCI, and on local test platforms). - name: Versions Compatibility Test # ~6mn From 2b27d07d06df02b0c0356c3c95b5a1ad05b0c1c4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 29 Aug 2021 21:39:06 -0700 Subject: [PATCH 116/274] attempt at adding m68k qemu tests with optional success (for the time being) --- .github/workflows/dev-short-tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index eca24be1c..710a949b9 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -213,6 +213,7 @@ jobs: { name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static }, { name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static }, { name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static }, + { name: M68K, xcc_pkg: gcc-m68k-linux-gnu, xcc: m68k-linux-gnu-gcc, xemu_pkg: qemu-system-m68k, xemu: qemu-m68k-static }, ] env: # Set environment variables XCC: ${{ matrix.xcc }} @@ -251,6 +252,11 @@ jobs: if: ${{ matrix.name == 'MIPS' }} run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: M68K + if: ${{ matrix.name == 'M68K' }} + continue-on-error: true + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check # For reference : icc tests From 333ecf6865e8ea1a1c7b2f5618e7c6f045f86b26 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 30 Aug 2021 06:37:50 -0700 Subject: [PATCH 117/274] add powerpc qemu emulation --- .github/workflows/dev-short-tests.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 710a949b9..86f2382f7 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -210,6 +210,7 @@ jobs: include: [ { name: ARM, xcc_pkg: gcc-arm-linux-gnueabi, xcc: arm-linux-gnueabi-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-arm-static }, { name: ARM64, xcc_pkg: gcc-aarch64-linux-gnu, xcc: aarch64-linux-gnu-gcc, xemu_pkg: qemu-system-arm, xemu: qemu-aarch64-static }, + { name: PPC, xcc_pkg: gcc-powerpc-linux-gnu, xcc: powerpc-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc-static }, { name: PPC64LE, xcc_pkg: gcc-powerpc64le-linux-gnu, xcc: powerpc64le-linux-gnu-gcc, xemu_pkg: qemu-system-ppc, xemu: qemu-ppc64le-static }, { name: S390X, xcc_pkg: gcc-s390x-linux-gnu, xcc: s390x-linux-gnu-gcc, xemu_pkg: qemu-system-s390x, xemu: qemu-s390x-static }, { name: MIPS, xcc_pkg: gcc-mips-linux-gnu, xcc: mips-linux-gnu-gcc, xemu_pkg: qemu-system-mips, xemu: qemu-mips-static }, @@ -240,6 +241,10 @@ jobs: if: ${{ matrix.name == 'ARM64' }} run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + - name: PPC + if: ${{ matrix.name == 'PPC' }} + run: | + LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: PPC64LE if: ${{ matrix.name == 'PPC64LE' }} run: | @@ -254,7 +259,7 @@ jobs: LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: M68K if: ${{ matrix.name == 'M68K' }} - continue-on-error: true + continue-on-error: true # disable reporting errors (alignment issues) run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check From ab8aa49b8d2383adfa9ef86ab4bd4a1a0d43c7fa Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Tue, 17 Aug 2021 11:31:15 -0400 Subject: [PATCH 118/274] Fix Benchmark Corruption Display --- programs/benchzstd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 32ce60593..d77959aac 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -523,7 +523,7 @@ BMK_benchMemAdvancedNoAlloc( DISPLAY("%02X ", ((const BYTE*)srcBuffer)[u+n]); DISPLAY(" \n"); DISPLAY("decode: "); - for (n=lowest; n>0; n++) + for (n=lowest; n>0; n--) DISPLAY("%02X ", resultBuffer[u-n]); DISPLAY(" :%02X: ", resultBuffer[u]); for (n=1; n<3; n++) From 80bc12b33a039d5bef59d7ca4ce8809feabbfbaa Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Tue, 17 Aug 2021 12:42:39 -0400 Subject: [PATCH 119/274] Initial Pipelined Implementation for ZSTD_fast --- lib/compress/zstd_fast.c | 259 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 254 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index b6a1a7e69..fa214e63d 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -183,6 +183,255 @@ _match: /* Requires: ip0, match0, offcode */ } +/** + * If you squint hard enough (and ignore repcodes), the search operation at any + * given position is broken into 4 stages: + * + * 1. Hash (map position to hash value via input read) + * 2. Lookup (map hash val to index via hashtable read) + * 3. Load (map index to value at that position via input read) + * 4. Compare + * + * Each of these steps involves a memory read at an address which is computed + * from the previous step. This means these steps must be sequenced and their + * latencies are cumulative. + * + * Rather than do 1->2->3->4 sequentially for a single position before moving + * onto the next, this implementation interleaves these operations across the + * next few positions: + * + * Pos | Time --> + * ----+------------------- + * N | ...4 + * N+1 | ... 3 4 + * N+2 | ... 2 3 4 + * N+3 | 1 2 3 + * N+4 | 1 2 + * N+5 | 1 + * + * This is very much analogous to the pipelining of execution in a CPU. And just + * like a CPU, we have to dump the pipeline when we find a match (i.e., take a + * branch). + * + * When this happens, we throw away our current state, and do the following prep + * to re-enter the loop: + * + * Pos | Time --> + * ----+------------------- + * N | 1 2 3 + * N+1 | 1 2 + * N+2 | 1 + * + * This is also the work we do at the beginning to enter the loop initially. + */ +FORCE_INLINE_TEMPLATE size_t +ZSTD_compressBlock_fast_generic_pipelined( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + size_t const stepSize = cParams->targetLength + !(cParams->targetLength); + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + + const BYTE* anchor = istart; + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + U32 rep_offset1 = rep[0]; + U32 rep_offset2 = rep[1]; + U32 offsetSaved = 0; + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + size_t hash2; /* hash for ip2 */ + size_t hash3; /* hash for ip3 */ + U32 idx0; /* match idx for ip0 */ + U32 idx1; /* match idx for ip1 */ + U32 idx2; /* match idx for ip2 */ + U32 mval; /* src value at match idx */ + U32 rval; /* src value at ip2 - repcode */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + + DEBUGLOG(5, "ZSTD_compressBlock_fast_generic_pipelined"); + ip0 += (ip0 == prefixStart); + { U32 const curr = (U32)(ip0 - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; + if (rep_offset2 > maxRep) offsetSaved = rep_offset2, rep_offset2 = 0; + if (rep_offset1 > maxRep) offsetSaved = rep_offset1, rep_offset1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + stepSize; + ip2 = ip1 + stepSize; + ip3 = ip2 + stepSize; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + hash2 = ZSTD_hashPtr(ip2, hlog, mls); + + idx0 = hashTable[hash0]; + idx1 = hashTable[hash1]; + + if (idx0 >= prefixStartIndex) { + mval = MEM_read32(base + idx0); + } else { + mval = MEM_read32(ip0) ^ 1; + } + + rval = MEM_read32(ip2 - rep_offset1); + + do { + current0 = ip0 - base; + + // DEBUGLOG(5, "Searching ip0 = %u", (U32)(ip0 - istart)); + + /* write back hash table entry */ + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) { + ip0 = ip2; + match0 = ip0 - rep_offset1; + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = 0; + mLength += 4; + goto _match; + } + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } + + /* load next rval */ + rval = MEM_read32(ip3 - rep_offset1); + + /* load match for ip[1] */ + if (idx1 >= prefixStartIndex) { + mval = MEM_read32(base + idx1); + } else { + mval = MEM_read32(ip1) ^ 1; /* guaranteed to not match. */ + } + + /* lookup ip[2] */ + idx2 = hashTable[hash2]; + + /* hash ip[3] */ + hash3 = ZSTD_hashPtr(ip3, hlog, mls); + + /* advance to next positions */ + { + size_t const step = ((size_t)(ip2 - anchor) >> (kSearchStrength - 1)) + stepSize; + assert(step >= 1); + + idx0 = idx1; + idx1 = idx2; + + hash0 = hash1; + hash1 = hash2; + hash2 = hash3; + + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + ip3 = ip3 + step; + } + } while (ip3 < ilimit); + +_cleanup: + + /* Find matches at end of block. */ + + /* TODO */ + + /* save reps for next block */ + rep[0] = rep_offset1 ? rep_offset1 : offsetSaved; + rep[1] = rep_offset2 ? rep_offset2 : offsetSaved; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx0 */ + + /* Compute the offset code. */ + match0 = base + idx0; + rep_offset2 = rep_offset1; + rep_offset1 = (U32)(ip0-match0); + offcode = rep_offset1 + ZSTD_REP_MOVE; + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } + +_match: /* Requires: ip0, match0, offcode */ + + /* Count the forward length. */ + mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength - MINMATCH); + + ip0 += mLength; + anchor = ip0; + + /* write next hash table entry */ + if (ip1 < ip0) { + hashTable[hash1] = ip1 - base; + } + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */ + while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4; + { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */ + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += rLength; + ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH); + anchor = ip0; + continue; /* faster when present (confirmed on gcc-8) ... (?) */ + } } } + + goto _start; +} + + size_t ZSTD_compressBlock_fast( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -193,13 +442,13 @@ size_t ZSTD_compressBlock_fast( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 4); case 5 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 5); case 6 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 6); case 7 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 7); } } @@ -402,7 +651,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( /* switch to "regular" variant if extDict is invalidated due to maxDistance */ if (prefixStartIndex == dictStartIndex) - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls); + return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, mls); /* Search Loop */ while (ip < ilimit) { /* < instead of <=, because (ip+1) */ From bc768bccc036fe0d60ff63fe240dfca7474636d9 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 12:47:14 -0400 Subject: [PATCH 120/274] Track Step Size Statefully, Rather than Recalculating Every Time --- lib/compress/zstd_fast.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index fa214e63d..ff2faab33 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -268,6 +268,10 @@ ZSTD_compressBlock_fast_generic_pipelined( const BYTE* match0; size_t mLength; + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + DEBUGLOG(5, "ZSTD_compressBlock_fast_generic_pipelined"); ip0 += (ip0 == prefixStart); { U32 const curr = (U32)(ip0 - base); @@ -280,6 +284,9 @@ ZSTD_compressBlock_fast_generic_pipelined( /* start each op */ _start: /* Requires: ip0 */ + step = stepSize; + nextStep = ip0 + kStepIncr; + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ ip1 = ip0 + stepSize; ip2 = ip1 + stepSize; @@ -348,8 +355,10 @@ _start: /* Requires: ip0 */ /* advance to next positions */ { - size_t const step = ((size_t)(ip2 - anchor) >> (kSearchStrength - 1)) + stepSize; - assert(step >= 1); + if (ip2 >= nextStep) { + step++; + nextStep += kStepIncr; + } idx0 = idx1; idx1 = idx2; From 387840af79a86660c8f83bcd6cc4de584de9f3a6 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 12:47:48 -0400 Subject: [PATCH 121/274] Re-Order Operations for Slightly Better Performance --- lib/compress/zstd_fast.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index ff2faab33..a1a9ef445 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -331,27 +331,27 @@ _start: /* Requires: ip0 */ goto _match; } + /* load match for ip[1] */ + if (idx0 >= prefixStartIndex) { + mval = MEM_read32(base + idx0); + } else { + mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */ + } + /* check match at ip[0] */ if (MEM_read32(ip0) == mval) { /* found a match! */ goto _offset; } - /* load next rval */ - rval = MEM_read32(ip3 - rep_offset1); - - /* load match for ip[1] */ - if (idx1 >= prefixStartIndex) { - mval = MEM_read32(base + idx1); - } else { - mval = MEM_read32(ip1) ^ 1; /* guaranteed to not match. */ - } + /* hash ip[3] */ + hash3 = ZSTD_hashPtr(ip3, hlog, mls); /* lookup ip[2] */ idx2 = hashTable[hash2]; - /* hash ip[3] */ - hash3 = ZSTD_hashPtr(ip3, hlog, mls); + /* load next rval */ + rval = MEM_read32(ip3 - rep_offset1); /* advance to next positions */ { From b092dd75b7e0ed48dc94fe58391aac7b805cb178 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 13:44:27 -0400 Subject: [PATCH 122/274] Shrink Pipeline from 4 Positions to 3 --- lib/compress/zstd_fast.c | 42 ++++++++++------------------------------ 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index a1a9ef445..411ffc118 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -247,7 +247,6 @@ ZSTD_compressBlock_fast_generic_pipelined( const BYTE* ip0 = istart; const BYTE* ip1; const BYTE* ip2; - const BYTE* ip3; U32 current0; U32 rep_offset1 = rep[0]; @@ -257,12 +256,9 @@ ZSTD_compressBlock_fast_generic_pipelined( size_t hash0; /* hash for ip0 */ size_t hash1; /* hash for ip1 */ size_t hash2; /* hash for ip2 */ - size_t hash3; /* hash for ip3 */ U32 idx0; /* match idx for ip0 */ U32 idx1; /* match idx for ip1 */ - U32 idx2; /* match idx for ip2 */ U32 mval; /* src value at match idx */ - U32 rval; /* src value at ip2 - repcode */ U32 offcode; const BYTE* match0; @@ -290,32 +286,20 @@ _start: /* Requires: ip0 */ /* calculate positions, ip0 - anchor == 0, so we skip step calc */ ip1 = ip0 + stepSize; ip2 = ip1 + stepSize; - ip3 = ip2 + stepSize; - if (ip3 >= ilimit) { + if (ip2 >= ilimit) { goto _cleanup; } hash0 = ZSTD_hashPtr(ip0, hlog, mls); hash1 = ZSTD_hashPtr(ip1, hlog, mls); - hash2 = ZSTD_hashPtr(ip2, hlog, mls); idx0 = hashTable[hash0]; - idx1 = hashTable[hash1]; - - if (idx0 >= prefixStartIndex) { - mval = MEM_read32(base + idx0); - } else { - mval = MEM_read32(ip0) ^ 1; - } - - rval = MEM_read32(ip2 - rep_offset1); do { + const U32 rval = MEM_read32(ip2 - rep_offset1); current0 = ip0 - base; - // DEBUGLOG(5, "Searching ip0 = %u", (U32)(ip0 - istart)); - /* write back hash table entry */ hashTable[hash0] = current0; @@ -331,7 +315,7 @@ _start: /* Requires: ip0 */ goto _match; } - /* load match for ip[1] */ + /* load match for ip[0] */ if (idx0 >= prefixStartIndex) { mval = MEM_read32(base + idx0); } else { @@ -344,35 +328,29 @@ _start: /* Requires: ip0 */ goto _offset; } - /* hash ip[3] */ - hash3 = ZSTD_hashPtr(ip3, hlog, mls); + /* hash ip[2] */ + hash2 = ZSTD_hashPtr(ip2, hlog, mls); - /* lookup ip[2] */ - idx2 = hashTable[hash2]; - - /* load next rval */ - rval = MEM_read32(ip3 - rep_offset1); + /* lookup ip[1] */ + idx1 = hashTable[hash1]; /* advance to next positions */ { - if (ip2 >= nextStep) { + if (ip1 >= nextStep) { step++; nextStep += kStepIncr; } idx0 = idx1; - idx1 = idx2; hash0 = hash1; hash1 = hash2; - hash2 = hash3; ip0 = ip1; ip1 = ip2; - ip2 = ip3; - ip3 = ip3 + step; + ip2 = ip2 + step; } - } while (ip3 < ilimit); + } while (ip2 < ilimit); _cleanup: From 35932ab2f1e129dce0d19bfa82787dc4dc262eed Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 15:21:43 -0400 Subject: [PATCH 123/274] Prefetch Input in Incompressible Sections (+0.25% Speed) --- lib/compress/zstd_fast.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 411ffc118..f7df66681 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -337,6 +337,7 @@ _start: /* Requires: ip0 */ /* advance to next positions */ { if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); step++; nextStep += kStepIncr; } From 7c24c3e6ce8faa5a6d23ef9d11c71a0a106b3bb3 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 16:02:01 -0400 Subject: [PATCH 124/274] Give Up on Searching End of Block Amusingly, it seems to be a non-trivial performance hit to add in final searches or even hash table insertions during cleanup. So let's not. It seems to not make any meaningful difference in compression ratio. --- lib/compress/zstd_fast.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index f7df66681..50bceef74 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -354,10 +354,9 @@ _start: /* Requires: ip0 */ } while (ip2 < ilimit); _cleanup: - - /* Find matches at end of block. */ - - /* TODO */ + /* Note that there are probably still a couple positions we could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ /* save reps for next block */ rep[0] = rep_offset1 ? rep_offset1 : offsetSaved; From 8706bc115a28757a7a684c4a6bcf435ad9e5eb03 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 16:11:22 -0400 Subject: [PATCH 125/274] Nit: Dedup idx0 and idx1 --- lib/compress/zstd_fast.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 50bceef74..f731b957d 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -256,8 +256,7 @@ ZSTD_compressBlock_fast_generic_pipelined( size_t hash0; /* hash for ip0 */ size_t hash1; /* hash for ip1 */ size_t hash2; /* hash for ip2 */ - U32 idx0; /* match idx for ip0 */ - U32 idx1; /* match idx for ip1 */ + U32 idx; /* match idx for ip0 */ U32 mval; /* src value at match idx */ U32 offcode; @@ -294,7 +293,7 @@ _start: /* Requires: ip0 */ hash0 = ZSTD_hashPtr(ip0, hlog, mls); hash1 = ZSTD_hashPtr(ip1, hlog, mls); - idx0 = hashTable[hash0]; + idx = hashTable[hash0]; do { const U32 rval = MEM_read32(ip2 - rep_offset1); @@ -316,8 +315,8 @@ _start: /* Requires: ip0 */ } /* load match for ip[0] */ - if (idx0 >= prefixStartIndex) { - mval = MEM_read32(base + idx0); + if (idx >= prefixStartIndex) { + mval = MEM_read32(base + idx); } else { mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */ } @@ -332,7 +331,7 @@ _start: /* Requires: ip0 */ hash2 = ZSTD_hashPtr(ip2, hlog, mls); /* lookup ip[1] */ - idx1 = hashTable[hash1]; + idx = hashTable[hash1]; /* advance to next positions */ { @@ -342,8 +341,6 @@ _start: /* Requires: ip0 */ nextStep += kStepIncr; } - idx0 = idx1; - hash0 = hash1; hash1 = hash2; @@ -365,10 +362,10 @@ _cleanup: /* Return the last literals size */ return (size_t)(iend - anchor); -_offset: /* Requires: ip0, idx0 */ +_offset: /* Requires: ip0, idx */ /* Compute the offset code. */ - match0 = base + idx0; + match0 = base + idx; rep_offset2 = rep_offset1; rep_offset1 = (U32)(ip0-match0); offcode = rep_offset1 + ZSTD_REP_MOVE; From 991d660ea9fc0e0453a6fa580831352478b56104 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 18 Aug 2021 16:15:53 -0400 Subject: [PATCH 126/274] Nit: Only Store 2 Hash Variables --- lib/compress/zstd_fast.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index f731b957d..c43c8a6af 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -255,7 +255,6 @@ ZSTD_compressBlock_fast_generic_pipelined( size_t hash0; /* hash for ip0 */ size_t hash1; /* hash for ip1 */ - size_t hash2; /* hash for ip2 */ U32 idx; /* match idx for ip0 */ U32 mval; /* src value at match idx */ @@ -327,11 +326,13 @@ _start: /* Requires: ip0 */ goto _offset; } + hash0 = hash1; + /* hash ip[2] */ - hash2 = ZSTD_hashPtr(ip2, hlog, mls); + hash1 = ZSTD_hashPtr(ip2, hlog, mls); /* lookup ip[1] */ - idx = hashTable[hash1]; + idx = hashTable[hash0]; /* advance to next positions */ { @@ -341,9 +342,6 @@ _start: /* Requires: ip0 */ nextStep += kStepIncr; } - hash0 = hash1; - hash1 = hash2; - ip0 = ip1; ip1 = ip2; ip2 = ip2 + step; From 57a100f6dcb46fff20eacdfc9fc000b0f226b76f Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 19 Aug 2021 13:58:09 -0400 Subject: [PATCH 127/274] Add `ip1 + 128` Prefetch; Tiny Cleanup --- lib/compress/zstd_fast.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index c43c8a6af..ebbef4919 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -295,7 +295,9 @@ _start: /* Requires: ip0 */ idx = hashTable[hash0]; do { + /* load repcode match for ip[2]*/ const U32 rval = MEM_read32(ip2 - rep_offset1); + current0 = ip0 - base; /* write back hash table entry */ @@ -334,18 +336,18 @@ _start: /* Requires: ip0 */ /* lookup ip[1] */ idx = hashTable[hash0]; - /* advance to next positions */ - { - if (ip1 >= nextStep) { - PREFETCH_L1(ip1 + 64); - step++; - nextStep += kStepIncr; - } - - ip0 = ip1; - ip1 = ip2; - ip2 = ip2 + step; + /* calculate step */ + if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + step++; + nextStep += kStepIncr; } + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 += step; } while (ip2 < ilimit); _cleanup: From 24fcccd05c6a3609715b9d9d1020129105c55116 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 20 Aug 2021 15:56:14 -0400 Subject: [PATCH 128/274] Unroll Loop Core; Reduce Frequency of Repcode Check & Step Calc (+>1% Speed) Unrolling the loop to handle 2 positions in each iteration allows us to reduce the frequency of some operations that don't need to happen at every position. One such operation is the step calculation, which is a very rough heuristic anyways. It's fine if we do this a position later. The other operation is the repcode check. But since the repcode check already tries expanding back one position, we're really not missing much of importance by only trying it every other position. This commit also slightly reorders some operations. --- lib/compress/zstd_fast.c | 47 +++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index ebbef4919..9b40558e1 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -247,6 +247,7 @@ ZSTD_compressBlock_fast_generic_pipelined( const BYTE* ip0 = istart; const BYTE* ip1; const BYTE* ip2; + const BYTE* ip3; U32 current0; U32 rep_offset1 = rep[0]; @@ -284,8 +285,9 @@ _start: /* Requires: ip0 */ /* calculate positions, ip0 - anchor == 0, so we skip step calc */ ip1 = ip0 + stepSize; ip2 = ip1 + stepSize; + ip3 = ip2 + stepSize; - if (ip2 >= ilimit) { + if (ip3 >= ilimit) { goto _cleanup; } @@ -298,9 +300,8 @@ _start: /* Requires: ip0 */ /* load repcode match for ip[2]*/ const U32 rval = MEM_read32(ip2 - rep_offset1); - current0 = ip0 - base; - /* write back hash table entry */ + current0 = ip0 - base; hashTable[hash0] = current0; /* check repcode at ip[2] */ @@ -328,16 +329,45 @@ _start: /* Requires: ip0 */ goto _offset; } - hash0 = hash1; + /* lookup ip[1] */ + idx = hashTable[hash1]; /* hash ip[2] */ + hash0 = hash1; hash1 = ZSTD_hashPtr(ip2, hlog, mls); + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + ip3 += step; + + /* write back hash table entry */ + current0 = ip0 - base; + hashTable[hash0] = current0; + + /* load match for ip[0] */ + if (idx >= prefixStartIndex) { + mval = MEM_read32(base + idx); + } else { + mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */ + } + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } + /* lookup ip[1] */ - idx = hashTable[hash0]; + idx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); /* calculate step */ - if (ip1 >= nextStep) { + if (ip2 >= nextStep) { PREFETCH_L1(ip1 + 64); PREFETCH_L1(ip1 + 128); step++; @@ -347,8 +377,9 @@ _start: /* Requires: ip0 */ /* advance to next positions */ ip0 = ip1; ip1 = ip2; - ip2 += step; - } while (ip2 < ilimit); + ip2 = ip3; + ip3 += step; + } while (ip3 < ilimit); _cleanup: /* Note that there are probably still a couple positions we could search. From 64054dec442a99e4c065be1319202e18bd4b8d8a Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 20 Aug 2021 17:06:41 -0400 Subject: [PATCH 129/274] Tweak Step --- lib/compress/zstd_fast.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 9b40558e1..d60a0bbe5 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -340,7 +340,6 @@ _start: /* Requires: ip0 */ ip0 = ip1; ip1 = ip2; ip2 = ip3; - ip3 += step; /* write back hash table entry */ current0 = ip0 - base; @@ -377,8 +376,8 @@ _start: /* Requires: ip0 */ /* advance to next positions */ ip0 = ip1; ip1 = ip2; - ip2 = ip3; - ip3 += step; + ip2 = ip2 + step; + ip3 = ip2 + step; } while (ip3 < ilimit); _cleanup: From 15e67bfa7e7ec1384e42001ef1eeb5af9a896f02 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 26 Aug 2021 13:29:58 -0400 Subject: [PATCH 130/274] Deduplicate Implementations This removes the old `ZSTD_compressBlock_fast_generic()` and renames the new `ZSTD_compressBlock_fast_generic_pipelined()` to replace it. This is functionally a no-op. --- lib/compress/zstd_fast.c | 177 +++++---------------------------------- 1 file changed, 21 insertions(+), 156 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index d60a0bbe5..33a392dfa 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -43,146 +43,6 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms, } -FORCE_INLINE_TEMPLATE size_t -ZSTD_compressBlock_fast_generic( - ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize, - U32 const mls) -{ - const ZSTD_compressionParameters* const cParams = &ms->cParams; - U32* const hashTable = ms->hashTable; - U32 const hlog = cParams->hashLog; - /* support stepSize of 0 */ - size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; - const BYTE* const base = ms->window.base; - const BYTE* const istart = (const BYTE*)src; - /* We check ip0 (ip + 0) and ip1 (ip + 1) each loop */ - const BYTE* ip0 = istart; - const BYTE* ip1; - const BYTE* anchor = istart; - const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); - const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); - const BYTE* const prefixStart = base + prefixStartIndex; - const BYTE* const iend = istart + srcSize; - const BYTE* const ilimit = iend - HASH_READ_SIZE; - U32 offset_1=rep[0], offset_2=rep[1]; - U32 offsetSaved = 0; - - /* init */ - DEBUGLOG(5, "ZSTD_compressBlock_fast_generic"); - ip0 += (ip0 == prefixStart); - ip1 = ip0 + 1; - { U32 const curr = (U32)(ip0 - base); - U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); - U32 const maxRep = curr - windowLow; - if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0; - if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; - } - - /* Main Search Loop */ -#ifdef __INTEL_COMPILER - /* From intel 'The vector pragma indicates that the loop should be - * vectorized if it is legal to do so'. Can be used together with - * #pragma ivdep (but have opted to exclude that because intel - * warns against using it).*/ - #pragma vector always -#endif - while (ip1 < ilimit) { /* < instead of <=, because check at ip0+2 */ - size_t mLength; - BYTE const* ip2 = ip0 + 2; - size_t const h0 = ZSTD_hashPtr(ip0, hlog, mls); - U32 const val0 = MEM_read32(ip0); - size_t const h1 = ZSTD_hashPtr(ip1, hlog, mls); - U32 const val1 = MEM_read32(ip1); - U32 const current0 = (U32)(ip0-base); - U32 const current1 = (U32)(ip1-base); - U32 const matchIndex0 = hashTable[h0]; - U32 const matchIndex1 = hashTable[h1]; - BYTE const* repMatch = ip2 - offset_1; - const BYTE* match0 = base + matchIndex0; - const BYTE* match1 = base + matchIndex1; - U32 offcode; - -#if defined(__aarch64__) - PREFETCH_L1(ip0+256); -#endif - - hashTable[h0] = current0; /* update hash table */ - hashTable[h1] = current1; /* update hash table */ - - assert(ip0 + 1 == ip1); - - if ((offset_1 > 0) & (MEM_read32(repMatch) == MEM_read32(ip2))) { - mLength = (ip2[-1] == repMatch[-1]) ? 1 : 0; - ip0 = ip2 - mLength; - match0 = repMatch - mLength; - mLength += 4; - offcode = 0; - goto _match; - } - if ((matchIndex0 > prefixStartIndex) && MEM_read32(match0) == val0) { - /* found a regular match */ - goto _offset; - } - if ((matchIndex1 > prefixStartIndex) && MEM_read32(match1) == val1) { - /* found a regular match after one literal */ - ip0 = ip1; - match0 = match1; - goto _offset; - } - { size_t const step = ((size_t)(ip0-anchor) >> (kSearchStrength - 1)) + stepSize; - assert(step >= 2); - ip0 += step; - ip1 += step; - continue; - } -_offset: /* Requires: ip0, match0 */ - /* Compute the offset code */ - offset_2 = offset_1; - offset_1 = (U32)(ip0-match0); - offcode = offset_1 + ZSTD_REP_MOVE; - mLength = 4; - /* Count the backwards match length */ - while (((ip0>anchor) & (match0>prefixStart)) - && (ip0[-1] == match0[-1])) { ip0--; match0--; mLength++; } /* catch up */ - -_match: /* Requires: ip0, match0, offcode */ - /* Count the forward length */ - mLength += ZSTD_count(ip0+mLength, match0+mLength, iend); - ZSTD_storeSeq(seqStore, (size_t)(ip0-anchor), anchor, iend, offcode, mLength-MINMATCH); - /* match found */ - ip0 += mLength; - anchor = ip0; - - if (ip0 <= ilimit) { - /* Fill Table */ - assert(base+current0+2 > istart); /* check base overflow */ - hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ - hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); - - if (offset_2 > 0) { /* offset_2==0 means offset_2 is invalidated */ - while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) ) { - /* store sequence */ - size_t const rLength = ZSTD_count(ip0+4, ip0+4-offset_2, iend) + 4; - { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */ - hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); - ip0 += rLength; - ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH); - anchor = ip0; - continue; /* faster when present (confirmed on gcc-8) ... (?) */ - } } } - ip1 = ip0 + 1; - } - - /* save reps for next block */ - rep[0] = offset_1 ? offset_1 : offsetSaved; - rep[1] = offset_2 ? offset_2 : offsetSaved; - - /* Return the last literals size */ - return (size_t)(iend - anchor); -} - - /** * If you squint hard enough (and ignore repcodes), the search operation at any * given position is broken into 4 stages: @@ -200,14 +60,20 @@ _match: /* Requires: ip0, match0, offcode */ * onto the next, this implementation interleaves these operations across the * next few positions: * + * R = Repcode Read & Compare + * H = Hash + * T = Table Lookup + * M = Match Read & Compare + * * Pos | Time --> * ----+------------------- - * N | ...4 - * N+1 | ... 3 4 - * N+2 | ... 2 3 4 - * N+3 | 1 2 3 - * N+4 | 1 2 - * N+5 | 1 + * N | ... M + * N+1 | ... TM + * N+2 | R H T M + * N+3 | H TM + * N+4 | R H T M + * N+5 | H ... + * N+6 | R ... * * This is very much analogous to the pipelining of execution in a CPU. And just * like a CPU, we have to dump the pipeline when we find a match (i.e., take a @@ -218,14 +84,13 @@ _match: /* Requires: ip0, match0, offcode */ * * Pos | Time --> * ----+------------------- - * N | 1 2 3 - * N+1 | 1 2 - * N+2 | 1 + * N | H T + * N+1 | H * * This is also the work we do at the beginning to enter the loop initially. */ FORCE_INLINE_TEMPLATE size_t -ZSTD_compressBlock_fast_generic_pipelined( +ZSTD_compressBlock_fast_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls) @@ -267,7 +132,7 @@ ZSTD_compressBlock_fast_generic_pipelined( const BYTE* nextStep; const size_t kStepIncr = (1 << (kSearchStrength - 1)); - DEBUGLOG(5, "ZSTD_compressBlock_fast_generic_pipelined"); + DEBUGLOG(5, "ZSTD_compressBlock_fast_generic"); ip0 += (ip0 == prefixStart); { U32 const curr = (U32)(ip0 - base); U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); @@ -456,13 +321,13 @@ size_t ZSTD_compressBlock_fast( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 4); case 5 : - return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 5); case 6 : - return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 6); case 7 : - return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 7); } } @@ -665,7 +530,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( /* switch to "regular" variant if extDict is invalidated due to maxDistance */ if (prefixStartIndex == dictStartIndex) - return ZSTD_compressBlock_fast_generic_pipelined(ms, seqStore, rep, src, srcSize, mls); + return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls); /* Search Loop */ while (ip < ilimit) { /* < instead of <=, because (ip+1) */ From 98d3df326b8dfddd11786e45e7ba8406ffc08942 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 26 Aug 2021 13:46:32 -0400 Subject: [PATCH 131/274] Change Target Size in Fuzzer It's a bit strange, because this is hitting the dictionary special case where the dictionary is contiguous with the input and still runs in the single- segment path. We should probably change that to hit the `extDict` path instead? --- tests/fuzzer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 960050f96..fff963176 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1966,7 +1966,7 @@ static int basicUnitTests(U32 const seed, double compressibility) 3742, 3670, 3670, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660, 3660 }; - size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940, + size_t const target_wdict_cSize[22+1] = { 2830, 2896, 2890, 2820, 2940, 2950, 2950, 2925, 2900, 2891, 2910, 2910, 2910, 2770, 2760, 2750, 2750, 2750, 2750, 2750, From d6fd7761c963db8b88c14210f9ca1f972fe7fd71 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 30 Aug 2021 12:27:49 -0400 Subject: [PATCH 132/274] Fix VS Build: Explicitly Cast to Narrow Ints --- lib/compress/zstd_fast.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 33a392dfa..2555e0720 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -166,7 +166,7 @@ _start: /* Requires: ip0 */ const U32 rval = MEM_read32(ip2 - rep_offset1); /* write back hash table entry */ - current0 = ip0 - base; + current0 = (U32)(ip0 - base); hashTable[hash0] = current0; /* check repcode at ip[2] */ @@ -207,7 +207,7 @@ _start: /* Requires: ip0 */ ip2 = ip3; /* write back hash table entry */ - current0 = ip0 - base; + current0 = (U32)(ip0 - base); hashTable[hash0] = current0; /* load match for ip[0] */ @@ -285,7 +285,7 @@ _match: /* Requires: ip0, match0, offcode */ /* write next hash table entry */ if (ip1 < ip0) { - hashTable[hash1] = ip1 - base; + hashTable[hash1] = (U32)(ip1 - base); } /* Fill table and check for immediate repcode. */ From b0977e4ed2e58a2db2eaf6be6721393fe964daa9 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 1 Sep 2021 14:45:00 -0400 Subject: [PATCH 133/274] Update results.csv --- tests/regression/results.csv | 360 +++++++++++++++++------------------ 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index bcecafae7..d2a1ea997 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -1,9 +1,9 @@ Data, Config, Method, Total compressed size -silesia.tar, level -5, compress simple, 6738593 -silesia.tar, level -3, compress simple, 6446372 -silesia.tar, level -1, compress simple, 6186042 +silesia.tar, level -5, compress simple, 7359401 +silesia.tar, level -3, compress simple, 6901672 +silesia.tar, level -1, compress simple, 6182241 silesia.tar, level 0, compress simple, 4861423 -silesia.tar, level 1, compress simple, 5334885 +silesia.tar, level 1, compress simple, 5331946 silesia.tar, level 3, compress simple, 4861423 silesia.tar, level 4, compress simple, 4799632 silesia.tar, level 5, compress simple, 4650202 @@ -15,12 +15,12 @@ silesia.tar, level 16, compress silesia.tar, level 19, compress simple, 4264388 silesia.tar, uncompressed literals, compress simple, 4861423 silesia.tar, uncompressed literals optimal, compress simple, 4264388 -silesia.tar, huffman literals, compress simple, 6186042 -github.tar, level -5, compress simple, 46856 -github.tar, level -3, compress simple, 43754 -github.tar, level -1, compress simple, 42490 +silesia.tar, huffman literals, compress simple, 6182241 +github.tar, level -5, compress simple, 66914 +github.tar, level -3, compress simple, 52127 +github.tar, level -1, compress simple, 42560 github.tar, level 0, compress simple, 38441 -github.tar, level 1, compress simple, 39265 +github.tar, level 1, compress simple, 39200 github.tar, level 3, compress simple, 38441 github.tar, level 4, compress simple, 38467 github.tar, level 5, compress simple, 38376 @@ -32,12 +32,12 @@ github.tar, level 16, compress github.tar, level 19, compress simple, 32837 github.tar, uncompressed literals, compress simple, 38441 github.tar, uncompressed literals optimal, compress simple, 32837 -github.tar, huffman literals, compress simple, 42490 -silesia, level -5, compress cctx, 6737607 -silesia, level -3, compress cctx, 6444677 -silesia, level -1, compress cctx, 6178460 +github.tar, huffman literals, compress simple, 42560 +silesia, level -5, compress cctx, 7354675 +silesia, level -3, compress cctx, 6902374 +silesia, level -1, compress cctx, 6177565 silesia, level 0, compress cctx, 4849551 -silesia, level 1, compress cctx, 5313202 +silesia, level 1, compress cctx, 5309097 silesia, level 3, compress cctx, 4849551 silesia, level 4, compress cctx, 4786969 silesia, level 5, compress cctx, 4638960 @@ -56,17 +56,17 @@ silesia, small chain log, compress silesia, explicit params, compress cctx, 4794480 silesia, uncompressed literals, compress cctx, 4849551 silesia, uncompressed literals optimal, compress cctx, 4283236 -silesia, huffman literals, compress cctx, 6178460 +silesia, huffman literals, compress cctx, 6177565 silesia, multithreaded with advanced params, compress cctx, 4849551 -github, level -5, compress cctx, 205285 +github, level -5, compress cctx, 232315 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 190643 +github, level -3, compress cctx, 220760 github, level -3 with dict, compress cctx, 48047 -github, level -1, compress cctx, 175568 +github, level -1, compress cctx, 175468 github, level -1 with dict, compress cctx, 43527 github, level 0, compress cctx, 136335 github, level 0 with dict, compress cctx, 41534 -github, level 1, compress cctx, 142465 +github, level 1, compress cctx, 142365 github, level 1 with dict, compress cctx, 42157 github, level 3, compress cctx, 136335 github, level 3 with dict, compress cctx, 41534 @@ -95,13 +95,13 @@ github, small chain log, compress github, explicit params, compress cctx, 140932 github, uncompressed literals, compress cctx, 136335 github, uncompressed literals optimal, compress cctx, 134064 -github, huffman literals, compress cctx, 175568 +github, huffman literals, compress cctx, 175468 github, multithreaded with advanced params, compress cctx, 141102 -silesia, level -5, zstdcli, 6737655 -silesia, level -3, zstdcli, 6444725 -silesia, level -1, zstdcli, 6178508 +silesia, level -5, zstdcli, 7354723 +silesia, level -3, zstdcli, 6902422 +silesia, level -1, zstdcli, 6177613 silesia, level 0, zstdcli, 4849599 -silesia, level 1, zstdcli, 5313250 +silesia, level 1, zstdcli, 5309145 silesia, level 3, zstdcli, 4849599 silesia, level 4, zstdcli, 4787017 silesia, level 5, zstdcli, 4639008 @@ -120,13 +120,13 @@ silesia, small chain log, zstdcli, silesia, explicit params, zstdcli, 4795856 silesia, uncompressed literals, zstdcli, 5128030 silesia, uncompressed literals optimal, zstdcli, 4317944 -silesia, huffman literals, zstdcli, 5326317 +silesia, huffman literals, zstdcli, 5326394 silesia, multithreaded with advanced params, zstdcli, 5128030 -silesia.tar, level -5, zstdcli, 6738934 -silesia.tar, level -3, zstdcli, 6448419 -silesia.tar, level -1, zstdcli, 6186912 +silesia.tar, level -5, zstdcli, 7363866 +silesia.tar, level -3, zstdcli, 6902158 +silesia.tar, level -1, zstdcli, 6182939 silesia.tar, level 0, zstdcli, 4861511 -silesia.tar, level 1, zstdcli, 5336318 +silesia.tar, level 1, zstdcli, 5333184 silesia.tar, level 3, zstdcli, 4861511 silesia.tar, level 4, zstdcli, 4800529 silesia.tar, level 5, zstdcli, 4651159 @@ -146,17 +146,17 @@ silesia.tar, small chain log, zstdcli, silesia.tar, explicit params, zstdcli, 4821277 silesia.tar, uncompressed literals, zstdcli, 5129559 silesia.tar, uncompressed literals optimal, zstdcli, 4307404 -silesia.tar, huffman literals, zstdcli, 5347610 +silesia.tar, huffman literals, zstdcli, 5344915 silesia.tar, multithreaded with advanced params, zstdcli, 5129559 -github, level -5, zstdcli, 207285 +github, level -5, zstdcli, 234315 github, level -5 with dict, zstdcli, 48718 -github, level -3, zstdcli, 192643 +github, level -3, zstdcli, 222760 github, level -3 with dict, zstdcli, 47395 -github, level -1, zstdcli, 177568 +github, level -1, zstdcli, 177468 github, level -1 with dict, zstdcli, 45170 github, level 0, zstdcli, 138335 github, level 0 with dict, zstdcli, 43148 -github, level 1, zstdcli, 144465 +github, level 1, zstdcli, 144365 github, level 1 with dict, zstdcli, 43682 github, level 3, zstdcli, 138335 github, level 3 with dict, zstdcli, 43148 @@ -185,18 +185,18 @@ github, small chain log, zstdcli, github, explicit params, zstdcli, 136197 github, uncompressed literals, zstdcli, 167915 github, uncompressed literals optimal, zstdcli, 159227 -github, huffman literals, zstdcli, 144465 +github, huffman literals, zstdcli, 144365 github, multithreaded with advanced params, zstdcli, 167915 -github.tar, level -5, zstdcli, 46860 -github.tar, level -5 with dict, zstdcli, 44575 -github.tar, level -3, zstdcli, 43758 -github.tar, level -3 with dict, zstdcli, 41451 -github.tar, level -1, zstdcli, 42494 -github.tar, level -1 with dict, zstdcli, 41135 +github.tar, level -5, zstdcli, 66918 +github.tar, level -5 with dict, zstdcli, 51529 +github.tar, level -3, zstdcli, 52131 +github.tar, level -3 with dict, zstdcli, 44246 +github.tar, level -1, zstdcli, 42564 +github.tar, level -1 with dict, zstdcli, 41140 github.tar, level 0, zstdcli, 38445 github.tar, level 0 with dict, zstdcli, 37999 -github.tar, level 1, zstdcli, 39269 -github.tar, level 1 with dict, zstdcli, 38284 +github.tar, level 1, zstdcli, 39204 +github.tar, level 1 with dict, zstdcli, 38288 github.tar, level 3, zstdcli, 38445 github.tar, level 3 with dict, zstdcli, 37999 github.tar, level 4, zstdcli, 38471 @@ -226,13 +226,13 @@ github.tar, small chain log, zstdcli, github.tar, explicit params, zstdcli, 41227 github.tar, uncompressed literals, zstdcli, 41126 github.tar, uncompressed literals optimal, zstdcli, 35392 -github.tar, huffman literals, zstdcli, 38781 +github.tar, huffman literals, zstdcli, 38857 github.tar, multithreaded with advanced params, zstdcli, 41126 -silesia, level -5, advanced one pass, 6737607 -silesia, level -3, advanced one pass, 6444677 -silesia, level -1, advanced one pass, 6178460 +silesia, level -5, advanced one pass, 7354675 +silesia, level -3, advanced one pass, 6902374 +silesia, level -1, advanced one pass, 6177565 silesia, level 0, advanced one pass, 4849551 -silesia, level 1, advanced one pass, 5313202 +silesia, level 1, advanced one pass, 5309097 silesia, level 3, advanced one pass, 4849551 silesia, level 4, advanced one pass, 4786969 silesia, level 5 row 1, advanced one pass, 4640753 @@ -260,13 +260,13 @@ silesia, small chain log, advanced silesia, explicit params, advanced one pass, 4795856 silesia, uncompressed literals, advanced one pass, 5127982 silesia, uncompressed literals optimal, advanced one pass, 4317896 -silesia, huffman literals, advanced one pass, 5326269 +silesia, huffman literals, advanced one pass, 5326346 silesia, multithreaded with advanced params, advanced one pass, 5127982 -silesia.tar, level -5, advanced one pass, 6738593 -silesia.tar, level -3, advanced one pass, 6446372 -silesia.tar, level -1, advanced one pass, 6186042 +silesia.tar, level -5, advanced one pass, 7359401 +silesia.tar, level -3, advanced one pass, 6901672 +silesia.tar, level -1, advanced one pass, 6182241 silesia.tar, level 0, advanced one pass, 4861423 -silesia.tar, level 1, advanced one pass, 5334885 +silesia.tar, level 1, advanced one pass, 5331946 silesia.tar, level 3, advanced one pass, 4861423 silesia.tar, level 4, advanced one pass, 4799632 silesia.tar, level 5 row 1, advanced one pass, 4652862 @@ -294,13 +294,13 @@ silesia.tar, small chain log, advanced silesia.tar, explicit params, advanced one pass, 4807383 silesia.tar, uncompressed literals, advanced one pass, 5129458 silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 -silesia.tar, huffman literals, advanced one pass, 5347335 +silesia.tar, huffman literals, advanced one pass, 5344545 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 -github, level -5, advanced one pass, 205285 +github, level -5, advanced one pass, 232315 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 190643 +github, level -3, advanced one pass, 220760 github, level -3 with dict, advanced one pass, 45395 -github, level -1, advanced one pass, 175568 +github, level -1, advanced one pass, 175468 github, level -1 with dict, advanced one pass, 43170 github, level 0, advanced one pass, 136335 github, level 0 with dict, advanced one pass, 41148 @@ -308,7 +308,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced one pass, 41148 github, level 0 with dict copy, advanced one pass, 41124 github, level 0 with dict load, advanced one pass, 42252 -github, level 1, advanced one pass, 142465 +github, level 1, advanced one pass, 142365 github, level 1 with dict, advanced one pass, 41682 github, level 1 with dict dms, advanced one pass, 41682 github, level 1 with dict dds, advanced one pass, 41682 @@ -419,26 +419,26 @@ github, small chain log, advanced github, explicit params, advanced one pass, 137727 github, uncompressed literals, advanced one pass, 165915 github, uncompressed literals optimal, advanced one pass, 157227 -github, huffman literals, advanced one pass, 142465 +github, huffman literals, advanced one pass, 142365 github, multithreaded with advanced params, advanced one pass, 165915 -github.tar, level -5, advanced one pass, 46856 -github.tar, level -5 with dict, advanced one pass, 44571 -github.tar, level -3, advanced one pass, 43754 -github.tar, level -3 with dict, advanced one pass, 41447 -github.tar, level -1, advanced one pass, 42490 -github.tar, level -1 with dict, advanced one pass, 41131 +github.tar, level -5, advanced one pass, 66914 +github.tar, level -5 with dict, advanced one pass, 51525 +github.tar, level -3, advanced one pass, 52127 +github.tar, level -3 with dict, advanced one pass, 44242 +github.tar, level -1, advanced one pass, 42560 +github.tar, level -1 with dict, advanced one pass, 41136 github.tar, level 0, advanced one pass, 38441 github.tar, level 0 with dict, advanced one pass, 37995 github.tar, level 0 with dict dms, advanced one pass, 38003 github.tar, level 0 with dict dds, advanced one pass, 38003 github.tar, level 0 with dict copy, advanced one pass, 37995 github.tar, level 0 with dict load, advanced one pass, 37956 -github.tar, level 1, advanced one pass, 39265 -github.tar, level 1 with dict, advanced one pass, 38280 -github.tar, level 1 with dict dms, advanced one pass, 38290 -github.tar, level 1 with dict dds, advanced one pass, 38290 -github.tar, level 1 with dict copy, advanced one pass, 38280 -github.tar, level 1 with dict load, advanced one pass, 38729 +github.tar, level 1, advanced one pass, 39200 +github.tar, level 1 with dict, advanced one pass, 38284 +github.tar, level 1 with dict dms, advanced one pass, 38294 +github.tar, level 1 with dict dds, advanced one pass, 38294 +github.tar, level 1 with dict copy, advanced one pass, 38284 +github.tar, level 1 with dict load, advanced one pass, 38724 github.tar, level 3, advanced one pass, 38441 github.tar, level 3 with dict, advanced one pass, 37995 github.tar, level 3 with dict dms, advanced one pass, 38003 @@ -544,13 +544,13 @@ github.tar, small chain log, advanced github.tar, explicit params, advanced one pass, 41227 github.tar, uncompressed literals, advanced one pass, 41122 github.tar, uncompressed literals optimal, advanced one pass, 35388 -github.tar, huffman literals, advanced one pass, 38777 +github.tar, huffman literals, advanced one pass, 38853 github.tar, multithreaded with advanced params, advanced one pass, 41122 -silesia, level -5, advanced one pass small out, 6737607 -silesia, level -3, advanced one pass small out, 6444677 -silesia, level -1, advanced one pass small out, 6178460 +silesia, level -5, advanced one pass small out, 7354675 +silesia, level -3, advanced one pass small out, 6902374 +silesia, level -1, advanced one pass small out, 6177565 silesia, level 0, advanced one pass small out, 4849551 -silesia, level 1, advanced one pass small out, 5313202 +silesia, level 1, advanced one pass small out, 5309097 silesia, level 3, advanced one pass small out, 4849551 silesia, level 4, advanced one pass small out, 4786969 silesia, level 5 row 1, advanced one pass small out, 4640753 @@ -578,13 +578,13 @@ silesia, small chain log, advanced silesia, explicit params, advanced one pass small out, 4795856 silesia, uncompressed literals, advanced one pass small out, 5127982 silesia, uncompressed literals optimal, advanced one pass small out, 4317896 -silesia, huffman literals, advanced one pass small out, 5326269 +silesia, huffman literals, advanced one pass small out, 5326346 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 -silesia.tar, level -5, advanced one pass small out, 6738593 -silesia.tar, level -3, advanced one pass small out, 6446372 -silesia.tar, level -1, advanced one pass small out, 6186042 +silesia.tar, level -5, advanced one pass small out, 7359401 +silesia.tar, level -3, advanced one pass small out, 6901672 +silesia.tar, level -1, advanced one pass small out, 6182241 silesia.tar, level 0, advanced one pass small out, 4861423 -silesia.tar, level 1, advanced one pass small out, 5334885 +silesia.tar, level 1, advanced one pass small out, 5331946 silesia.tar, level 3, advanced one pass small out, 4861423 silesia.tar, level 4, advanced one pass small out, 4799632 silesia.tar, level 5 row 1, advanced one pass small out, 4652862 @@ -612,13 +612,13 @@ silesia.tar, small chain log, advanced silesia.tar, explicit params, advanced one pass small out, 4807383 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 -silesia.tar, huffman literals, advanced one pass small out, 5347335 +silesia.tar, huffman literals, advanced one pass small out, 5344545 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 -github, level -5, advanced one pass small out, 205285 +github, level -5, advanced one pass small out, 232315 github, level -5 with dict, advanced one pass small out, 46718 -github, level -3, advanced one pass small out, 190643 +github, level -3, advanced one pass small out, 220760 github, level -3 with dict, advanced one pass small out, 45395 -github, level -1, advanced one pass small out, 175568 +github, level -1, advanced one pass small out, 175468 github, level -1 with dict, advanced one pass small out, 43170 github, level 0, advanced one pass small out, 136335 github, level 0 with dict, advanced one pass small out, 41148 @@ -626,7 +626,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced one pass small out, 41148 github, level 0 with dict copy, advanced one pass small out, 41124 github, level 0 with dict load, advanced one pass small out, 42252 -github, level 1, advanced one pass small out, 142465 +github, level 1, advanced one pass small out, 142365 github, level 1 with dict, advanced one pass small out, 41682 github, level 1 with dict dms, advanced one pass small out, 41682 github, level 1 with dict dds, advanced one pass small out, 41682 @@ -737,26 +737,26 @@ github, small chain log, advanced github, explicit params, advanced one pass small out, 137727 github, uncompressed literals, advanced one pass small out, 165915 github, uncompressed literals optimal, advanced one pass small out, 157227 -github, huffman literals, advanced one pass small out, 142465 +github, huffman literals, advanced one pass small out, 142365 github, multithreaded with advanced params, advanced one pass small out, 165915 -github.tar, level -5, advanced one pass small out, 46856 -github.tar, level -5 with dict, advanced one pass small out, 44571 -github.tar, level -3, advanced one pass small out, 43754 -github.tar, level -3 with dict, advanced one pass small out, 41447 -github.tar, level -1, advanced one pass small out, 42490 -github.tar, level -1 with dict, advanced one pass small out, 41131 +github.tar, level -5, advanced one pass small out, 66914 +github.tar, level -5 with dict, advanced one pass small out, 51525 +github.tar, level -3, advanced one pass small out, 52127 +github.tar, level -3 with dict, advanced one pass small out, 44242 +github.tar, level -1, advanced one pass small out, 42560 +github.tar, level -1 with dict, advanced one pass small out, 41136 github.tar, level 0, advanced one pass small out, 38441 github.tar, level 0 with dict, advanced one pass small out, 37995 github.tar, level 0 with dict dms, advanced one pass small out, 38003 github.tar, level 0 with dict dds, advanced one pass small out, 38003 github.tar, level 0 with dict copy, advanced one pass small out, 37995 github.tar, level 0 with dict load, advanced one pass small out, 37956 -github.tar, level 1, advanced one pass small out, 39265 -github.tar, level 1 with dict, advanced one pass small out, 38280 -github.tar, level 1 with dict dms, advanced one pass small out, 38290 -github.tar, level 1 with dict dds, advanced one pass small out, 38290 -github.tar, level 1 with dict copy, advanced one pass small out, 38280 -github.tar, level 1 with dict load, advanced one pass small out, 38729 +github.tar, level 1, advanced one pass small out, 39200 +github.tar, level 1 with dict, advanced one pass small out, 38284 +github.tar, level 1 with dict dms, advanced one pass small out, 38294 +github.tar, level 1 with dict dds, advanced one pass small out, 38294 +github.tar, level 1 with dict copy, advanced one pass small out, 38284 +github.tar, level 1 with dict load, advanced one pass small out, 38724 github.tar, level 3, advanced one pass small out, 38441 github.tar, level 3 with dict, advanced one pass small out, 37995 github.tar, level 3 with dict dms, advanced one pass small out, 38003 @@ -862,13 +862,13 @@ github.tar, small chain log, advanced github.tar, explicit params, advanced one pass small out, 41227 github.tar, uncompressed literals, advanced one pass small out, 41122 github.tar, uncompressed literals optimal, advanced one pass small out, 35388 -github.tar, huffman literals, advanced one pass small out, 38777 +github.tar, huffman literals, advanced one pass small out, 38853 github.tar, multithreaded with advanced params, advanced one pass small out, 41122 -silesia, level -5, advanced streaming, 6882505 -silesia, level -3, advanced streaming, 6568376 -silesia, level -1, advanced streaming, 6183403 +silesia, level -5, advanced streaming, 7292053 +silesia, level -3, advanced streaming, 6867875 +silesia, level -1, advanced streaming, 6183923 silesia, level 0, advanced streaming, 4849551 -silesia, level 1, advanced streaming, 5314161 +silesia, level 1, advanced streaming, 5312694 silesia, level 3, advanced streaming, 4849551 silesia, level 4, advanced streaming, 4786969 silesia, level 5 row 1, advanced streaming, 4640753 @@ -896,13 +896,13 @@ silesia, small chain log, advanced silesia, explicit params, advanced streaming, 4795884 silesia, uncompressed literals, advanced streaming, 5127982 silesia, uncompressed literals optimal, advanced streaming, 4317896 -silesia, huffman literals, advanced streaming, 5331171 +silesia, huffman literals, advanced streaming, 5332234 silesia, multithreaded with advanced params, advanced streaming, 5127982 -silesia.tar, level -5, advanced streaming, 6982759 -silesia.tar, level -3, advanced streaming, 6641283 -silesia.tar, level -1, advanced streaming, 6190795 +silesia.tar, level -5, advanced streaming, 7260007 +silesia.tar, level -3, advanced streaming, 6845151 +silesia.tar, level -1, advanced streaming, 6187938 silesia.tar, level 0, advanced streaming, 4861425 -silesia.tar, level 1, advanced streaming, 5336941 +silesia.tar, level 1, advanced streaming, 5334890 silesia.tar, level 3, advanced streaming, 4861425 silesia.tar, level 4, advanced streaming, 4799632 silesia.tar, level 5 row 1, advanced streaming, 4652866 @@ -930,13 +930,13 @@ silesia.tar, small chain log, advanced silesia.tar, explicit params, advanced streaming, 4807403 silesia.tar, uncompressed literals, advanced streaming, 5129461 silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 -silesia.tar, huffman literals, advanced streaming, 5352360 +silesia.tar, huffman literals, advanced streaming, 5350519 silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 -github, level -5, advanced streaming, 205285 +github, level -5, advanced streaming, 232315 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 190643 +github, level -3, advanced streaming, 220760 github, level -3 with dict, advanced streaming, 45395 -github, level -1, advanced streaming, 175568 +github, level -1, advanced streaming, 175468 github, level -1 with dict, advanced streaming, 43170 github, level 0, advanced streaming, 136335 github, level 0 with dict, advanced streaming, 41148 @@ -944,7 +944,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced streaming, 41148 github, level 0 with dict copy, advanced streaming, 41124 github, level 0 with dict load, advanced streaming, 42252 -github, level 1, advanced streaming, 142465 +github, level 1, advanced streaming, 142365 github, level 1 with dict, advanced streaming, 41682 github, level 1 with dict dms, advanced streaming, 41682 github, level 1 with dict dds, advanced streaming, 41682 @@ -1055,26 +1055,26 @@ github, small chain log, advanced github, explicit params, advanced streaming, 137727 github, uncompressed literals, advanced streaming, 165915 github, uncompressed literals optimal, advanced streaming, 157227 -github, huffman literals, advanced streaming, 142465 +github, huffman literals, advanced streaming, 142365 github, multithreaded with advanced params, advanced streaming, 165915 -github.tar, level -5, advanced streaming, 46747 -github.tar, level -5 with dict, advanced streaming, 44440 -github.tar, level -3, advanced streaming, 43537 -github.tar, level -3 with dict, advanced streaming, 41112 -github.tar, level -1, advanced streaming, 42465 -github.tar, level -1 with dict, advanced streaming, 41196 +github.tar, level -5, advanced streaming, 64132 +github.tar, level -5 with dict, advanced streaming, 48642 +github.tar, level -3, advanced streaming, 50964 +github.tar, level -3 with dict, advanced streaming, 42750 +github.tar, level -1, advanced streaming, 42536 +github.tar, level -1 with dict, advanced streaming, 41198 github.tar, level 0, advanced streaming, 38441 github.tar, level 0 with dict, advanced streaming, 37995 github.tar, level 0 with dict dms, advanced streaming, 38003 github.tar, level 0 with dict dds, advanced streaming, 38003 github.tar, level 0 with dict copy, advanced streaming, 37995 github.tar, level 0 with dict load, advanced streaming, 37956 -github.tar, level 1, advanced streaming, 39342 -github.tar, level 1 with dict, advanced streaming, 38293 -github.tar, level 1 with dict dms, advanced streaming, 38303 -github.tar, level 1 with dict dds, advanced streaming, 38303 -github.tar, level 1 with dict copy, advanced streaming, 38293 -github.tar, level 1 with dict load, advanced streaming, 38766 +github.tar, level 1, advanced streaming, 39270 +github.tar, level 1 with dict, advanced streaming, 38316 +github.tar, level 1 with dict dms, advanced streaming, 38326 +github.tar, level 1 with dict dds, advanced streaming, 38326 +github.tar, level 1 with dict copy, advanced streaming, 38316 +github.tar, level 1 with dict load, advanced streaming, 38761 github.tar, level 3, advanced streaming, 38441 github.tar, level 3 with dict, advanced streaming, 37995 github.tar, level 3 with dict dms, advanced streaming, 38003 @@ -1180,13 +1180,13 @@ github.tar, small chain log, advanced github.tar, explicit params, advanced streaming, 41227 github.tar, uncompressed literals, advanced streaming, 41122 github.tar, uncompressed literals optimal, advanced streaming, 35388 -github.tar, huffman literals, advanced streaming, 38800 +github.tar, huffman literals, advanced streaming, 38874 github.tar, multithreaded with advanced params, advanced streaming, 41122 -silesia, level -5, old streaming, 6882505 -silesia, level -3, old streaming, 6568376 -silesia, level -1, old streaming, 6183403 +silesia, level -5, old streaming, 7292053 +silesia, level -3, old streaming, 6867875 +silesia, level -1, old streaming, 6183923 silesia, level 0, old streaming, 4849551 -silesia, level 1, old streaming, 5314161 +silesia, level 1, old streaming, 5312694 silesia, level 3, old streaming, 4849551 silesia, level 4, old streaming, 4786969 silesia, level 5, old streaming, 4638960 @@ -1199,12 +1199,12 @@ silesia, level 19, old stre silesia, no source size, old streaming, 4849515 silesia, uncompressed literals, old streaming, 4849551 silesia, uncompressed literals optimal, old streaming, 4283236 -silesia, huffman literals, old streaming, 6183403 -silesia.tar, level -5, old streaming, 6982759 -silesia.tar, level -3, old streaming, 6641283 -silesia.tar, level -1, old streaming, 6190795 +silesia, huffman literals, old streaming, 6183923 +silesia.tar, level -5, old streaming, 7260007 +silesia.tar, level -3, old streaming, 6845151 +silesia.tar, level -1, old streaming, 6187938 silesia.tar, level 0, old streaming, 4861425 -silesia.tar, level 1, old streaming, 5336941 +silesia.tar, level 1, old streaming, 5334890 silesia.tar, level 3, old streaming, 4861425 silesia.tar, level 4, old streaming, 4799632 silesia.tar, level 5, old streaming, 4650207 @@ -1217,16 +1217,16 @@ silesia.tar, level 19, old stre silesia.tar, no source size, old streaming, 4861421 silesia.tar, uncompressed literals, old streaming, 4861425 silesia.tar, uncompressed literals optimal, old streaming, 4264388 -silesia.tar, huffman literals, old streaming, 6190795 -github, level -5, old streaming, 205285 +silesia.tar, huffman literals, old streaming, 6187938 +github, level -5, old streaming, 232315 github, level -5 with dict, old streaming, 46718 -github, level -3, old streaming, 190643 +github, level -3, old streaming, 220760 github, level -3 with dict, old streaming, 45395 -github, level -1, old streaming, 175568 +github, level -1, old streaming, 175468 github, level -1 with dict, old streaming, 43170 github, level 0, old streaming, 136335 github, level 0 with dict, old streaming, 41148 -github, level 1, old streaming, 142465 +github, level 1, old streaming, 142365 github, level 1 with dict, old streaming, 41682 github, level 3, old streaming, 136335 github, level 3 with dict, old streaming, 41148 @@ -1250,17 +1250,17 @@ github, no source size, old stre github, no source size with dict, old streaming, 40654 github, uncompressed literals, old streaming, 136335 github, uncompressed literals optimal, old streaming, 134064 -github, huffman literals, old streaming, 175568 -github.tar, level -5, old streaming, 46747 -github.tar, level -5 with dict, old streaming, 44440 -github.tar, level -3, old streaming, 43537 -github.tar, level -3 with dict, old streaming, 41112 -github.tar, level -1, old streaming, 42465 -github.tar, level -1 with dict, old streaming, 41196 +github, huffman literals, old streaming, 175468 +github.tar, level -5, old streaming, 64132 +github.tar, level -5 with dict, old streaming, 48642 +github.tar, level -3, old streaming, 50964 +github.tar, level -3 with dict, old streaming, 42750 +github.tar, level -1, old streaming, 42536 +github.tar, level -1 with dict, old streaming, 41198 github.tar, level 0, old streaming, 38441 github.tar, level 0 with dict, old streaming, 37995 -github.tar, level 1, old streaming, 39342 -github.tar, level 1 with dict, old streaming, 38293 +github.tar, level 1, old streaming, 39270 +github.tar, level 1 with dict, old streaming, 38316 github.tar, level 3, old streaming, 38441 github.tar, level 3 with dict, old streaming, 37995 github.tar, level 4, old streaming, 38467 @@ -1283,12 +1283,12 @@ github.tar, no source size, old stre github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38441 github.tar, uncompressed literals optimal, old streaming, 32837 -github.tar, huffman literals, old streaming, 42465 -silesia, level -5, old streaming advanced, 6882505 -silesia, level -3, old streaming advanced, 6568376 -silesia, level -1, old streaming advanced, 6183403 +github.tar, huffman literals, old streaming, 42536 +silesia, level -5, old streaming advanced, 7292053 +silesia, level -3, old streaming advanced, 6867875 +silesia, level -1, old streaming advanced, 6183923 silesia, level 0, old streaming advanced, 4849551 -silesia, level 1, old streaming advanced, 5314161 +silesia, level 1, old streaming advanced, 5312694 silesia, level 3, old streaming advanced, 4849551 silesia, level 4, old streaming advanced, 4786969 silesia, level 5, old streaming advanced, 4638960 @@ -1308,13 +1308,13 @@ silesia, small chain log, old stre silesia, explicit params, old streaming advanced, 4795884 silesia, uncompressed literals, old streaming advanced, 4849551 silesia, uncompressed literals optimal, old streaming advanced, 4283236 -silesia, huffman literals, old streaming advanced, 6183403 +silesia, huffman literals, old streaming advanced, 6183923 silesia, multithreaded with advanced params, old streaming advanced, 4849551 -silesia.tar, level -5, old streaming advanced, 6982759 -silesia.tar, level -3, old streaming advanced, 6641283 -silesia.tar, level -1, old streaming advanced, 6190795 +silesia.tar, level -5, old streaming advanced, 7260007 +silesia.tar, level -3, old streaming advanced, 6845151 +silesia.tar, level -1, old streaming advanced, 6187938 silesia.tar, level 0, old streaming advanced, 4861425 -silesia.tar, level 1, old streaming advanced, 5336941 +silesia.tar, level 1, old streaming advanced, 5334890 silesia.tar, level 3, old streaming advanced, 4861425 silesia.tar, level 4, old streaming advanced, 4799632 silesia.tar, level 5, old streaming advanced, 4650207 @@ -1334,17 +1334,17 @@ silesia.tar, small chain log, old stre silesia.tar, explicit params, old streaming advanced, 4807403 silesia.tar, uncompressed literals, old streaming advanced, 4861425 silesia.tar, uncompressed literals optimal, old streaming advanced, 4264388 -silesia.tar, huffman literals, old streaming advanced, 6190795 +silesia.tar, huffman literals, old streaming advanced, 6187938 silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 -github, level -5, old streaming advanced, 216734 +github, level -5, old streaming advanced, 241214 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 192160 +github, level -3, old streaming advanced, 222937 github, level -3 with dict, old streaming advanced, 44956 -github, level -1, old streaming advanced, 181108 +github, level -1, old streaming advanced, 181107 github, level -1 with dict, old streaming advanced, 42383 github, level 0, old streaming advanced, 141104 github, level 0 with dict, old streaming advanced, 41113 -github, level 1, old streaming advanced, 143692 +github, level 1, old streaming advanced, 143693 github, level 1 with dict, old streaming advanced, 42430 github, level 3, old streaming advanced, 141104 github, level 3 with dict, old streaming advanced, 41113 @@ -1375,18 +1375,18 @@ github, small chain log, old stre github, explicit params, old streaming advanced, 140937 github, uncompressed literals, old streaming advanced, 141104 github, uncompressed literals optimal, old streaming advanced, 134064 -github, huffman literals, old streaming advanced, 181108 +github, huffman literals, old streaming advanced, 181107 github, multithreaded with advanced params, old streaming advanced, 141104 -github.tar, level -5, old streaming advanced, 46747 -github.tar, level -5 with dict, old streaming advanced, 44824 -github.tar, level -3, old streaming advanced, 43537 -github.tar, level -3 with dict, old streaming advanced, 41800 -github.tar, level -1, old streaming advanced, 42465 -github.tar, level -1 with dict, old streaming advanced, 41471 +github.tar, level -5, old streaming advanced, 64132 +github.tar, level -5 with dict, old streaming advanced, 48982 +github.tar, level -3, old streaming advanced, 50964 +github.tar, level -3 with dict, old streaming advanced, 43357 +github.tar, level -1, old streaming advanced, 42536 +github.tar, level -1 with dict, old streaming advanced, 41494 github.tar, level 0, old streaming advanced, 38441 github.tar, level 0 with dict, old streaming advanced, 38013 -github.tar, level 1, old streaming advanced, 39342 -github.tar, level 1 with dict, old streaming advanced, 38940 +github.tar, level 1, old streaming advanced, 39270 +github.tar, level 1 with dict, old streaming advanced, 38934 github.tar, level 3, old streaming advanced, 38441 github.tar, level 3 with dict, old streaming advanced, 38013 github.tar, level 4, old streaming advanced, 38467 @@ -1416,7 +1416,7 @@ github.tar, small chain log, old stre github.tar, explicit params, old streaming advanced, 41227 github.tar, uncompressed literals, old streaming advanced, 38441 github.tar, uncompressed literals optimal, old streaming advanced, 32837 -github.tar, huffman literals, old streaming advanced, 42465 +github.tar, huffman literals, old streaming advanced, 42536 github.tar, multithreaded with advanced params, old streaming advanced, 38441 github, level -5 with dict, old streaming cdict, 46718 github, level -3 with dict, old streaming cdict, 45395 @@ -1433,11 +1433,11 @@ github, level 13 with dict, old stre github, level 16 with dict, old streaming cdict, 37577 github, level 19 with dict, old streaming cdict, 37576 github, no source size with dict, old streaming cdict, 40654 -github.tar, level -5 with dict, old streaming cdict, 45018 -github.tar, level -3 with dict, old streaming cdict, 41886 -github.tar, level -1 with dict, old streaming cdict, 41636 +github.tar, level -5 with dict, old streaming cdict, 49146 +github.tar, level -3 with dict, old streaming cdict, 43468 +github.tar, level -1 with dict, old streaming cdict, 41662 github.tar, level 0 with dict, old streaming cdict, 37956 -github.tar, level 1 with dict, old streaming cdict, 38766 +github.tar, level 1 with dict, old streaming cdict, 38761 github.tar, level 3 with dict, old streaming cdict, 37956 github.tar, level 4 with dict, old streaming cdict, 37927 github.tar, level 5 with dict, old streaming cdict, 37600 From 414e24becfa2f5127bd6583216755d8d9149a6ed Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 1 Sep 2021 12:25:20 -0400 Subject: [PATCH 134/274] Add 8 bytes to FSE workspace --- lib/common/fse.h | 3 ++- lib/compress/fse_compress.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/common/fse.h b/lib/common/fse.h index df8280ccd..714bfd3e7 100644 --- a/lib/common/fse.h +++ b/lib/common/fse.h @@ -336,8 +336,9 @@ size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); /* FSE_buildCTable_wksp() : * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`. + * See FSE_buildCTable_wksp() for breakdown of workspace usage. */ -#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2) +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */) #define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)) size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index 16948245e..faca767c5 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -116,7 +116,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, /* Case for no low prob count symbols. Lay down 8 bytes at a time * to reduce branch misses since we are operating on a small block */ - BYTE* const spread = tableSymbol + tableSize; /* size = tableSize */ + BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */ { U64 const add = 0x0101010101010101ull; size_t pos = 0; U64 sv = 0; From 70d89e5a128c73f81d362332f4b6b1b2b8764f15 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Sep 2021 13:02:07 -0700 Subject: [PATCH 135/274] minor rebalancing of level 13 This new setup is slighly better on `silesia.tar` : Ratio : 3.649 -> 3.655 Speed : 11.9 MB/s -> 12.2 MB/s At the cost of more memory : 24 MB -> 32 MB The new memory budget is a reasonable interpolation between neighboring levels 12 and 14: level 12 : 24 MB level 13 : 32 MB (increased from 24 MB) level 14 : 48 MB Window size remains unaffected (4 MB) --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 2f02d512c..e68f7352a 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -6207,7 +6207,7 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 22, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 11 */ { 22, 21, 22, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ - { 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 13 */ + { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */ From 40e44bd56d2aab4c97c23d894bb666a4fcb43d5f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Sep 2021 13:26:39 -0700 Subject: [PATCH 136/274] updated regression tests --- tests/regression/results.csv | 58 ++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index bcecafae7..f120e5f2c 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -10,7 +10,7 @@ silesia.tar, level 5, compress silesia.tar, level 6, compress simple, 4616811 silesia.tar, level 7, compress simple, 4576828 silesia.tar, level 9, compress simple, 4552584 -silesia.tar, level 13, compress simple, 4491768 +silesia.tar, level 13, compress simple, 4502955 silesia.tar, level 16, compress simple, 4356834 silesia.tar, level 19, compress simple, 4264388 silesia.tar, uncompressed literals, compress simple, 4861423 @@ -27,7 +27,7 @@ github.tar, level 5, compress github.tar, level 6, compress simple, 38610 github.tar, level 7, compress simple, 38073 github.tar, level 9, compress simple, 36767 -github.tar, level 13, compress simple, 35621 +github.tar, level 13, compress simple, 35501 github.tar, level 16, compress simple, 40255 github.tar, level 19, compress simple, 32837 github.tar, uncompressed literals, compress simple, 38441 @@ -44,7 +44,7 @@ silesia, level 5, compress silesia, level 6, compress cctx, 4605369 silesia, level 7, compress cctx, 4567203 silesia, level 9, compress cctx, 4543311 -silesia, level 13, compress cctx, 4482131 +silesia, level 13, compress cctx, 4493990 silesia, level 16, compress cctx, 4360251 silesia, level 19, compress cctx, 4283236 silesia, long distance mode, compress cctx, 4849551 @@ -108,7 +108,7 @@ silesia, level 5, zstdcli, silesia, level 6, zstdcli, 4605417 silesia, level 7, zstdcli, 4567251 silesia, level 9, zstdcli, 4543359 -silesia, level 13, zstdcli, 4482179 +silesia, level 13, zstdcli, 4494038 silesia, level 16, zstdcli, 4360299 silesia, level 19, zstdcli, 4283284 silesia, long distance mode, zstdcli, 4840807 @@ -133,7 +133,7 @@ silesia.tar, level 5, zstdcli, silesia.tar, level 6, zstdcli, 4618402 silesia.tar, level 7, zstdcli, 4578883 silesia.tar, level 9, zstdcli, 4553498 -silesia.tar, level 13, zstdcli, 4491772 +silesia.tar, level 13, zstdcli, 4502959 silesia.tar, level 16, zstdcli, 4356838 silesia.tar, level 19, zstdcli, 4264392 silesia.tar, no source size, zstdcli, 4861507 @@ -209,7 +209,7 @@ github.tar, level 7, zstdcli, github.tar, level 7 with dict, zstdcli, 37873 github.tar, level 9, zstdcli, 36771 github.tar, level 9 with dict, zstdcli, 36623 -github.tar, level 13, zstdcli, 35625 +github.tar, level 13, zstdcli, 35505 github.tar, level 13 with dict, zstdcli, 38730 github.tar, level 16, zstdcli, 40259 github.tar, level 16 with dict, zstdcli, 33643 @@ -247,7 +247,7 @@ silesia, level 11 row 1, advanced silesia, level 11 row 2, advanced one pass, 4521406 silesia, level 12 row 1, advanced one pass, 4503117 silesia, level 12 row 2, advanced one pass, 4505152 -silesia, level 13, advanced one pass, 4482131 +silesia, level 13, advanced one pass, 4493990 silesia, level 16, advanced one pass, 4360251 silesia, level 19, advanced one pass, 4283236 silesia, no source size, advanced one pass, 4849551 @@ -281,7 +281,7 @@ silesia.tar, level 11 row 1, advanced silesia.tar, level 11 row 2, advanced one pass, 4530257 silesia.tar, level 12 row 1, advanced one pass, 4513603 silesia.tar, level 12 row 2, advanced one pass, 4514568 -silesia.tar, level 13, advanced one pass, 4491768 +silesia.tar, level 13, advanced one pass, 4502955 silesia.tar, level 16, advanced one pass, 4356834 silesia.tar, level 19, advanced one pass, 4264388 silesia.tar, no source size, advanced one pass, 4861423 @@ -515,12 +515,12 @@ github.tar, level 12 row 2 with dict dms, advanced github.tar, level 12 row 2 with dict dds, advanced one pass, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 github.tar, level 12 row 2 with dict load, advanced one pass, 36460 -github.tar, level 13, advanced one pass, 35621 +github.tar, level 13, advanced one pass, 35501 github.tar, level 13 with dict, advanced one pass, 38726 github.tar, level 13 with dict dms, advanced one pass, 38903 github.tar, level 13 with dict dds, advanced one pass, 38903 github.tar, level 13 with dict copy, advanced one pass, 38726 -github.tar, level 13 with dict load, advanced one pass, 36372 +github.tar, level 13 with dict load, advanced one pass, 36010 github.tar, level 16, advanced one pass, 40255 github.tar, level 16 with dict, advanced one pass, 33639 github.tar, level 16 with dict dms, advanced one pass, 33544 @@ -565,7 +565,7 @@ silesia, level 11 row 1, advanced silesia, level 11 row 2, advanced one pass small out, 4521406 silesia, level 12 row 1, advanced one pass small out, 4503117 silesia, level 12 row 2, advanced one pass small out, 4505152 -silesia, level 13, advanced one pass small out, 4482131 +silesia, level 13, advanced one pass small out, 4493990 silesia, level 16, advanced one pass small out, 4360251 silesia, level 19, advanced one pass small out, 4283236 silesia, no source size, advanced one pass small out, 4849551 @@ -599,7 +599,7 @@ silesia.tar, level 11 row 1, advanced silesia.tar, level 11 row 2, advanced one pass small out, 4530257 silesia.tar, level 12 row 1, advanced one pass small out, 4513603 silesia.tar, level 12 row 2, advanced one pass small out, 4514568 -silesia.tar, level 13, advanced one pass small out, 4491768 +silesia.tar, level 13, advanced one pass small out, 4502955 silesia.tar, level 16, advanced one pass small out, 4356834 silesia.tar, level 19, advanced one pass small out, 4264388 silesia.tar, no source size, advanced one pass small out, 4861423 @@ -833,12 +833,12 @@ github.tar, level 12 row 2 with dict dms, advanced github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 github.tar, level 12 row 2 with dict load, advanced one pass small out, 36460 -github.tar, level 13, advanced one pass small out, 35621 +github.tar, level 13, advanced one pass small out, 35501 github.tar, level 13 with dict, advanced one pass small out, 38726 github.tar, level 13 with dict dms, advanced one pass small out, 38903 github.tar, level 13 with dict dds, advanced one pass small out, 38903 github.tar, level 13 with dict copy, advanced one pass small out, 38726 -github.tar, level 13 with dict load, advanced one pass small out, 36372 +github.tar, level 13 with dict load, advanced one pass small out, 36010 github.tar, level 16, advanced one pass small out, 40255 github.tar, level 16 with dict, advanced one pass small out, 33639 github.tar, level 16 with dict dms, advanced one pass small out, 33544 @@ -883,7 +883,7 @@ silesia, level 11 row 1, advanced silesia, level 11 row 2, advanced streaming, 4521406 silesia, level 12 row 1, advanced streaming, 4503117 silesia, level 12 row 2, advanced streaming, 4505152 -silesia, level 13, advanced streaming, 4482131 +silesia, level 13, advanced streaming, 4493990 silesia, level 16, advanced streaming, 4360251 silesia, level 19, advanced streaming, 4283236 silesia, no source size, advanced streaming, 4849515 @@ -917,7 +917,7 @@ silesia.tar, level 11 row 1, advanced silesia.tar, level 11 row 2, advanced streaming, 4530259 silesia.tar, level 12 row 1, advanced streaming, 4513603 silesia.tar, level 12 row 2, advanced streaming, 4514569 -silesia.tar, level 13, advanced streaming, 4491769 +silesia.tar, level 13, advanced streaming, 4502955 silesia.tar, level 16, advanced streaming, 4356834 silesia.tar, level 19, advanced streaming, 4264388 silesia.tar, no source size, advanced streaming, 4861421 @@ -1151,12 +1151,12 @@ github.tar, level 12 row 2 with dict dms, advanced github.tar, level 12 row 2 with dict dds, advanced streaming, 36986 github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 github.tar, level 12 row 2 with dict load, advanced streaming, 36460 -github.tar, level 13, advanced streaming, 35621 +github.tar, level 13, advanced streaming, 35501 github.tar, level 13 with dict, advanced streaming, 38726 github.tar, level 13 with dict dms, advanced streaming, 38903 github.tar, level 13 with dict dds, advanced streaming, 38903 github.tar, level 13 with dict copy, advanced streaming, 38726 -github.tar, level 13 with dict load, advanced streaming, 36372 +github.tar, level 13 with dict load, advanced streaming, 36010 github.tar, level 16, advanced streaming, 40255 github.tar, level 16 with dict, advanced streaming, 33639 github.tar, level 16 with dict dms, advanced streaming, 33544 @@ -1193,7 +1193,7 @@ silesia, level 5, old stre silesia, level 6, old streaming, 4605369 silesia, level 7, old streaming, 4567203 silesia, level 9, old streaming, 4543311 -silesia, level 13, old streaming, 4482131 +silesia, level 13, old streaming, 4493990 silesia, level 16, old streaming, 4360251 silesia, level 19, old streaming, 4283236 silesia, no source size, old streaming, 4849515 @@ -1211,7 +1211,7 @@ silesia.tar, level 5, old stre silesia.tar, level 6, old streaming, 4616816 silesia.tar, level 7, old streaming, 4576830 silesia.tar, level 9, old streaming, 4552590 -silesia.tar, level 13, old streaming, 4491769 +silesia.tar, level 13, old streaming, 4502955 silesia.tar, level 16, old streaming, 4356834 silesia.tar, level 19, old streaming, 4264388 silesia.tar, no source size, old streaming, 4861421 @@ -1273,7 +1273,7 @@ github.tar, level 7, old stre github.tar, level 7 with dict, old streaming, 37848 github.tar, level 9, old streaming, 36767 github.tar, level 9 with dict, old streaming, 36457 -github.tar, level 13, old streaming, 35621 +github.tar, level 13, old streaming, 35501 github.tar, level 13 with dict, old streaming, 38726 github.tar, level 16, old streaming, 40255 github.tar, level 16 with dict, old streaming, 33639 @@ -1295,7 +1295,7 @@ silesia, level 5, old stre silesia, level 6, old streaming advanced, 4605369 silesia, level 7, old streaming advanced, 4567203 silesia, level 9, old streaming advanced, 4543311 -silesia, level 13, old streaming advanced, 4482131 +silesia, level 13, old streaming advanced, 4493990 silesia, level 16, old streaming advanced, 4360251 silesia, level 19, old streaming advanced, 4283236 silesia, no source size, old streaming advanced, 4849515 @@ -1321,7 +1321,7 @@ silesia.tar, level 5, old stre silesia.tar, level 6, old streaming advanced, 4616816 silesia.tar, level 7, old streaming advanced, 4576830 silesia.tar, level 9, old streaming advanced, 4552590 -silesia.tar, level 13, old streaming advanced, 4491769 +silesia.tar, level 13, old streaming advanced, 4502955 silesia.tar, level 16, old streaming advanced, 4356834 silesia.tar, level 19, old streaming advanced, 4264388 silesia.tar, no source size, old streaming advanced, 4861421 @@ -1359,7 +1359,7 @@ github, level 7 with dict, old stre github, level 9, old streaming advanced, 138676 github, level 9 with dict, old streaming advanced, 38981 github, level 13, old streaming advanced, 138676 -github, level 13 with dict, old streaming advanced, 39731 +github, level 13 with dict, old streaming advanced, 39721 github, level 16, old streaming advanced, 138676 github, level 16 with dict, old streaming advanced, 40789 github, level 19, old streaming advanced, 134064 @@ -1399,8 +1399,8 @@ github.tar, level 7, old stre github.tar, level 7 with dict, old streaming advanced, 37322 github.tar, level 9, old streaming advanced, 36767 github.tar, level 9 with dict, old streaming advanced, 36233 -github.tar, level 13, old streaming advanced, 35621 -github.tar, level 13 with dict, old streaming advanced, 36035 +github.tar, level 13, old streaming advanced, 35501 +github.tar, level 13 with dict, old streaming advanced, 35807 github.tar, level 16, old streaming advanced, 40255 github.tar, level 16 with dict, old streaming advanced, 38736 github.tar, level 19, old streaming advanced, 32837 @@ -1444,7 +1444,7 @@ github.tar, level 5 with dict, old stre github.tar, level 6 with dict, old streaming cdict, 37829 github.tar, level 7 with dict, old streaming cdict, 37371 github.tar, level 9 with dict, old streaming cdict, 36352 -github.tar, level 13 with dict, old streaming cdict, 36372 +github.tar, level 13 with dict, old streaming cdict, 36010 github.tar, level 16 with dict, old streaming cdict, 39353 github.tar, level 19 with dict, old streaming cdict, 32676 github.tar, no source size with dict, old streaming cdict, 38000 @@ -1459,7 +1459,7 @@ github, level 5 with dict, old stre github, level 6 with dict, old streaming advanced cdict, 39363 github, level 7 with dict, old streaming advanced cdict, 38924 github, level 9 with dict, old streaming advanced cdict, 38981 -github, level 13 with dict, old streaming advanced cdict, 39731 +github, level 13 with dict, old streaming advanced cdict, 39721 github, level 16 with dict, old streaming advanced cdict, 40789 github, level 19 with dict, old streaming advanced cdict, 37576 github, no source size with dict, old streaming advanced cdict, 40608 @@ -1474,7 +1474,7 @@ github.tar, level 5 with dict, old stre github.tar, level 6 with dict, old streaming advanced cdict, 37786 github.tar, level 7 with dict, old streaming advanced cdict, 37322 github.tar, level 9 with dict, old streaming advanced cdict, 36233 -github.tar, level 13 with dict, old streaming advanced cdict, 36035 +github.tar, level 13 with dict, old streaming advanced cdict, 35807 github.tar, level 16 with dict, old streaming advanced cdict, 38736 github.tar, level 19 with dict, old streaming advanced cdict, 32876 github.tar, no source size with dict, old streaming advanced cdict, 38015 From d88c1d95ceb49fb2ca1af9af3173a4e4cfe439c3 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Wed, 1 Sep 2021 13:48:11 -0700 Subject: [PATCH 137/274] Remove inlining for opt --- lib/compress/zstd_opt.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 19999470e..301f985cb 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -253,11 +253,10 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP * Provides the cost of the match part (offset + matchLength) of a sequence * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence. * optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) */ -FORCE_INLINE_TEMPLATE U32 -ZSTD_getMatchPrice(U32 const offset, - U32 const matchLength, - const optState_t* const optPtr, - int const optLevel) +static U32 ZSTD_getMatchPrice(U32 const offset, + U32 const matchLength, + const optState_t* const optPtr, + int const optLevel) { U32 price; U32 const offCode = ZSTD_highbit32(offset+1); @@ -485,11 +484,9 @@ static U32 ZSTD_insertBt1( } } -FORCE_INLINE_TEMPLATE -void ZSTD_updateTree_internal( - ZSTD_matchState_t* ms, - const BYTE* const ip, const BYTE* const iend, - const U32 mls, const ZSTD_dictMode_e dictMode) +static void ZSTD_updateTree_internal(ZSTD_matchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + const U32 mls, const ZSTD_dictMode_e dictMode) { const BYTE* const base = ms->window.base; U32 const target = (U32)(ip - base); @@ -511,8 +508,7 @@ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) { ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict); } -FORCE_INLINE_TEMPLATE -U32 ZSTD_insertBtAndGetAllMatches ( +static U32 ZSTD_insertBtAndGetAllMatches ( ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */ ZSTD_matchState_t* ms, U32* nextToUpdate3, @@ -745,7 +741,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( } -FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches ( +static U32 ZSTD_BtGetAllMatches ( ZSTD_match_t* matches, /* store result (match found, increasing size) in this table */ ZSTD_matchState_t* ms, U32* nextToUpdate3, @@ -932,7 +928,7 @@ listStats(const U32* table, int lastEltID) #endif -FORCE_INLINE_TEMPLATE size_t +static size_t ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], From eab692211eca2943439b7894b210a85e6931bdd9 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 3 Sep 2021 12:51:02 -0700 Subject: [PATCH 138/274] removed pretty-print of sizes in benchmark This is less appropriate for this mode : benchmark is about accuracy, it's important to read the exact values. --- lib/compress/zstd_opt.c | 3 ++- programs/benchzstd.c | 24 +++++++++--------------- programs/util.c | 7 ++++--- programs/util.h | 8 ++++++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 301f985cb..c8d403cf5 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -987,7 +987,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, * in every price. We include the literal length to avoid negative * prices when we subtract the previous literal length. */ - opt[0].price = ZSTD_litLengthPrice(litlen, optStatePtr, optLevel); + opt[0].price = (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel); /* large match -> immediate encoding */ { U32 const maxML = matches[nbMatches-1].len; @@ -1007,6 +1007,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, } } /* set prices for first matches starting position == 0 */ + assert(opt[0].price >= 0); { U32 const literalsPrice = opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel); U32 pos; U32 matchNb; diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 32ce60593..262efb1b1 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -181,7 +181,7 @@ BMK_initCCtx(ZSTD_CCtx* ctx, CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_minMatch, (int)comprParams->minMatch)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_targetLength, (int)comprParams->targetLength)); CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_literalCompressionMode, (int)adv->literalCompressionMode)); - CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, comprParams->strategy)); + CHECK_Z(ZSTD_CCtx_setParameter(ctx, ZSTD_c_strategy, (int)comprParams->strategy)); CHECK_Z(ZSTD_CCtx_loadDictionary(ctx, dictBuffer, dictBufferSize)); } @@ -393,8 +393,6 @@ BMK_benchMemAdvancedNoAlloc( BMK_benchParams_t cbp, dbp; BMK_initCCtxArgs cctxprep; BMK_initDCtxArgs dctxprep; - UTIL_HumanReadableSize_t hr_isize; - UTIL_HumanReadableSize_t hr_osize; cbp.benchFn = local_defaultCompress; /* ZSTD_compress2 */ cbp.benchPayload = cctx; @@ -431,10 +429,9 @@ BMK_benchMemAdvancedNoAlloc( dctxprep.dictBuffer = dictBuffer; dctxprep.dictBufferSize = dictBufferSize; - hr_isize = UTIL_makeHumanReadableSize((U64) srcSize); - DISPLAYLEVEL(2, "\r%70s\r", ""); /* blank line */ - DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> \r", marks[markNb], displayName, hr_isize.precision, hr_isize.value, hr_isize.suffix); + assert(srcSize < UINT_MAX); + DISPLAYLEVEL(2, "%2s-%-17.17s :%10u -> \r", marks[markNb], displayName, (unsigned)srcSize); while (!(compressionCompleted && decompressionCompleted)) { if (!compressionCompleted) { @@ -446,7 +443,7 @@ BMK_benchMemAdvancedNoAlloc( { BMK_runTime_t const cResult = BMK_extract_runTime(cOutcome); cSize = cResult.sumOfReturn; - ratio = (double)srcSize / cSize; + ratio = (double)srcSize / (double)cSize; { BMK_benchResult_t newResult; newResult.cSpeed = (U64)((double)srcSize * TIMELOOP_NANOSEC / cResult.nanoSecPerRun); benchResult.cSize = cSize; @@ -455,11 +452,10 @@ BMK_benchMemAdvancedNoAlloc( } } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - hr_osize = UTIL_makeHumanReadableSize((U64) cSize); - DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f), %6.*f MB/s\r", + assert(cSize < UINT_MAX); + DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s\r", marks[markNb], displayName, - hr_isize.precision, hr_isize.value, hr_isize.suffix, - hr_osize.precision, hr_osize.value, hr_osize.suffix, + (unsigned)srcSize, (unsigned)cSize, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); } @@ -480,11 +476,9 @@ BMK_benchMemAdvancedNoAlloc( } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - hr_osize = UTIL_makeHumanReadableSize((U64) cSize); - DISPLAYLEVEL(2, "%2s-%-17.17s : %.*f%s -> %.*f%s (%5.*f), %6.*f MB/s, %6.1f MB/s \r", + DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s, %6.1f MB/s \r", marks[markNb], displayName, - hr_isize.precision, hr_isize.value, hr_isize.suffix, - hr_osize.precision, hr_osize.value, hr_osize.suffix, + (unsigned)srcSize, (unsigned)cSize, ratioAccuracy, ratio, benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, (double)benchResult.dSpeed / MB_UNIT); diff --git a/programs/util.c b/programs/util.c index b29177818..61cde727e 100644 --- a/programs/util.c +++ b/programs/util.c @@ -308,7 +308,8 @@ U64 UTIL_getFileSizeStat(const stat_t* statbuf) return (U64)statbuf->st_size; } -UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) { +UTIL_HumanReadableSize_t UTIL_makeHumanReadableSize(U64 size) +{ UTIL_HumanReadableSize_t hrs; if (g_utilDisplayLevel > 3) { @@ -1121,9 +1122,9 @@ DWORD CountSetBits(ULONG_PTR bitMask) { DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1; DWORD bitSetCount = 0; - ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT; + ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT; DWORD i; - + for (i = 0; i <= LSHIFT; ++i) { bitSetCount += ((bitMask & bitTest)?1:0); diff --git a/programs/util.h b/programs/util.h index 7632b9a0a..5e529b7eb 100644 --- a/programs/util.h +++ b/programs/util.h @@ -180,9 +180,13 @@ U64 UTIL_getFileSize(const char* infilename); U64 UTIL_getTotalFileSize(const char* const * fileNamesTable, unsigned nbFiles); /** - * Take a size in bytes and prepare the components to pretty-print it in a - * scaled way. The components in the returned struct should be passed in + * Take @size in bytes, + * prepare the components to pretty-print it in a scaled way. + * The components in the returned struct should be passed in * precision, value, suffix order to a "%.*f%s" format string. + * Output policy is sensible to @g_utilDisplayLevel, + * for verbose mode (@g_utilDisplayLevel >= 4), + * does not scale down. */ typedef struct { double value; From f0fc8cb3e19e4685bec012bd0bc881b2d5664899 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 3 Sep 2021 13:44:07 -0700 Subject: [PATCH 139/274] Disable console notification by default within the library As a library, the default shouldn't be to write anything on console. `cover` and `fastcover` have a `g_displayLevel` variable to control this behavior. It's now set to 0 (no display) by default. Setting notification to a higher level should be an explicit operation by a console application. --- lib/compress/zstd_opt.c | 15 ++++++++------- lib/dictBuilder/cover.c | 4 ++-- lib/dictBuilder/fastcover.c | 8 ++++---- tests/fuzzer.c | 17 +++++++++-------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index c8d403cf5..fe23663e6 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -1008,7 +1008,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, /* set prices for first matches starting position == 0 */ assert(opt[0].price >= 0); - { U32 const literalsPrice = opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel); + { U32 const literalsPrice = (U32)opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel); U32 pos; U32 matchNb; for (pos = 1; pos < minMatch; pos++) { @@ -1025,7 +1025,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, opt[pos].mlen = pos; opt[pos].off = offset; opt[pos].litlen = litlen; - opt[pos].price = sequencePrice; + opt[pos].price = (int)sequencePrice; } } last_pos = pos-1; } @@ -1040,9 +1040,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, /* Fix current position with one literal if cheaper */ { U32 const litlen = (opt[cur-1].mlen == 0) ? opt[cur-1].litlen + 1 : 1; int const price = opt[cur-1].price - + ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel) - + ZSTD_litLengthPrice(litlen, optStatePtr, optLevel) - - ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel); + + (int)ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel) + + (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel) + - (int)ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel); assert(price < 1000000000); /* overflow check */ if (price <= opt[cur].price) { DEBUGLOG(7, "cPos:%zi==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)", @@ -1085,9 +1085,10 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */ } + assert(opt[cur].price >= 0); { U32 const ll0 = (opt[cur].mlen != 0); U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0; - U32 const previousPrice = opt[cur].price; + U32 const previousPrice = (U32)opt[cur].price; U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel); U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch); U32 matchNb; @@ -1127,7 +1128,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */ U32 const pos = cur + mlen; - int const price = basePrice + ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); + int const price = (int)basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); if ((pos > last_pos) || (price < opt[pos].price)) { DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)", diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c index 8364444d1..ec5a169c0 100644 --- a/lib/dictBuilder/cover.c +++ b/lib/dictBuilder/cover.c @@ -47,7 +47,7 @@ * Console display ***************************************/ #ifndef LOCALDISPLAYLEVEL -static int g_displayLevel = 2; +static int g_displayLevel = 0; #endif #undef DISPLAY #define DISPLAY(...) \ @@ -735,7 +735,7 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover( COVER_map_t activeDmers; parameters.splitPoint = 1.0; /* Initialize global data */ - g_displayLevel = parameters.zParams.notificationLevel; + g_displayLevel = (int)parameters.zParams.notificationLevel; /* Checks */ if (!COVER_checkParameters(parameters, dictBufferCapacity)) { DISPLAYLEVEL(1, "Cover parameters incorrect\n"); diff --git a/lib/dictBuilder/fastcover.c b/lib/dictBuilder/fastcover.c index ed789f92f..f4a2eed99 100644 --- a/lib/dictBuilder/fastcover.c +++ b/lib/dictBuilder/fastcover.c @@ -44,7 +44,7 @@ * Console display ***************************************/ #ifndef LOCALDISPLAYLEVEL -static int g_displayLevel = 2; +static int g_displayLevel = 0; #endif #undef DISPLAY #define DISPLAY(...) \ @@ -549,7 +549,7 @@ ZDICT_trainFromBuffer_fastCover(void* dictBuffer, size_t dictBufferCapacity, ZDICT_cover_params_t coverParams; FASTCOVER_accel_t accelParams; /* Initialize global data */ - g_displayLevel = parameters.zParams.notificationLevel; + g_displayLevel = (int)parameters.zParams.notificationLevel; /* Assign splitPoint and f if not provided */ parameters.splitPoint = 1.0; parameters.f = parameters.f == 0 ? DEFAULT_F : parameters.f; @@ -632,7 +632,7 @@ ZDICT_optimizeTrainFromBuffer_fastCover( const unsigned accel = parameters->accel == 0 ? DEFAULT_ACCEL : parameters->accel; const unsigned shrinkDict = 0; /* Local variables */ - const int displayLevel = parameters->zParams.notificationLevel; + const int displayLevel = (int)parameters->zParams.notificationLevel; unsigned iteration = 1; unsigned d; unsigned k; @@ -716,7 +716,7 @@ ZDICT_optimizeTrainFromBuffer_fastCover( data->parameters.splitPoint = splitPoint; data->parameters.steps = kSteps; data->parameters.shrinkDict = shrinkDict; - data->parameters.zParams.notificationLevel = g_displayLevel; + data->parameters.zParams.notificationLevel = (unsigned)g_displayLevel; /* Check the parameters */ if (!FASTCOVER_checkParameters(data->parameters, dictBufferCapacity, data->ctx->f, accel)) { diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 960050f96..92a2efa42 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1832,8 +1832,7 @@ static int basicUnitTests(U32 const seed, double compressibility) /* Simple API skippable frame test */ DISPLAYLEVEL(3, "test%3i : read/write a skippable frame : ", testNb++); - { - U32 i; + { U32 i; unsigned readMagic; unsigned long long receivedSize; size_t skippableSize; @@ -1841,9 +1840,10 @@ static int basicUnitTests(U32 const seed, double compressibility) char* const skipBuff = (char*)malloc(skipLen); assert(skipBuff != NULL); for (i = 0; i < skipLen; i++) - skipBuff[i] = (BYTE) ((seed + i) % 256); - skippableSize = ZSTD_writeSkippableFrame((BYTE*)compressedBuffer, compressedBufferSize, - skipBuff, skipLen, seed % 15); + skipBuff[i] = (char) ((seed + i) % 256); + skippableSize = ZSTD_writeSkippableFrame( + compressedBuffer, compressedBufferSize, + skipBuff, skipLen, seed % 15); CHECK_Z(skippableSize); CHECK_EQ(1, ZSTD_isSkippableFrame(compressedBuffer, skippableSize)); receivedSize = ZSTD_readSkippableFrame(decodedBuffer, CNBuffSize, &readMagic, compressedBuffer, skippableSize); @@ -1860,8 +1860,9 @@ static int basicUnitTests(U32 const seed, double compressibility) unsigned readMagic; unsigned long long receivedSize; size_t skippableSize; - skippableSize = ZSTD_writeSkippableFrame((BYTE*)compressedBuffer, compressedBufferSize, - CNBuffer, 0, seed % 15); + skippableSize = ZSTD_writeSkippableFrame( + compressedBuffer, compressedBufferSize, + CNBuffer, 0, seed % 15); CHECK_EQ(ZSTD_SKIPPABLEHEADERSIZE, skippableSize); CHECK_EQ(1, ZSTD_isSkippableFrame(compressedBuffer, skippableSize)); receivedSize = ZSTD_readSkippableFrame(NULL, 0, &readMagic, compressedBuffer, skippableSize); @@ -3670,7 +3671,7 @@ static int longUnitTests(U32 const seed, double compressibility) CHECK(cdict != NULL); CHECK_Z(ZSTD_CCtx_refCDict(cctx, cdict)); - CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_forceAttachDict, attachPref)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_forceAttachDict, (int)attachPref)); cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); CHECK_Z(cSize); From 27a8bbe26539cca301da3e013955b57e7275d82c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 3 Sep 2021 16:07:31 -0700 Subject: [PATCH 140/274] new initializer for ll price --- lib/compress/zstd_opt.c | 47 +++++++++++----- lib/dictBuilder/zdict.c | 25 ++++++--- tests/regression/results.csv | 104 +++++++++++++++++------------------ 3 files changed, 102 insertions(+), 74 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index fe23663e6..48e1eec80 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -24,11 +24,11 @@ * Price functions for optimal parser ***************************************/ -#if 0 /* approximation at bit level */ +#if 0 /* approximation at bit level (for tests) */ # define BITCOST_ACCURACY 0 # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) -# define WEIGHT(stat) ((void)opt, ZSTD_bitWeight(stat)) -#elif 0 /* fractional bit accuracy */ +# define WEIGHT(stat, opt) ((void)opt, ZSTD_bitWeight(stat)) +#elif 0 /* fractional bit accuracy (for tests) */ # define BITCOST_ACCURACY 8 # define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) # define WEIGHT(stat,opt) ((void)opt, ZSTD_fracWeight(stat)) @@ -94,10 +94,21 @@ static U32 ZSTD_downscaleStat(unsigned* table, U32 lastEltIndex, int malus) return sum; } +static U32 sum_u32(const unsigned table[], size_t nbElts) +{ + size_t n; + U32 total = 0; + for (n=0; nlitLengthSum == 0) : init statistics * take hints from dictionary if there is one - * or init from zero, using src for literals stats, or flat 1 for match symbols + * and init from zero if there is none, + * using src for literals stats, and baseline stats for sequence symbols * otherwise downscale existing stats, to be used as seed for next block. */ static void @@ -177,11 +188,16 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1); } - { unsigned ll; - for (ll=0; ll<=MaxLL; ll++) - optPtr->litLengthFreq[ll] = 1; + { unsigned const baseLLfreqs[MaxLL+1] = { + 4, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 + }; + memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); + //unsigned ll; for (ll=0; ll<=MaxLL; ll++) optPtr->litLengthFreq[ll] = 1; optPtr->litLengthSum = MaxLL+1; } - optPtr->litLengthSum = MaxLL+1; { unsigned ml; for (ml=0; ml<=MaxML; ml++) @@ -189,11 +205,16 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, } optPtr->matchLengthSum = MaxML+1; - { unsigned of; - for (of=0; of<=MaxOff; of++) - optPtr->offCodeFreq[of] = 1; + { unsigned const baseOFCfreqs[MaxOff+1] = { + 8, 4, 3, 3, 3, 4, 4, 4, + 4, 4, 3, 3, 3, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + }; + //memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); + unsigned of; for (of=0; of<=MaxOff; of++) optPtr->offCodeFreq[of] = 1; optPtr->offCodeSum = MaxOff+1; } - optPtr->offCodeSum = MaxOff+1; + } @@ -901,11 +922,11 @@ static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_ ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock); } + /*-******************************* * Optimal parser *********************************/ - static U32 ZSTD_totalLen(ZSTD_optimal_t sol) { return sol.litlen + sol.mlen; diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index 459cbe4d1..9edc77fe8 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -139,7 +139,7 @@ static unsigned ZDICT_NbCommonBytes (size_t val) _BitScanForward64( &r, (U64)val ); return (unsigned)(r>>3); # elif defined(__GNUC__) && (__GNUC__ >= 3) - return (__builtin_ctzll((U64)val) >> 3); + return (unsigned)(__builtin_ctzll((U64)val) >> 3); # else static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; @@ -150,7 +150,7 @@ static unsigned ZDICT_NbCommonBytes (size_t val) _BitScanForward( &r, (U32)val ); return (unsigned)(r>>3); # elif defined(__GNUC__) && (__GNUC__ >= 3) - return (__builtin_ctz((U32)val) >> 3); + return (unsigned)(__builtin_ctz((U32)val) >> 3); # else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; @@ -163,7 +163,7 @@ static unsigned ZDICT_NbCommonBytes (size_t val) _BitScanReverse64( &r, val ); return (unsigned)(r>>3); # elif defined(__GNUC__) && (__GNUC__ >= 3) - return (__builtin_clzll(val) >> 3); + return (unsigned)(__builtin_clzll(val) >> 3); # else unsigned r; const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */ @@ -178,7 +178,7 @@ static unsigned ZDICT_NbCommonBytes (size_t val) _BitScanReverse( &r, (unsigned long)val ); return (unsigned)(r>>3); # elif defined(__GNUC__) && (__GNUC__ >= 3) - return (__builtin_clz((U32)val) >> 3); + return (unsigned)(__builtin_clz((U32)val) >> 3); # else unsigned r; if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } @@ -235,7 +235,7 @@ static dictItem ZDICT_analyzePos( U32 savings[LLIMIT] = {0}; const BYTE* b = (const BYTE*)buffer; size_t maxLength = LLIMIT; - size_t pos = suffix[start]; + size_t pos = (size_t)suffix[start]; U32 end = start; dictItem solution; @@ -369,7 +369,7 @@ static dictItem ZDICT_analyzePos( savings[i] = savings[i-1] + (lengthList[i] * (i-3)); DISPLAYLEVEL(4, "Selected dict at position %u, of length %u : saves %u (ratio: %.2f) \n", - (unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / maxLength); + (unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / (double)maxLength); solution.pos = (U32)pos; solution.length = (U32)maxLength; @@ -379,7 +379,7 @@ static dictItem ZDICT_analyzePos( { U32 id; for (id=start; id= elt.pos) && (table[u].pos < elt.pos)) { /* overlap, existing < new */ /* append */ - int const addedLength = (int)eltEnd - (table[u].pos + table[u].length); + int const addedLength = (int)eltEnd - (int)(table[u].pos + table[u].length); table[u].savings += elt.length / 8; /* rough approx bonus */ if (addedLength > 0) { /* otherwise, elt fully included into existing */ table[u].length += addedLength; @@ -766,6 +766,13 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize, pos += fileSizes[u]; } + if (notificationLevel >= 4) { + /* writeStats */ + DISPLAYLEVEL(4, "Offset Code Frequencies : \n"); + for (u=0; u<=offcodeMax; u++) { + DISPLAYLEVEL(4, "%2u :%7u \n", u, offcodeCount[u]); + } } + /* analyze, build stats, starting with literals */ { size_t maxNbBits = HUF_buildCTable (hufTable, countLit, 255, huffLog); if (HUF_isError(maxNbBits)) { @@ -872,7 +879,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize, MEM_writeLE32(dstPtr+8, bestRepOffset[2].offset); #else /* at this stage, we don't use the result of "most common first offset", - as the impact of statistics is not properly evaluated */ + * as the impact of statistics is not properly evaluated */ MEM_writeLE32(dstPtr+0, repStartValue[0]); MEM_writeLE32(dstPtr+4, repStartValue[1]); MEM_writeLE32(dstPtr+8, repStartValue[2]); diff --git a/tests/regression/results.csv b/tests/regression/results.csv index f120e5f2c..a552cb888 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -11,10 +11,10 @@ silesia.tar, level 6, compress silesia.tar, level 7, compress simple, 4576828 silesia.tar, level 9, compress simple, 4552584 silesia.tar, level 13, compress simple, 4502955 -silesia.tar, level 16, compress simple, 4356834 -silesia.tar, level 19, compress simple, 4264388 +silesia.tar, level 16, compress simple, 4356970 +silesia.tar, level 19, compress simple, 4264314 silesia.tar, uncompressed literals, compress simple, 4861423 -silesia.tar, uncompressed literals optimal, compress simple, 4264388 +silesia.tar, uncompressed literals optimal, compress simple, 4264314 silesia.tar, huffman literals, compress simple, 6186042 github.tar, level -5, compress simple, 46856 github.tar, level -3, compress simple, 43754 @@ -29,9 +29,9 @@ github.tar, level 7, compress github.tar, level 9, compress simple, 36767 github.tar, level 13, compress simple, 35501 github.tar, level 16, compress simple, 40255 -github.tar, level 19, compress simple, 32837 +github.tar, level 19, compress simple, 32820 github.tar, uncompressed literals, compress simple, 38441 -github.tar, uncompressed literals optimal, compress simple, 32837 +github.tar, uncompressed literals optimal, compress simple, 32820 github.tar, huffman literals, compress simple, 42490 silesia, level -5, compress cctx, 6737607 silesia, level -3, compress cctx, 6444677 @@ -45,8 +45,8 @@ silesia, level 6, compress silesia, level 7, compress cctx, 4567203 silesia, level 9, compress cctx, 4543311 silesia, level 13, compress cctx, 4493990 -silesia, level 16, compress cctx, 4360251 -silesia, level 19, compress cctx, 4283236 +silesia, level 16, compress cctx, 4360072 +silesia, level 19, compress cctx, 4282792 silesia, long distance mode, compress cctx, 4849551 silesia, multithreaded, compress cctx, 4849551 silesia, multithreaded long distance mode, compress cctx, 4849551 @@ -55,7 +55,7 @@ silesia, small hash log, compress silesia, small chain log, compress cctx, 4912199 silesia, explicit params, compress cctx, 4794480 silesia, uncompressed literals, compress cctx, 4849551 -silesia, uncompressed literals optimal, compress cctx, 4283236 +silesia, uncompressed literals optimal, compress cctx, 4282792 silesia, huffman literals, compress cctx, 6178460 silesia, multithreaded with advanced params, compress cctx, 4849551 github, level -5, compress cctx, 205285 @@ -109,8 +109,8 @@ silesia, level 6, zstdcli, silesia, level 7, zstdcli, 4567251 silesia, level 9, zstdcli, 4543359 silesia, level 13, zstdcli, 4494038 -silesia, level 16, zstdcli, 4360299 -silesia, level 19, zstdcli, 4283284 +silesia, level 16, zstdcli, 4360120 +silesia, level 19, zstdcli, 4282840 silesia, long distance mode, zstdcli, 4840807 silesia, multithreaded, zstdcli, 4849599 silesia, multithreaded long distance mode, zstdcli, 4840807 @@ -119,7 +119,7 @@ silesia, small hash log, zstdcli, silesia, small chain log, zstdcli, 4912247 silesia, explicit params, zstdcli, 4795856 silesia, uncompressed literals, zstdcli, 5128030 -silesia, uncompressed literals optimal, zstdcli, 4317944 +silesia, uncompressed literals optimal, zstdcli, 4318048 silesia, huffman literals, zstdcli, 5326317 silesia, multithreaded with advanced params, zstdcli, 5128030 silesia.tar, level -5, zstdcli, 6738934 @@ -134,8 +134,8 @@ silesia.tar, level 6, zstdcli, silesia.tar, level 7, zstdcli, 4578883 silesia.tar, level 9, zstdcli, 4553498 silesia.tar, level 13, zstdcli, 4502959 -silesia.tar, level 16, zstdcli, 4356838 -silesia.tar, level 19, zstdcli, 4264392 +silesia.tar, level 16, zstdcli, 4356974 +silesia.tar, level 19, zstdcli, 4264318 silesia.tar, no source size, zstdcli, 4861507 silesia.tar, long distance mode, zstdcli, 4853225 silesia.tar, multithreaded, zstdcli, 4861511 @@ -213,7 +213,7 @@ github.tar, level 13, zstdcli, github.tar, level 13 with dict, zstdcli, 38730 github.tar, level 16, zstdcli, 40259 github.tar, level 16 with dict, zstdcli, 33643 -github.tar, level 19, zstdcli, 32841 +github.tar, level 19, zstdcli, 32824 github.tar, level 19 with dict, zstdcli, 32899 github.tar, no source size, zstdcli, 38442 github.tar, no source size with dict, zstdcli, 38004 @@ -225,7 +225,7 @@ github.tar, small hash log, zstdcli, github.tar, small chain log, zstdcli, 41673 github.tar, explicit params, zstdcli, 41227 github.tar, uncompressed literals, zstdcli, 41126 -github.tar, uncompressed literals optimal, zstdcli, 35392 +github.tar, uncompressed literals optimal, zstdcli, 35498 github.tar, huffman literals, zstdcli, 38781 github.tar, multithreaded with advanced params, zstdcli, 41126 silesia, level -5, advanced one pass, 6737607 @@ -248,8 +248,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced one pass, 4503117 silesia, level 12 row 2, advanced one pass, 4505152 silesia, level 13, advanced one pass, 4493990 -silesia, level 16, advanced one pass, 4360251 -silesia, level 19, advanced one pass, 4283236 +silesia, level 16, advanced one pass, 4360072 +silesia, level 19, advanced one pass, 4282792 silesia, no source size, advanced one pass, 4849551 silesia, long distance mode, advanced one pass, 4840738 silesia, multithreaded, advanced one pass, 4849551 @@ -259,7 +259,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced one pass, 4912199 silesia, explicit params, advanced one pass, 4795856 silesia, uncompressed literals, advanced one pass, 5127982 -silesia, uncompressed literals optimal, advanced one pass, 4317896 +silesia, uncompressed literals optimal, advanced one pass, 4318000 silesia, huffman literals, advanced one pass, 5326269 silesia, multithreaded with advanced params, advanced one pass, 5127982 silesia.tar, level -5, advanced one pass, 6738593 @@ -282,8 +282,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced one pass, 4513603 silesia.tar, level 12 row 2, advanced one pass, 4514568 silesia.tar, level 13, advanced one pass, 4502955 -silesia.tar, level 16, advanced one pass, 4356834 -silesia.tar, level 19, advanced one pass, 4264388 +silesia.tar, level 16, advanced one pass, 4356970 +silesia.tar, level 19, advanced one pass, 4264314 silesia.tar, no source size, advanced one pass, 4861423 silesia.tar, long distance mode, advanced one pass, 4847753 silesia.tar, multithreaded, advanced one pass, 4861507 @@ -527,7 +527,7 @@ github.tar, level 16 with dict dms, advanced github.tar, level 16 with dict dds, advanced one pass, 33544 github.tar, level 16 with dict copy, advanced one pass, 33639 github.tar, level 16 with dict load, advanced one pass, 39353 -github.tar, level 19, advanced one pass, 32837 +github.tar, level 19, advanced one pass, 32820 github.tar, level 19 with dict, advanced one pass, 32895 github.tar, level 19 with dict dms, advanced one pass, 32672 github.tar, level 19 with dict dds, advanced one pass, 32672 @@ -543,7 +543,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass, 41669 github.tar, explicit params, advanced one pass, 41227 github.tar, uncompressed literals, advanced one pass, 41122 -github.tar, uncompressed literals optimal, advanced one pass, 35388 +github.tar, uncompressed literals optimal, advanced one pass, 35494 github.tar, huffman literals, advanced one pass, 38777 github.tar, multithreaded with advanced params, advanced one pass, 41122 silesia, level -5, advanced one pass small out, 6737607 @@ -566,8 +566,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced one pass small out, 4503117 silesia, level 12 row 2, advanced one pass small out, 4505152 silesia, level 13, advanced one pass small out, 4493990 -silesia, level 16, advanced one pass small out, 4360251 -silesia, level 19, advanced one pass small out, 4283236 +silesia, level 16, advanced one pass small out, 4360072 +silesia, level 19, advanced one pass small out, 4282792 silesia, no source size, advanced one pass small out, 4849551 silesia, long distance mode, advanced one pass small out, 4840738 silesia, multithreaded, advanced one pass small out, 4849551 @@ -577,7 +577,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced one pass small out, 4912199 silesia, explicit params, advanced one pass small out, 4795856 silesia, uncompressed literals, advanced one pass small out, 5127982 -silesia, uncompressed literals optimal, advanced one pass small out, 4317896 +silesia, uncompressed literals optimal, advanced one pass small out, 4318000 silesia, huffman literals, advanced one pass small out, 5326269 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 silesia.tar, level -5, advanced one pass small out, 6738593 @@ -600,8 +600,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced one pass small out, 4513603 silesia.tar, level 12 row 2, advanced one pass small out, 4514568 silesia.tar, level 13, advanced one pass small out, 4502955 -silesia.tar, level 16, advanced one pass small out, 4356834 -silesia.tar, level 19, advanced one pass small out, 4264388 +silesia.tar, level 16, advanced one pass small out, 4356970 +silesia.tar, level 19, advanced one pass small out, 4264314 silesia.tar, no source size, advanced one pass small out, 4861423 silesia.tar, long distance mode, advanced one pass small out, 4847753 silesia.tar, multithreaded, advanced one pass small out, 4861507 @@ -845,7 +845,7 @@ github.tar, level 16 with dict dms, advanced github.tar, level 16 with dict dds, advanced one pass small out, 33544 github.tar, level 16 with dict copy, advanced one pass small out, 33639 github.tar, level 16 with dict load, advanced one pass small out, 39353 -github.tar, level 19, advanced one pass small out, 32837 +github.tar, level 19, advanced one pass small out, 32820 github.tar, level 19 with dict, advanced one pass small out, 32895 github.tar, level 19 with dict dms, advanced one pass small out, 32672 github.tar, level 19 with dict dds, advanced one pass small out, 32672 @@ -861,7 +861,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass small out, 41669 github.tar, explicit params, advanced one pass small out, 41227 github.tar, uncompressed literals, advanced one pass small out, 41122 -github.tar, uncompressed literals optimal, advanced one pass small out, 35388 +github.tar, uncompressed literals optimal, advanced one pass small out, 35494 github.tar, huffman literals, advanced one pass small out, 38777 github.tar, multithreaded with advanced params, advanced one pass small out, 41122 silesia, level -5, advanced streaming, 6882505 @@ -884,8 +884,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced streaming, 4503117 silesia, level 12 row 2, advanced streaming, 4505152 silesia, level 13, advanced streaming, 4493990 -silesia, level 16, advanced streaming, 4360251 -silesia, level 19, advanced streaming, 4283236 +silesia, level 16, advanced streaming, 4360072 +silesia, level 19, advanced streaming, 4282792 silesia, no source size, advanced streaming, 4849515 silesia, long distance mode, advanced streaming, 4840738 silesia, multithreaded, advanced streaming, 4849551 @@ -895,7 +895,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced streaming, 4912199 silesia, explicit params, advanced streaming, 4795884 silesia, uncompressed literals, advanced streaming, 5127982 -silesia, uncompressed literals optimal, advanced streaming, 4317896 +silesia, uncompressed literals optimal, advanced streaming, 4318000 silesia, huffman literals, advanced streaming, 5331171 silesia, multithreaded with advanced params, advanced streaming, 5127982 silesia.tar, level -5, advanced streaming, 6982759 @@ -918,8 +918,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced streaming, 4513603 silesia.tar, level 12 row 2, advanced streaming, 4514569 silesia.tar, level 13, advanced streaming, 4502955 -silesia.tar, level 16, advanced streaming, 4356834 -silesia.tar, level 19, advanced streaming, 4264388 +silesia.tar, level 16, advanced streaming, 4356970 +silesia.tar, level 19, advanced streaming, 4264314 silesia.tar, no source size, advanced streaming, 4861421 silesia.tar, long distance mode, advanced streaming, 4847753 silesia.tar, multithreaded, advanced streaming, 4861507 @@ -1163,7 +1163,7 @@ github.tar, level 16 with dict dms, advanced github.tar, level 16 with dict dds, advanced streaming, 33544 github.tar, level 16 with dict copy, advanced streaming, 33639 github.tar, level 16 with dict load, advanced streaming, 39353 -github.tar, level 19, advanced streaming, 32837 +github.tar, level 19, advanced streaming, 32820 github.tar, level 19 with dict, advanced streaming, 32895 github.tar, level 19 with dict dms, advanced streaming, 32672 github.tar, level 19 with dict dds, advanced streaming, 32672 @@ -1179,7 +1179,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced streaming, 41669 github.tar, explicit params, advanced streaming, 41227 github.tar, uncompressed literals, advanced streaming, 41122 -github.tar, uncompressed literals optimal, advanced streaming, 35388 +github.tar, uncompressed literals optimal, advanced streaming, 35494 github.tar, huffman literals, advanced streaming, 38800 github.tar, multithreaded with advanced params, advanced streaming, 41122 silesia, level -5, old streaming, 6882505 @@ -1194,11 +1194,11 @@ silesia, level 6, old stre silesia, level 7, old streaming, 4567203 silesia, level 9, old streaming, 4543311 silesia, level 13, old streaming, 4493990 -silesia, level 16, old streaming, 4360251 -silesia, level 19, old streaming, 4283236 +silesia, level 16, old streaming, 4360072 +silesia, level 19, old streaming, 4282792 silesia, no source size, old streaming, 4849515 silesia, uncompressed literals, old streaming, 4849551 -silesia, uncompressed literals optimal, old streaming, 4283236 +silesia, uncompressed literals optimal, old streaming, 4282792 silesia, huffman literals, old streaming, 6183403 silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -3, old streaming, 6641283 @@ -1212,11 +1212,11 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming, 4576830 silesia.tar, level 9, old streaming, 4552590 silesia.tar, level 13, old streaming, 4502955 -silesia.tar, level 16, old streaming, 4356834 -silesia.tar, level 19, old streaming, 4264388 +silesia.tar, level 16, old streaming, 4356970 +silesia.tar, level 19, old streaming, 4264314 silesia.tar, no source size, old streaming, 4861421 silesia.tar, uncompressed literals, old streaming, 4861425 -silesia.tar, uncompressed literals optimal, old streaming, 4264388 +silesia.tar, uncompressed literals optimal, old streaming, 4264314 silesia.tar, huffman literals, old streaming, 6190795 github, level -5, old streaming, 205285 github, level -5 with dict, old streaming, 46718 @@ -1277,12 +1277,12 @@ github.tar, level 13, old stre github.tar, level 13 with dict, old streaming, 38726 github.tar, level 16, old streaming, 40255 github.tar, level 16 with dict, old streaming, 33639 -github.tar, level 19, old streaming, 32837 +github.tar, level 19, old streaming, 32820 github.tar, level 19 with dict, old streaming, 32895 github.tar, no source size, old streaming, 38438 github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38441 -github.tar, uncompressed literals optimal, old streaming, 32837 +github.tar, uncompressed literals optimal, old streaming, 32820 github.tar, huffman literals, old streaming, 42465 silesia, level -5, old streaming advanced, 6882505 silesia, level -3, old streaming advanced, 6568376 @@ -1296,8 +1296,8 @@ silesia, level 6, old stre silesia, level 7, old streaming advanced, 4567203 silesia, level 9, old streaming advanced, 4543311 silesia, level 13, old streaming advanced, 4493990 -silesia, level 16, old streaming advanced, 4360251 -silesia, level 19, old streaming advanced, 4283236 +silesia, level 16, old streaming advanced, 4360072 +silesia, level 19, old streaming advanced, 4282792 silesia, no source size, old streaming advanced, 4849515 silesia, long distance mode, old streaming advanced, 4849551 silesia, multithreaded, old streaming advanced, 4849551 @@ -1307,7 +1307,7 @@ silesia, small hash log, old stre silesia, small chain log, old streaming advanced, 4912199 silesia, explicit params, old streaming advanced, 4795884 silesia, uncompressed literals, old streaming advanced, 4849551 -silesia, uncompressed literals optimal, old streaming advanced, 4283236 +silesia, uncompressed literals optimal, old streaming advanced, 4282792 silesia, huffman literals, old streaming advanced, 6183403 silesia, multithreaded with advanced params, old streaming advanced, 4849551 silesia.tar, level -5, old streaming advanced, 6982759 @@ -1322,8 +1322,8 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming advanced, 4576830 silesia.tar, level 9, old streaming advanced, 4552590 silesia.tar, level 13, old streaming advanced, 4502955 -silesia.tar, level 16, old streaming advanced, 4356834 -silesia.tar, level 19, old streaming advanced, 4264388 +silesia.tar, level 16, old streaming advanced, 4356970 +silesia.tar, level 19, old streaming advanced, 4264314 silesia.tar, no source size, old streaming advanced, 4861421 silesia.tar, long distance mode, old streaming advanced, 4861425 silesia.tar, multithreaded, old streaming advanced, 4861425 @@ -1333,7 +1333,7 @@ silesia.tar, small hash log, old stre silesia.tar, small chain log, old streaming advanced, 4917019 silesia.tar, explicit params, old streaming advanced, 4807403 silesia.tar, uncompressed literals, old streaming advanced, 4861425 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4264388 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4264314 silesia.tar, huffman literals, old streaming advanced, 6190795 silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 github, level -5, old streaming advanced, 216734 @@ -1403,7 +1403,7 @@ github.tar, level 13, old stre github.tar, level 13 with dict, old streaming advanced, 35807 github.tar, level 16, old streaming advanced, 40255 github.tar, level 16 with dict, old streaming advanced, 38736 -github.tar, level 19, old streaming advanced, 32837 +github.tar, level 19, old streaming advanced, 32820 github.tar, level 19 with dict, old streaming advanced, 32876 github.tar, no source size, old streaming advanced, 38438 github.tar, no source size with dict, old streaming advanced, 38015 @@ -1415,7 +1415,7 @@ github.tar, small hash log, old stre github.tar, small chain log, old streaming advanced, 41669 github.tar, explicit params, old streaming advanced, 41227 github.tar, uncompressed literals, old streaming advanced, 38441 -github.tar, uncompressed literals optimal, old streaming advanced, 32837 +github.tar, uncompressed literals optimal, old streaming advanced, 32820 github.tar, huffman literals, old streaming advanced, 42465 github.tar, multithreaded with advanced params, old streaming advanced, 38441 github, level -5 with dict, old streaming cdict, 46718 From 23a9368c45a0c87ec1a34f8a7fbeff3807dfe967 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 3 Sep 2021 17:41:42 -0700 Subject: [PATCH 141/274] new starting offcode table for zstd_opt --- lib/compress/zstd_opt.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 48e1eec80..784bb918a 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -196,7 +196,6 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, 1, 1, 1, 1 }; memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); - //unsigned ll; for (ll=0; ll<=MaxLL; ll++) optPtr->litLengthFreq[ll] = 1; optPtr->litLengthSum = MaxLL+1; } { unsigned ml; @@ -206,13 +205,12 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, optPtr->matchLengthSum = MaxML+1; { unsigned const baseOFCfreqs[MaxOff+1] = { - 8, 4, 3, 3, 3, 4, 4, 4, - 4, 4, 3, 3, 3, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - }; - //memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); - unsigned of; for (of=0; of<=MaxOff; of++) optPtr->offCodeFreq[of] = 1; optPtr->offCodeSum = MaxOff+1; + 6, 2, 1, 1, 2, 3, 4, 4, + 4, 3, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); } From 08ceda3dfc9c1e4ae7e35d210e0318a696f7f394 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 4 Sep 2021 00:52:44 -0700 Subject: [PATCH 142/274] new statistics update policy small general compression ratio improvement for btopt+ strategies/ --- lib/compress/zstd_opt.c | 50 ++++++++++++++++++++++++----------------- programs/benchzstd.c | 20 +++++++++-------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 784bb918a..a7b23e798 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -79,21 +79,6 @@ static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel) } -/* ZSTD_downscaleStat() : - * reduce all elements in table by a factor 2^(ZSTD_FREQ_DIV+malus) - * return the resulting sum of elements */ -static U32 ZSTD_downscaleStat(unsigned* table, U32 lastEltIndex, int malus) -{ - U32 s, sum=0; - DEBUGLOG(5, "ZSTD_downscaleStat (nbElts=%u)", (unsigned)lastEltIndex+1); - assert(ZSTD_FREQ_DIV+malus > 0 && ZSTD_FREQ_DIV+malus < 31); - for (s=0; s> (ZSTD_FREQ_DIV+malus)); - sum += table[s]; - } - return sum; -} - static U32 sum_u32(const unsigned table[], size_t nbElts) { size_t n; @@ -104,6 +89,31 @@ static U32 sum_u32(const unsigned table[], size_t nbElts) return total; } +static U32 ZSTD_downscaleStats(unsigned* table, U32 lastEltIndex, U32 shift) +{ + U32 s, sum=0; + DEBUGLOG(5, "ZSTD_downscaleStats (nbElts=%u, shift=%u)", (unsigned)lastEltIndex+1, (unsigned)shift); + assert(shift < 30); + for (s=0; s> shift); + sum += table[s]; + } + return sum; +} + +/* ZSTD_scaleStats() : + * reduce all elements in table is sum too large + * return the resulting sum of elements */ +static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget) +{ + U32 const prevsum = sum_u32(table, lastEltIndex+1); + U32 const factor = prevsum >> logTarget; + DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget); + assert(logTarget < 30); + if (factor <= 1) return prevsum; + return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor)); +} + /* ZSTD_rescaleFreqs() : * if first block (detected by optPtr->litLengthSum == 0) : init statistics * take hints from dictionary if there is one @@ -185,7 +195,7 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, if (compressedLiterals) { unsigned lit = MaxLit; HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */ - optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1); + optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8); } { unsigned const baseLLfreqs[MaxLL+1] = { @@ -219,10 +229,10 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, } else { /* new block : re-use previous statistics, scaled down */ if (compressedLiterals) - optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1); - optPtr->litLengthSum = ZSTD_downscaleStat(optPtr->litLengthFreq, MaxLL, 0); - optPtr->matchLengthSum = ZSTD_downscaleStat(optPtr->matchLengthFreq, MaxML, 0); - optPtr->offCodeSum = ZSTD_downscaleStat(optPtr->offCodeFreq, MaxOff, 0); + optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 10); + optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 9); + optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 9); + optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 9); } ZSTD_setBasePrices(optPtr, optLevel); diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 262efb1b1..2366cf2d7 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -70,6 +70,8 @@ static const size_t maxMemory = (sizeof(size_t)==4) ? #define DISPLAY(...) { fprintf(stderr, __VA_ARGS__); fflush(NULL); } #define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */ +#define OUTPUT(...) { fprintf(stdout, __VA_ARGS__); fflush(NULL); } +#define OUTPUTLEVEL(l, ...) if (displayLevel>=l) { OUTPUT(__VA_ARGS__); } /* ************************************* @@ -429,9 +431,9 @@ BMK_benchMemAdvancedNoAlloc( dctxprep.dictBuffer = dictBuffer; dctxprep.dictBufferSize = dictBufferSize; - DISPLAYLEVEL(2, "\r%70s\r", ""); /* blank line */ + OUTPUTLEVEL(2, "\r%70s\r", ""); /* blank line */ assert(srcSize < UINT_MAX); - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u -> \r", marks[markNb], displayName, (unsigned)srcSize); + OUTPUTLEVEL(2, "%2s-%-17.17s :%10u -> \r", marks[markNb], displayName, (unsigned)srcSize); while (!(compressionCompleted && decompressionCompleted)) { if (!compressionCompleted) { @@ -453,7 +455,7 @@ BMK_benchMemAdvancedNoAlloc( { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; assert(cSize < UINT_MAX); - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s\r", + OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s\r", marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratioAccuracy, ratio, @@ -476,7 +478,7 @@ BMK_benchMemAdvancedNoAlloc( } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - DISPLAYLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s, %6.1f MB/s \r", + OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s, %6.1f MB/s \r", marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratioAccuracy, ratio, @@ -537,13 +539,13 @@ BMK_benchMemAdvancedNoAlloc( double const cSpeed = (double)benchResult.cSpeed / MB_UNIT; double const dSpeed = (double)benchResult.dSpeed / MB_UNIT; if (adv->additionalParam) { - DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, adv->additionalParam); + OUTPUT("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s (param=%d)\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName, adv->additionalParam); } else { - DISPLAY("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName); + OUTPUT("-%-3i%11i (%5.3f) %6.2f MB/s %6.1f MB/s %s\n", cLevel, (int)cSize, ratio, cSpeed, dSpeed, displayName); } } - DISPLAYLEVEL(2, "%2i#\n", cLevel); + OUTPUTLEVEL(2, "%2i#\n", cLevel); } /* Bench */ benchResult.cMem = (1ULL << (comprParams->windowLog)) + ZSTD_sizeof_CCtx(cctx); @@ -672,7 +674,7 @@ static BMK_benchOutcome_t BMK_benchCLevel(const void* srcBuffer, size_t benchedS } if (displayLevel == 1 && !adv->additionalParam) /* --quiet mode */ - DISPLAY("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", + OUTPUT("bench %s %s: input %u bytes, %u seconds, %u KB blocks\n", ZSTD_VERSION_STRING, ZSTD_GIT_COMMIT_STRING, (unsigned)benchedSize, adv->nbSeconds, (unsigned)(adv->blockSize>>10)); @@ -762,7 +764,7 @@ static int BMK_loadFiles(void* buffer, size_t bufferSize, } { FILE* const f = fopen(fileNamesTable[n], "rb"); if (f==NULL) RETURN_ERROR_INT(10, "impossible to open file %s", fileNamesTable[n]); - DISPLAYLEVEL(2, "Loading %s... \r", fileNamesTable[n]); + OUTPUTLEVEL(2, "Loading %s... \r", fileNamesTable[n]); if (fileSize > bufferSize-pos) fileSize = bufferSize-pos, nbFiles=n; /* buffer too small - stop after this file */ { size_t const readSize = fread(((char*)buffer)+pos, 1, (size_t)fileSize, f); if (readSize != (size_t)fileSize) RETURN_ERROR_INT(11, "could not read %s", fileNamesTable[n]); From 30fe49af4e4f11a7783f3dc2e0f05a800bdfd022 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 7 Sep 2021 10:08:35 -0400 Subject: [PATCH 143/274] Fix patch-from help msg typo --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index b786b7e4d..317ec87e0 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -962,7 +962,7 @@ static void FIO_adjustParamsForPatchFromMode(FIO_prefs_t* const prefs, DISPLAYLEVEL(1, "- Use --single-thread mode in the zstd cli\n"); DISPLAYLEVEL(1, "- Set a larger targetLength (eg. --zstd=targetLength=4096)\n"); DISPLAYLEVEL(1, "- Set a larger chainLog (eg. --zstd=chainLog=%u)\n", ZSTD_CHAINLOG_MAX); - DISPLAYLEVEL(1, "Also consdier playing around with searchLog and hashLog\n"); + DISPLAYLEVEL(1, "Also consider playing around with searchLog and hashLog\n"); } } From b096a5c62632b39ec6ad6eb68bc3bafc50be8df4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 7 Sep 2021 09:55:14 -0700 Subject: [PATCH 144/274] updated regression tests --- tests/regression/results.csv | 234 +++++++++++++++++------------------ 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index a552cb888..ee02857c1 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -11,10 +11,10 @@ silesia.tar, level 6, compress silesia.tar, level 7, compress simple, 4576828 silesia.tar, level 9, compress simple, 4552584 silesia.tar, level 13, compress simple, 4502955 -silesia.tar, level 16, compress simple, 4356970 -silesia.tar, level 19, compress simple, 4264314 +silesia.tar, level 16, compress simple, 4358753 +silesia.tar, level 19, compress simple, 4263936 silesia.tar, uncompressed literals, compress simple, 4861423 -silesia.tar, uncompressed literals optimal, compress simple, 4264314 +silesia.tar, uncompressed literals optimal, compress simple, 4263936 silesia.tar, huffman literals, compress simple, 6186042 github.tar, level -5, compress simple, 46856 github.tar, level -3, compress simple, 43754 @@ -28,10 +28,10 @@ github.tar, level 6, compress github.tar, level 7, compress simple, 38073 github.tar, level 9, compress simple, 36767 github.tar, level 13, compress simple, 35501 -github.tar, level 16, compress simple, 40255 -github.tar, level 19, compress simple, 32820 +github.tar, level 16, compress simple, 40357 +github.tar, level 19, compress simple, 32506 github.tar, uncompressed literals, compress simple, 38441 -github.tar, uncompressed literals optimal, compress simple, 32820 +github.tar, uncompressed literals optimal, compress simple, 32506 github.tar, huffman literals, compress simple, 42490 silesia, level -5, compress cctx, 6737607 silesia, level -3, compress cctx, 6444677 @@ -45,8 +45,8 @@ silesia, level 6, compress silesia, level 7, compress cctx, 4567203 silesia, level 9, compress cctx, 4543311 silesia, level 13, compress cctx, 4493990 -silesia, level 16, compress cctx, 4360072 -silesia, level 19, compress cctx, 4282792 +silesia, level 16, compress cctx, 4358530 +silesia, level 19, compress cctx, 4288570 silesia, long distance mode, compress cctx, 4849551 silesia, multithreaded, compress cctx, 4849551 silesia, multithreaded long distance mode, compress cctx, 4849551 @@ -55,7 +55,7 @@ silesia, small hash log, compress silesia, small chain log, compress cctx, 4912199 silesia, explicit params, compress cctx, 4794480 silesia, uncompressed literals, compress cctx, 4849551 -silesia, uncompressed literals optimal, compress cctx, 4282792 +silesia, uncompressed literals optimal, compress cctx, 4288570 silesia, huffman literals, compress cctx, 6178460 silesia, multithreaded with advanced params, compress cctx, 4849551 github, level -5, compress cctx, 205285 @@ -109,8 +109,8 @@ silesia, level 6, zstdcli, silesia, level 7, zstdcli, 4567251 silesia, level 9, zstdcli, 4543359 silesia, level 13, zstdcli, 4494038 -silesia, level 16, zstdcli, 4360120 -silesia, level 19, zstdcli, 4282840 +silesia, level 16, zstdcli, 4358578 +silesia, level 19, zstdcli, 4288618 silesia, long distance mode, zstdcli, 4840807 silesia, multithreaded, zstdcli, 4849599 silesia, multithreaded long distance mode, zstdcli, 4840807 @@ -119,7 +119,7 @@ silesia, small hash log, zstdcli, silesia, small chain log, zstdcli, 4912247 silesia, explicit params, zstdcli, 4795856 silesia, uncompressed literals, zstdcli, 5128030 -silesia, uncompressed literals optimal, zstdcli, 4318048 +silesia, uncompressed literals optimal, zstdcli, 4318014 silesia, huffman literals, zstdcli, 5326317 silesia, multithreaded with advanced params, zstdcli, 5128030 silesia.tar, level -5, zstdcli, 6738934 @@ -134,8 +134,8 @@ silesia.tar, level 6, zstdcli, silesia.tar, level 7, zstdcli, 4578883 silesia.tar, level 9, zstdcli, 4553498 silesia.tar, level 13, zstdcli, 4502959 -silesia.tar, level 16, zstdcli, 4356974 -silesia.tar, level 19, zstdcli, 4264318 +silesia.tar, level 16, zstdcli, 4358757 +silesia.tar, level 19, zstdcli, 4263940 silesia.tar, no source size, zstdcli, 4861507 silesia.tar, long distance mode, zstdcli, 4853225 silesia.tar, multithreaded, zstdcli, 4861511 @@ -145,7 +145,7 @@ silesia.tar, small hash log, zstdcli, silesia.tar, small chain log, zstdcli, 4917020 silesia.tar, explicit params, zstdcli, 4821277 silesia.tar, uncompressed literals, zstdcli, 5129559 -silesia.tar, uncompressed literals optimal, zstdcli, 4307404 +silesia.tar, uncompressed literals optimal, zstdcli, 4307883 silesia.tar, huffman literals, zstdcli, 5347610 silesia.tar, multithreaded with advanced params, zstdcli, 5129559 github, level -5, zstdcli, 207285 @@ -210,11 +210,11 @@ github.tar, level 7 with dict, zstdcli, github.tar, level 9, zstdcli, 36771 github.tar, level 9 with dict, zstdcli, 36623 github.tar, level 13, zstdcli, 35505 -github.tar, level 13 with dict, zstdcli, 38730 -github.tar, level 16, zstdcli, 40259 -github.tar, level 16 with dict, zstdcli, 33643 -github.tar, level 19, zstdcli, 32824 -github.tar, level 19 with dict, zstdcli, 32899 +github.tar, level 13 with dict, zstdcli, 37009 +github.tar, level 16, zstdcli, 40361 +github.tar, level 16 with dict, zstdcli, 33479 +github.tar, level 19, zstdcli, 32510 +github.tar, level 19 with dict, zstdcli, 32973 github.tar, no source size, zstdcli, 38442 github.tar, no source size with dict, zstdcli, 38004 github.tar, long distance mode, zstdcli, 39730 @@ -225,7 +225,7 @@ github.tar, small hash log, zstdcli, github.tar, small chain log, zstdcli, 41673 github.tar, explicit params, zstdcli, 41227 github.tar, uncompressed literals, zstdcli, 41126 -github.tar, uncompressed literals optimal, zstdcli, 35498 +github.tar, uncompressed literals optimal, zstdcli, 35284 github.tar, huffman literals, zstdcli, 38781 github.tar, multithreaded with advanced params, zstdcli, 41126 silesia, level -5, advanced one pass, 6737607 @@ -248,8 +248,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced one pass, 4503117 silesia, level 12 row 2, advanced one pass, 4505152 silesia, level 13, advanced one pass, 4493990 -silesia, level 16, advanced one pass, 4360072 -silesia, level 19, advanced one pass, 4282792 +silesia, level 16, advanced one pass, 4358530 +silesia, level 19, advanced one pass, 4288570 silesia, no source size, advanced one pass, 4849551 silesia, long distance mode, advanced one pass, 4840738 silesia, multithreaded, advanced one pass, 4849551 @@ -259,7 +259,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced one pass, 4912199 silesia, explicit params, advanced one pass, 4795856 silesia, uncompressed literals, advanced one pass, 5127982 -silesia, uncompressed literals optimal, advanced one pass, 4318000 +silesia, uncompressed literals optimal, advanced one pass, 4317966 silesia, huffman literals, advanced one pass, 5326269 silesia, multithreaded with advanced params, advanced one pass, 5127982 silesia.tar, level -5, advanced one pass, 6738593 @@ -282,8 +282,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced one pass, 4513603 silesia.tar, level 12 row 2, advanced one pass, 4514568 silesia.tar, level 13, advanced one pass, 4502955 -silesia.tar, level 16, advanced one pass, 4356970 -silesia.tar, level 19, advanced one pass, 4264314 +silesia.tar, level 16, advanced one pass, 4358753 +silesia.tar, level 19, advanced one pass, 4263936 silesia.tar, no source size, advanced one pass, 4861423 silesia.tar, long distance mode, advanced one pass, 4847753 silesia.tar, multithreaded, advanced one pass, 4861507 @@ -293,7 +293,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced one pass, 4917039 silesia.tar, explicit params, advanced one pass, 4807383 silesia.tar, uncompressed literals, advanced one pass, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 +silesia.tar, uncompressed literals optimal, advanced one pass, 4307879 silesia.tar, huffman literals, advanced one pass, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 github, level -5, advanced one pass, 205285 @@ -516,23 +516,23 @@ github.tar, level 12 row 2 with dict dds, advanced github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 github.tar, level 12 row 2 with dict load, advanced one pass, 36460 github.tar, level 13, advanced one pass, 35501 -github.tar, level 13 with dict, advanced one pass, 38726 -github.tar, level 13 with dict dms, advanced one pass, 38903 -github.tar, level 13 with dict dds, advanced one pass, 38903 -github.tar, level 13 with dict copy, advanced one pass, 38726 +github.tar, level 13 with dict, advanced one pass, 37005 +github.tar, level 13 with dict dms, advanced one pass, 37180 +github.tar, level 13 with dict dds, advanced one pass, 37180 +github.tar, level 13 with dict copy, advanced one pass, 37005 github.tar, level 13 with dict load, advanced one pass, 36010 -github.tar, level 16, advanced one pass, 40255 -github.tar, level 16 with dict, advanced one pass, 33639 -github.tar, level 16 with dict dms, advanced one pass, 33544 -github.tar, level 16 with dict dds, advanced one pass, 33544 -github.tar, level 16 with dict copy, advanced one pass, 33639 -github.tar, level 16 with dict load, advanced one pass, 39353 -github.tar, level 19, advanced one pass, 32820 -github.tar, level 19 with dict, advanced one pass, 32895 -github.tar, level 19 with dict dms, advanced one pass, 32672 -github.tar, level 19 with dict dds, advanced one pass, 32672 -github.tar, level 19 with dict copy, advanced one pass, 32895 -github.tar, level 19 with dict load, advanced one pass, 32676 +github.tar, level 16, advanced one pass, 40357 +github.tar, level 16 with dict, advanced one pass, 33475 +github.tar, level 16 with dict dms, advanced one pass, 33357 +github.tar, level 16 with dict dds, advanced one pass, 33357 +github.tar, level 16 with dict copy, advanced one pass, 33475 +github.tar, level 16 with dict load, advanced one pass, 39064 +github.tar, level 19, advanced one pass, 32506 +github.tar, level 19 with dict, advanced one pass, 32969 +github.tar, level 19 with dict dms, advanced one pass, 32624 +github.tar, level 19 with dict dds, advanced one pass, 32624 +github.tar, level 19 with dict copy, advanced one pass, 32969 +github.tar, level 19 with dict load, advanced one pass, 32570 github.tar, no source size, advanced one pass, 38441 github.tar, no source size with dict, advanced one pass, 37995 github.tar, long distance mode, advanced one pass, 39757 @@ -543,7 +543,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass, 41669 github.tar, explicit params, advanced one pass, 41227 github.tar, uncompressed literals, advanced one pass, 41122 -github.tar, uncompressed literals optimal, advanced one pass, 35494 +github.tar, uncompressed literals optimal, advanced one pass, 35280 github.tar, huffman literals, advanced one pass, 38777 github.tar, multithreaded with advanced params, advanced one pass, 41122 silesia, level -5, advanced one pass small out, 6737607 @@ -566,8 +566,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced one pass small out, 4503117 silesia, level 12 row 2, advanced one pass small out, 4505152 silesia, level 13, advanced one pass small out, 4493990 -silesia, level 16, advanced one pass small out, 4360072 -silesia, level 19, advanced one pass small out, 4282792 +silesia, level 16, advanced one pass small out, 4358530 +silesia, level 19, advanced one pass small out, 4288570 silesia, no source size, advanced one pass small out, 4849551 silesia, long distance mode, advanced one pass small out, 4840738 silesia, multithreaded, advanced one pass small out, 4849551 @@ -577,7 +577,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced one pass small out, 4912199 silesia, explicit params, advanced one pass small out, 4795856 silesia, uncompressed literals, advanced one pass small out, 5127982 -silesia, uncompressed literals optimal, advanced one pass small out, 4318000 +silesia, uncompressed literals optimal, advanced one pass small out, 4317966 silesia, huffman literals, advanced one pass small out, 5326269 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 silesia.tar, level -5, advanced one pass small out, 6738593 @@ -600,8 +600,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced one pass small out, 4513603 silesia.tar, level 12 row 2, advanced one pass small out, 4514568 silesia.tar, level 13, advanced one pass small out, 4502955 -silesia.tar, level 16, advanced one pass small out, 4356970 -silesia.tar, level 19, advanced one pass small out, 4264314 +silesia.tar, level 16, advanced one pass small out, 4358753 +silesia.tar, level 19, advanced one pass small out, 4263936 silesia.tar, no source size, advanced one pass small out, 4861423 silesia.tar, long distance mode, advanced one pass small out, 4847753 silesia.tar, multithreaded, advanced one pass small out, 4861507 @@ -611,7 +611,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced one pass small out, 4917039 silesia.tar, explicit params, advanced one pass small out, 4807383 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 +silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307879 silesia.tar, huffman literals, advanced one pass small out, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 github, level -5, advanced one pass small out, 205285 @@ -834,23 +834,23 @@ github.tar, level 12 row 2 with dict dds, advanced github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 github.tar, level 12 row 2 with dict load, advanced one pass small out, 36460 github.tar, level 13, advanced one pass small out, 35501 -github.tar, level 13 with dict, advanced one pass small out, 38726 -github.tar, level 13 with dict dms, advanced one pass small out, 38903 -github.tar, level 13 with dict dds, advanced one pass small out, 38903 -github.tar, level 13 with dict copy, advanced one pass small out, 38726 +github.tar, level 13 with dict, advanced one pass small out, 37005 +github.tar, level 13 with dict dms, advanced one pass small out, 37180 +github.tar, level 13 with dict dds, advanced one pass small out, 37180 +github.tar, level 13 with dict copy, advanced one pass small out, 37005 github.tar, level 13 with dict load, advanced one pass small out, 36010 -github.tar, level 16, advanced one pass small out, 40255 -github.tar, level 16 with dict, advanced one pass small out, 33639 -github.tar, level 16 with dict dms, advanced one pass small out, 33544 -github.tar, level 16 with dict dds, advanced one pass small out, 33544 -github.tar, level 16 with dict copy, advanced one pass small out, 33639 -github.tar, level 16 with dict load, advanced one pass small out, 39353 -github.tar, level 19, advanced one pass small out, 32820 -github.tar, level 19 with dict, advanced one pass small out, 32895 -github.tar, level 19 with dict dms, advanced one pass small out, 32672 -github.tar, level 19 with dict dds, advanced one pass small out, 32672 -github.tar, level 19 with dict copy, advanced one pass small out, 32895 -github.tar, level 19 with dict load, advanced one pass small out, 32676 +github.tar, level 16, advanced one pass small out, 40357 +github.tar, level 16 with dict, advanced one pass small out, 33475 +github.tar, level 16 with dict dms, advanced one pass small out, 33357 +github.tar, level 16 with dict dds, advanced one pass small out, 33357 +github.tar, level 16 with dict copy, advanced one pass small out, 33475 +github.tar, level 16 with dict load, advanced one pass small out, 39064 +github.tar, level 19, advanced one pass small out, 32506 +github.tar, level 19 with dict, advanced one pass small out, 32969 +github.tar, level 19 with dict dms, advanced one pass small out, 32624 +github.tar, level 19 with dict dds, advanced one pass small out, 32624 +github.tar, level 19 with dict copy, advanced one pass small out, 32969 +github.tar, level 19 with dict load, advanced one pass small out, 32570 github.tar, no source size, advanced one pass small out, 38441 github.tar, no source size with dict, advanced one pass small out, 37995 github.tar, long distance mode, advanced one pass small out, 39757 @@ -861,7 +861,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass small out, 41669 github.tar, explicit params, advanced one pass small out, 41227 github.tar, uncompressed literals, advanced one pass small out, 41122 -github.tar, uncompressed literals optimal, advanced one pass small out, 35494 +github.tar, uncompressed literals optimal, advanced one pass small out, 35280 github.tar, huffman literals, advanced one pass small out, 38777 github.tar, multithreaded with advanced params, advanced one pass small out, 41122 silesia, level -5, advanced streaming, 6882505 @@ -884,8 +884,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced streaming, 4503117 silesia, level 12 row 2, advanced streaming, 4505152 silesia, level 13, advanced streaming, 4493990 -silesia, level 16, advanced streaming, 4360072 -silesia, level 19, advanced streaming, 4282792 +silesia, level 16, advanced streaming, 4358530 +silesia, level 19, advanced streaming, 4288570 silesia, no source size, advanced streaming, 4849515 silesia, long distance mode, advanced streaming, 4840738 silesia, multithreaded, advanced streaming, 4849551 @@ -895,7 +895,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced streaming, 4912199 silesia, explicit params, advanced streaming, 4795884 silesia, uncompressed literals, advanced streaming, 5127982 -silesia, uncompressed literals optimal, advanced streaming, 4318000 +silesia, uncompressed literals optimal, advanced streaming, 4317966 silesia, huffman literals, advanced streaming, 5331171 silesia, multithreaded with advanced params, advanced streaming, 5127982 silesia.tar, level -5, advanced streaming, 6982759 @@ -918,8 +918,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced streaming, 4513603 silesia.tar, level 12 row 2, advanced streaming, 4514569 silesia.tar, level 13, advanced streaming, 4502955 -silesia.tar, level 16, advanced streaming, 4356970 -silesia.tar, level 19, advanced streaming, 4264314 +silesia.tar, level 16, advanced streaming, 4358753 +silesia.tar, level 19, advanced streaming, 4263936 silesia.tar, no source size, advanced streaming, 4861421 silesia.tar, long distance mode, advanced streaming, 4847753 silesia.tar, multithreaded, advanced streaming, 4861507 @@ -929,7 +929,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced streaming, 4917019 silesia.tar, explicit params, advanced streaming, 4807403 silesia.tar, uncompressed literals, advanced streaming, 5129461 -silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 +silesia.tar, uncompressed literals optimal, advanced streaming, 4307879 silesia.tar, huffman literals, advanced streaming, 5352360 silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 github, level -5, advanced streaming, 205285 @@ -1152,23 +1152,23 @@ github.tar, level 12 row 2 with dict dds, advanced github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 github.tar, level 12 row 2 with dict load, advanced streaming, 36460 github.tar, level 13, advanced streaming, 35501 -github.tar, level 13 with dict, advanced streaming, 38726 -github.tar, level 13 with dict dms, advanced streaming, 38903 -github.tar, level 13 with dict dds, advanced streaming, 38903 -github.tar, level 13 with dict copy, advanced streaming, 38726 +github.tar, level 13 with dict, advanced streaming, 37005 +github.tar, level 13 with dict dms, advanced streaming, 37180 +github.tar, level 13 with dict dds, advanced streaming, 37180 +github.tar, level 13 with dict copy, advanced streaming, 37005 github.tar, level 13 with dict load, advanced streaming, 36010 -github.tar, level 16, advanced streaming, 40255 -github.tar, level 16 with dict, advanced streaming, 33639 -github.tar, level 16 with dict dms, advanced streaming, 33544 -github.tar, level 16 with dict dds, advanced streaming, 33544 -github.tar, level 16 with dict copy, advanced streaming, 33639 -github.tar, level 16 with dict load, advanced streaming, 39353 -github.tar, level 19, advanced streaming, 32820 -github.tar, level 19 with dict, advanced streaming, 32895 -github.tar, level 19 with dict dms, advanced streaming, 32672 -github.tar, level 19 with dict dds, advanced streaming, 32672 -github.tar, level 19 with dict copy, advanced streaming, 32895 -github.tar, level 19 with dict load, advanced streaming, 32676 +github.tar, level 16, advanced streaming, 40357 +github.tar, level 16 with dict, advanced streaming, 33475 +github.tar, level 16 with dict dms, advanced streaming, 33357 +github.tar, level 16 with dict dds, advanced streaming, 33357 +github.tar, level 16 with dict copy, advanced streaming, 33475 +github.tar, level 16 with dict load, advanced streaming, 39064 +github.tar, level 19, advanced streaming, 32506 +github.tar, level 19 with dict, advanced streaming, 32969 +github.tar, level 19 with dict dms, advanced streaming, 32624 +github.tar, level 19 with dict dds, advanced streaming, 32624 +github.tar, level 19 with dict copy, advanced streaming, 32969 +github.tar, level 19 with dict load, advanced streaming, 32570 github.tar, no source size, advanced streaming, 38438 github.tar, no source size with dict, advanced streaming, 38000 github.tar, long distance mode, advanced streaming, 39757 @@ -1179,7 +1179,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced streaming, 41669 github.tar, explicit params, advanced streaming, 41227 github.tar, uncompressed literals, advanced streaming, 41122 -github.tar, uncompressed literals optimal, advanced streaming, 35494 +github.tar, uncompressed literals optimal, advanced streaming, 35280 github.tar, huffman literals, advanced streaming, 38800 github.tar, multithreaded with advanced params, advanced streaming, 41122 silesia, level -5, old streaming, 6882505 @@ -1194,11 +1194,11 @@ silesia, level 6, old stre silesia, level 7, old streaming, 4567203 silesia, level 9, old streaming, 4543311 silesia, level 13, old streaming, 4493990 -silesia, level 16, old streaming, 4360072 -silesia, level 19, old streaming, 4282792 +silesia, level 16, old streaming, 4358530 +silesia, level 19, old streaming, 4288570 silesia, no source size, old streaming, 4849515 silesia, uncompressed literals, old streaming, 4849551 -silesia, uncompressed literals optimal, old streaming, 4282792 +silesia, uncompressed literals optimal, old streaming, 4288570 silesia, huffman literals, old streaming, 6183403 silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -3, old streaming, 6641283 @@ -1212,11 +1212,11 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming, 4576830 silesia.tar, level 9, old streaming, 4552590 silesia.tar, level 13, old streaming, 4502955 -silesia.tar, level 16, old streaming, 4356970 -silesia.tar, level 19, old streaming, 4264314 +silesia.tar, level 16, old streaming, 4358753 +silesia.tar, level 19, old streaming, 4263936 silesia.tar, no source size, old streaming, 4861421 silesia.tar, uncompressed literals, old streaming, 4861425 -silesia.tar, uncompressed literals optimal, old streaming, 4264314 +silesia.tar, uncompressed literals optimal, old streaming, 4263936 silesia.tar, huffman literals, old streaming, 6190795 github, level -5, old streaming, 205285 github, level -5 with dict, old streaming, 46718 @@ -1274,15 +1274,15 @@ github.tar, level 7 with dict, old stre github.tar, level 9, old streaming, 36767 github.tar, level 9 with dict, old streaming, 36457 github.tar, level 13, old streaming, 35501 -github.tar, level 13 with dict, old streaming, 38726 -github.tar, level 16, old streaming, 40255 -github.tar, level 16 with dict, old streaming, 33639 -github.tar, level 19, old streaming, 32820 -github.tar, level 19 with dict, old streaming, 32895 +github.tar, level 13 with dict, old streaming, 37005 +github.tar, level 16, old streaming, 40357 +github.tar, level 16 with dict, old streaming, 33475 +github.tar, level 19, old streaming, 32506 +github.tar, level 19 with dict, old streaming, 32969 github.tar, no source size, old streaming, 38438 github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38441 -github.tar, uncompressed literals optimal, old streaming, 32820 +github.tar, uncompressed literals optimal, old streaming, 32506 github.tar, huffman literals, old streaming, 42465 silesia, level -5, old streaming advanced, 6882505 silesia, level -3, old streaming advanced, 6568376 @@ -1296,8 +1296,8 @@ silesia, level 6, old stre silesia, level 7, old streaming advanced, 4567203 silesia, level 9, old streaming advanced, 4543311 silesia, level 13, old streaming advanced, 4493990 -silesia, level 16, old streaming advanced, 4360072 -silesia, level 19, old streaming advanced, 4282792 +silesia, level 16, old streaming advanced, 4358530 +silesia, level 19, old streaming advanced, 4288570 silesia, no source size, old streaming advanced, 4849515 silesia, long distance mode, old streaming advanced, 4849551 silesia, multithreaded, old streaming advanced, 4849551 @@ -1307,7 +1307,7 @@ silesia, small hash log, old stre silesia, small chain log, old streaming advanced, 4912199 silesia, explicit params, old streaming advanced, 4795884 silesia, uncompressed literals, old streaming advanced, 4849551 -silesia, uncompressed literals optimal, old streaming advanced, 4282792 +silesia, uncompressed literals optimal, old streaming advanced, 4288570 silesia, huffman literals, old streaming advanced, 6183403 silesia, multithreaded with advanced params, old streaming advanced, 4849551 silesia.tar, level -5, old streaming advanced, 6982759 @@ -1322,8 +1322,8 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming advanced, 4576830 silesia.tar, level 9, old streaming advanced, 4552590 silesia.tar, level 13, old streaming advanced, 4502955 -silesia.tar, level 16, old streaming advanced, 4356970 -silesia.tar, level 19, old streaming advanced, 4264314 +silesia.tar, level 16, old streaming advanced, 4358753 +silesia.tar, level 19, old streaming advanced, 4263936 silesia.tar, no source size, old streaming advanced, 4861421 silesia.tar, long distance mode, old streaming advanced, 4861425 silesia.tar, multithreaded, old streaming advanced, 4861425 @@ -1333,7 +1333,7 @@ silesia.tar, small hash log, old stre silesia.tar, small chain log, old streaming advanced, 4917019 silesia.tar, explicit params, old streaming advanced, 4807403 silesia.tar, uncompressed literals, old streaming advanced, 4861425 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4264314 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4263936 silesia.tar, huffman literals, old streaming advanced, 6190795 silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 github, level -5, old streaming advanced, 216734 @@ -1401,10 +1401,10 @@ github.tar, level 9, old stre github.tar, level 9 with dict, old streaming advanced, 36233 github.tar, level 13, old streaming advanced, 35501 github.tar, level 13 with dict, old streaming advanced, 35807 -github.tar, level 16, old streaming advanced, 40255 -github.tar, level 16 with dict, old streaming advanced, 38736 -github.tar, level 19, old streaming advanced, 32820 -github.tar, level 19 with dict, old streaming advanced, 32876 +github.tar, level 16, old streaming advanced, 40357 +github.tar, level 16 with dict, old streaming advanced, 38730 +github.tar, level 19, old streaming advanced, 32506 +github.tar, level 19 with dict, old streaming advanced, 32900 github.tar, no source size, old streaming advanced, 38438 github.tar, no source size with dict, old streaming advanced, 38015 github.tar, long distance mode, old streaming advanced, 38441 @@ -1415,7 +1415,7 @@ github.tar, small hash log, old stre github.tar, small chain log, old streaming advanced, 41669 github.tar, explicit params, old streaming advanced, 41227 github.tar, uncompressed literals, old streaming advanced, 38441 -github.tar, uncompressed literals optimal, old streaming advanced, 32820 +github.tar, uncompressed literals optimal, old streaming advanced, 32506 github.tar, huffman literals, old streaming advanced, 42465 github.tar, multithreaded with advanced params, old streaming advanced, 38441 github, level -5 with dict, old streaming cdict, 46718 @@ -1445,8 +1445,8 @@ github.tar, level 6 with dict, old stre github.tar, level 7 with dict, old streaming cdict, 37371 github.tar, level 9 with dict, old streaming cdict, 36352 github.tar, level 13 with dict, old streaming cdict, 36010 -github.tar, level 16 with dict, old streaming cdict, 39353 -github.tar, level 19 with dict, old streaming cdict, 32676 +github.tar, level 16 with dict, old streaming cdict, 39064 +github.tar, level 19 with dict, old streaming cdict, 32570 github.tar, no source size with dict, old streaming cdict, 38000 github, level -5 with dict, old streaming advanced cdict, 49562 github, level -3 with dict, old streaming advanced cdict, 44956 @@ -1475,6 +1475,6 @@ github.tar, level 6 with dict, old stre github.tar, level 7 with dict, old streaming advanced cdict, 37322 github.tar, level 9 with dict, old streaming advanced cdict, 36233 github.tar, level 13 with dict, old streaming advanced cdict, 35807 -github.tar, level 16 with dict, old streaming advanced cdict, 38736 -github.tar, level 19 with dict, old streaming advanced cdict, 32876 +github.tar, level 16 with dict, old streaming advanced cdict, 38730 +github.tar, level 19 with dict, old streaming advanced cdict, 32900 github.tar, no source size with dict, old streaming advanced cdict, 38015 From 42a3ed752a473d813e84ac9cf5d86589060a54ce Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Sep 2021 07:56:43 -0700 Subject: [PATCH 145/274] removed frequency booster for stat initialization of btultra2 used to be necessary to counter-balance the fixed-weight frequency update which has been recently changed for an adaptive rate (targeting stable starting frequency stats). --- lib/compress/zstd_opt.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index a7b23e798..f77d5eb00 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -14,7 +14,6 @@ #define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */ -#define ZSTD_FREQ_DIV 4 /* log factor when using previous stats to init next stats */ #define ZSTD_MAX_PRICE (1<<30) #define ZSTD_PREDEF_THRESHOLD 1024 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */ @@ -1253,28 +1252,7 @@ size_t ZSTD_compressBlock_btopt( } -/* used in 2-pass strategy */ -static U32 ZSTD_upscaleStat(unsigned* table, U32 lastEltIndex, int bonus) -{ - U32 s, sum=0; - assert(ZSTD_FREQ_DIV+bonus >= 0); - for (s=0; slitSum = ZSTD_upscaleStat(optPtr->litFreq, MaxLit, 0); - optPtr->litLengthSum = ZSTD_upscaleStat(optPtr->litLengthFreq, MaxLL, 0); - optPtr->matchLengthSum = ZSTD_upscaleStat(optPtr->matchLengthFreq, MaxML, 0); - optPtr->offCodeSum = ZSTD_upscaleStat(optPtr->offCodeFreq, MaxOff, 0); -} /* ZSTD_initStats_ultra(): * make a first compression pass, just to seed stats with more accurate starting values. @@ -1305,8 +1283,6 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms, ms->window.lowLimit = ms->window.dictLimit; ms->nextToUpdate = ms->window.dictLimit; - /* re-inforce weight of collected statistics */ - ZSTD_upscaleStats(&ms->opt); } size_t ZSTD_compressBlock_btultra( From ef78611c269bc96cf88748cdd0e6d9e5c3ad74b7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Sep 2021 08:58:28 -0700 Subject: [PATCH 146/274] change update rate to 11/10/10/10 better for larger blocks, very small inefficiency on small block. --- lib/compress/zstd_opt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index f77d5eb00..9f658bee4 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -228,10 +228,10 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, } else { /* new block : re-use previous statistics, scaled down */ if (compressedLiterals) - optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 10); - optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 9); - optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 9); - optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 9); + optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 11); + optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 10); + optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 10); + optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 10); } ZSTD_setBasePrices(optPtr, optLevel); From 7fce9a41b599eab4c5e586a984e436a38eee7121 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Sep 2021 14:05:57 -0700 Subject: [PATCH 147/274] change update rate to 12/11/11/11 better for large files, and sources with relatively "stable" entropy, like silesia.tar. slightly worse for files with rapidly changing entropy, like Calgary.tar/. Updated small files tests in fuzzer --- lib/compress/zstd_opt.c | 8 ++++---- tests/fuzzer.c | 26 ++++++++++++-------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 9f658bee4..a42bd66ef 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -228,10 +228,10 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, } else { /* new block : re-use previous statistics, scaled down */ if (compressedLiterals) - optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 11); - optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 10); - optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 10); - optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 10); + optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12); + optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11); + optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11); + optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11); } ZSTD_setBasePrices(optPtr, optLevel); diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 92a2efa42..15e6d6ce0 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -42,7 +42,7 @@ #include "util.h" #include "timefn.h" /* SEC_TO_MICRO, UTIL_time_t, UTIL_TIME_INITIALIZER, UTIL_clockSpanMicro, UTIL_getTime */ /* must be included after util.h, due to ERROR macro redefinition issue on Visual Studio */ -#include "zstd_internal.h" /* ZSTD_WORKSPACETOOLARGE_MAXDURATION, ZSTD_WORKSPACETOOLARGE_FACTOR, KB, MB */ +#include "zstd_internal.h" /* ZSTD_WORKSPACETOOLARGE_MAXDURATION, ZSTD_WORKSPACETOOLARGE_FACTOR, KB, MB */ #include "threading.h" /* ZSTD_pthread_create, ZSTD_pthread_join */ @@ -128,7 +128,7 @@ static U32 FUZ_highbit32(U32 v32) #define CHECK_VAR(var, fn) var = fn; if (ZSTD_isError(var)) { DISPLAYLEVEL(1, "%s : fails : %s \n", #fn, ZSTD_getErrorName(var)); goto _output_error; } #define CHECK_NEWV(var, fn) size_t const CHECK_VAR(var, fn) -#define CHECK(fn) { CHECK_NEWV(err, fn); } +#define CHECK(fn) { CHECK_NEWV(__err, fn); } #define CHECKPLUS(var, fn, more) { CHECK_NEWV(var, fn); more; } #define CHECK_OP(op, lhs, rhs) { \ @@ -1956,6 +1956,9 @@ static int basicUnitTests(U32 const seed, double compressibility) } } DISPLAYLEVEL(3, "OK \n"); + /* Note : these tests should be replaced by proper regression tests, + * but existing ones do not focus on small data + dictionary + all levels. + */ if ((int)(compressibility * 100 + 0.1) == FUZ_compressibility_default) { /* test only valid with known input */ size_t const flatdictSize = 22 KB; size_t const contentSize = 9 KB; @@ -1964,14 +1967,14 @@ static int basicUnitTests(U32 const seed, double compressibility) /* These upper bounds are generally within a few bytes of the compressed size */ size_t target_nodict_cSize[22+1] = { 3840, 3770, 3870, 3830, 3770, 3770, 3770, 3770, 3750, 3750, - 3742, 3670, 3670, 3660, 3660, - 3660, 3660, 3660, 3660, 3660, + 3742, 3675, 3674, 3665, 3664, + 3663, 3662, 3661, 3660, 3660, 3660, 3660, 3660 }; size_t const target_wdict_cSize[22+1] = { 2830, 2890, 2890, 2820, 2940, 2950, 2950, 2925, 2900, 2891, - 2910, 2910, 2910, 2770, 2760, - 2750, 2750, 2750, 2750, 2750, - 2750, 2750, 2750 }; + 2910, 2910, 2910, 2780, 2775, + 2765, 2760, 2755, 2754, 2753, + 2753, 2753, 2753 }; int l = 1; int const maxLevel = ZSTD_maxCLevel(); /* clevels with strategies that support rowhash on small inputs */ @@ -3472,11 +3475,7 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(3, "error! l: %d dict: %zu srcSize: %zu cctx size cpar: %zu, cctx size level: %zu\n", level, dictSize, srcSize, cctxSizeUsingCParams, cctxSizeUsingLevel); goto _output_error; - } - } - } - } - } + } } } } } DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "test%3i : thread pool API tests : \n", testNb++) @@ -3592,8 +3591,7 @@ static int longUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "longtest%3i : testing ldm no regressions in size for opt parser : ", testNb++); - { - size_t cSizeLdm; + { size_t cSizeLdm; size_t cSizeNoLdm; ZSTD_CCtx* const cctx = ZSTD_createCCtx(); From 4f0b1b9ee5b6e1000c36e4696758ecd57cdb39b7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Sep 2021 14:37:42 -0700 Subject: [PATCH 148/274] update regression tests --- tests/regression/results.csv | 234 +++++++++++++++++------------------ 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index ee02857c1..8fb176965 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -11,10 +11,10 @@ silesia.tar, level 6, compress silesia.tar, level 7, compress simple, 4576828 silesia.tar, level 9, compress simple, 4552584 silesia.tar, level 13, compress simple, 4502955 -silesia.tar, level 16, compress simple, 4358753 -silesia.tar, level 19, compress simple, 4263936 +silesia.tar, level 16, compress simple, 4360526 +silesia.tar, level 19, compress simple, 4267266 silesia.tar, uncompressed literals, compress simple, 4861423 -silesia.tar, uncompressed literals optimal, compress simple, 4263936 +silesia.tar, uncompressed literals optimal, compress simple, 4267266 silesia.tar, huffman literals, compress simple, 6186042 github.tar, level -5, compress simple, 46856 github.tar, level -3, compress simple, 43754 @@ -28,10 +28,10 @@ github.tar, level 6, compress github.tar, level 7, compress simple, 38073 github.tar, level 9, compress simple, 36767 github.tar, level 13, compress simple, 35501 -github.tar, level 16, compress simple, 40357 -github.tar, level 19, compress simple, 32506 +github.tar, level 16, compress simple, 40471 +github.tar, level 19, compress simple, 32134 github.tar, uncompressed literals, compress simple, 38441 -github.tar, uncompressed literals optimal, compress simple, 32506 +github.tar, uncompressed literals optimal, compress simple, 32134 github.tar, huffman literals, compress simple, 42490 silesia, level -5, compress cctx, 6737607 silesia, level -3, compress cctx, 6444677 @@ -45,8 +45,8 @@ silesia, level 6, compress silesia, level 7, compress cctx, 4567203 silesia, level 9, compress cctx, 4543311 silesia, level 13, compress cctx, 4493990 -silesia, level 16, compress cctx, 4358530 -silesia, level 19, compress cctx, 4288570 +silesia, level 16, compress cctx, 4359864 +silesia, level 19, compress cctx, 4296880 silesia, long distance mode, compress cctx, 4849551 silesia, multithreaded, compress cctx, 4849551 silesia, multithreaded long distance mode, compress cctx, 4849551 @@ -55,7 +55,7 @@ silesia, small hash log, compress silesia, small chain log, compress cctx, 4912199 silesia, explicit params, compress cctx, 4794480 silesia, uncompressed literals, compress cctx, 4849551 -silesia, uncompressed literals optimal, compress cctx, 4288570 +silesia, uncompressed literals optimal, compress cctx, 4296880 silesia, huffman literals, compress cctx, 6178460 silesia, multithreaded with advanced params, compress cctx, 4849551 github, level -5, compress cctx, 205285 @@ -109,8 +109,8 @@ silesia, level 6, zstdcli, silesia, level 7, zstdcli, 4567251 silesia, level 9, zstdcli, 4543359 silesia, level 13, zstdcli, 4494038 -silesia, level 16, zstdcli, 4358578 -silesia, level 19, zstdcli, 4288618 +silesia, level 16, zstdcli, 4359912 +silesia, level 19, zstdcli, 4296928 silesia, long distance mode, zstdcli, 4840807 silesia, multithreaded, zstdcli, 4849599 silesia, multithreaded long distance mode, zstdcli, 4840807 @@ -119,7 +119,7 @@ silesia, small hash log, zstdcli, silesia, small chain log, zstdcli, 4912247 silesia, explicit params, zstdcli, 4795856 silesia, uncompressed literals, zstdcli, 5128030 -silesia, uncompressed literals optimal, zstdcli, 4318014 +silesia, uncompressed literals optimal, zstdcli, 4319566 silesia, huffman literals, zstdcli, 5326317 silesia, multithreaded with advanced params, zstdcli, 5128030 silesia.tar, level -5, zstdcli, 6738934 @@ -134,8 +134,8 @@ silesia.tar, level 6, zstdcli, silesia.tar, level 7, zstdcli, 4578883 silesia.tar, level 9, zstdcli, 4553498 silesia.tar, level 13, zstdcli, 4502959 -silesia.tar, level 16, zstdcli, 4358757 -silesia.tar, level 19, zstdcli, 4263940 +silesia.tar, level 16, zstdcli, 4360530 +silesia.tar, level 19, zstdcli, 4267270 silesia.tar, no source size, zstdcli, 4861507 silesia.tar, long distance mode, zstdcli, 4853225 silesia.tar, multithreaded, zstdcli, 4861511 @@ -145,7 +145,7 @@ silesia.tar, small hash log, zstdcli, silesia.tar, small chain log, zstdcli, 4917020 silesia.tar, explicit params, zstdcli, 4821277 silesia.tar, uncompressed literals, zstdcli, 5129559 -silesia.tar, uncompressed literals optimal, zstdcli, 4307883 +silesia.tar, uncompressed literals optimal, zstdcli, 4310145 silesia.tar, huffman literals, zstdcli, 5347610 silesia.tar, multithreaded with advanced params, zstdcli, 5129559 github, level -5, zstdcli, 207285 @@ -210,11 +210,11 @@ github.tar, level 7 with dict, zstdcli, github.tar, level 9, zstdcli, 36771 github.tar, level 9 with dict, zstdcli, 36623 github.tar, level 13, zstdcli, 35505 -github.tar, level 13 with dict, zstdcli, 37009 -github.tar, level 16, zstdcli, 40361 -github.tar, level 16 with dict, zstdcli, 33479 -github.tar, level 19, zstdcli, 32510 -github.tar, level 19 with dict, zstdcli, 32973 +github.tar, level 13 with dict, zstdcli, 37134 +github.tar, level 16, zstdcli, 40475 +github.tar, level 16 with dict, zstdcli, 33382 +github.tar, level 19, zstdcli, 32138 +github.tar, level 19 with dict, zstdcli, 32713 github.tar, no source size, zstdcli, 38442 github.tar, no source size with dict, zstdcli, 38004 github.tar, long distance mode, zstdcli, 39730 @@ -225,7 +225,7 @@ github.tar, small hash log, zstdcli, github.tar, small chain log, zstdcli, 41673 github.tar, explicit params, zstdcli, 41227 github.tar, uncompressed literals, zstdcli, 41126 -github.tar, uncompressed literals optimal, zstdcli, 35284 +github.tar, uncompressed literals optimal, zstdcli, 35401 github.tar, huffman literals, zstdcli, 38781 github.tar, multithreaded with advanced params, zstdcli, 41126 silesia, level -5, advanced one pass, 6737607 @@ -248,8 +248,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced one pass, 4503117 silesia, level 12 row 2, advanced one pass, 4505152 silesia, level 13, advanced one pass, 4493990 -silesia, level 16, advanced one pass, 4358530 -silesia, level 19, advanced one pass, 4288570 +silesia, level 16, advanced one pass, 4359864 +silesia, level 19, advanced one pass, 4296880 silesia, no source size, advanced one pass, 4849551 silesia, long distance mode, advanced one pass, 4840738 silesia, multithreaded, advanced one pass, 4849551 @@ -259,7 +259,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced one pass, 4912199 silesia, explicit params, advanced one pass, 4795856 silesia, uncompressed literals, advanced one pass, 5127982 -silesia, uncompressed literals optimal, advanced one pass, 4317966 +silesia, uncompressed literals optimal, advanced one pass, 4319518 silesia, huffman literals, advanced one pass, 5326269 silesia, multithreaded with advanced params, advanced one pass, 5127982 silesia.tar, level -5, advanced one pass, 6738593 @@ -282,8 +282,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced one pass, 4513603 silesia.tar, level 12 row 2, advanced one pass, 4514568 silesia.tar, level 13, advanced one pass, 4502955 -silesia.tar, level 16, advanced one pass, 4358753 -silesia.tar, level 19, advanced one pass, 4263936 +silesia.tar, level 16, advanced one pass, 4360526 +silesia.tar, level 19, advanced one pass, 4267266 silesia.tar, no source size, advanced one pass, 4861423 silesia.tar, long distance mode, advanced one pass, 4847753 silesia.tar, multithreaded, advanced one pass, 4861507 @@ -293,7 +293,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced one pass, 4917039 silesia.tar, explicit params, advanced one pass, 4807383 silesia.tar, uncompressed literals, advanced one pass, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass, 4307879 +silesia.tar, uncompressed literals optimal, advanced one pass, 4310141 silesia.tar, huffman literals, advanced one pass, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 github, level -5, advanced one pass, 205285 @@ -516,23 +516,23 @@ github.tar, level 12 row 2 with dict dds, advanced github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 github.tar, level 12 row 2 with dict load, advanced one pass, 36460 github.tar, level 13, advanced one pass, 35501 -github.tar, level 13 with dict, advanced one pass, 37005 -github.tar, level 13 with dict dms, advanced one pass, 37180 -github.tar, level 13 with dict dds, advanced one pass, 37180 -github.tar, level 13 with dict copy, advanced one pass, 37005 +github.tar, level 13 with dict, advanced one pass, 37130 +github.tar, level 13 with dict dms, advanced one pass, 37267 +github.tar, level 13 with dict dds, advanced one pass, 37267 +github.tar, level 13 with dict copy, advanced one pass, 37130 github.tar, level 13 with dict load, advanced one pass, 36010 -github.tar, level 16, advanced one pass, 40357 -github.tar, level 16 with dict, advanced one pass, 33475 -github.tar, level 16 with dict dms, advanced one pass, 33357 -github.tar, level 16 with dict dds, advanced one pass, 33357 -github.tar, level 16 with dict copy, advanced one pass, 33475 -github.tar, level 16 with dict load, advanced one pass, 39064 -github.tar, level 19, advanced one pass, 32506 -github.tar, level 19 with dict, advanced one pass, 32969 -github.tar, level 19 with dict dms, advanced one pass, 32624 -github.tar, level 19 with dict dds, advanced one pass, 32624 -github.tar, level 19 with dict copy, advanced one pass, 32969 -github.tar, level 19 with dict load, advanced one pass, 32570 +github.tar, level 16, advanced one pass, 40471 +github.tar, level 16 with dict, advanced one pass, 33378 +github.tar, level 16 with dict dms, advanced one pass, 33213 +github.tar, level 16 with dict dds, advanced one pass, 33213 +github.tar, level 16 with dict copy, advanced one pass, 33378 +github.tar, level 16 with dict load, advanced one pass, 39081 +github.tar, level 19, advanced one pass, 32134 +github.tar, level 19 with dict, advanced one pass, 32709 +github.tar, level 19 with dict dms, advanced one pass, 32553 +github.tar, level 19 with dict dds, advanced one pass, 32553 +github.tar, level 19 with dict copy, advanced one pass, 32709 +github.tar, level 19 with dict load, advanced one pass, 32474 github.tar, no source size, advanced one pass, 38441 github.tar, no source size with dict, advanced one pass, 37995 github.tar, long distance mode, advanced one pass, 39757 @@ -543,7 +543,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass, 41669 github.tar, explicit params, advanced one pass, 41227 github.tar, uncompressed literals, advanced one pass, 41122 -github.tar, uncompressed literals optimal, advanced one pass, 35280 +github.tar, uncompressed literals optimal, advanced one pass, 35397 github.tar, huffman literals, advanced one pass, 38777 github.tar, multithreaded with advanced params, advanced one pass, 41122 silesia, level -5, advanced one pass small out, 6737607 @@ -566,8 +566,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced one pass small out, 4503117 silesia, level 12 row 2, advanced one pass small out, 4505152 silesia, level 13, advanced one pass small out, 4493990 -silesia, level 16, advanced one pass small out, 4358530 -silesia, level 19, advanced one pass small out, 4288570 +silesia, level 16, advanced one pass small out, 4359864 +silesia, level 19, advanced one pass small out, 4296880 silesia, no source size, advanced one pass small out, 4849551 silesia, long distance mode, advanced one pass small out, 4840738 silesia, multithreaded, advanced one pass small out, 4849551 @@ -577,7 +577,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced one pass small out, 4912199 silesia, explicit params, advanced one pass small out, 4795856 silesia, uncompressed literals, advanced one pass small out, 5127982 -silesia, uncompressed literals optimal, advanced one pass small out, 4317966 +silesia, uncompressed literals optimal, advanced one pass small out, 4319518 silesia, huffman literals, advanced one pass small out, 5326269 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 silesia.tar, level -5, advanced one pass small out, 6738593 @@ -600,8 +600,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced one pass small out, 4513603 silesia.tar, level 12 row 2, advanced one pass small out, 4514568 silesia.tar, level 13, advanced one pass small out, 4502955 -silesia.tar, level 16, advanced one pass small out, 4358753 -silesia.tar, level 19, advanced one pass small out, 4263936 +silesia.tar, level 16, advanced one pass small out, 4360526 +silesia.tar, level 19, advanced one pass small out, 4267266 silesia.tar, no source size, advanced one pass small out, 4861423 silesia.tar, long distance mode, advanced one pass small out, 4847753 silesia.tar, multithreaded, advanced one pass small out, 4861507 @@ -611,7 +611,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced one pass small out, 4917039 silesia.tar, explicit params, advanced one pass small out, 4807383 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307879 +silesia.tar, uncompressed literals optimal, advanced one pass small out, 4310141 silesia.tar, huffman literals, advanced one pass small out, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 github, level -5, advanced one pass small out, 205285 @@ -834,23 +834,23 @@ github.tar, level 12 row 2 with dict dds, advanced github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 github.tar, level 12 row 2 with dict load, advanced one pass small out, 36460 github.tar, level 13, advanced one pass small out, 35501 -github.tar, level 13 with dict, advanced one pass small out, 37005 -github.tar, level 13 with dict dms, advanced one pass small out, 37180 -github.tar, level 13 with dict dds, advanced one pass small out, 37180 -github.tar, level 13 with dict copy, advanced one pass small out, 37005 +github.tar, level 13 with dict, advanced one pass small out, 37130 +github.tar, level 13 with dict dms, advanced one pass small out, 37267 +github.tar, level 13 with dict dds, advanced one pass small out, 37267 +github.tar, level 13 with dict copy, advanced one pass small out, 37130 github.tar, level 13 with dict load, advanced one pass small out, 36010 -github.tar, level 16, advanced one pass small out, 40357 -github.tar, level 16 with dict, advanced one pass small out, 33475 -github.tar, level 16 with dict dms, advanced one pass small out, 33357 -github.tar, level 16 with dict dds, advanced one pass small out, 33357 -github.tar, level 16 with dict copy, advanced one pass small out, 33475 -github.tar, level 16 with dict load, advanced one pass small out, 39064 -github.tar, level 19, advanced one pass small out, 32506 -github.tar, level 19 with dict, advanced one pass small out, 32969 -github.tar, level 19 with dict dms, advanced one pass small out, 32624 -github.tar, level 19 with dict dds, advanced one pass small out, 32624 -github.tar, level 19 with dict copy, advanced one pass small out, 32969 -github.tar, level 19 with dict load, advanced one pass small out, 32570 +github.tar, level 16, advanced one pass small out, 40471 +github.tar, level 16 with dict, advanced one pass small out, 33378 +github.tar, level 16 with dict dms, advanced one pass small out, 33213 +github.tar, level 16 with dict dds, advanced one pass small out, 33213 +github.tar, level 16 with dict copy, advanced one pass small out, 33378 +github.tar, level 16 with dict load, advanced one pass small out, 39081 +github.tar, level 19, advanced one pass small out, 32134 +github.tar, level 19 with dict, advanced one pass small out, 32709 +github.tar, level 19 with dict dms, advanced one pass small out, 32553 +github.tar, level 19 with dict dds, advanced one pass small out, 32553 +github.tar, level 19 with dict copy, advanced one pass small out, 32709 +github.tar, level 19 with dict load, advanced one pass small out, 32474 github.tar, no source size, advanced one pass small out, 38441 github.tar, no source size with dict, advanced one pass small out, 37995 github.tar, long distance mode, advanced one pass small out, 39757 @@ -861,7 +861,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced one pass small out, 41669 github.tar, explicit params, advanced one pass small out, 41227 github.tar, uncompressed literals, advanced one pass small out, 41122 -github.tar, uncompressed literals optimal, advanced one pass small out, 35280 +github.tar, uncompressed literals optimal, advanced one pass small out, 35397 github.tar, huffman literals, advanced one pass small out, 38777 github.tar, multithreaded with advanced params, advanced one pass small out, 41122 silesia, level -5, advanced streaming, 6882505 @@ -884,8 +884,8 @@ silesia, level 11 row 2, advanced silesia, level 12 row 1, advanced streaming, 4503117 silesia, level 12 row 2, advanced streaming, 4505152 silesia, level 13, advanced streaming, 4493990 -silesia, level 16, advanced streaming, 4358530 -silesia, level 19, advanced streaming, 4288570 +silesia, level 16, advanced streaming, 4359864 +silesia, level 19, advanced streaming, 4296880 silesia, no source size, advanced streaming, 4849515 silesia, long distance mode, advanced streaming, 4840738 silesia, multithreaded, advanced streaming, 4849551 @@ -895,7 +895,7 @@ silesia, small hash log, advanced silesia, small chain log, advanced streaming, 4912199 silesia, explicit params, advanced streaming, 4795884 silesia, uncompressed literals, advanced streaming, 5127982 -silesia, uncompressed literals optimal, advanced streaming, 4317966 +silesia, uncompressed literals optimal, advanced streaming, 4319518 silesia, huffman literals, advanced streaming, 5331171 silesia, multithreaded with advanced params, advanced streaming, 5127982 silesia.tar, level -5, advanced streaming, 6982759 @@ -918,8 +918,8 @@ silesia.tar, level 11 row 2, advanced silesia.tar, level 12 row 1, advanced streaming, 4513603 silesia.tar, level 12 row 2, advanced streaming, 4514569 silesia.tar, level 13, advanced streaming, 4502955 -silesia.tar, level 16, advanced streaming, 4358753 -silesia.tar, level 19, advanced streaming, 4263936 +silesia.tar, level 16, advanced streaming, 4360526 +silesia.tar, level 19, advanced streaming, 4267266 silesia.tar, no source size, advanced streaming, 4861421 silesia.tar, long distance mode, advanced streaming, 4847753 silesia.tar, multithreaded, advanced streaming, 4861507 @@ -929,7 +929,7 @@ silesia.tar, small hash log, advanced silesia.tar, small chain log, advanced streaming, 4917019 silesia.tar, explicit params, advanced streaming, 4807403 silesia.tar, uncompressed literals, advanced streaming, 5129461 -silesia.tar, uncompressed literals optimal, advanced streaming, 4307879 +silesia.tar, uncompressed literals optimal, advanced streaming, 4310141 silesia.tar, huffman literals, advanced streaming, 5352360 silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 github, level -5, advanced streaming, 205285 @@ -1152,23 +1152,23 @@ github.tar, level 12 row 2 with dict dds, advanced github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 github.tar, level 12 row 2 with dict load, advanced streaming, 36460 github.tar, level 13, advanced streaming, 35501 -github.tar, level 13 with dict, advanced streaming, 37005 -github.tar, level 13 with dict dms, advanced streaming, 37180 -github.tar, level 13 with dict dds, advanced streaming, 37180 -github.tar, level 13 with dict copy, advanced streaming, 37005 +github.tar, level 13 with dict, advanced streaming, 37130 +github.tar, level 13 with dict dms, advanced streaming, 37267 +github.tar, level 13 with dict dds, advanced streaming, 37267 +github.tar, level 13 with dict copy, advanced streaming, 37130 github.tar, level 13 with dict load, advanced streaming, 36010 -github.tar, level 16, advanced streaming, 40357 -github.tar, level 16 with dict, advanced streaming, 33475 -github.tar, level 16 with dict dms, advanced streaming, 33357 -github.tar, level 16 with dict dds, advanced streaming, 33357 -github.tar, level 16 with dict copy, advanced streaming, 33475 -github.tar, level 16 with dict load, advanced streaming, 39064 -github.tar, level 19, advanced streaming, 32506 -github.tar, level 19 with dict, advanced streaming, 32969 -github.tar, level 19 with dict dms, advanced streaming, 32624 -github.tar, level 19 with dict dds, advanced streaming, 32624 -github.tar, level 19 with dict copy, advanced streaming, 32969 -github.tar, level 19 with dict load, advanced streaming, 32570 +github.tar, level 16, advanced streaming, 40471 +github.tar, level 16 with dict, advanced streaming, 33378 +github.tar, level 16 with dict dms, advanced streaming, 33213 +github.tar, level 16 with dict dds, advanced streaming, 33213 +github.tar, level 16 with dict copy, advanced streaming, 33378 +github.tar, level 16 with dict load, advanced streaming, 39081 +github.tar, level 19, advanced streaming, 32134 +github.tar, level 19 with dict, advanced streaming, 32709 +github.tar, level 19 with dict dms, advanced streaming, 32553 +github.tar, level 19 with dict dds, advanced streaming, 32553 +github.tar, level 19 with dict copy, advanced streaming, 32709 +github.tar, level 19 with dict load, advanced streaming, 32474 github.tar, no source size, advanced streaming, 38438 github.tar, no source size with dict, advanced streaming, 38000 github.tar, long distance mode, advanced streaming, 39757 @@ -1179,7 +1179,7 @@ github.tar, small hash log, advanced github.tar, small chain log, advanced streaming, 41669 github.tar, explicit params, advanced streaming, 41227 github.tar, uncompressed literals, advanced streaming, 41122 -github.tar, uncompressed literals optimal, advanced streaming, 35280 +github.tar, uncompressed literals optimal, advanced streaming, 35397 github.tar, huffman literals, advanced streaming, 38800 github.tar, multithreaded with advanced params, advanced streaming, 41122 silesia, level -5, old streaming, 6882505 @@ -1194,11 +1194,11 @@ silesia, level 6, old stre silesia, level 7, old streaming, 4567203 silesia, level 9, old streaming, 4543311 silesia, level 13, old streaming, 4493990 -silesia, level 16, old streaming, 4358530 -silesia, level 19, old streaming, 4288570 +silesia, level 16, old streaming, 4359864 +silesia, level 19, old streaming, 4296880 silesia, no source size, old streaming, 4849515 silesia, uncompressed literals, old streaming, 4849551 -silesia, uncompressed literals optimal, old streaming, 4288570 +silesia, uncompressed literals optimal, old streaming, 4296880 silesia, huffman literals, old streaming, 6183403 silesia.tar, level -5, old streaming, 6982759 silesia.tar, level -3, old streaming, 6641283 @@ -1212,11 +1212,11 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming, 4576830 silesia.tar, level 9, old streaming, 4552590 silesia.tar, level 13, old streaming, 4502955 -silesia.tar, level 16, old streaming, 4358753 -silesia.tar, level 19, old streaming, 4263936 +silesia.tar, level 16, old streaming, 4360526 +silesia.tar, level 19, old streaming, 4267266 silesia.tar, no source size, old streaming, 4861421 silesia.tar, uncompressed literals, old streaming, 4861425 -silesia.tar, uncompressed literals optimal, old streaming, 4263936 +silesia.tar, uncompressed literals optimal, old streaming, 4267266 silesia.tar, huffman literals, old streaming, 6190795 github, level -5, old streaming, 205285 github, level -5 with dict, old streaming, 46718 @@ -1274,15 +1274,15 @@ github.tar, level 7 with dict, old stre github.tar, level 9, old streaming, 36767 github.tar, level 9 with dict, old streaming, 36457 github.tar, level 13, old streaming, 35501 -github.tar, level 13 with dict, old streaming, 37005 -github.tar, level 16, old streaming, 40357 -github.tar, level 16 with dict, old streaming, 33475 -github.tar, level 19, old streaming, 32506 -github.tar, level 19 with dict, old streaming, 32969 +github.tar, level 13 with dict, old streaming, 37130 +github.tar, level 16, old streaming, 40471 +github.tar, level 16 with dict, old streaming, 33378 +github.tar, level 19, old streaming, 32134 +github.tar, level 19 with dict, old streaming, 32709 github.tar, no source size, old streaming, 38438 github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38441 -github.tar, uncompressed literals optimal, old streaming, 32506 +github.tar, uncompressed literals optimal, old streaming, 32134 github.tar, huffman literals, old streaming, 42465 silesia, level -5, old streaming advanced, 6882505 silesia, level -3, old streaming advanced, 6568376 @@ -1296,8 +1296,8 @@ silesia, level 6, old stre silesia, level 7, old streaming advanced, 4567203 silesia, level 9, old streaming advanced, 4543311 silesia, level 13, old streaming advanced, 4493990 -silesia, level 16, old streaming advanced, 4358530 -silesia, level 19, old streaming advanced, 4288570 +silesia, level 16, old streaming advanced, 4359864 +silesia, level 19, old streaming advanced, 4296880 silesia, no source size, old streaming advanced, 4849515 silesia, long distance mode, old streaming advanced, 4849551 silesia, multithreaded, old streaming advanced, 4849551 @@ -1307,7 +1307,7 @@ silesia, small hash log, old stre silesia, small chain log, old streaming advanced, 4912199 silesia, explicit params, old streaming advanced, 4795884 silesia, uncompressed literals, old streaming advanced, 4849551 -silesia, uncompressed literals optimal, old streaming advanced, 4288570 +silesia, uncompressed literals optimal, old streaming advanced, 4296880 silesia, huffman literals, old streaming advanced, 6183403 silesia, multithreaded with advanced params, old streaming advanced, 4849551 silesia.tar, level -5, old streaming advanced, 6982759 @@ -1322,8 +1322,8 @@ silesia.tar, level 6, old stre silesia.tar, level 7, old streaming advanced, 4576830 silesia.tar, level 9, old streaming advanced, 4552590 silesia.tar, level 13, old streaming advanced, 4502955 -silesia.tar, level 16, old streaming advanced, 4358753 -silesia.tar, level 19, old streaming advanced, 4263936 +silesia.tar, level 16, old streaming advanced, 4360526 +silesia.tar, level 19, old streaming advanced, 4267266 silesia.tar, no source size, old streaming advanced, 4861421 silesia.tar, long distance mode, old streaming advanced, 4861425 silesia.tar, multithreaded, old streaming advanced, 4861425 @@ -1333,7 +1333,7 @@ silesia.tar, small hash log, old stre silesia.tar, small chain log, old streaming advanced, 4917019 silesia.tar, explicit params, old streaming advanced, 4807403 silesia.tar, uncompressed literals, old streaming advanced, 4861425 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4263936 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4267266 silesia.tar, huffman literals, old streaming advanced, 6190795 silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 github, level -5, old streaming advanced, 216734 @@ -1401,10 +1401,10 @@ github.tar, level 9, old stre github.tar, level 9 with dict, old streaming advanced, 36233 github.tar, level 13, old streaming advanced, 35501 github.tar, level 13 with dict, old streaming advanced, 35807 -github.tar, level 16, old streaming advanced, 40357 -github.tar, level 16 with dict, old streaming advanced, 38730 -github.tar, level 19, old streaming advanced, 32506 -github.tar, level 19 with dict, old streaming advanced, 32900 +github.tar, level 16, old streaming advanced, 40471 +github.tar, level 16 with dict, old streaming advanced, 38578 +github.tar, level 19, old streaming advanced, 32134 +github.tar, level 19 with dict, old streaming advanced, 32702 github.tar, no source size, old streaming advanced, 38438 github.tar, no source size with dict, old streaming advanced, 38015 github.tar, long distance mode, old streaming advanced, 38441 @@ -1415,7 +1415,7 @@ github.tar, small hash log, old stre github.tar, small chain log, old streaming advanced, 41669 github.tar, explicit params, old streaming advanced, 41227 github.tar, uncompressed literals, old streaming advanced, 38441 -github.tar, uncompressed literals optimal, old streaming advanced, 32506 +github.tar, uncompressed literals optimal, old streaming advanced, 32134 github.tar, huffman literals, old streaming advanced, 42465 github.tar, multithreaded with advanced params, old streaming advanced, 38441 github, level -5 with dict, old streaming cdict, 46718 @@ -1445,8 +1445,8 @@ github.tar, level 6 with dict, old stre github.tar, level 7 with dict, old streaming cdict, 37371 github.tar, level 9 with dict, old streaming cdict, 36352 github.tar, level 13 with dict, old streaming cdict, 36010 -github.tar, level 16 with dict, old streaming cdict, 39064 -github.tar, level 19 with dict, old streaming cdict, 32570 +github.tar, level 16 with dict, old streaming cdict, 39081 +github.tar, level 19 with dict, old streaming cdict, 32474 github.tar, no source size with dict, old streaming cdict, 38000 github, level -5 with dict, old streaming advanced cdict, 49562 github, level -3 with dict, old streaming advanced cdict, 44956 @@ -1475,6 +1475,6 @@ github.tar, level 6 with dict, old stre github.tar, level 7 with dict, old streaming advanced cdict, 37322 github.tar, level 9 with dict, old streaming advanced cdict, 36233 github.tar, level 13 with dict, old streaming advanced cdict, 35807 -github.tar, level 16 with dict, old streaming advanced cdict, 38730 -github.tar, level 19 with dict, old streaming advanced cdict, 32900 +github.tar, level 16 with dict, old streaming advanced cdict, 38578 +github.tar, level 19 with dict, old streaming advanced cdict, 32702 github.tar, no source size with dict, old streaming advanced cdict, 38015 From b7f46ebc234ba4ee691a2f19233179b3c90676f6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Sep 2021 14:45:53 -0700 Subject: [PATCH 149/274] use ZSTD_memcpy() for better portability notably within kernel space --- lib/compress/zstd_opt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index a42bd66ef..bb43c4ed0 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -204,7 +204,7 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); + ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); } { unsigned ml; @@ -219,7 +219,7 @@ ZSTD_rescaleFreqs(optState_t* const optPtr, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); + ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); } From 5449ede2e6e4f15d10b30f0908c8bd7b4182ced6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Sep 2021 15:12:28 -0700 Subject: [PATCH 150/274] make automated-benchmarking faster by employing parallel compilation of object files. --- tests/automated_benchmarking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/automated_benchmarking.py b/tests/automated_benchmarking.py index 458bda451..bd995b198 100644 --- a/tests/automated_benchmarking.py +++ b/tests/automated_benchmarking.py @@ -87,7 +87,7 @@ def clone_and_build(build): git clone {github_url} zstd-{user}-{sha} && cd zstd-{user}-{sha} && {checkout_command} - make && + make -j && cd ../ """.format( user=build["user"], @@ -100,7 +100,7 @@ def clone_and_build(build): ) return "zstd-{user}-{sha}/zstd".format(user=build["user"], sha=build["hash"]) else: - os.system("cd ../ && make && cd tests") + os.system("cd ../ && make -j && cd tests") return "../zstd" From 193aa49673f98c3ad5791dae7024a1c3ee791f38 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Mon, 6 Sep 2021 16:04:48 -0400 Subject: [PATCH 151/274] meson: fix type error for integer option meson forgave using the wrong type, but this isn't guaranteed. muon simply failed. --- build/meson/meson_options.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/meson/meson_options.txt b/build/meson/meson_options.txt index 90a81c539..accf3fa10 100644 --- a/build/meson/meson_options.txt +++ b/build/meson/meson_options.txt @@ -10,7 +10,7 @@ # Read guidelines from https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting -option('legacy_level', type: 'integer', min: 0, max: 7, value: '5', +option('legacy_level', type: 'integer', min: 0, max: 7, value: 5, description: 'Support any legacy format: 7 to 1 for v0.7+ to v0.1+') option('debug_level', type: 'integer', min: 0, max: 9, value: 1, description: 'Enable run-time debug. See lib/common/debug.h') From 640c5b1f7740193733bb6322a783903f18150a4b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 12 Sep 2021 01:36:18 -0700 Subject: [PATCH 152/274] fix automated_benchmarking make it able to process text output sent into either stdout or stderr --- programs/benchzstd.c | 5 +---- tests/automated_benchmarking.py | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 2366cf2d7..c7675057f 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -373,10 +373,7 @@ BMK_benchMemAdvancedNoAlloc( if (adv->mode == BMK_decodeOnly) { cSizes[nbBlocks] = thisBlockSize; benchResult.cSize = thisBlockSize; - } - } - } - } + } } } } /* warming up `compressedBuffer` */ if (adv->mode == BMK_decodeOnly) { diff --git a/tests/automated_benchmarking.py b/tests/automated_benchmarking.py index bd995b198..e6da90244 100644 --- a/tests/automated_benchmarking.py +++ b/tests/automated_benchmarking.py @@ -112,9 +112,9 @@ def parse_benchmark_output(output): def benchmark_single(executable, level, filename): return parse_benchmark_output(( subprocess.run( - [executable, "-qb{}".format(level), filename], stderr=subprocess.PIPE + [executable, "-qb{}".format(level), filename], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, ) - .stderr.decode("utf-8") + .stdout.decode("utf-8") .split(" ") )) @@ -145,7 +145,7 @@ def benchmark(build, filenames, levels, iterations): def benchmark_dictionary_single(executable, filenames_directory, dictionary_filename, level, iterations): cspeeds, dspeeds = [], [] for _ in range(iterations): - output = subprocess.run([executable, "-qb{}".format(level), "-D", dictionary_filename, "-r", filenames_directory], stderr=subprocess.PIPE).stderr.decode("utf-8").split(" ") + output = subprocess.run([executable, "-qb{}".format(level), "-D", dictionary_filename, "-r", filenames_directory], stdout=subprocess.PIPE).stdout.decode("utf-8").split(" ") cspeed, dspeed = parse_benchmark_output(output) cspeeds.append(cspeed) dspeeds.append(dspeed) From b6b2855b8060d20053dc81d0aa5dd1a0b822a8de Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 12 Sep 2021 10:22:35 -0700 Subject: [PATCH 153/274] updated regression tests --- tests/regression/results.csv | 262 +++++++++++++++++------------------ 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 503e5cef2..ba48c8111 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -97,137 +97,137 @@ github, uncompressed literals, compress github, uncompressed literals optimal, compress cctx, 134064 github, huffman literals, compress cctx, 175468 github, multithreaded with advanced params, compress cctx, 141102 -silesia, level -5, zstdcli, compression error -silesia, level -3, zstdcli, compression error -silesia, level -1, zstdcli, compression error -silesia, level 0, zstdcli, compression error -silesia, level 1, zstdcli, compression error -silesia, level 3, zstdcli, compression error -silesia, level 4, zstdcli, compression error -silesia, level 5, zstdcli, compression error -silesia, level 6, zstdcli, compression error -silesia, level 7, zstdcli, compression error -silesia, level 9, zstdcli, compression error -silesia, level 13, zstdcli, compression error -silesia, level 16, zstdcli, compression error -silesia, level 19, zstdcli, compression error -silesia, long distance mode, zstdcli, compression error -silesia, multithreaded, zstdcli, compression error -silesia, multithreaded long distance mode, zstdcli, compression error -silesia, small window log, zstdcli, compression error -silesia, small hash log, zstdcli, compression error -silesia, small chain log, zstdcli, compression error -silesia, explicit params, zstdcli, compression error -silesia, uncompressed literals, zstdcli, compression error -silesia, uncompressed literals optimal, zstdcli, compression error -silesia, huffman literals, zstdcli, compression error -silesia, multithreaded with advanced params, zstdcli, compression error -silesia.tar, level -5, zstdcli, compression error -silesia.tar, level -3, zstdcli, compression error -silesia.tar, level -1, zstdcli, compression error -silesia.tar, level 0, zstdcli, compression error -silesia.tar, level 1, zstdcli, compression error -silesia.tar, level 3, zstdcli, compression error -silesia.tar, level 4, zstdcli, compression error -silesia.tar, level 5, zstdcli, compression error -silesia.tar, level 6, zstdcli, compression error -silesia.tar, level 7, zstdcli, compression error -silesia.tar, level 9, zstdcli, compression error -silesia.tar, level 13, zstdcli, compression error -silesia.tar, level 16, zstdcli, compression error -silesia.tar, level 19, zstdcli, compression error -silesia.tar, no source size, zstdcli, compression error -silesia.tar, long distance mode, zstdcli, compression error -silesia.tar, multithreaded, zstdcli, compression error -silesia.tar, multithreaded long distance mode, zstdcli, compression error -silesia.tar, small window log, zstdcli, compression error -silesia.tar, small hash log, zstdcli, compression error -silesia.tar, small chain log, zstdcli, compression error -silesia.tar, explicit params, zstdcli, compression error -silesia.tar, uncompressed literals, zstdcli, compression error -silesia.tar, uncompressed literals optimal, zstdcli, compression error -silesia.tar, huffman literals, zstdcli, compression error -silesia.tar, multithreaded with advanced params, zstdcli, compression error -github, level -5, zstdcli, compression error -github, level -5 with dict, zstdcli, compression error -github, level -3, zstdcli, compression error -github, level -3 with dict, zstdcli, compression error -github, level -1, zstdcli, compression error -github, level -1 with dict, zstdcli, compression error -github, level 0, zstdcli, compression error -github, level 0 with dict, zstdcli, compression error -github, level 1, zstdcli, compression error -github, level 1 with dict, zstdcli, compression error -github, level 3, zstdcli, compression error -github, level 3 with dict, zstdcli, compression error -github, level 4, zstdcli, compression error -github, level 4 with dict, zstdcli, compression error -github, level 5, zstdcli, compression error -github, level 5 with dict, zstdcli, compression error -github, level 6, zstdcli, compression error -github, level 6 with dict, zstdcli, compression error -github, level 7, zstdcli, compression error -github, level 7 with dict, zstdcli, compression error -github, level 9, zstdcli, compression error -github, level 9 with dict, zstdcli, compression error -github, level 13, zstdcli, compression error -github, level 13 with dict, zstdcli, compression error -github, level 16, zstdcli, compression error -github, level 16 with dict, zstdcli, compression error -github, level 19, zstdcli, compression error -github, level 19 with dict, zstdcli, compression error -github, long distance mode, zstdcli, compression error -github, multithreaded, zstdcli, compression error -github, multithreaded long distance mode, zstdcli, compression error -github, small window log, zstdcli, compression error -github, small hash log, zstdcli, compression error -github, small chain log, zstdcli, compression error -github, explicit params, zstdcli, compression error -github, uncompressed literals, zstdcli, compression error -github, uncompressed literals optimal, zstdcli, compression error -github, huffman literals, zstdcli, compression error -github, multithreaded with advanced params, zstdcli, compression error -github.tar, level -5, zstdcli, compression error -github.tar, level -5 with dict, zstdcli, compression error -github.tar, level -3, zstdcli, compression error -github.tar, level -3 with dict, zstdcli, compression error -github.tar, level -1, zstdcli, compression error -github.tar, level -1 with dict, zstdcli, compression error -github.tar, level 0, zstdcli, compression error -github.tar, level 0 with dict, zstdcli, compression error -github.tar, level 1, zstdcli, compression error -github.tar, level 1 with dict, zstdcli, compression error -github.tar, level 3, zstdcli, compression error -github.tar, level 3 with dict, zstdcli, compression error -github.tar, level 4, zstdcli, compression error -github.tar, level 4 with dict, zstdcli, compression error -github.tar, level 5, zstdcli, compression error -github.tar, level 5 with dict, zstdcli, compression error -github.tar, level 6, zstdcli, compression error -github.tar, level 6 with dict, zstdcli, compression error -github.tar, level 7, zstdcli, compression error -github.tar, level 7 with dict, zstdcli, compression error -github.tar, level 9, zstdcli, compression error -github.tar, level 9 with dict, zstdcli, compression error -github.tar, level 13, zstdcli, compression error -github.tar, level 13 with dict, zstdcli, compression error -github.tar, level 16, zstdcli, compression error -github.tar, level 16 with dict, zstdcli, compression error -github.tar, level 19, zstdcli, compression error -github.tar, level 19 with dict, zstdcli, compression error -github.tar, no source size, zstdcli, compression error -github.tar, no source size with dict, zstdcli, compression error -github.tar, long distance mode, zstdcli, compression error -github.tar, multithreaded, zstdcli, compression error -github.tar, multithreaded long distance mode, zstdcli, compression error -github.tar, small window log, zstdcli, compression error -github.tar, small hash log, zstdcli, compression error -github.tar, small chain log, zstdcli, compression error -github.tar, explicit params, zstdcli, compression error -github.tar, uncompressed literals, zstdcli, compression error -github.tar, uncompressed literals optimal, zstdcli, compression error -github.tar, huffman literals, zstdcli, compression error -github.tar, multithreaded with advanced params, zstdcli, compression error +silesia, level -5, zstdcli, 7354723 +silesia, level -3, zstdcli, 6902422 +silesia, level -1, zstdcli, 6177613 +silesia, level 0, zstdcli, 4849599 +silesia, level 1, zstdcli, 5309145 +silesia, level 3, zstdcli, 4849599 +silesia, level 4, zstdcli, 4787017 +silesia, level 5, zstdcli, 4639008 +silesia, level 6, zstdcli, 4605417 +silesia, level 7, zstdcli, 4567251 +silesia, level 9, zstdcli, 4543359 +silesia, level 13, zstdcli, 4494038 +silesia, level 16, zstdcli, 4359912 +silesia, level 19, zstdcli, 4296928 +silesia, long distance mode, zstdcli, 4840807 +silesia, multithreaded, zstdcli, 4849599 +silesia, multithreaded long distance mode, zstdcli, 4840807 +silesia, small window log, zstdcli, 7095967 +silesia, small hash log, zstdcli, 6526189 +silesia, small chain log, zstdcli, 4912247 +silesia, explicit params, zstdcli, 4795856 +silesia, uncompressed literals, zstdcli, 5128030 +silesia, uncompressed literals optimal, zstdcli, 4319566 +silesia, huffman literals, zstdcli, 5326394 +silesia, multithreaded with advanced params, zstdcli, 5128030 +silesia.tar, level -5, zstdcli, 7363866 +silesia.tar, level -3, zstdcli, 6902158 +silesia.tar, level -1, zstdcli, 6182939 +silesia.tar, level 0, zstdcli, 4861511 +silesia.tar, level 1, zstdcli, 5333184 +silesia.tar, level 3, zstdcli, 4861511 +silesia.tar, level 4, zstdcli, 4800529 +silesia.tar, level 5, zstdcli, 4651159 +silesia.tar, level 6, zstdcli, 4618402 +silesia.tar, level 7, zstdcli, 4578883 +silesia.tar, level 9, zstdcli, 4553498 +silesia.tar, level 13, zstdcli, 4502959 +silesia.tar, level 16, zstdcli, 4360530 +silesia.tar, level 19, zstdcli, 4267270 +silesia.tar, no source size, zstdcli, 4861507 +silesia.tar, long distance mode, zstdcli, 4853225 +silesia.tar, multithreaded, zstdcli, 4861511 +silesia.tar, multithreaded long distance mode, zstdcli, 4853225 +silesia.tar, small window log, zstdcli, 7101576 +silesia.tar, small hash log, zstdcli, 6529286 +silesia.tar, small chain log, zstdcli, 4917020 +silesia.tar, explicit params, zstdcli, 4821277 +silesia.tar, uncompressed literals, zstdcli, 5129559 +silesia.tar, uncompressed literals optimal, zstdcli, 4310145 +silesia.tar, huffman literals, zstdcli, 5344915 +silesia.tar, multithreaded with advanced params, zstdcli, 5129559 +github, level -5, zstdcli, 234315 +github, level -5 with dict, zstdcli, 48718 +github, level -3, zstdcli, 222760 +github, level -3 with dict, zstdcli, 47395 +github, level -1, zstdcli, 177468 +github, level -1 with dict, zstdcli, 45170 +github, level 0, zstdcli, 138335 +github, level 0 with dict, zstdcli, 43148 +github, level 1, zstdcli, 144365 +github, level 1 with dict, zstdcli, 43682 +github, level 3, zstdcli, 138335 +github, level 3 with dict, zstdcli, 43148 +github, level 4, zstdcli, 138199 +github, level 4 with dict, zstdcli, 43251 +github, level 5, zstdcli, 137121 +github, level 5 with dict, zstdcli, 40728 +github, level 6, zstdcli, 137122 +github, level 6 with dict, zstdcli, 40636 +github, level 7, zstdcli, 137122 +github, level 7 with dict, zstdcli, 40745 +github, level 9, zstdcli, 137122 +github, level 9 with dict, zstdcli, 41393 +github, level 13, zstdcli, 136064 +github, level 13 with dict, zstdcli, 41743 +github, level 16, zstdcli, 136064 +github, level 16 with dict, zstdcli, 39577 +github, level 19, zstdcli, 136064 +github, level 19 with dict, zstdcli, 39576 +github, long distance mode, zstdcli, 138335 +github, multithreaded, zstdcli, 138335 +github, multithreaded long distance mode, zstdcli, 138335 +github, small window log, zstdcli, 138335 +github, small hash log, zstdcli, 137590 +github, small chain log, zstdcli, 138341 +github, explicit params, zstdcli, 136197 +github, uncompressed literals, zstdcli, 167915 +github, uncompressed literals optimal, zstdcli, 159227 +github, huffman literals, zstdcli, 144365 +github, multithreaded with advanced params, zstdcli, 167915 +github.tar, level -5, zstdcli, 66918 +github.tar, level -5 with dict, zstdcli, 51529 +github.tar, level -3, zstdcli, 52131 +github.tar, level -3 with dict, zstdcli, 44246 +github.tar, level -1, zstdcli, 42564 +github.tar, level -1 with dict, zstdcli, 41140 +github.tar, level 0, zstdcli, 38445 +github.tar, level 0 with dict, zstdcli, 37999 +github.tar, level 1, zstdcli, 39204 +github.tar, level 1 with dict, zstdcli, 38288 +github.tar, level 3, zstdcli, 38445 +github.tar, level 3 with dict, zstdcli, 37999 +github.tar, level 4, zstdcli, 38471 +github.tar, level 4 with dict, zstdcli, 37952 +github.tar, level 5, zstdcli, 38380 +github.tar, level 5 with dict, zstdcli, 39032 +github.tar, level 6, zstdcli, 38614 +github.tar, level 6 with dict, zstdcli, 38614 +github.tar, level 7, zstdcli, 38077 +github.tar, level 7 with dict, zstdcli, 37873 +github.tar, level 9, zstdcli, 36771 +github.tar, level 9 with dict, zstdcli, 36623 +github.tar, level 13, zstdcli, 35505 +github.tar, level 13 with dict, zstdcli, 37134 +github.tar, level 16, zstdcli, 40475 +github.tar, level 16 with dict, zstdcli, 33382 +github.tar, level 19, zstdcli, 32138 +github.tar, level 19 with dict, zstdcli, 32713 +github.tar, no source size, zstdcli, 38442 +github.tar, no source size with dict, zstdcli, 38004 +github.tar, long distance mode, zstdcli, 39730 +github.tar, multithreaded, zstdcli, 38445 +github.tar, multithreaded long distance mode, zstdcli, 39730 +github.tar, small window log, zstdcli, 198544 +github.tar, small hash log, zstdcli, 129874 +github.tar, small chain log, zstdcli, 41673 +github.tar, explicit params, zstdcli, 41227 +github.tar, uncompressed literals, zstdcli, 41126 +github.tar, uncompressed literals optimal, zstdcli, 35401 +github.tar, huffman literals, zstdcli, 38857 +github.tar, multithreaded with advanced params, zstdcli, 41126 silesia, level -5, advanced one pass, 7354675 silesia, level -3, advanced one pass, 6902374 silesia, level -1, advanced one pass, 6177565 From 1daf3c8dbc71027b2d57ac6a01f161247fdb70aa Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 9 Sep 2021 08:28:12 -0700 Subject: [PATCH 154/274] Use 32 buckets for log2 bucketing in huffman sort --- lib/compress/huf_compress.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 67b7ef956..db11ab3dc 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -435,7 +435,7 @@ typedef struct { typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32]; /* Number of buckets available for HUF_sort() */ -#define RANK_POSITION_TABLE_SIZE 128 +#define RANK_POSITION_TABLE_SIZE 192 typedef struct { huffNodeTable huffNodeTbl; @@ -444,18 +444,15 @@ typedef struct { /* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing. * Strategy is to use as many buckets as possible for representing distinct - * counts while using the remainder to represent all counts up to HUF_BLOCKSIZE_MAX - * using log2 bucketing. + * counts while using the remainder to represent all "large" counts. * - * To satisfy this requirement for 128 buckets, we can do the following: - * Let buckets 0-114 represent distinct counts of [0, 114] - * Let buckets 115 to 126 represent counts of [115, HUF_BLOCKSIZE_MAX]. (the final bucket 127 must remain empty) - * - * Note that we don't actually need 17 buckets (assuming 2^17 maxcount) for log2 bucketing since - * the first few buckets in the log2 bucketing representation are already covered by the distinct count bucketing. + * To satisfy this requirement for 192 buckets, we can do the following: + * Let buckets 0-166 represent distinct counts of [0, 166] + * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing. */ -#define RANK_POSITION_LOG_BUCKETS_BEGIN (RANK_POSITION_TABLE_SIZE - 1) - BIT_highbit32(HUF_BLOCKSIZE_MAX) - 1 -#define RANK_POSITION_DISTINCT_COUNT_CUTOFF RANK_POSITION_LOG_BUCKETS_BEGIN + BIT_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) +#define RANK_POSITION_MAX_COUNT_LOG 32 +#define RANK_POSITION_LOG_BUCKETS_BEGIN (RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */ +#define RANK_POSITION_DISTINCT_COUNT_CUTOFF RANK_POSITION_LOG_BUCKETS_BEGIN + BIT_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */ /* Return the appropriate bucket index for a given count. See definition of * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy. From 4a498fb9c35fa61a0c07f873fb891e11b92804a1 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 9 Sep 2021 08:55:43 -0700 Subject: [PATCH 155/274] Add a dictionary training large corpus test --- tests/playTests.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 774655aa9..45d1d3fe8 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -936,8 +936,13 @@ cat tmp | zstd -14 -f --size-hint=5500 | zstd -t # considerably too low println "\n===> dictionary tests " - -println "- test with raw dict (content only) " +println "- Test high/low compressibility corpus training" +datagen -g12M -P90 > tmpCorpusHighCompress +datagen -g12M -P5 > tmpCorpusLowCompress +zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress +zstd --train -B2K tmpCorpusLowCompress -o tmpDictLowCompress +rm -f tmpCorpusHighCompress tmpCorpusLowCompress tmpDictHighCompress tmpDictLowCompress +println "- Test with raw dict (content only) " datagen > tmpDict datagen -g1M | $MD5SUM > tmp1 datagen -g1M | zstd -D tmpDict | zstd -D tmpDict -dvq | $MD5SUM > tmp2 From d45d0ad9d81c69f27a1c813c65f3c86d31f87762 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 9 Sep 2021 09:02:21 -0700 Subject: [PATCH 156/274] Update regression test --- tests/regression/results.csv | 382 +++++++++++++++++------------------ 1 file changed, 191 insertions(+), 191 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index f70ee55d6..e3ed129bc 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -2,18 +2,18 @@ Data, Config, Method, silesia.tar, level -5, compress simple, 7359401 silesia.tar, level -3, compress simple, 6901672 silesia.tar, level -1, compress simple, 6182241 -silesia.tar, level 0, compress simple, 4861423 +silesia.tar, level 0, compress simple, 4861424 silesia.tar, level 1, compress simple, 5331946 -silesia.tar, level 3, compress simple, 4861423 +silesia.tar, level 3, compress simple, 4861424 silesia.tar, level 4, compress simple, 4799632 silesia.tar, level 5, compress simple, 4650202 silesia.tar, level 6, compress simple, 4616811 -silesia.tar, level 7, compress simple, 4576828 +silesia.tar, level 7, compress simple, 4576829 silesia.tar, level 9, compress simple, 4552584 -silesia.tar, level 13, compress simple, 4502955 +silesia.tar, level 13, compress simple, 4502956 silesia.tar, level 16, compress simple, 4356834 silesia.tar, level 19, compress simple, 4264388 -silesia.tar, uncompressed literals, compress simple, 4861423 +silesia.tar, uncompressed literals, compress simple, 4861424 silesia.tar, uncompressed literals optimal, compress simple, 4264388 silesia.tar, huffman literals, compress simple, 6182241 github.tar, level -5, compress simple, 66914 @@ -36,28 +36,28 @@ github.tar, huffman literals, compress silesia, level -5, compress cctx, 7354675 silesia, level -3, compress cctx, 6902374 silesia, level -1, compress cctx, 6177565 -silesia, level 0, compress cctx, 4849551 -silesia, level 1, compress cctx, 5309097 -silesia, level 3, compress cctx, 4849551 -silesia, level 4, compress cctx, 4786969 -silesia, level 5, compress cctx, 4638960 +silesia, level 0, compress cctx, 4849553 +silesia, level 1, compress cctx, 5309098 +silesia, level 3, compress cctx, 4849553 +silesia, level 4, compress cctx, 4786968 +silesia, level 5, compress cctx, 4638961 silesia, level 6, compress cctx, 4605369 -silesia, level 7, compress cctx, 4567203 -silesia, level 9, compress cctx, 4543311 +silesia, level 7, compress cctx, 4567204 +silesia, level 9, compress cctx, 4543310 silesia, level 13, compress cctx, 4493990 silesia, level 16, compress cctx, 4360251 -silesia, level 19, compress cctx, 4283236 -silesia, long distance mode, compress cctx, 4849551 -silesia, multithreaded, compress cctx, 4849551 -silesia, multithreaded long distance mode, compress cctx, 4849551 +silesia, level 19, compress cctx, 4283237 +silesia, long distance mode, compress cctx, 4849553 +silesia, multithreaded, compress cctx, 4849553 +silesia, multithreaded long distance mode, compress cctx, 4849553 silesia, small window log, compress cctx, 7084179 silesia, small hash log, compress cctx, 6526141 -silesia, small chain log, compress cctx, 4912199 -silesia, explicit params, compress cctx, 4794480 -silesia, uncompressed literals, compress cctx, 4849551 -silesia, uncompressed literals optimal, compress cctx, 4283236 +silesia, small chain log, compress cctx, 4912197 +silesia, explicit params, compress cctx, 4794481 +silesia, uncompressed literals, compress cctx, 4849553 +silesia, uncompressed literals optimal, compress cctx, 4283237 silesia, huffman literals, compress cctx, 6177565 -silesia, multithreaded with advanced params, compress cctx, 4849551 +silesia, multithreaded with advanced params, compress cctx, 4849553 github, level -5, compress cctx, 232315 github, level -5 with dict, compress cctx, 47294 github, level -3, compress cctx, 220760 @@ -100,23 +100,23 @@ github, multithreaded with advanced params, compress silesia, level -5, zstdcli, 7354723 silesia, level -3, zstdcli, 6902422 silesia, level -1, zstdcli, 6177613 -silesia, level 0, zstdcli, 4849599 -silesia, level 1, zstdcli, 5309145 -silesia, level 3, zstdcli, 4849599 -silesia, level 4, zstdcli, 4787017 -silesia, level 5, zstdcli, 4639008 +silesia, level 0, zstdcli, 4849601 +silesia, level 1, zstdcli, 5309146 +silesia, level 3, zstdcli, 4849601 +silesia, level 4, zstdcli, 4787016 +silesia, level 5, zstdcli, 4639009 silesia, level 6, zstdcli, 4605417 -silesia, level 7, zstdcli, 4567251 -silesia, level 9, zstdcli, 4543359 +silesia, level 7, zstdcli, 4567252 +silesia, level 9, zstdcli, 4543358 silesia, level 13, zstdcli, 4494038 silesia, level 16, zstdcli, 4360299 -silesia, level 19, zstdcli, 4283284 +silesia, level 19, zstdcli, 4283285 silesia, long distance mode, zstdcli, 4840807 -silesia, multithreaded, zstdcli, 4849599 +silesia, multithreaded, zstdcli, 4849601 silesia, multithreaded long distance mode, zstdcli, 4840807 silesia, small window log, zstdcli, 7095967 silesia, small hash log, zstdcli, 6526189 -silesia, small chain log, zstdcli, 4912247 +silesia, small chain log, zstdcli, 4912245 silesia, explicit params, zstdcli, 4795856 silesia, uncompressed literals, zstdcli, 5128030 silesia, uncompressed literals optimal, zstdcli, 4317944 @@ -125,25 +125,25 @@ silesia, multithreaded with advanced params, zstdcli, silesia.tar, level -5, zstdcli, 7363866 silesia.tar, level -3, zstdcli, 6902158 silesia.tar, level -1, zstdcli, 6182939 -silesia.tar, level 0, zstdcli, 4861511 -silesia.tar, level 1, zstdcli, 5333184 -silesia.tar, level 3, zstdcli, 4861511 -silesia.tar, level 4, zstdcli, 4800529 -silesia.tar, level 5, zstdcli, 4651159 +silesia.tar, level 0, zstdcli, 4861512 +silesia.tar, level 1, zstdcli, 5333183 +silesia.tar, level 3, zstdcli, 4861512 +silesia.tar, level 4, zstdcli, 4800528 +silesia.tar, level 5, zstdcli, 4651160 silesia.tar, level 6, zstdcli, 4618402 -silesia.tar, level 7, zstdcli, 4578883 -silesia.tar, level 9, zstdcli, 4553498 -silesia.tar, level 13, zstdcli, 4502959 +silesia.tar, level 7, zstdcli, 4578884 +silesia.tar, level 9, zstdcli, 4553499 +silesia.tar, level 13, zstdcli, 4502960 silesia.tar, level 16, zstdcli, 4356838 silesia.tar, level 19, zstdcli, 4264392 -silesia.tar, no source size, zstdcli, 4861507 +silesia.tar, no source size, zstdcli, 4861508 silesia.tar, long distance mode, zstdcli, 4853225 -silesia.tar, multithreaded, zstdcli, 4861511 +silesia.tar, multithreaded, zstdcli, 4861512 silesia.tar, multithreaded long distance mode, zstdcli, 4853225 silesia.tar, small window log, zstdcli, 7101576 -silesia.tar, small hash log, zstdcli, 6529286 -silesia.tar, small chain log, zstdcli, 4917020 -silesia.tar, explicit params, zstdcli, 4821277 +silesia.tar, small hash log, zstdcli, 6529289 +silesia.tar, small chain log, zstdcli, 4917022 +silesia.tar, explicit params, zstdcli, 4821274 silesia.tar, uncompressed literals, zstdcli, 5129559 silesia.tar, uncompressed literals optimal, zstdcli, 4307404 silesia.tar, huffman literals, zstdcli, 5344915 @@ -231,32 +231,32 @@ github.tar, multithreaded with advanced params, zstdcli, silesia, level -5, advanced one pass, 7354675 silesia, level -3, advanced one pass, 6902374 silesia, level -1, advanced one pass, 6177565 -silesia, level 0, advanced one pass, 4849551 -silesia, level 1, advanced one pass, 5309097 -silesia, level 3, advanced one pass, 4849551 -silesia, level 4, advanced one pass, 4786969 -silesia, level 5 row 1, advanced one pass, 4640753 -silesia, level 5 row 2, advanced one pass, 4638960 -silesia, level 5, advanced one pass, 4638960 +silesia, level 0, advanced one pass, 4849553 +silesia, level 1, advanced one pass, 5309098 +silesia, level 3, advanced one pass, 4849553 +silesia, level 4, advanced one pass, 4786968 +silesia, level 5 row 1, advanced one pass, 4640752 +silesia, level 5 row 2, advanced one pass, 4638961 +silesia, level 5, advanced one pass, 4638961 silesia, level 6, advanced one pass, 4605369 -silesia, level 7 row 1, advanced one pass, 4564870 -silesia, level 7 row 2, advanced one pass, 4567203 -silesia, level 7, advanced one pass, 4567203 -silesia, level 9, advanced one pass, 4543311 +silesia, level 7 row 1, advanced one pass, 4564868 +silesia, level 7 row 2, advanced one pass, 4567204 +silesia, level 7, advanced one pass, 4567204 +silesia, level 9, advanced one pass, 4543310 silesia, level 11 row 1, advanced one pass, 4519288 -silesia, level 11 row 2, advanced one pass, 4521406 -silesia, level 12 row 1, advanced one pass, 4503117 -silesia, level 12 row 2, advanced one pass, 4505152 +silesia, level 11 row 2, advanced one pass, 4521399 +silesia, level 12 row 1, advanced one pass, 4503116 +silesia, level 12 row 2, advanced one pass, 4505153 silesia, level 13, advanced one pass, 4493990 silesia, level 16, advanced one pass, 4360251 -silesia, level 19, advanced one pass, 4283236 -silesia, no source size, advanced one pass, 4849551 -silesia, long distance mode, advanced one pass, 4840738 -silesia, multithreaded, advanced one pass, 4849551 +silesia, level 19, advanced one pass, 4283237 +silesia, no source size, advanced one pass, 4849553 +silesia, long distance mode, advanced one pass, 4840737 +silesia, multithreaded, advanced one pass, 4849553 silesia, multithreaded long distance mode, advanced one pass, 4840759 silesia, small window log, advanced one pass, 7095919 silesia, small hash log, advanced one pass, 6526141 -silesia, small chain log, advanced one pass, 4912199 +silesia, small chain log, advanced one pass, 4912197 silesia, explicit params, advanced one pass, 4795856 silesia, uncompressed literals, advanced one pass, 5127982 silesia, uncompressed literals optimal, advanced one pass, 4317896 @@ -265,33 +265,33 @@ silesia, multithreaded with advanced params, advanced silesia.tar, level -5, advanced one pass, 7359401 silesia.tar, level -3, advanced one pass, 6901672 silesia.tar, level -1, advanced one pass, 6182241 -silesia.tar, level 0, advanced one pass, 4861423 +silesia.tar, level 0, advanced one pass, 4861424 silesia.tar, level 1, advanced one pass, 5331946 -silesia.tar, level 3, advanced one pass, 4861423 +silesia.tar, level 3, advanced one pass, 4861424 silesia.tar, level 4, advanced one pass, 4799632 silesia.tar, level 5 row 1, advanced one pass, 4652862 silesia.tar, level 5 row 2, advanced one pass, 4650202 silesia.tar, level 5, advanced one pass, 4650202 silesia.tar, level 6, advanced one pass, 4616811 -silesia.tar, level 7 row 1, advanced one pass, 4575392 -silesia.tar, level 7 row 2, advanced one pass, 4576828 -silesia.tar, level 7, advanced one pass, 4576828 +silesia.tar, level 7 row 1, advanced one pass, 4575393 +silesia.tar, level 7 row 2, advanced one pass, 4576829 +silesia.tar, level 7, advanced one pass, 4576829 silesia.tar, level 9, advanced one pass, 4552584 -silesia.tar, level 11 row 1, advanced one pass, 4529458 -silesia.tar, level 11 row 2, advanced one pass, 4530257 -silesia.tar, level 12 row 1, advanced one pass, 4513603 +silesia.tar, level 11 row 1, advanced one pass, 4529461 +silesia.tar, level 11 row 2, advanced one pass, 4530256 +silesia.tar, level 12 row 1, advanced one pass, 4513604 silesia.tar, level 12 row 2, advanced one pass, 4514568 -silesia.tar, level 13, advanced one pass, 4502955 +silesia.tar, level 13, advanced one pass, 4502956 silesia.tar, level 16, advanced one pass, 4356834 silesia.tar, level 19, advanced one pass, 4264388 -silesia.tar, no source size, advanced one pass, 4861423 -silesia.tar, long distance mode, advanced one pass, 4847753 -silesia.tar, multithreaded, advanced one pass, 4861507 +silesia.tar, no source size, advanced one pass, 4861424 +silesia.tar, long distance mode, advanced one pass, 4847752 +silesia.tar, multithreaded, advanced one pass, 4861508 silesia.tar, multithreaded long distance mode, advanced one pass, 4853221 silesia.tar, small window log, advanced one pass, 7101530 -silesia.tar, small hash log, advanced one pass, 6529228 -silesia.tar, small chain log, advanced one pass, 4917039 -silesia.tar, explicit params, advanced one pass, 4807383 +silesia.tar, small hash log, advanced one pass, 6529231 +silesia.tar, small chain log, advanced one pass, 4917041 +silesia.tar, explicit params, advanced one pass, 4807381 silesia.tar, uncompressed literals, advanced one pass, 5129458 silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 silesia.tar, huffman literals, advanced one pass, 5344545 @@ -549,32 +549,32 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced one pass small out, 7354675 silesia, level -3, advanced one pass small out, 6902374 silesia, level -1, advanced one pass small out, 6177565 -silesia, level 0, advanced one pass small out, 4849551 -silesia, level 1, advanced one pass small out, 5309097 -silesia, level 3, advanced one pass small out, 4849551 -silesia, level 4, advanced one pass small out, 4786969 -silesia, level 5 row 1, advanced one pass small out, 4640753 -silesia, level 5 row 2, advanced one pass small out, 4638960 -silesia, level 5, advanced one pass small out, 4638960 +silesia, level 0, advanced one pass small out, 4849553 +silesia, level 1, advanced one pass small out, 5309098 +silesia, level 3, advanced one pass small out, 4849553 +silesia, level 4, advanced one pass small out, 4786968 +silesia, level 5 row 1, advanced one pass small out, 4640752 +silesia, level 5 row 2, advanced one pass small out, 4638961 +silesia, level 5, advanced one pass small out, 4638961 silesia, level 6, advanced one pass small out, 4605369 -silesia, level 7 row 1, advanced one pass small out, 4564870 -silesia, level 7 row 2, advanced one pass small out, 4567203 -silesia, level 7, advanced one pass small out, 4567203 -silesia, level 9, advanced one pass small out, 4543311 +silesia, level 7 row 1, advanced one pass small out, 4564868 +silesia, level 7 row 2, advanced one pass small out, 4567204 +silesia, level 7, advanced one pass small out, 4567204 +silesia, level 9, advanced one pass small out, 4543310 silesia, level 11 row 1, advanced one pass small out, 4519288 -silesia, level 11 row 2, advanced one pass small out, 4521406 -silesia, level 12 row 1, advanced one pass small out, 4503117 -silesia, level 12 row 2, advanced one pass small out, 4505152 +silesia, level 11 row 2, advanced one pass small out, 4521399 +silesia, level 12 row 1, advanced one pass small out, 4503116 +silesia, level 12 row 2, advanced one pass small out, 4505153 silesia, level 13, advanced one pass small out, 4493990 silesia, level 16, advanced one pass small out, 4360251 -silesia, level 19, advanced one pass small out, 4283236 -silesia, no source size, advanced one pass small out, 4849551 -silesia, long distance mode, advanced one pass small out, 4840738 -silesia, multithreaded, advanced one pass small out, 4849551 +silesia, level 19, advanced one pass small out, 4283237 +silesia, no source size, advanced one pass small out, 4849553 +silesia, long distance mode, advanced one pass small out, 4840737 +silesia, multithreaded, advanced one pass small out, 4849553 silesia, multithreaded long distance mode, advanced one pass small out, 4840759 silesia, small window log, advanced one pass small out, 7095919 silesia, small hash log, advanced one pass small out, 6526141 -silesia, small chain log, advanced one pass small out, 4912199 +silesia, small chain log, advanced one pass small out, 4912197 silesia, explicit params, advanced one pass small out, 4795856 silesia, uncompressed literals, advanced one pass small out, 5127982 silesia, uncompressed literals optimal, advanced one pass small out, 4317896 @@ -583,33 +583,33 @@ silesia, multithreaded with advanced params, advanced silesia.tar, level -5, advanced one pass small out, 7359401 silesia.tar, level -3, advanced one pass small out, 6901672 silesia.tar, level -1, advanced one pass small out, 6182241 -silesia.tar, level 0, advanced one pass small out, 4861423 +silesia.tar, level 0, advanced one pass small out, 4861424 silesia.tar, level 1, advanced one pass small out, 5331946 -silesia.tar, level 3, advanced one pass small out, 4861423 +silesia.tar, level 3, advanced one pass small out, 4861424 silesia.tar, level 4, advanced one pass small out, 4799632 silesia.tar, level 5 row 1, advanced one pass small out, 4652862 silesia.tar, level 5 row 2, advanced one pass small out, 4650202 silesia.tar, level 5, advanced one pass small out, 4650202 silesia.tar, level 6, advanced one pass small out, 4616811 -silesia.tar, level 7 row 1, advanced one pass small out, 4575392 -silesia.tar, level 7 row 2, advanced one pass small out, 4576828 -silesia.tar, level 7, advanced one pass small out, 4576828 +silesia.tar, level 7 row 1, advanced one pass small out, 4575393 +silesia.tar, level 7 row 2, advanced one pass small out, 4576829 +silesia.tar, level 7, advanced one pass small out, 4576829 silesia.tar, level 9, advanced one pass small out, 4552584 -silesia.tar, level 11 row 1, advanced one pass small out, 4529458 -silesia.tar, level 11 row 2, advanced one pass small out, 4530257 -silesia.tar, level 12 row 1, advanced one pass small out, 4513603 +silesia.tar, level 11 row 1, advanced one pass small out, 4529461 +silesia.tar, level 11 row 2, advanced one pass small out, 4530256 +silesia.tar, level 12 row 1, advanced one pass small out, 4513604 silesia.tar, level 12 row 2, advanced one pass small out, 4514568 -silesia.tar, level 13, advanced one pass small out, 4502955 +silesia.tar, level 13, advanced one pass small out, 4502956 silesia.tar, level 16, advanced one pass small out, 4356834 silesia.tar, level 19, advanced one pass small out, 4264388 -silesia.tar, no source size, advanced one pass small out, 4861423 -silesia.tar, long distance mode, advanced one pass small out, 4847753 -silesia.tar, multithreaded, advanced one pass small out, 4861507 +silesia.tar, no source size, advanced one pass small out, 4861424 +silesia.tar, long distance mode, advanced one pass small out, 4847752 +silesia.tar, multithreaded, advanced one pass small out, 4861508 silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853221 silesia.tar, small window log, advanced one pass small out, 7101530 -silesia.tar, small hash log, advanced one pass small out, 6529228 -silesia.tar, small chain log, advanced one pass small out, 4917039 -silesia.tar, explicit params, advanced one pass small out, 4807383 +silesia.tar, small hash log, advanced one pass small out, 6529231 +silesia.tar, small chain log, advanced one pass small out, 4917041 +silesia.tar, explicit params, advanced one pass small out, 4807381 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 silesia.tar, huffman literals, advanced one pass small out, 5344545 @@ -867,33 +867,33 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, advanced streaming, 7292053 silesia, level -3, advanced streaming, 6867875 silesia, level -1, advanced streaming, 6183923 -silesia, level 0, advanced streaming, 4849551 +silesia, level 0, advanced streaming, 4849553 silesia, level 1, advanced streaming, 5312694 -silesia, level 3, advanced streaming, 4849551 -silesia, level 4, advanced streaming, 4786969 -silesia, level 5 row 1, advanced streaming, 4640753 -silesia, level 5 row 2, advanced streaming, 4638960 -silesia, level 5, advanced streaming, 4638960 +silesia, level 3, advanced streaming, 4849553 +silesia, level 4, advanced streaming, 4786968 +silesia, level 5 row 1, advanced streaming, 4640752 +silesia, level 5 row 2, advanced streaming, 4638961 +silesia, level 5, advanced streaming, 4638961 silesia, level 6, advanced streaming, 4605369 -silesia, level 7 row 1, advanced streaming, 4564870 -silesia, level 7 row 2, advanced streaming, 4567203 -silesia, level 7, advanced streaming, 4567203 -silesia, level 9, advanced streaming, 4543311 +silesia, level 7 row 1, advanced streaming, 4564868 +silesia, level 7 row 2, advanced streaming, 4567204 +silesia, level 7, advanced streaming, 4567204 +silesia, level 9, advanced streaming, 4543310 silesia, level 11 row 1, advanced streaming, 4519288 -silesia, level 11 row 2, advanced streaming, 4521406 -silesia, level 12 row 1, advanced streaming, 4503117 -silesia, level 12 row 2, advanced streaming, 4505152 +silesia, level 11 row 2, advanced streaming, 4521399 +silesia, level 12 row 1, advanced streaming, 4503116 +silesia, level 12 row 2, advanced streaming, 4505153 silesia, level 13, advanced streaming, 4493990 silesia, level 16, advanced streaming, 4360251 -silesia, level 19, advanced streaming, 4283236 -silesia, no source size, advanced streaming, 4849515 -silesia, long distance mode, advanced streaming, 4840738 -silesia, multithreaded, advanced streaming, 4849551 +silesia, level 19, advanced streaming, 4283237 +silesia, no source size, advanced streaming, 4849517 +silesia, long distance mode, advanced streaming, 4840737 +silesia, multithreaded, advanced streaming, 4849553 silesia, multithreaded long distance mode, advanced streaming, 4840759 silesia, small window log, advanced streaming, 7112062 silesia, small hash log, advanced streaming, 6526141 -silesia, small chain log, advanced streaming, 4912199 -silesia, explicit params, advanced streaming, 4795884 +silesia, small chain log, advanced streaming, 4912197 +silesia, explicit params, advanced streaming, 4795883 silesia, uncompressed literals, advanced streaming, 5127982 silesia, uncompressed literals optimal, advanced streaming, 4317896 silesia, huffman literals, advanced streaming, 5332234 @@ -901,33 +901,33 @@ silesia, multithreaded with advanced params, advanced silesia.tar, level -5, advanced streaming, 7260007 silesia.tar, level -3, advanced streaming, 6845151 silesia.tar, level -1, advanced streaming, 6187938 -silesia.tar, level 0, advanced streaming, 4861425 +silesia.tar, level 0, advanced streaming, 4861426 silesia.tar, level 1, advanced streaming, 5334890 -silesia.tar, level 3, advanced streaming, 4861425 +silesia.tar, level 3, advanced streaming, 4861426 silesia.tar, level 4, advanced streaming, 4799632 silesia.tar, level 5 row 1, advanced streaming, 4652866 silesia.tar, level 5 row 2, advanced streaming, 4650207 silesia.tar, level 5, advanced streaming, 4650207 silesia.tar, level 6, advanced streaming, 4616816 -silesia.tar, level 7 row 1, advanced streaming, 4575393 -silesia.tar, level 7 row 2, advanced streaming, 4576830 -silesia.tar, level 7, advanced streaming, 4576830 +silesia.tar, level 7 row 1, advanced streaming, 4575394 +silesia.tar, level 7 row 2, advanced streaming, 4576831 +silesia.tar, level 7, advanced streaming, 4576831 silesia.tar, level 9, advanced streaming, 4552590 -silesia.tar, level 11 row 1, advanced streaming, 4529458 -silesia.tar, level 11 row 2, advanced streaming, 4530259 -silesia.tar, level 12 row 1, advanced streaming, 4513603 +silesia.tar, level 11 row 1, advanced streaming, 4529461 +silesia.tar, level 11 row 2, advanced streaming, 4530258 +silesia.tar, level 12 row 1, advanced streaming, 4513604 silesia.tar, level 12 row 2, advanced streaming, 4514569 -silesia.tar, level 13, advanced streaming, 4502955 +silesia.tar, level 13, advanced streaming, 4502956 silesia.tar, level 16, advanced streaming, 4356834 silesia.tar, level 19, advanced streaming, 4264388 -silesia.tar, no source size, advanced streaming, 4861421 -silesia.tar, long distance mode, advanced streaming, 4847753 -silesia.tar, multithreaded, advanced streaming, 4861507 +silesia.tar, no source size, advanced streaming, 4861422 +silesia.tar, long distance mode, advanced streaming, 4847752 +silesia.tar, multithreaded, advanced streaming, 4861508 silesia.tar, multithreaded long distance mode, advanced streaming, 4853221 silesia.tar, small window log, advanced streaming, 7118769 -silesia.tar, small hash log, advanced streaming, 6529231 -silesia.tar, small chain log, advanced streaming, 4917019 -silesia.tar, explicit params, advanced streaming, 4807403 +silesia.tar, small hash log, advanced streaming, 6529234 +silesia.tar, small chain log, advanced streaming, 4917021 +silesia.tar, explicit params, advanced streaming, 4807401 silesia.tar, uncompressed literals, advanced streaming, 5129461 silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 silesia.tar, huffman literals, advanced streaming, 5350519 @@ -1185,37 +1185,37 @@ github.tar, multithreaded with advanced params, advanced silesia, level -5, old streaming, 7292053 silesia, level -3, old streaming, 6867875 silesia, level -1, old streaming, 6183923 -silesia, level 0, old streaming, 4849551 +silesia, level 0, old streaming, 4849553 silesia, level 1, old streaming, 5312694 -silesia, level 3, old streaming, 4849551 -silesia, level 4, old streaming, 4786969 -silesia, level 5, old streaming, 4638960 +silesia, level 3, old streaming, 4849553 +silesia, level 4, old streaming, 4786968 +silesia, level 5, old streaming, 4638961 silesia, level 6, old streaming, 4605369 -silesia, level 7, old streaming, 4567203 -silesia, level 9, old streaming, 4543311 +silesia, level 7, old streaming, 4567204 +silesia, level 9, old streaming, 4543310 silesia, level 13, old streaming, 4493990 silesia, level 16, old streaming, 4360251 -silesia, level 19, old streaming, 4283236 -silesia, no source size, old streaming, 4849515 -silesia, uncompressed literals, old streaming, 4849551 -silesia, uncompressed literals optimal, old streaming, 4283236 +silesia, level 19, old streaming, 4283237 +silesia, no source size, old streaming, 4849517 +silesia, uncompressed literals, old streaming, 4849553 +silesia, uncompressed literals optimal, old streaming, 4283237 silesia, huffman literals, old streaming, 6183923 silesia.tar, level -5, old streaming, 7260007 silesia.tar, level -3, old streaming, 6845151 silesia.tar, level -1, old streaming, 6187938 -silesia.tar, level 0, old streaming, 4861425 +silesia.tar, level 0, old streaming, 4861426 silesia.tar, level 1, old streaming, 5334890 -silesia.tar, level 3, old streaming, 4861425 +silesia.tar, level 3, old streaming, 4861426 silesia.tar, level 4, old streaming, 4799632 silesia.tar, level 5, old streaming, 4650207 silesia.tar, level 6, old streaming, 4616816 -silesia.tar, level 7, old streaming, 4576830 +silesia.tar, level 7, old streaming, 4576831 silesia.tar, level 9, old streaming, 4552590 -silesia.tar, level 13, old streaming, 4502955 +silesia.tar, level 13, old streaming, 4502956 silesia.tar, level 16, old streaming, 4356834 silesia.tar, level 19, old streaming, 4264388 -silesia.tar, no source size, old streaming, 4861421 -silesia.tar, uncompressed literals, old streaming, 4861425 +silesia.tar, no source size, old streaming, 4861422 +silesia.tar, uncompressed literals, old streaming, 4861426 silesia.tar, uncompressed literals optimal, old streaming, 4264388 silesia.tar, huffman literals, old streaming, 6187938 github, level -5, old streaming, 232315 @@ -1287,55 +1287,55 @@ github.tar, huffman literals, old stre silesia, level -5, old streaming advanced, 7292053 silesia, level -3, old streaming advanced, 6867875 silesia, level -1, old streaming advanced, 6183923 -silesia, level 0, old streaming advanced, 4849551 +silesia, level 0, old streaming advanced, 4849553 silesia, level 1, old streaming advanced, 5312694 -silesia, level 3, old streaming advanced, 4849551 -silesia, level 4, old streaming advanced, 4786969 -silesia, level 5, old streaming advanced, 4638960 +silesia, level 3, old streaming advanced, 4849553 +silesia, level 4, old streaming advanced, 4786968 +silesia, level 5, old streaming advanced, 4638961 silesia, level 6, old streaming advanced, 4605369 -silesia, level 7, old streaming advanced, 4567203 -silesia, level 9, old streaming advanced, 4543311 +silesia, level 7, old streaming advanced, 4567204 +silesia, level 9, old streaming advanced, 4543310 silesia, level 13, old streaming advanced, 4493990 silesia, level 16, old streaming advanced, 4360251 -silesia, level 19, old streaming advanced, 4283236 -silesia, no source size, old streaming advanced, 4849515 -silesia, long distance mode, old streaming advanced, 4849551 -silesia, multithreaded, old streaming advanced, 4849551 -silesia, multithreaded long distance mode, old streaming advanced, 4849551 +silesia, level 19, old streaming advanced, 4283237 +silesia, no source size, old streaming advanced, 4849517 +silesia, long distance mode, old streaming advanced, 4849553 +silesia, multithreaded, old streaming advanced, 4849553 +silesia, multithreaded long distance mode, old streaming advanced, 4849553 silesia, small window log, old streaming advanced, 7112062 silesia, small hash log, old streaming advanced, 6526141 -silesia, small chain log, old streaming advanced, 4912199 -silesia, explicit params, old streaming advanced, 4795884 -silesia, uncompressed literals, old streaming advanced, 4849551 -silesia, uncompressed literals optimal, old streaming advanced, 4283236 +silesia, small chain log, old streaming advanced, 4912197 +silesia, explicit params, old streaming advanced, 4795883 +silesia, uncompressed literals, old streaming advanced, 4849553 +silesia, uncompressed literals optimal, old streaming advanced, 4283237 silesia, huffman literals, old streaming advanced, 6183923 -silesia, multithreaded with advanced params, old streaming advanced, 4849551 +silesia, multithreaded with advanced params, old streaming advanced, 4849553 silesia.tar, level -5, old streaming advanced, 7260007 silesia.tar, level -3, old streaming advanced, 6845151 silesia.tar, level -1, old streaming advanced, 6187938 -silesia.tar, level 0, old streaming advanced, 4861425 +silesia.tar, level 0, old streaming advanced, 4861426 silesia.tar, level 1, old streaming advanced, 5334890 -silesia.tar, level 3, old streaming advanced, 4861425 +silesia.tar, level 3, old streaming advanced, 4861426 silesia.tar, level 4, old streaming advanced, 4799632 silesia.tar, level 5, old streaming advanced, 4650207 silesia.tar, level 6, old streaming advanced, 4616816 -silesia.tar, level 7, old streaming advanced, 4576830 +silesia.tar, level 7, old streaming advanced, 4576831 silesia.tar, level 9, old streaming advanced, 4552590 -silesia.tar, level 13, old streaming advanced, 4502955 +silesia.tar, level 13, old streaming advanced, 4502956 silesia.tar, level 16, old streaming advanced, 4356834 silesia.tar, level 19, old streaming advanced, 4264388 -silesia.tar, no source size, old streaming advanced, 4861421 -silesia.tar, long distance mode, old streaming advanced, 4861425 -silesia.tar, multithreaded, old streaming advanced, 4861425 -silesia.tar, multithreaded long distance mode, old streaming advanced, 4861425 +silesia.tar, no source size, old streaming advanced, 4861422 +silesia.tar, long distance mode, old streaming advanced, 4861426 +silesia.tar, multithreaded, old streaming advanced, 4861426 +silesia.tar, multithreaded long distance mode, old streaming advanced, 4861426 silesia.tar, small window log, old streaming advanced, 7118772 -silesia.tar, small hash log, old streaming advanced, 6529231 -silesia.tar, small chain log, old streaming advanced, 4917019 -silesia.tar, explicit params, old streaming advanced, 4807403 -silesia.tar, uncompressed literals, old streaming advanced, 4861425 +silesia.tar, small hash log, old streaming advanced, 6529234 +silesia.tar, small chain log, old streaming advanced, 4917021 +silesia.tar, explicit params, old streaming advanced, 4807401 +silesia.tar, uncompressed literals, old streaming advanced, 4861426 silesia.tar, uncompressed literals optimal, old streaming advanced, 4264388 silesia.tar, huffman literals, old streaming advanced, 6187938 -silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4861426 github, level -5, old streaming advanced, 241214 github, level -5 with dict, old streaming advanced, 49562 github, level -3, old streaming advanced, 222937 From a418b4e4787f495abcc1f2e7768bd52a8d5ffc82 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 13 Sep 2021 16:59:20 -0700 Subject: [PATCH 157/274] [rsyncable] Ensure ZSTD_compressBound() is respected In degenerate cases `--rsyncable` could create very small blocks (1 byte). This causes the compressed output to be larger than `ZSTD_compressBound()`. Fix the issue by ensuring that rsyncable mode never outputs blocks smaller than 128 KB. The minimum job size is 512 KB, so we shouldn't lose many synchronization points from skipping any that cause blocks smaller than 128 KB. And even if we do, that is fine, because we'll find the next one. This fixes the `raw_dictionary_round_trip` oss-fuzz assert. Credit to OSS-Fuzz --- lib/compress/zstdmt_compress.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 22aa3e124..943238468 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -807,6 +807,15 @@ typedef struct { static const roundBuff_t kNullRoundBuff = {NULL, 0, 0}; #define RSYNC_LENGTH 32 +/* Don't create chunks smaller than the zstd block size. + * This stops us from regressing compression ratio too much, + * and ensures our output fits in ZSTD_compressBound(). + * + * If this is shrunk < ZSTD_BLOCKSIZELOG_MIN then + * ZSTD_COMPRESSBOUND() will need to be updated. + */ +#define RSYNC_MIN_BLOCK_LOG ZSTD_BLOCKSIZELOG_MAX +#define RSYNC_MIN_BLOCK_SIZE (1<targetSectionSize >> 10); U32 const rsyncBits = (assert(jobSizeKB >= 1), ZSTD_highbit32(jobSizeKB) + 10); + /* We refuse to create jobs < RSYNC_MIN_BLOCK_SIZE bytes, so make sure our + * expected job size is at least 4x larger. */ + assert(rsyncBits >= RSYNC_MIN_BLOCK_LOG + 2); DEBUGLOG(4, "rsyncLog = %u", rsyncBits); mtctx->rsync.hash = 0; mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1; @@ -1678,6 +1690,11 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) if (!mtctx->params.rsyncable) /* Rsync is disabled. */ return syncPoint; + if (mtctx->inBuff.filled + input.size - input.pos < RSYNC_MIN_BLOCK_SIZE) + /* We don't emit synchronization points if it would produce too small blocks. + * We don't have enough input to find a synchronization point, so don't look. + */ + return syncPoint; if (mtctx->inBuff.filled + syncPoint.toLoad < RSYNC_LENGTH) /* Not enough to compute the hash. * We will miss any synchronization points in this RSYNC_LENGTH byte @@ -1688,14 +1705,24 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) */ return syncPoint; /* Initialize the loop variables. */ - if (mtctx->inBuff.filled >= RSYNC_LENGTH) { + if (mtctx->inBuff.filled < RSYNC_MIN_BLOCK_SIZE - RSYNC_LENGTH) { + /* We don't need to scan the first RSYNC_MIN_BLOCK_SIZE positions + * because they can't possibly be a sync point. So we can start + * part way through the input buffer. + */ + pos = RSYNC_MIN_BLOCK_SIZE - mtctx->inBuff.filled; + assert(pos <= input.size - input.pos /* validated earlier */); + assert(pos >= RSYNC_LENGTH); + prev = istart + pos - RSYNC_LENGTH; + hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); + } else if (mtctx->inBuff.filled >= RSYNC_LENGTH) { /* We have enough bytes buffered to initialize the hash. * Start scanning at the beginning of the input. */ pos = 0; prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH; hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); - if ((hash & hitMask) == hitMask) { + if ((hash & hitMask) == hitMask && mtctx->inBuff.filled >= RSYNC_MIN_BLOCK_SIZE) { /* We're already at a sync point so don't load any more until * we're able to flush this sync point. * This likely happened because the job table was full so we @@ -1728,6 +1755,7 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH]; /* if (pos >= RSYNC_LENGTH) assert(ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); */ hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower); + assert(mtctx->inBuff.filled + pos >= RSYNC_MIN_BLOCK_SIZE); if ((hash & hitMask) == hitMask) { syncPoint.toLoad = pos + 1; syncPoint.flush = 1; From 9d9e2ed00baa70652c1b8255b3ff16057a702f2e Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 14 Sep 2021 11:57:26 -0700 Subject: [PATCH 158/274] [rsyncable] Fix test failures Test failures showed up on the daily cron job. They didn't show up in CI because the condition is somewhat rare, and didn't trigger during the CI tests. This PR fixes up the logic in `findSynchronizationPoint()` to correctly handle the edge case. It also un-comments an assert that helps catch the issue, and verify that rsyncable mode is calculating the correct hash. After the fix, the test that failed passes: ``` ./zstreamtest --newapi -t1 --no-big-tests -s9680 ``` --- lib/compress/zstdmt_compress.c | 36 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 943238468..19e8ce427 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -1705,24 +1705,32 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) */ return syncPoint; /* Initialize the loop variables. */ - if (mtctx->inBuff.filled < RSYNC_MIN_BLOCK_SIZE - RSYNC_LENGTH) { + if (mtctx->inBuff.filled < RSYNC_MIN_BLOCK_SIZE) { /* We don't need to scan the first RSYNC_MIN_BLOCK_SIZE positions * because they can't possibly be a sync point. So we can start * part way through the input buffer. */ pos = RSYNC_MIN_BLOCK_SIZE - mtctx->inBuff.filled; - assert(pos <= input.size - input.pos /* validated earlier */); - assert(pos >= RSYNC_LENGTH); - prev = istart + pos - RSYNC_LENGTH; - hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); - } else if (mtctx->inBuff.filled >= RSYNC_LENGTH) { - /* We have enough bytes buffered to initialize the hash. + if (pos >= RSYNC_LENGTH) { + prev = istart + pos - RSYNC_LENGTH; + hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); + } else { + assert(mtctx->inBuff.filled >= RSYNC_LENGTH); + prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH; + hash = ZSTD_rollingHash_compute(prev + pos, (RSYNC_LENGTH - pos)); + hash = ZSTD_rollingHash_append(hash, istart, pos); + } + } else { + /* We have enough bytes buffered to initialize the hash, + * and are have processed enough bytes to find a sync point. * Start scanning at the beginning of the input. */ + assert(mtctx->inBuff.filled >= RSYNC_MIN_BLOCK_SIZE); + assert(RSYNC_MIN_BLOCK_SIZE >= RSYNC_LENGTH); pos = 0; prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH; hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH); - if ((hash & hitMask) == hitMask && mtctx->inBuff.filled >= RSYNC_MIN_BLOCK_SIZE) { + if ((hash & hitMask) == hitMask) { /* We're already at a sync point so don't load any more until * we're able to flush this sync point. * This likely happened because the job table was full so we @@ -1732,16 +1740,6 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) syncPoint.flush = 1; return syncPoint; } - } else { - /* We don't have enough bytes buffered to initialize the hash, but - * we know we have at least RSYNC_LENGTH bytes total. - * Start scanning after the first RSYNC_LENGTH bytes less the bytes - * already buffered. - */ - pos = RSYNC_LENGTH - mtctx->inBuff.filled; - prev = (BYTE const*)mtctx->inBuff.buffer.start - pos; - hash = ZSTD_rollingHash_compute(mtctx->inBuff.buffer.start, mtctx->inBuff.filled); - hash = ZSTD_rollingHash_append(hash, istart, pos); } /* Starting with the hash of the previous RSYNC_LENGTH bytes, roll * through the input. If we hit a synchronization point, then cut the @@ -1753,7 +1751,7 @@ findSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input) */ for (; pos < syncPoint.toLoad; ++pos) { BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH]; - /* if (pos >= RSYNC_LENGTH) assert(ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); */ + assert(pos < RSYNC_LENGTH || ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower); assert(mtctx->inBuff.filled + pos >= RSYNC_MIN_BLOCK_SIZE); if ((hash & hitMask) == hitMask) { From bd84e4a9d3914f27139ced2b233b69d882229604 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Wed, 15 Sep 2021 09:08:41 -0700 Subject: [PATCH 159/274] Revert opt outlining change --- lib/compress/zstd_opt.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 301f985cb..19999470e 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -253,10 +253,11 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP * Provides the cost of the match part (offset + matchLength) of a sequence * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence. * optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) */ -static U32 ZSTD_getMatchPrice(U32 const offset, - U32 const matchLength, - const optState_t* const optPtr, - int const optLevel) +FORCE_INLINE_TEMPLATE U32 +ZSTD_getMatchPrice(U32 const offset, + U32 const matchLength, + const optState_t* const optPtr, + int const optLevel) { U32 price; U32 const offCode = ZSTD_highbit32(offset+1); @@ -484,9 +485,11 @@ static U32 ZSTD_insertBt1( } } -static void ZSTD_updateTree_internal(ZSTD_matchState_t* ms, - const BYTE* const ip, const BYTE* const iend, - const U32 mls, const ZSTD_dictMode_e dictMode) +FORCE_INLINE_TEMPLATE +void ZSTD_updateTree_internal( + ZSTD_matchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + const U32 mls, const ZSTD_dictMode_e dictMode) { const BYTE* const base = ms->window.base; U32 const target = (U32)(ip - base); @@ -508,7 +511,8 @@ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) { ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict); } -static U32 ZSTD_insertBtAndGetAllMatches ( +FORCE_INLINE_TEMPLATE +U32 ZSTD_insertBtAndGetAllMatches ( ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */ ZSTD_matchState_t* ms, U32* nextToUpdate3, @@ -741,7 +745,7 @@ static U32 ZSTD_insertBtAndGetAllMatches ( } -static U32 ZSTD_BtGetAllMatches ( +FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches ( ZSTD_match_t* matches, /* store result (match found, increasing size) in this table */ ZSTD_matchState_t* ms, U32* nextToUpdate3, @@ -928,7 +932,7 @@ listStats(const U32* table, int lastEltID) #endif -static size_t +FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], From a7aa2c5df6ced5f3c2019a825cfb08a619cf6851 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Wed, 15 Sep 2021 09:51:42 -0700 Subject: [PATCH 160/274] Fix NCountWriteBound --- lib/compress/fse_compress.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c index faca767c5..5547b4ac0 100644 --- a/lib/compress/fse_compress.c +++ b/lib/compress/fse_compress.c @@ -221,7 +221,11 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, ****************************************************************/ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) { - size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3; + size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog + + 4 /* bitCount initialized at 4 */ + + 2 /* first two symbols may use one additional bit each */) / 8) + + 1 /* round up to whole nb bytes */ + + 2 /* additional two bytes for bitstream flush */; return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ } From 8bf699aa59372d7c2bb4216bcf8037cab7dae51e Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 17 Sep 2021 11:42:08 -0700 Subject: [PATCH 161/274] [build] Add support for ASM files in Make + CMake * Extract out common portion of `lib/Makefile` into `lib/libzstd.mk`. Most relevantly, the way we find library files. * Use `lib/libzstd.mk` in the other Makefiles instead of repeating the same code. * Add a test `tests/test-variants.sh` that checks that the builds of `make -C programs allVariants` are correct, and run it in Actions. * Adds support for ASM files in the CMake build. The Meson build is not updated because it lists every file in zstd, and supports ASM off the bat, so the Huffman ASM commit will just add the ASM file to the list. The Visual Studios build is not updated because I'm not adding ASM support to Visual Studios yet. --- .circleci/config.yml | 13 +- .github/workflows/dev-short-tests.yml | 10 +- Makefile | 12 +- build/cmake/lib/CMakeLists.txt | 4 +- contrib/freestanding_lib/freestanding.py | 3 +- contrib/linux-kernel/test/Makefile | 8 +- contrib/pzstd/Makefile | 16 +- lib/Makefile | 207 +++++------------------ lib/compress/huf_compress.c | 5 +- lib/libzstd.mk | 185 ++++++++++++++++++++ programs/Makefile | 128 +++----------- tests/Makefile | 52 +++--- tests/fuzz/Makefile | 30 +++- tests/fuzzer.c | 2 +- tests/regression/Makefile | 1 + tests/test-variants.sh | 115 +++++++++++++ 16 files changed, 455 insertions(+), 336 deletions(-) create mode 100644 lib/libzstd.mk create mode 100755 tests/test-variants.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 035177edc..65bb3c227 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,6 +7,8 @@ jobs: # preinstalled to reduce installation time. docker: - image: fbopensource/zstd-circleci-primary:0.0.1 + # TODO: Re-enable aarch64 build: + # make aarch64build && make clean steps: - checkout - run: @@ -14,12 +16,11 @@ jobs: command: | ./tests/test-license.py cc -v; CFLAGS="-O0 -Werror -pedantic" make all && make clean - make c99build ; make clean - make c11build ; make clean - make aarch64build ; make clean - make -j regressiontest; make clean - make shortest ; make clean - make cxxtest ; make clean + make c99build && make clean + make c11build && make clean + make -j regressiontest&& make clean + make shortest && make clean + make cxxtest && make clean # the second half of the jobs are in this test short-tests-1: docker: diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index cdc9d7fe3..5d7e54b51 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -200,6 +200,15 @@ jobs: make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + test-variants: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: make all variants & validate + run: | + make -j -C programs allVariants MOREFLAGS=-O0 + ./tests/test-variants.sh + qemu-consistency: name: QEMU ${{ matrix.name }} @@ -263,7 +272,6 @@ jobs: run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - # This test currently fails on Github Actions specifically. # Possible reason : TTY emulation. # Note that the same test works fine locally and on travisCI. diff --git a/Makefile b/Makefile index b9265e7f8..ff49fc0d8 100644 --- a/Makefile +++ b/Makefile @@ -217,7 +217,7 @@ armbuild: clean CC=arm-linux-gnueabi-gcc CFLAGS="-Werror" $(MAKE) allzstd aarch64build: clean - CC=aarch64-linux-gnu-gcc CFLAGS="-Werror" $(MAKE) allzstd + CC=aarch64-linux-gnu-gcc CFLAGS="-Werror -O0" $(MAKE) allzstd ppcbuild: clean CC=powerpc-linux-gnu-gcc CFLAGS="-m32 -Wno-attributes -Werror" $(MAKE) -j allzstd @@ -381,23 +381,23 @@ cmakebuild: c89build: clean $(CC) -v - CFLAGS="-std=c89 -Werror" $(MAKE) allmost # will fail, due to missing support for `long long` + CFLAGS="-std=c89 -Werror -O0" $(MAKE) allmost # will fail, due to missing support for `long long` gnu90build: clean $(CC) -v - CFLAGS="-std=gnu90 -Werror" $(MAKE) allmost + CFLAGS="-std=gnu90 -Werror -O0" $(MAKE) allmost c99build: clean $(CC) -v - CFLAGS="-std=c99 -Werror" $(MAKE) allmost + CFLAGS="-std=c99 -Werror -O0" $(MAKE) allmost gnu99build: clean $(CC) -v - CFLAGS="-std=gnu99 -Werror" $(MAKE) allmost + CFLAGS="-std=gnu99 -Werror -O0" $(MAKE) allmost c11build: clean $(CC) -v - CFLAGS="-std=c11 -Werror" $(MAKE) allmost + CFLAGS="-std=c11 -Werror -O0" $(MAKE) allmost bmix64build: clean $(CC) -v diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index 5f756652e..d91ebe1f0 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -7,7 +7,7 @@ # in the COPYING file in the root directory of this source tree). # ################################################################ -project(libzstd C) +project(libzstd C ASM) set(CMAKE_INCLUDE_CURRENT_DIR TRUE) option(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON) @@ -22,7 +22,7 @@ include_directories(${LIBRARY_DIR} ${LIBRARY_DIR}/common) file(GLOB CommonSources ${LIBRARY_DIR}/common/*.c) file(GLOB CompressSources ${LIBRARY_DIR}/compress/*.c) -file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c) +file(GLOB DecompressSources ${LIBRARY_DIR}/decompress/*.c ${LIBRARY_DIR}/decompress/*.S) file(GLOB DictBuilderSources ${LIBRARY_DIR}/dictBuilder/*.c) set(Sources diff --git a/contrib/freestanding_lib/freestanding.py b/contrib/freestanding_lib/freestanding.py index a191f592f..cd9d63774 100755 --- a/contrib/freestanding_lib/freestanding.py +++ b/contrib/freestanding_lib/freestanding.py @@ -460,7 +460,8 @@ class Freestanding(object): print(*args, **kwargs) def _copy_file(self, lib_path): - if not (lib_path.endswith(".c") or lib_path.endswith(".h")): + suffixes = [".c", ".h", ".S"] + if not any((lib_path.endswith(suffix) for suffix in suffixes)): return if lib_path in SKIPPED_FILES: self._log(f"\tSkipping file: {lib_path}") diff --git a/contrib/linux-kernel/test/Makefile b/contrib/linux-kernel/test/Makefile index 2908839fd..dc76a5f40 100644 --- a/contrib/linux-kernel/test/Makefile +++ b/contrib/linux-kernel/test/Makefile @@ -18,9 +18,13 @@ CPPFLAGS += -DZSTD_ASAN_DONT_POISON_WORKSPACE LINUX_ZSTD_MODULE := $(wildcard $(LINUX_ZSTDLIB)/*.c) LINUX_ZSTD_COMMON := $(wildcard $(LINUX_ZSTDLIB)/common/*.c) LINUX_ZSTD_COMPRESS := $(wildcard $(LINUX_ZSTDLIB)/compress/*.c) -LINUX_ZSTD_DECOMPRESS := $(wildcard $(LINUX_ZSTDLIB)/decompress/*.c) +LINUX_ZSTD_DECOMPRESS := $(wildcard $(LINUX_ZSTDLIB)/decompress/*.c $(LINUX_ZSTDLIB)/decompress/*.S) LINUX_ZSTD_FILES := $(LINUX_ZSTD_MODULE) $(LINUX_ZSTD_COMMON) $(LINUX_ZSTD_COMPRESS) $(LINUX_ZSTD_DECOMPRESS) -LINUX_ZSTD_OBJECTS := $(LINUX_ZSTD_FILES:.c=.o) +LINUX_ZSTD_OBJECTS0 := $(LINUX_ZSTD_FILES:.c=.o) +LINUX_ZSTD_OBJECTS := $(LINUX_ZSTD_OBJECTS0:.S=.o) + +%.o: %.S + $(CC) -c $(CPPFLAGS) $(CFLAGS) $^ -o $@ liblinuxzstd.a: $(LINUX_ZSTD_OBJECTS) $(AR) $(ARFLAGS) $@ $^ diff --git a/contrib/pzstd/Makefile b/contrib/pzstd/Makefile index 25265e79a..3d930cca9 100644 --- a/contrib/pzstd/Makefile +++ b/contrib/pzstd/Makefile @@ -57,19 +57,6 @@ LD_COMMAND = $(CXX) $^ $(ALL_LDFLAGS) $(LIBS) -pthread -o $@ CC_COMMAND = $(CC) $(DEPFLAGS) $(ALL_CFLAGS) -c $< -o $@ CXX_COMMAND = $(CXX) $(DEPFLAGS) $(ALL_CXXFLAGS) -c $< -o $@ -# Get a list of all zstd files so we rebuild the static library when we need to -ZSTDCOMMON_FILES := $(wildcard $(ZSTDDIR)/common/*.c) \ - $(wildcard $(ZSTDDIR)/common/*.h) -ZSTDCOMP_FILES := $(wildcard $(ZSTDDIR)/compress/*.c) \ - $(wildcard $(ZSTDDIR)/compress/*.h) -ZSTDDECOMP_FILES := $(wildcard $(ZSTDDIR)/decompress/*.c) \ - $(wildcard $(ZSTDDIR)/decompress/*.h) -ZSTDPROG_FILES := $(wildcard $(PROGDIR)/*.c) \ - $(wildcard $(PROGDIR)/*.h) -ZSTD_FILES := $(wildcard $(ZSTDDIR)/*.h) \ - $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) \ - $(ZSTDPROG_FILES) - # List all the pzstd source files so we can determine their dependencies PZSTD_SRCS := $(wildcard *.cpp) PZSTD_TESTS := $(wildcard test/*.cpp) @@ -189,7 +176,8 @@ roundtrip: test/RoundTripTest$(EXT) # Use the static library that zstd builds for simplicity and # so we get the compiler options correct -$(ZSTDDIR)/libzstd.a: $(ZSTD_FILES) +.PHONY: $(ZSTDDIR)/libzstd.a +$(ZSTDDIR)/libzstd.a: CFLAGS="$(ALL_CFLAGS)" LDFLAGS="$(ALL_LDFLAGS)" $(MAKE) -C $(ZSTDDIR) libzstd.a # Rules to build the tests diff --git a/lib/Makefile b/lib/Makefile index 376a6690c..9b74e708c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -8,110 +8,13 @@ # You may select, at your option, one of the above-listed licenses. # ################################################################ -# Note: by default, the static library is built single-threaded and dynamic library is built -# multi-threaded. It is possible to force multi or single threaded builds by appending -# -mt or -nomt to the build target (like lib-mt for multi-threaded, lib-nomt for single-threaded). -.PHONY: default -default: lib-release - -# define silent mode as default (verbose mode with V=1 or VERBOSE=1) -$(V)$(VERBOSE).SILENT: - -# When cross-compiling from linux to windows, -# one might need to specify TARGET_SYSTEM as "Windows." -# Building from Fedora fails without it. -# (but Ubuntu and Debian don't need to set anything) -TARGET_SYSTEM ?= $(OS) - -# Version numbers -LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h` -LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h` -LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h` -LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT) -LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT)) -LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT)) -LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT)) -LIBVER := $(shell echo $(LIBVER_SCRIPT)) -VERSION?= $(LIBVER) -CCVER := $(shell $(CC) --version) - -# ZSTD_LIB_MINIFY is a helper variable that -# configures a bunch of other variables to space-optimized defaults. -ZSTD_LIB_MINIFY ?= 0 -ifneq ($(ZSTD_LIB_MINIFY), 0) - HAVE_CC_OZ ?= $(shell echo "" | $(CC) -Oz -x c -c - -o /dev/null 2> /dev/null && echo 1 || echo 0) - ZSTD_LEGACY_SUPPORT ?= 0 - ZSTD_LIB_DEPRECATED ?= 0 - HUF_FORCE_DECOMPRESS_X1 ?= 1 - ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 1 - ZSTD_NO_INLINE ?= 1 - ZSTD_STRIP_ERROR_STRINGS ?= 1 -ifneq ($(HAVE_CC_OZ), 0) - # Some compilers (clang) support an even more space-optimized setting. - CFLAGS += -Oz -else - CFLAGS += -Os -endif - CFLAGS += -fno-stack-protector -fomit-frame-pointer -fno-ident \ - -DDYNAMIC_BMI2=0 -DNDEBUG -else - CFLAGS += -O3 -endif - -DEBUGLEVEL ?= 0 -CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -DDEBUGLEVEL=$(DEBUGLEVEL) -ifeq ($(TARGET_SYSTEM),Windows_NT) # MinGW assumed - CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting -endif -DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ - -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ - -Wstrict-prototypes -Wundef -Wpointer-arith \ - -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ - -Wredundant-decls -Wmissing-prototypes -Wc++-compat -CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) -FLAGS = $(CPPFLAGS) $(CFLAGS) - -CPPFLAGS_DYNLIB = -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded -LDFLAGS_DYNLIB = -pthread -CPPFLAGS_STATLIB = # static library build defaults to single-threaded - -HAVE_COLORNEVER = $(shell echo a | grep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) -GREP_OPTIONS ?= -ifeq ($HAVE_COLORNEVER, 1) - GREP_OPTIONS += --color=never -endif -GREP = grep $(GREP_OPTIONS) -SED_ERE_OPT ?= -E - -ZSTDCOMMON_FILES := $(sort $(wildcard common/*.c)) -ZSTDCOMP_FILES := $(sort $(wildcard compress/*.c)) -ZSTDDECOMP_FILES := $(sort $(wildcard decompress/*.c)) -ZDICT_FILES := $(sort $(wildcard dictBuilder/*.c)) -ZDEPR_FILES := $(sort $(wildcard deprecated/*.c)) -ZSTD_FILES := $(ZSTDCOMMON_FILES) - -ifeq ($(findstring GCC,$(CCVER)),GCC) -decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize -endif - # Modules ZSTD_LIB_COMPRESSION ?= 1 ZSTD_LIB_DECOMPRESSION ?= 1 ZSTD_LIB_DICTBUILDER ?= 1 ZSTD_LIB_DEPRECATED ?= 0 -# Legacy support -ZSTD_LEGACY_SUPPORT ?= 5 -ZSTD_LEGACY_MULTITHREADED_API ?= 0 - -# Build size optimizations -HUF_FORCE_DECOMPRESS_X1 ?= 0 -HUF_FORCE_DECOMPRESS_X2 ?= 0 -ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 0 -ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG ?= 0 -ZSTD_NO_INLINE ?= 0 -ZSTD_STRIP_ERROR_STRINGS ?= 0 - +# Input variables for libzstd.mk ifeq ($(ZSTD_LIB_COMPRESSION), 0) ZSTD_LIB_DICTBUILDER = 0 ZSTD_LIB_DEPRECATED = 0 @@ -122,86 +25,46 @@ ifeq ($(ZSTD_LIB_DECOMPRESSION), 0) ZSTD_LIB_DEPRECATED = 0 endif +include libzstd.mk + +ZSTD_FILES := $(ZSTD_COMMON_FILES) $(ZSTD_LEGACY_FILES) + ifneq ($(ZSTD_LIB_COMPRESSION), 0) - ZSTD_FILES += $(ZSTDCOMP_FILES) + ZSTD_FILES += $(ZSTD_COMPRESS_FILES) endif ifneq ($(ZSTD_LIB_DECOMPRESSION), 0) - ZSTD_FILES += $(ZSTDDECOMP_FILES) + ZSTD_FILES += $(ZSTD_DECOMPRESS_FILES) endif ifneq ($(ZSTD_LIB_DEPRECATED), 0) - ZSTD_FILES += $(ZDEPR_FILES) + ZSTD_FILES += $(ZSTD_DEPRECATED_FILES) endif ifneq ($(ZSTD_LIB_DICTBUILDER), 0) - ZSTD_FILES += $(ZDICT_FILES) + ZSTD_FILES += $(ZSTD_DICTBUILDER_FILES) endif -ifneq ($(HUF_FORCE_DECOMPRESS_X1), 0) - CFLAGS += -DHUF_FORCE_DECOMPRESS_X1 -endif - -ifneq ($(HUF_FORCE_DECOMPRESS_X2), 0) - CFLAGS += -DHUF_FORCE_DECOMPRESS_X2 -endif - -ifneq ($(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT), 0) - CFLAGS += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT -endif - -ifneq ($(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG), 0) - CFLAGS += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG -endif - -ifneq ($(ZSTD_NO_INLINE), 0) - CFLAGS += -DZSTD_NO_INLINE -endif - -ifneq ($(ZSTD_STRIP_ERROR_STRINGS), 0) - CFLAGS += -DZSTD_STRIP_ERROR_STRINGS -endif - -ifneq ($(ZSTD_LEGACY_MULTITHREADED_API), 0) - CFLAGS += -DZSTD_LEGACY_MULTITHREADED_API -endif - -ifneq ($(ZSTD_LEGACY_SUPPORT), 0) -ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0) - ZSTD_FILES += $(shell ls legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]') -endif -endif -CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) - ZSTD_LOCAL_SRC := $(notdir $(ZSTD_FILES)) -ZSTD_LOCAL_OBJ := $(ZSTD_LOCAL_SRC:.c=.o) +ZSTD_LOCAL_OBJ0 := $(ZSTD_LOCAL_SRC:.c=.o) +ZSTD_LOCAL_OBJ := $(ZSTD_LOCAL_OBJ0:.S=.o) -ZSTD_SUBDIR := common compress decompress dictBuilder legacy deprecated -vpath %.c $(ZSTD_SUBDIR) +VERSION := $(ZSTD_VERSION) -UNAME := $(shell uname) +# Note: by default, the static library is built single-threaded and dynamic library is built +# multi-threaded. It is possible to force multi or single threaded builds by appending +# -mt or -nomt to the build target (like lib-mt for multi-threaded, lib-nomt for single-threaded). +.PHONY: default +default: lib-release -ifndef BUILD_DIR -ifeq ($(UNAME), Darwin) - ifeq ($(shell md5 < /dev/null > /dev/null; echo $$?), 0) - HASH ?= md5 - endif -else ifeq ($(UNAME), FreeBSD) - HASH ?= gmd5sum -else ifeq ($(UNAME), NetBSD) - HASH ?= md5 -n -else ifeq ($(UNAME), OpenBSD) - HASH ?= md5 +CPPFLAGS_DYNLIB = -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded +LDFLAGS_DYNLIB = -pthread +CPPFLAGS_STATLIB = # static library build defaults to single-threaded + + +ifeq ($(findstring GCC,$(CCVER)),GCC) +decompress/zstd_decompress_block.o : CFLAGS+=-fno-tree-vectorize endif -HASH ?= md5sum - -HASH_DIR = conf_$(shell echo $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ZSTD_FILES) | $(HASH) | cut -f 1 -d " " ) -HAVE_HASH :=$(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0) -ifeq ($(HAVE_HASH),0) - $(info warning : could not find HASH ($(HASH)), needed to differentiate builds using different flags) - BUILD_DIR := obj/generic_noconf -endif -endif # BUILD_DIR # macOS linker doesn't support -soname, and use different extension @@ -218,13 +81,6 @@ else SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER) endif -SET_CACHE_DIRECTORY = \ - +$(MAKE) --no-print-directory $@ \ - BUILD_DIR=obj/$(HASH_DIR) \ - CPPFLAGS="$(CPPFLAGS)" \ - CFLAGS="$(CFLAGS)" \ - LDFLAGS="$(LDFLAGS)" - .PHONY: all all: lib @@ -233,6 +89,13 @@ all: lib .PHONY: libzstd.a # must be run every time libzstd.a: CPPFLAGS += $(CPPFLAGS_STATLIB) +SET_CACHE_DIRECTORY = \ + +$(MAKE) --no-print-directory $@ \ + BUILD_DIR=obj/$(HASH_DIR) \ + CPPFLAGS="$(CPPFLAGS)" \ + CFLAGS="$(CFLAGS)" \ + LDFLAGS="$(LDFLAGS)" + ifndef BUILD_DIR # determine BUILD_DIR from compilation flags @@ -343,6 +206,14 @@ $(ZSTD_STATLIB_DIR)/%.o : %.c $(ZSTD_STATLIB_DIR)/%.d | $(ZSTD_STATLIB_DIR) @echo CC $@ $(COMPILE.c) $(DEPFLAGS) $(ZSTD_STATLIB_DIR)/$*.d $(OUTPUT_OPTION) $< +$(ZSTD_DYNLIB_DIR)/%.o : %.S | $(ZSTD_DYNLIB_DIR) + @echo AS $@ + $(COMPILE.c) $(OUTPUT_OPTION) $< + +$(ZSTD_STATLIB_DIR)/%.o : %.S | $(ZSTD_STATLIB_DIR) + @echo AS $@ + $(COMPILE.c) $(OUTPUT_OPTION) $< + MKDIR ?= mkdir $(BUILD_DIR) $(ZSTD_DYNLIB_DIR) $(ZSTD_STATLIB_DIR): $(MKDIR) -p $@ diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index db11ab3dc..915778eb1 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -445,7 +445,7 @@ typedef struct { /* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing. * Strategy is to use as many buckets as possible for representing distinct * counts while using the remainder to represent all "large" counts. - * + * * To satisfy this requirement for 192 buckets, we can do the following: * Let buckets 0-166 represent distinct counts of [0, 166] * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing. @@ -517,7 +517,7 @@ static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) } /* Classic quicksort by descending with partially iterative calls - * to reduce worst case callstack size. + * to reduce worst case callstack size. */ static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) { int const kInsertionSortThreshold = 8; @@ -813,6 +813,7 @@ FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int id assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0); /* We didn't overwrite any bits in the bit container. */ assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + (void)dirtyBits; } #endif } diff --git a/lib/libzstd.mk b/lib/libzstd.mk new file mode 100644 index 000000000..45ee1ce62 --- /dev/null +++ b/lib/libzstd.mk @@ -0,0 +1,185 @@ +# ################################################################ +# Copyright (c) Yann Collet, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# You may select, at your option, one of the above-listed licenses. +# ################################################################ + +################################################################## +# Input Variables +################################################################## + +# Zstd lib directory +LIBZSTD ?= ./ + +# Legacy support +ZSTD_LEGACY_SUPPORT ?= 5 +ZSTD_LEGACY_MULTITHREADED_API ?= 0 + +# Build size optimizations +HUF_FORCE_DECOMPRESS_X1 ?= 0 +HUF_FORCE_DECOMPRESS_X2 ?= 0 +ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 0 +ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG ?= 0 +ZSTD_NO_INLINE ?= 0 +ZSTD_STRIP_ERROR_STRINGS ?= 0 + +# Assembly support +ZSTD_NO_ASM ?= 0 + +################################################################## +# libzstd helpers +################################################################## + +# Make 4.3 doesn't support '\#' anymore (https://lwn.net/Articles/810071/) +NUM_SYMBOL := \# + +# define silent mode as default (verbose mode with V=1 or VERBOSE=1) +$(V)$(VERBOSE).SILENT: + +# When cross-compiling from linux to windows, +# one might need to specify TARGET_SYSTEM as "Windows." +# Building from Fedora fails without it. +# (but Ubuntu and Debian don't need to set anything) +TARGET_SYSTEM ?= $(OS) + +# Version numbers +LIBVER_SRC := $(LIBZSTD)/zstd.h +LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` +LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` +LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` +LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT) +LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT)) +LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT)) +LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT)) +LIBVER := $(shell echo $(LIBVER_SCRIPT)) +CCVER := $(shell $(CC) --version) +ZSTD_VERSION?= $(LIBVER) + +# ZSTD_LIB_MINIFY is a helper variable that +# configures a bunch of other variables to space-optimized defaults. +ZSTD_LIB_MINIFY ?= 0 +ifneq ($(ZSTD_LIB_MINIFY), 0) + HAVE_CC_OZ ?= $(shell echo "" | $(CC) -Oz -x c -c - -o /dev/null 2> /dev/null && echo 1 || echo 0) + ZSTD_LEGACY_SUPPORT ?= 0 + ZSTD_LIB_DEPRECATED ?= 0 + HUF_FORCE_DECOMPRESS_X1 ?= 1 + ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT ?= 1 + ZSTD_NO_INLINE ?= 1 + ZSTD_STRIP_ERROR_STRINGS ?= 1 +ifneq ($(HAVE_CC_OZ), 0) + # Some compilers (clang) support an even more space-optimized setting. + CFLAGS += -Oz +else + CFLAGS += -Os +endif + CFLAGS += -fno-stack-protector -fomit-frame-pointer -fno-ident \ + -DDYNAMIC_BMI2=0 -DNDEBUG +else + CFLAGS += -O3 +endif + +DEBUGLEVEL ?= 0 +CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -DDEBUGLEVEL=$(DEBUGLEVEL) +ifeq ($(TARGET_SYSTEM),Windows_NT) # MinGW assumed + CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting +endif +DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ + -Wstrict-prototypes -Wundef -Wpointer-arith \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls -Wmissing-prototypes -Wc++-compat +CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) +LDFLAGS += $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) + +HAVE_COLORNEVER = $(shell echo a | grep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) +GREP_OPTIONS ?= +ifeq ($HAVE_COLORNEVER, 1) + GREP_OPTIONS += --color=never +endif +GREP = grep $(GREP_OPTIONS) +SED_ERE_OPT ?= -E + +ZSTD_COMMON_FILES := $(sort $(wildcard $(LIBZSTD)/common/*.c)) +ZSTD_COMPRESS_FILES := $(sort $(wildcard $(LIBZSTD)/compress/*.c)) +ZSTD_DECOMPRESS_FILES := $(sort $(wildcard $(LIBZSTD)/decompress/*.c)) +ZSTD_DICTBUILDER_FILES := $(sort $(wildcard $(LIBZSTD)/dictBuilder/*.c)) +ZSTD_DEPRECATED_FILES := $(sort $(wildcard $(LIBZSTD)/deprecated/*.c)) +ZSTD_LEGACY_FILES := + +ZSTD_DECOMPRESS_AMD64_ASM_FILES := $(sort $(wildcard $(LIBZSTD)/decompress/*_amd64.S)) + +ifneq ($(ZSTD_NO_ASM), 0) + CPPFLAGS += -DHUF_DISABLE_ASM +else + # Unconditionally add the ASM files they are disabled by + # macros in the .S file. + ZSTD_DECOMPRESS_FILES += $(ZSTD_DECOMPRESS_AMD64_ASM_FILES) +endif + +ifneq ($(HUF_FORCE_DECOMPRESS_X1), 0) + CFLAGS += -DHUF_FORCE_DECOMPRESS_X1 +endif + +ifneq ($(HUF_FORCE_DECOMPRESS_X2), 0) + CFLAGS += -DHUF_FORCE_DECOMPRESS_X2 +endif + +ifneq ($(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT), 0) + CFLAGS += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +endif + +ifneq ($(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG), 0) + CFLAGS += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +endif + +ifneq ($(ZSTD_NO_INLINE), 0) + CFLAGS += -DZSTD_NO_INLINE +endif + +ifneq ($(ZSTD_STRIP_ERROR_STRINGS), 0) + CFLAGS += -DZSTD_STRIP_ERROR_STRINGS +endif + +ifneq ($(ZSTD_LEGACY_MULTITHREADED_API), 0) + CFLAGS += -DZSTD_LEGACY_MULTITHREADED_API +endif + +ifneq ($(ZSTD_LEGACY_SUPPORT), 0) +ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0) + ZSTD_LEGACY_FILES += $(shell ls $(LIBZSTD)/legacy/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]') +endif +endif +CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) + +UNAME := $(shell uname) + +ifndef BUILD_DIR +ifeq ($(UNAME), Darwin) + ifeq ($(shell md5 < /dev/null > /dev/null; echo $$?), 0) + HASH ?= md5 + endif +else ifeq ($(UNAME), FreeBSD) + HASH ?= gmd5sum +else ifeq ($(UNAME), NetBSD) + HASH ?= md5 -n +else ifeq ($(UNAME), OpenBSD) + HASH ?= md5 +endif +HASH ?= md5sum + +HASH_DIR = conf_$(shell echo $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ZSTD_FILES) | $(HASH) | cut -f 1 -d " " ) +HAVE_HASH :=$(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0) +ifeq ($(HAVE_HASH),0) + $(info warning : could not find HASH ($(HASH)), needed to differentiate builds using different flags) + BUILD_DIR := obj/generic_noconf +endif +endif # BUILD_DIR + +ZSTD_SUBDIR := $(LIBZSTD)/common $(LIBZSTD)/compress $(LIBZSTD)/decompress $(LIBZSTD)/dictBuilder $(LIBZSTD)/legacy $(LIBZSTD)/deprecated +vpath %.c $(ZSTD_SUBDIR) +vpath %.S $(ZSTD_SUBDIR) diff --git a/programs/Makefile b/programs/Makefile index ad05dbe1d..ef094fb74 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -9,7 +9,7 @@ # ########################################################################## # zstd : Command Line Utility, supporting gzip-like arguments # zstd32 : Same as zstd, but forced to compile in 32-bits mode -# zstd_nolegacy : zstd without support of decompression of legacy versions +# zstd-nolegacy : zstd without support of decompression of legacy versions # zstd-small : minimal zstd without dictionary builder and benchmark # zstd-compress : compressor-only version of zstd # zstd-decompress : decompressor-only version of zstd @@ -18,31 +18,9 @@ .PHONY: default default: zstd-release -# silent mode by default; verbose can be triggered by V=1 or VERBOSE=1 -$(V)$(VERBOSE).SILENT: +LIBZSTD := ../lib - -ZSTDDIR := ../lib - -# Version numbers -LIBVER_SRC := $(ZSTDDIR)/zstd.h -LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` -LIBVER_MINOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` -LIBVER_PATCH_SCRIPT:=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < $(LIBVER_SRC)` -LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT) -LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT)) -LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT)) -LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT)) -LIBVER := $(shell echo $(LIBVER_SCRIPT)) - -ZSTD_VERSION = $(LIBVER) - -HAVE_COLORNEVER = $(shell echo a | grep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) -GREP_OPTIONS ?= -ifeq ($HAVE_COLORNEVER, 1) - GREP_OPTIONS += --color=never -endif -GREP = grep $(GREP_OPTIONS) +include $(LIBZSTD)/libzstd.mk ifeq ($(shell $(CC) -v 2>&1 | $(GREP) -c "gcc version "), 1) ALIGN_LOOP = -falign-loops=32 @@ -50,78 +28,25 @@ else ALIGN_LOOP = endif -DEBUGLEVEL ?= 0 -CPPFLAGS += -DXXH_NAMESPACE=ZSTD_ -DDEBUGLEVEL=$(DEBUGLEVEL) -ifeq ($(OS),Windows_NT) # MinGW assumed - CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting -endif -CFLAGS ?= -O3 -DEBUGFLAGS+=-Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ - -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ - -Wstrict-prototypes -Wundef -Wpointer-arith \ - -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ - -Wredundant-decls -Wmissing-prototypes -Wc++-compat -CFLAGS += $(DEBUGFLAGS) -CPPFLAGS += $(MOREFLAGS) -LDFLAGS += $(MOREFLAGS) -FLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) - -ZSTDLIB_COMMON := $(ZSTDDIR)/common -ZSTDLIB_COMPRESS := $(ZSTDDIR)/compress -ZSTDLIB_DECOMPRESS := $(ZSTDDIR)/decompress -ZDICT_DIR := $(ZSTDDIR)/dictBuilder -ZSTDLEGACY_DIR := $(ZSTDDIR)/legacy - -vpath %.c $(ZSTDLIB_COMMON) $(ZSTDLIB_COMPRESS) $(ZSTDLIB_DECOMPRESS) $(ZDICT_DIR) $(ZSTDLEGACY_DIR) - -ZSTDLIB_COMMON_C := $(wildcard $(ZSTDLIB_COMMON)/*.c) -ZSTDLIB_COMPRESS_C := $(wildcard $(ZSTDLIB_COMPRESS)/*.c) -ZSTDLIB_DECOMPRESS_C := $(wildcard $(ZSTDLIB_DECOMPRESS)/*.c) -ZSTDLIB_CORE_SRC := $(ZSTDLIB_DECOMPRESS_C) $(ZSTDLIB_COMMON_C) $(ZSTDLIB_COMPRESS_C) -ZDICT_SRC := $(wildcard $(ZDICT_DIR)/*.c) - -ZSTD_LEGACY_SUPPORT ?= 5 -ZSTDLEGACY_SRC := -ifneq ($(ZSTD_LEGACY_SUPPORT), 0) -ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0) - ZSTDLEGACY_SRC += $(shell ls $(ZSTDLEGACY_DIR)/*.c | $(GREP) 'v0[$(ZSTD_LEGACY_SUPPORT)-7]') -endif -endif +ZSTDLIB_COMMON_SRC := $(sort $(ZSTD_COMMON_FILES)) +ZSTDLIB_COMPRESS_SRC := $(sort $(ZSTD_COMPRESS_FILES)) +ZSTDLIB_DECOMPRESS_SRC := $(sort $(ZSTD_DECOMPRESS_FILES)) +ZSTDLIB_CORE_SRC := $(sort $(ZSTD_DECOMPRESS_FILES) $(ZSTD_COMMON_FILES) $(ZSTD_COMPRESS_FILES)) +ZDICT_SRC := $(sort $(ZSTD_DICTBUILDER_FILES)) +ZSTDLEGACY_SRC := $(sort $(ZSTD_LEGACY_FILES)) # Sort files in alphabetical order for reproducible builds ZSTDLIB_FULL_SRC = $(sort $(ZSTDLIB_CORE_SRC) $(ZSTDLEGACY_SRC) $(ZDICT_SRC)) ZSTDLIB_LOCAL_SRC = $(notdir $(ZSTDLIB_FULL_SRC)) -ZSTDLIB_LOCAL_OBJ := $(ZSTDLIB_LOCAL_SRC:.c=.o) +ZSTDLIB_LOCAL_OBJ0 := $(ZSTDLIB_LOCAL_SRC:.c=.o) +ZSTDLIB_LOCAL_OBJ := $(ZSTDLIB_LOCAL_OBJ0:.S=.o) ZSTD_CLI_SRC := $(wildcard *.c) ZSTD_CLI_OBJ := $(ZSTD_CLI_SRC:.c=.o) ZSTD_ALL_SRC = $(ZSTDLIB_LOCAL_SRC) $(ZSTD_CLI_SRC) -ZSTD_ALL_OBJ := $(ZSTD_ALL_SRC:.c=.o) - -UNAME := $(shell uname) - -ifndef BUILD_DIR -ifeq ($(UNAME), Darwin) - ifeq ($(shell md5 < /dev/null > /dev/null; echo $$?), 0) - HASH ?= md5 - endif -else ifeq ($(UNAME), FreeBSD) - HASH ?= gmd5sum -else ifeq ($(UNAME), NetBSD) - HASH ?= md5 -n -else ifeq ($(UNAME), OpenBSD) - HASH ?= md5 -endif -HASH ?= md5sum -HAVE_HASH :=$(shell echo 1 | $(HASH) > /dev/null && echo 1 || echo 0) - -HASH_DIR = conf_$(shell echo $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LDLIBS) $(ZSTD_FILES) | $(HASH) | cut -f 1 -d " ") -ifeq ($(HAVE_HASH),0) - $(info warning : could not find HASH ($(HASH)), needed to differentiate builds using different flags) - BUILD_DIR := obj/generic_noconf -endif -endif # BUILD_DIR +ZSTD_ALL_OBJ0 := $(ZSTD_ALL_SRC:.c=.o) +ZSTD_ALL_OBJ := $(ZSTD_ALL_OBJ0:.S=.o) # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) @@ -139,9 +64,6 @@ endif VOID = /dev/null -# Make 4.3 doesn't support '\#' anymore (https://lwn.net/Articles/810071/) -NUM_SYMBOL := \# - # thread detection NO_THREAD_MSG := ==> no threads, building without multithreading support HAVE_PTHREAD := $(shell printf '$(NUM_SYMBOL)include \nint main(void) { return 0; }' > have_pthread.c && $(CC) $(FLAGS) -o have_pthread$(EXT) have_pthread.c -pthread 2> $(VOID) && rm have_pthread$(EXT) && echo 1 || echo 0; rm have_pthread.c) @@ -212,7 +134,7 @@ SET_CACHE_DIRECTORY = \ all: zstd .PHONY: allVariants -allVariants: zstd zstd-compress zstd-decompress zstd-small zstd-nolegacy zstd-dictBuilder +allVariants: zstd zstd-compress zstd-decompress zstd-small zstd-frugal zstd-nolegacy zstd-dictBuilder .PHONY: zstd # must always be run zstd : CPPFLAGS += $(THREAD_CPP) $(ZLIBCPP) $(LZMACPP) $(LZ4CPP) @@ -276,6 +198,7 @@ zstd32 : $(ZSTDLIB_FULL_SRC) $(ZSTD_CLI_SRC) ## zstd-nolegacy: same scope as zstd, with just support of legacy formats removed zstd-nolegacy : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD) $(LZ4LD) $(DEBUGFLAGS_LD) +zstd-nolegacy : CPPFLAGS += -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 zstd-nolegacy : $(ZSTDLIB_CORE_SRC) $(ZDICT_SRC) $(ZSTD_CLI_OBJ) $(CC) $(FLAGS) $^ -o $@$(EXT) $(LDFLAGS) @@ -299,7 +222,7 @@ zstd-noxz : zstd ## zstd-dll: zstd executable linked to dynamic library libzstd (must have same version) .PHONY: zstd-dll -zstd-dll : LDFLAGS+= -L$(ZSTDDIR) +zstd-dll : LDFLAGS+= -L$(LIBZSTD) zstd-dll : LDLIBS += -lzstd zstd-dll : ZSTDLIB_LOCAL_SRC = xxhash.c zstd-dll : zstd @@ -323,18 +246,17 @@ zstd-pgo : ## zstd-small: minimal target, supporting only zstd compression and decompression. no bench. no legacy. no other format. zstd-small: CFLAGS = -Os -s zstd-frugal zstd-small: $(ZSTDLIB_CORE_SRC) zstdcli.c util.c timefn.c fileio.c - $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOTRACE $^ -o $@$(EXT) + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT) -zstd-decompress: $(ZSTDLIB_COMMON_C) $(ZSTDLIB_DECOMPRESS_C) zstdcli.c util.c timefn.c fileio.c - $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT) +zstd-decompress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_DECOMPRESS_SRC) zstdcli.c util.c timefn.c fileio.c + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NOCOMPRESS -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT) -zstd-compress: $(ZSTDLIB_COMMON_C) $(ZSTDLIB_COMPRESS_C) zstdcli.c util.c timefn.c fileio.c - $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT) +zstd-compress: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) zstdcli.c util.c timefn.c fileio.c + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODICT -DZSTD_NODECOMPRESS -DZSTD_NOTRACE -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=0 $^ -o $@$(EXT) ## zstd-dictBuilder: executable supporting dictionary creation and compression (only) -zstd-dictBuilder: CPPFLAGS += -DZSTD_NOBENCH -DZSTD_NODECOMPRESS -DZSTD_NOTRACE -zstd-dictBuilder: $(ZSTDLIB_COMMON_C) $(ZSTDLIB_COMPRESS_C) $(ZDICT_SRC) zstdcli.c util.c timefn.c fileio.c dibio.c - $(CC) $(FLAGS) $^ -o $@$(EXT) +zstd-dictBuilder: $(ZSTDLIB_COMMON_SRC) $(ZSTDLIB_COMPRESS_SRC) $(ZDICT_SRC) zstdcli.c util.c timefn.c fileio.c dibio.c + $(CC) $(FLAGS) -DZSTD_NOBENCH -DZSTD_NODECOMPRESS -DZSTD_NOTRACE $^ -o $@$(EXT) zstdmt: zstd ln -sf zstd zstdmt @@ -398,6 +320,10 @@ $(BUILD_DIR)/%.o : %.c $(BUILD_DIR)/%.d | $(BUILD_DIR) @echo CC $@ $(COMPILE.c) $(DEPFLAGS) $(BUILD_DIR)/$*.d $(OUTPUT_OPTION) $< +$(BUILD_DIR)/%.o : %.S | $(BUILD_DIR) + @echo AS $@ + $(COMPILE.c) $(OUTPUT_OPTION) $< + MKDIR ?= mkdir $(BUILD_DIR): ; $(MKDIR) -p $@ diff --git a/tests/Makefile b/tests/Makefile index 85553007d..56c448340 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,5 @@ -# ################################################################ + + # ################################################################ # Copyright (c) Yann Collet, Facebook, Inc. # All rights reserved. # @@ -19,46 +20,43 @@ # zstreamtest32: Same as zstreamtest, but forced to compile in 32-bits mode # ########################################################################## -ZSTDDIR = ../lib +LIBZSTD = ../lib + +ZSTD_LEGACY_SUPPORT ?= 0 + +DEBUGLEVEL ?= 2 +export DEBUGLEVEL # transmit value to sub-makefiles + +include $(LIBZSTD)/libzstd.mk + +ZSTDDIR = $(LIBZSTD) PRGDIR = ../programs PYTHON ?= python3 TESTARTEFACT := versionsTest -DEBUGLEVEL ?= 2 -export DEBUGLEVEL # transmit value to sub-makefiles -DEBUGFLAGS = -g -DDEBUGLEVEL=$(DEBUGLEVEL) +DEBUGFLAGS += -g -Wno-c++-compat CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ -DZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY=1 -ifeq ($(OS),Windows_NT) # MinGW assumed -CPPFLAGS += -D__USE_MINGW_ANSI_STDIO # compatibility with %zu formatting -endif -CFLAGS ?= -O3 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ - -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ - -Wstrict-prototypes -Wundef \ - -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ - -Wredundant-decls -Wmissing-prototypes -Wno-deprecated-declarations -CFLAGS += $(DEBUGFLAGS) -CPPFLAGS += $(MOREFLAGS) - -ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c -ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c -ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c +ZSTDCOMMON_FILES := $(sort $(ZSTD_COMMON_FILES)) +ZSTDCOMP_FILES := $(sort $(ZSTD_COMPRESS_FILES)) +ZSTDDECOMP_FILES := $(sort $(ZSTD_DECOMPRESS_FILES)) ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) -ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c +ZDICT_FILES := $(sort $(ZSTD_DICTBUILDER_FILES)) ZSTD_F1 := $(wildcard $(ZSTD_FILES)) ZSTD_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdm_,$(ZSTD_F1)) ZSTD_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdc_,$(ZSTD_OBJ1)) ZSTD_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdd_,$(ZSTD_OBJ2)) -ZSTD_OBJECTS := $(ZSTD_OBJ3:.c=.o) +ZSTD_OBJ4 := $(ZSTD_OBJ3:.c=.o) +ZSTD_OBJECTS := $(ZSTD_OBJ4:.S=.o) ZSTDMT_OBJ1 := $(subst $(ZSTDDIR)/common/,zstdmt_m_,$(ZSTD_F1)) ZSTDMT_OBJ2 := $(subst $(ZSTDDIR)/compress/,zstdmt_c_,$(ZSTDMT_OBJ1)) ZSTDMT_OBJ3 := $(subst $(ZSTDDIR)/decompress/,zstdmt_d_,$(ZSTDMT_OBJ2)) -ZSTDMT_OBJECTS := $(ZSTDMT_OBJ3:.c=.o) +ZSTDMT_OBJ4 := $(ZSTDMT_OBJ3:.c=.o) +ZSTDMT_OBJECTS := $(ZSTDMT_OBJ4:.S=.o) # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) @@ -119,6 +117,9 @@ zstdc_%.o : $(ZSTDDIR)/compress/%.c zstdd_%.o : $(ZSTDDIR)/decompress/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ +zstdd_%.o : $(ZSTDDIR)/decompress/%.S + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + zstdmt%.o : CPPFLAGS += $(MULTITHREAD_CPP) zstdmt_m_%.o : $(ZSTDDIR)/common/%.c @@ -130,6 +131,9 @@ zstdmt_c_%.o : $(ZSTDDIR)/compress/%.c zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ +zstdmt_d_%.o : $(ZSTDDIR)/decompress/%.S + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + fullbench32: CPPFLAGS += -m32 fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP) -Wno-deprecated-declarations fullbench fullbench32 : LDFLAGS += $(MULTITHREAD_LD) @@ -201,7 +205,7 @@ bigdict: $(ZSTDMT_OBJECTS) $(PRGDIR)/datagen.c bigdict.c invalidDictionaries : $(ZSTD_OBJECTS) invalidDictionaries.c -legacy : CPPFLAGS += -I$(ZSTDDIR)/legacy -DZSTD_LEGACY_SUPPORT=4 +legacy : CPPFLAGS += -I$(ZSTDDIR)/legacy -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=4 legacy : $(ZSTD_FILES) $(wildcard $(ZSTDDIR)/legacy/*.c) legacy.c decodecorpus : LDLIBS += -lm diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index 5c54ccd77..72dbccb57 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -23,6 +23,12 @@ else endif CORPORA_URL_PREFIX:=https://github.com/facebook/zstd/releases/download/fuzz-corpora/ +LIBZSTD = ../../lib +DEBUGLEVEL ?= 2 +ZSTD_LEGACY_SUPPORT ?= 1 + +include $(LIBZSTD)/libzstd.mk + ZSTDDIR = ../../lib PRGDIR = ../../programs CONTRIBDIR = ../../contrib @@ -34,7 +40,7 @@ FUZZ_EXTRA_FLAGS := -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ -Wstrict-prototypes -Wundef \ -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ - -Wredundant-decls \ + -Wredundant-decls -Wno-deprecated-declarations \ -g -fno-omit-frame-pointer FUZZ_CFLAGS := $(FUZZ_EXTRA_FLAGS) $(CFLAGS) FUZZ_CXXFLAGS := $(FUZZ_EXTRA_FLAGS) -std=c++11 $(CXXFLAGS) @@ -50,11 +56,11 @@ FUZZ_SRC := $(PRGDIR)/util.c ./fuzz_helpers.c ./zstd_helpers.c ./fuzz_data_produ SEEKABLE_HEADERS = $(CONTRIBDIR)/seekable_format/zstd_seekable.h SEEKABLE_OBJS = $(CONTRIBDIR)/seekable_format/zstdseek_compress.c $(CONTRIBDIR)/seekable_format/zstdseek_decompress.c -ZSTDCOMMON_SRC := $(ZSTDDIR)/common/*.c -ZSTDCOMP_SRC := $(ZSTDDIR)/compress/*.c -ZSTDDECOMP_SRC := $(ZSTDDIR)/decompress/*.c -ZSTDDICT_SRC := $(ZSTDDIR)/dictBuilder/*.c -ZSTDLEGACY_SRC := $(ZSTDDIR)/legacy/*.c +ZSTDCOMMON_SRC := $(ZSTD_COMMON_FILES) +ZSTDCOMP_SRC := $(ZSTD_COMPRESS_FILES) +ZSTDDECOMP_SRC := $(ZSTD_DECOMPRESS_FILES) +ZSTDDICT_SRC := $(ZSTD_DICTBUILDER_FILES) +ZSTDLEGACY_SRC := $(ZSTD_LEGACY_FILES) FUZZ_SRC := \ $(FUZZ_SRC) \ $(ZSTDDECOMP_SRC) \ @@ -71,7 +77,8 @@ FUZZ_D_OBJ4 := $(subst $(ZSTDDIR)/dictBuilder/,d_lib_dictBuilder_,$(FUZZ_D_OBJ3) FUZZ_D_OBJ5 := $(subst $(ZSTDDIR)/legacy/,d_lib_legacy_,$(FUZZ_D_OBJ4)) FUZZ_D_OBJ6 := $(subst $(PRGDIR)/,d_prg_,$(FUZZ_D_OBJ5)) FUZZ_D_OBJ7 := $(subst $\./,d_fuzz_,$(FUZZ_D_OBJ6)) -FUZZ_DECOMPRESS_OBJ := $(FUZZ_D_OBJ7:.c=.o) +FUZZ_D_OBJ8 := $(FUZZ_D_OBJ7:.c=.o) +FUZZ_DECOMPRESS_OBJ := $(FUZZ_D_OBJ8:.S=.o) FUZZ_RT_OBJ1 := $(subst $(ZSTDDIR)/common/,rt_lib_common_,$(FUZZ_SRC)) FUZZ_RT_OBJ2 := $(subst $(ZSTDDIR)/compress/,rt_lib_compress_,$(FUZZ_RT_OBJ1)) @@ -80,7 +87,8 @@ FUZZ_RT_OBJ4 := $(subst $(ZSTDDIR)/dictBuilder/,rt_lib_dictBuilder_,$(FUZZ_RT_OB FUZZ_RT_OBJ5 := $(subst $(ZSTDDIR)/legacy/,rt_lib_legacy_,$(FUZZ_RT_OBJ4)) FUZZ_RT_OBJ6 := $(subst $(PRGDIR)/,rt_prg_,$(FUZZ_RT_OBJ5)) FUZZ_RT_OBJ7 := $(subst $\./,rt_fuzz_,$(FUZZ_RT_OBJ6)) -FUZZ_ROUND_TRIP_OBJ := $(FUZZ_RT_OBJ7:.c=.o) +FUZZ_RT_OBJ8 := $(FUZZ_RT_OBJ7:.c=.o) +FUZZ_ROUND_TRIP_OBJ := $(FUZZ_RT_OBJ8:.S=.o) .PHONY: default all clean cleanall @@ -117,6 +125,9 @@ rt_lib_compress_%.o: $(ZSTDDIR)/compress/%.c rt_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ +rt_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.S + $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ + rt_lib_dictBuilder_%.o: $(ZSTDDIR)/dictBuilder/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $(FUZZ_ROUND_TRIP_FLAGS) $< -c -o $@ @@ -138,6 +149,9 @@ d_lib_compress_%.o: $(ZSTDDIR)/compress/%.c d_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ +d_lib_decompress_%.o: $(ZSTDDIR)/decompress/%.S + $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ + d_lib_dictBuilder_%.o: $(ZSTDDIR)/dictBuilder/%.c $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $< -c -o $@ diff --git a/tests/fuzzer.c b/tests/fuzzer.c index ce79f53ac..c4de54247 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1528,7 +1528,7 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(3, "test%3i : resize context to full CCtx size : ", testNb++); staticCCtx = ZSTD_initStaticCStream(staticCCtxBuffer, staticCCtxSize); - DISPLAYLEVEL(4, "staticCCtxBuffer = %p, staticCCtx = %p , ", staticCCtxBuffer, staticCCtx); + DISPLAYLEVEL(4, "staticCCtxBuffer = %p, staticCCtx = %p , ", staticCCtxBuffer, (void*)staticCCtx); if (staticCCtx == NULL) goto _output_error; DISPLAYLEVEL(3, "OK \n"); diff --git a/tests/regression/Makefile b/tests/regression/Makefile index 3a5a64e5b..a440c6c94 100644 --- a/tests/regression/Makefile +++ b/tests/regression/Makefile @@ -46,6 +46,7 @@ result.o: result.c result.h test.o: test.c data.h config.h method.h $(CC) $(REGRESSION_CFLAGS) $(REGRESSION_CPPFLAGS) $< -c -o $@ +.PHONY: libzstd.a libzstd.a: $(MAKE) -C $(LIBDIR) libzstd.a-mt cp $(LIBDIR)/libzstd.a . diff --git a/tests/test-variants.sh b/tests/test-variants.sh new file mode 100755 index 000000000..f3a9e065b --- /dev/null +++ b/tests/test-variants.sh @@ -0,0 +1,115 @@ +#!/bin/sh +set -e +set -u +set -x + + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) +PROG_DIR="$SCRIPT_DIR/../programs" + +ZSTD="$PROG_DIR/zstd" +ZSTD_COMPRESS="$PROG_DIR/zstd-compress" +ZSTD_DECOMPRESS="$PROG_DIR/zstd-decompress" +ZSTD_NOLEGACY="$PROG_DIR/zstd-nolegacy" +ZSTD_DICTBUILDER="$PROG_DIR/zstd-dictBuilder" +ZSTD_FRUGAL="$PROG_DIR/zstd-frugal" +ZSTD_NOMT="$PROG_DIR/zstd-nomt" + +println() { + printf '%b\n' "${*}" +} + +die() { + println "$@" 1>&2 + exit 1 +} + +symbol_present() { + (nm $1 || echo "symbol_present $@ failed") | grep $2 +} + +symbol_not_present() { + symbol_present $@ && die "Binary '$1' mistakenly contains symbol '$2'" ||: +} + +compress_not_present() { + symbol_not_present "$1" ZSTD_compress +} + +decompress_not_present() { + symbol_not_present "$1" ZSTD_decompress +} + +dict_not_present() { + symbol_not_present "$1" ZDICT_ + symbol_not_present "$1" COVER_ +} + +cliextra_not_present() { + symbol_not_present "$1" TRACE_ + symbol_not_present "$1" BMK_ +} + +legacy_not_present() { + symbol_not_present "$1" ZSTDv0 +} + +test_help() { + "$1" --help | grep -- "$2" +} + +test_no_help() { + test_help $@ && die "'$1' supports '$2' when it shouldn't" ||: +} + +extras_not_present() { + dict_not_present $@ + legacy_not_present $@ + cliextra_not_present $@ + test_no_help $@ "--train" + test_no_help $@ "-b#" +} + +test_compress() { + echo "hello" | "$1" | "$ZSTD" -t +} + +test_decompress() { + echo "hello" | "$ZSTD" | "$1" -t +} + +test_zstd() { + test_compress $@ + test_decompress $@ +} + +extras_not_present "$ZSTD_FRUGAL" +extras_not_present "$ZSTD_COMPRESS" +extras_not_present "$ZSTD_DECOMPRESS" + +compress_not_present "$ZSTD_DECOMPRESS" + +decompress_not_present "$ZSTD_COMPRESS" +decompress_not_present "$ZSTD_DICTBUILDER" + +cliextra_not_present "$ZSTD_DICTBUILDER" + +legacy_not_present "$ZSTD_DICTBUILDER" +legacy_not_present "$ZSTD_NOLEGACY" + +symbol_not_present "$ZSTD" ZSTDv01 +symbol_not_present "$ZSTD" ZSTDv02 +symbol_not_present "$ZSTD" ZSTDv03 +symbol_not_present "$ZSTD" ZSTDv04 + +test_compress "$ZSTD_COMPRESS" +test_decompress "$ZSTD_DECOMPRESS" + +test_zstd "$ZSTD_FRUGAL" +test_zstd "$ZSTD_NOLEGACY" + +test_help "$ZSTD" '-b#' +test_help "$ZSTD" --train +test_help "$ZSTD_DICTBUILDER" --train + +println "Success!" From d7542aacd99ad922dd179e729ce411c107963ab3 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 17 Sep 2021 12:58:04 -0700 Subject: [PATCH 162/274] [fuzzer] Add huf_decompress fuzzer Add a fuzzer for Huffman decompression. Fix several bugs in Huffman decompression, mostly related to `op == NULL` and pointer underflow. --- lib/decompress/huf_decompress.c | 166 +++++++++++++++++--------------- tests/fuzz/Makefile | 6 +- tests/fuzz/fuzz.py | 1 + tests/fuzz/huf_decompress.c | 64 ++++++++++++ 4 files changed, 159 insertions(+), 78 deletions(-) create mode 100644 tests/fuzz/huf_decompress.c diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index b93c9a003..f41a02bb5 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -304,11 +304,13 @@ HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, cons BYTE* const pStart = p; /* up to 4 symbols at a time */ - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { - HUF_DECODE_SYMBOLX1_2(p, bitDPtr); - HUF_DECODE_SYMBOLX1_1(p, bitDPtr); - HUF_DECODE_SYMBOLX1_2(p, bitDPtr); - HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + if ((pEnd - p) > 3) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_1(p, bitDPtr); + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + } } /* [0-3] symbols remaining */ @@ -388,33 +390,36 @@ HUF_decompress4X1_usingDTable_internal_body( U32 endSignal = 1; if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */ - for ( ; (endSignal) & (op4 < olimit) ; ) { - HUF_DECODE_SYMBOLX1_2(op1, &bitD1); - HUF_DECODE_SYMBOLX1_2(op2, &bitD2); - HUF_DECODE_SYMBOLX1_2(op3, &bitD3); - HUF_DECODE_SYMBOLX1_2(op4, &bitD4); - HUF_DECODE_SYMBOLX1_1(op1, &bitD1); - HUF_DECODE_SYMBOLX1_1(op2, &bitD2); - HUF_DECODE_SYMBOLX1_1(op3, &bitD3); - HUF_DECODE_SYMBOLX1_1(op4, &bitD4); - HUF_DECODE_SYMBOLX1_2(op1, &bitD1); - HUF_DECODE_SYMBOLX1_2(op2, &bitD2); - HUF_DECODE_SYMBOLX1_2(op3, &bitD3); - HUF_DECODE_SYMBOLX1_2(op4, &bitD4); - HUF_DECODE_SYMBOLX1_0(op1, &bitD1); - HUF_DECODE_SYMBOLX1_0(op2, &bitD2); - HUF_DECODE_SYMBOLX1_0(op3, &bitD3); - HUF_DECODE_SYMBOLX1_0(op4, &bitD4); - endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; - endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; - endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; - endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit) ; ) { + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_1(op1, &bitD1); + HUF_DECODE_SYMBOLX1_1(op2, &bitD2); + HUF_DECODE_SYMBOLX1_1(op3, &bitD3); + HUF_DECODE_SYMBOLX1_1(op4, &bitD4); + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_0(op1, &bitD1); + HUF_DECODE_SYMBOLX1_0(op2, &bitD2); + HUF_DECODE_SYMBOLX1_0(op3, &bitD3); + HUF_DECODE_SYMBOLX1_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; + } } /* check corruption */ @@ -753,19 +758,23 @@ HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, BYTE* const pStart = p; /* up to 8 symbols at a time */ - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { - HUF_DECODE_SYMBOLX2_2(p, bitDPtr); - HUF_DECODE_SYMBOLX2_1(p, bitDPtr); - HUF_DECODE_SYMBOLX2_2(p, bitDPtr); - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } } /* closer to end : up to 2 symbols at a time */ - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + if ((size_t)(pEnd - p) >= 2) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); - while (p <= pEnd-2) - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + while (p <= pEnd-2) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + } if (p < pEnd) p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog); @@ -841,57 +850,60 @@ HUF_decompress4X2_usingDTable_internal_body( U32 const dtLog = dtd.tableLog; if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); /* 16-32 symbols per loop (4-8 symbols per stream) */ - for ( ; (endSignal) & (op4 < olimit); ) { + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit); ) { #if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) - HUF_DECODE_SYMBOLX2_2(op1, &bitD1); - HUF_DECODE_SYMBOLX2_1(op1, &bitD1); - HUF_DECODE_SYMBOLX2_2(op1, &bitD1); - HUF_DECODE_SYMBOLX2_0(op1, &bitD1); - HUF_DECODE_SYMBOLX2_2(op2, &bitD2); - HUF_DECODE_SYMBOLX2_1(op2, &bitD2); - HUF_DECODE_SYMBOLX2_2(op2, &bitD2); - HUF_DECODE_SYMBOLX2_0(op2, &bitD2); - endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; - endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; - HUF_DECODE_SYMBOLX2_2(op3, &bitD3); - HUF_DECODE_SYMBOLX2_1(op3, &bitD3); - HUF_DECODE_SYMBOLX2_2(op3, &bitD3); - HUF_DECODE_SYMBOLX2_0(op3, &bitD3); - HUF_DECODE_SYMBOLX2_2(op4, &bitD4); - HUF_DECODE_SYMBOLX2_1(op4, &bitD4); - HUF_DECODE_SYMBOLX2_2(op4, &bitD4); - HUF_DECODE_SYMBOLX2_0(op4, &bitD4); - endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; - endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; #else - HUF_DECODE_SYMBOLX2_2(op1, &bitD1); - HUF_DECODE_SYMBOLX2_2(op2, &bitD2); - HUF_DECODE_SYMBOLX2_2(op3, &bitD3); - HUF_DECODE_SYMBOLX2_2(op4, &bitD4); - HUF_DECODE_SYMBOLX2_1(op1, &bitD1); - HUF_DECODE_SYMBOLX2_1(op2, &bitD2); - HUF_DECODE_SYMBOLX2_1(op3, &bitD3); - HUF_DECODE_SYMBOLX2_1(op4, &bitD4); - HUF_DECODE_SYMBOLX2_2(op1, &bitD1); - HUF_DECODE_SYMBOLX2_2(op2, &bitD2); - HUF_DECODE_SYMBOLX2_2(op3, &bitD3); - HUF_DECODE_SYMBOLX2_2(op4, &bitD4); - HUF_DECODE_SYMBOLX2_0(op1, &bitD1); - HUF_DECODE_SYMBOLX2_0(op2, &bitD2); - HUF_DECODE_SYMBOLX2_0(op3, &bitD3); - HUF_DECODE_SYMBOLX2_0(op4, &bitD4); - endSignal = (U32)LIKELY( - (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) - & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) - & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) - & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished)); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal = (U32)LIKELY( + (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished)); #endif + } } /* check corruption */ diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index 72dbccb57..d733f7cad 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -112,7 +112,8 @@ FUZZ_TARGETS := \ fse_read_ncount \ sequence_compression_api \ seekable_roundtrip \ - huf_round_trip + huf_round_trip \ + huf_decompress all: libregression.a $(FUZZ_TARGETS) @@ -218,6 +219,9 @@ seekable_roundtrip: $(FUZZ_HEADERS) $(SEEKABLE_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) $ huf_round_trip: $(FUZZ_HEADERS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_huf_round_trip.o $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_ROUND_TRIP_OBJ) rt_fuzz_huf_round_trip.o $(LIB_FUZZING_ENGINE) -o $@ +huf_decompress: $(FUZZ_HEADERS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_huf_decompress.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(FUZZ_DECOMPRESS_OBJ) d_fuzz_huf_decompress.o $(LIB_FUZZING_ENGINE) -o $@ + libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h $(PRGDIR)/util.c d_fuzz_regression_driver.o $(AR) $(FUZZ_ARFLAGS) $@ d_fuzz_regression_driver.o diff --git a/tests/fuzz/fuzz.py b/tests/fuzz/fuzz.py index 057a47ecb..0c56cccb2 100755 --- a/tests/fuzz/fuzz.py +++ b/tests/fuzz/fuzz.py @@ -64,6 +64,7 @@ TARGET_INFO = { 'sequence_compression_api': TargetInfo(InputType.RAW_DATA), 'seekable_roundtrip': TargetInfo(InputType.RAW_DATA), 'huf_round_trip': TargetInfo(InputType.RAW_DATA), + 'huf_decompress': TargetInfo(InputType.RAW_DATA), } TARGETS = list(TARGET_INFO.keys()) ALL_TARGETS = TARGETS + ['all'] diff --git a/tests/fuzz/huf_decompress.c b/tests/fuzz/huf_decompress.c new file mode 100644 index 000000000..7ede9ec53 --- /dev/null +++ b/tests/fuzz/huf_decompress.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/** + * This fuzz target performs a zstd round-trip test (compress & decompress), + * compares the result with the original, and calls abort() on corruption. + */ + +#define HUF_STATIC_LINKING_ONLY + +#include +#include +#include +#include +#include "common/cpu.h" +#include "common/huf.h" +#include "fuzz_helpers.h" +#include "fuzz_data_producer.h" + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size); + /* Select random parameters: #streams, X1 or X2 decoding, bmi2 */ + int const streams = FUZZ_dataProducer_int32Range(producer, 0, 1); + int const symbols = FUZZ_dataProducer_int32Range(producer, 0, 1); + int const bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()) && FUZZ_dataProducer_int32Range(producer, 0, 1); + /* Select a random cBufSize - it may be too small */ + size_t const dBufSize = FUZZ_dataProducer_uint32Range(producer, 0, 8 * size + 500); + size_t const maxTableLog = FUZZ_dataProducer_uint32Range(producer, 1, HUF_TABLELOG_MAX); + HUF_DTable* dt = (HUF_DTable*)FUZZ_malloc(HUF_DTABLE_SIZE(maxTableLog) * sizeof(HUF_DTable)); + size_t const wkspSize = HUF_WORKSPACE_SIZE; + void* wksp = FUZZ_malloc(wkspSize); + void* dBuf = FUZZ_malloc(dBufSize); + dt[0] = maxTableLog * 0x01000001; + size = FUZZ_dataProducer_remainingBytes(producer); + + if (symbols == 0) { + size_t const err = HUF_readDTableX1_wksp_bmi2(dt, src, size, wksp, wkspSize, bmi2); + if (ZSTD_isError(err)) + goto _out; + } else { + size_t const err = HUF_readDTableX2_wksp(dt, src, size, wksp, wkspSize); + if (ZSTD_isError(err)) + goto _out; + } + if (streams == 0) + HUF_decompress1X_usingDTable_bmi2(dBuf, dBufSize, src, size, dt, bmi2); + else + HUF_decompress4X_usingDTable_bmi2(dBuf, dBufSize, src, size, dt, bmi2); + +_out: + free(dt); + free(wksp); + free(dBuf); + FUZZ_dataProducer_free(producer); + return 0; +} From 4eef2088893f443b43a5343fe634c5227feb2f9c Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Sun, 19 Sep 2021 09:57:06 +0800 Subject: [PATCH 163/274] add msvc2019 to build.generic.cmd --- build/VS_scripts/build.generic.cmd | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/build/VS_scripts/build.generic.cmd b/build/VS_scripts/build.generic.cmd index a7ca4d067..b24e6ed4b 100644 --- a/build/VS_scripts/build.generic.cmd +++ b/build/VS_scripts/build.generic.cmd @@ -19,10 +19,10 @@ GOTO build :display_help echo Syntax: build.generic.cmd msbuild_version msbuild_platform msbuild_configuration msbuild_toolset -echo msbuild_version: VS installed version (VS2012, VS2013, VS2015, VS2017, ...) +echo msbuild_version: VS installed version (VS2012, VS2013, VS2015, VS2017, VS2019, ...) echo msbuild_platform: Platform (x64 or Win32) echo msbuild_configuration: VS configuration (Release or Debug) -echo msbuild_toolset: Platform Toolset (v100, v110, v120, v140, v141) +echo msbuild_toolset: Platform Toolset (v100, v110, v120, v140, v141, v142, ...) EXIT /B 1 @@ -43,6 +43,16 @@ IF %msbuild_version% == VS2017 ( IF EXIST %msbuild_vs2017enterprise% SET msbuild=%msbuild_vs2017enterprise% ) +:: VS2019 +SET msbuild_vs2019community="%programfiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" +SET msbuild_vs2019professional="%programfiles(x86)%\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe" +SET msbuild_vs2019enterprise="%programfiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe" +IF %msbuild_version% == VS2019 ( + IF EXIST %msbuild_vs2019community% SET msbuild=%msbuild_vs2019community% + IF EXIST %msbuild_vs2019professional% SET msbuild=%msbuild_vs2019professional% + IF EXIST %msbuild_vs2019enterprise% SET msbuild=%msbuild_vs2019enterprise% +) + SET project="%~p0\..\VS2010\zstd.sln" SET msbuild_params=/verbosity:minimal /nologo /t:Clean,Build /p:Platform=%msbuild_platform% /p:Configuration=%msbuild_configuration% From a5f2c45528032ed20c33e0f8cd2c163a800a0017 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 17 Sep 2021 11:43:04 -0700 Subject: [PATCH 164/274] Huffman ASM --- build/meson/lib/meson.build | 1 + build/single_file_libs/zstd-in.c | 2 + build/single_file_libs/zstddeclib-in.c | 2 + contrib/linux-kernel/Makefile | 1 + contrib/linux-kernel/decompress_sources.h | 5 + contrib/linux-kernel/test/macro-test.sh | 1 + lib/common/compiler.h | 4 +- lib/common/error_private.h | 79 +++ lib/common/huf.h | 7 +- lib/common/zstd_internal.h | 120 ++-- lib/compress/huf_compress.c | 1 + lib/decompress/huf_decompress.c | 755 ++++++++++++++++++---- lib/decompress/huf_decompress_amd64.S | 561 ++++++++++++++++ lib/zstd.h | 2 +- tests/fuzz/huf_decompress.c | 2 +- 15 files changed, 1348 insertions(+), 195 deletions(-) create mode 100644 lib/decompress/huf_decompress_amd64.S diff --git a/build/meson/lib/meson.build b/build/meson/lib/meson.build index 5da538729..1f4f8c25d 100644 --- a/build/meson/lib/meson.build +++ b/build/meson/lib/meson.build @@ -37,6 +37,7 @@ libzstd_sources = [join_paths(zstd_rootdir, 'lib/common/entropy_common.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_opt.c'), join_paths(zstd_rootdir, 'lib/compress/zstd_ldm.c'), join_paths(zstd_rootdir, 'lib/decompress/huf_decompress.c'), + join_paths(zstd_rootdir, 'lib/decompress/huf_decompress_amd64.S'), join_paths(zstd_rootdir, 'lib/decompress/zstd_decompress.c'), join_paths(zstd_rootdir, 'lib/decompress/zstd_decompress_block.c'), join_paths(zstd_rootdir, 'lib/decompress/zstd_ddict.c'), diff --git a/build/single_file_libs/zstd-in.c b/build/single_file_libs/zstd-in.c index 1b27953a6..f73a2e72c 100644 --- a/build/single_file_libs/zstd-in.c +++ b/build/single_file_libs/zstd-in.c @@ -43,6 +43,8 @@ #define ZSTD_MULTITHREAD #endif #define ZSTD_TRACE 0 +/* TODO: Can't amalgamate ASM function */ +#define HUF_DISABLE_ASM 1 /* Include zstd_deps.h first with all the options we need enabled. */ #define ZSTD_DEPS_NEED_MALLOC diff --git a/build/single_file_libs/zstddeclib-in.c b/build/single_file_libs/zstddeclib-in.c index 019d9c260..a5fd958e4 100644 --- a/build/single_file_libs/zstddeclib-in.c +++ b/build/single_file_libs/zstddeclib-in.c @@ -39,6 +39,8 @@ #define ZSTD_LEGACY_SUPPORT 0 #define ZSTD_STRIP_ERROR_STRINGS #define ZSTD_TRACE 0 +/* TODO: Can't amalgamate ASM function */ +#define HUF_DISABLE_ASM 1 /* Include zstd_deps.h first with all the options we need enabled. */ #define ZSTD_DEPS_NEED_MALLOC diff --git a/contrib/linux-kernel/Makefile b/contrib/linux-kernel/Makefile index c391df7c0..f85179fc4 100644 --- a/contrib/linux-kernel/Makefile +++ b/contrib/linux-kernel/Makefile @@ -35,6 +35,7 @@ libzstd: -DXXH_STATIC_LINKING_ONLY \ -DMEM_FORCE_MEMORY_ACCESS=0 \ -D__GNUC__ \ + -D__linux__=1 \ -DSTATIC_BMI2=0 \ -DZSTD_ADDRESS_SANITIZER=0 \ -DZSTD_MEMORY_SANITIZER=0 \ diff --git a/contrib/linux-kernel/decompress_sources.h b/contrib/linux-kernel/decompress_sources.h index f35bef03e..aef953c6b 100644 --- a/contrib/linux-kernel/decompress_sources.h +++ b/contrib/linux-kernel/decompress_sources.h @@ -21,6 +21,11 @@ #include "common/error_private.c" #include "common/fse_decompress.c" #include "common/zstd_common.c" +/* + * Disable the ASM Huffman implementation because we need to + * include all the sources. + */ +#define HUF_DISABLE_ASM 1 #include "decompress/huf_decompress.c" #include "decompress/zstd_ddict.c" #include "decompress/zstd_decompress.c" diff --git a/contrib/linux-kernel/test/macro-test.sh b/contrib/linux-kernel/test/macro-test.sh index c688ac03b..bde6cbb56 100755 --- a/contrib/linux-kernel/test/macro-test.sh +++ b/contrib/linux-kernel/test/macro-test.sh @@ -42,3 +42,4 @@ test_not_present "ZSTD_DLL_IMPORT" test_not_present "__ICCARM__" test_not_present "_MSC_VER" test_not_present "_WIN32" +test_not_present "__linux__" diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 012ff0221..9d7d968ce 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -108,7 +108,7 @@ #if ((defined(__clang__) && __has_attribute(__target__)) \ || (defined(__GNUC__) \ && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ - && (defined(__x86_64__) || defined(_M_X86)) \ + && (defined(__x86_64__) || defined(_M_X64)) \ && !defined(__BMI2__) # define DYNAMIC_BMI2 1 #else @@ -212,7 +212,7 @@ # elif defined(ZSTD_ARCH_ARM_NEON) # include # endif -#endif +#endif /* compat. with non-clang compilers */ #ifndef __has_builtin diff --git a/lib/common/error_private.h b/lib/common/error_private.h index 6d8b9f776..007d81066 100644 --- a/lib/common/error_private.h +++ b/lib/common/error_private.h @@ -22,6 +22,8 @@ extern "C" { * Dependencies ******************************************/ #include "../zstd_errors.h" /* enum list */ +#include "compiler.h" +#include "debug.h" #include "zstd_deps.h" /* size_t */ @@ -73,6 +75,83 @@ ERR_STATIC const char* ERR_getErrorName(size_t code) return ERR_getErrorString(ERR_getErrorCode(code)); } +/** + * Ignore: this is an internal helper. + * + * This is a helper function to help force C99-correctness during compilation. + * Under strict compilation modes, variadic macro arguments can't be empty. + * However, variadic function arguments can be. Using a function therefore lets + * us statically check that at least one (string) argument was passed, + * independent of the compilation flags. + */ +static INLINE_KEYWORD UNUSED_ATTR +void _force_has_format_string(const char *format, ...) { + (void)format; +} + +/** + * Ignore: this is an internal helper. + * + * We want to force this function invocation to be syntactically correct, but + * we don't want to force runtime evaluation of its arguments. + */ +#define _FORCE_HAS_FORMAT_STRING(...) \ + if (0) { \ + _force_has_format_string(__VA_ARGS__); \ + } + +#define ERR_QUOTE(str) #str + +/** + * Return the specified error if the condition evaluates to true. + * + * In debug modes, prints additional information. + * In order to do that (particularly, printing the conditional that failed), + * this can't just wrap RETURN_ERROR(). + */ +#define RETURN_ERROR_IF(cond, err, ...) \ + if (cond) { \ + RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } + +/** + * Unconditionally return the specified error. + * + * In debug modes, prints additional information. + */ +#define RETURN_ERROR(err, ...) \ + do { \ + RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } while(0); + +/** + * If the provided expression evaluates to an error code, returns that error code. + * + * In debug modes, prints additional information. + */ +#define FORWARD_IF_ERROR(err, ...) \ + do { \ + size_t const err_code = (err); \ + if (ERR_isError(err_code)) { \ + RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ + __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return err_code; \ + } \ + } while(0); + #if defined (__cplusplus) } #endif diff --git a/lib/common/huf.h b/lib/common/huf.h index a3ae06e4d..85518481e 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -116,11 +116,11 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, /* *** Constants *** */ -#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */ +#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */ #define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ #define HUF_SYMBOLVALUE_MAX 255 -#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ #if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) # error "HUF_TABLELOG_MAX is too large !" #endif @@ -353,6 +353,9 @@ size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t ds #ifndef HUF_FORCE_DECOMPRESS_X2 size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2); #endif +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2); +#endif #endif /* HUF_STATIC_LINKING_ONLY */ diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 3134a5abc..aaf7d4665 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -58,81 +58,6 @@ extern "C" { #define MIN(a,b) ((a)<(b) ? (a) : (b)) #define MAX(a,b) ((a)>(b) ? (a) : (b)) -/** - * Ignore: this is an internal helper. - * - * This is a helper function to help force C99-correctness during compilation. - * Under strict compilation modes, variadic macro arguments can't be empty. - * However, variadic function arguments can be. Using a function therefore lets - * us statically check that at least one (string) argument was passed, - * independent of the compilation flags. - */ -static INLINE_KEYWORD UNUSED_ATTR -void _force_has_format_string(const char *format, ...) { - (void)format; -} - -/** - * Ignore: this is an internal helper. - * - * We want to force this function invocation to be syntactically correct, but - * we don't want to force runtime evaluation of its arguments. - */ -#define _FORCE_HAS_FORMAT_STRING(...) \ - if (0) { \ - _force_has_format_string(__VA_ARGS__); \ - } - -/** - * Return the specified error if the condition evaluates to true. - * - * In debug modes, prints additional information. - * In order to do that (particularly, printing the conditional that failed), - * this can't just wrap RETURN_ERROR(). - */ -#define RETURN_ERROR_IF(cond, err, ...) \ - if (cond) { \ - RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ - __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \ - _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ - RAWLOG(3, ": " __VA_ARGS__); \ - RAWLOG(3, "\n"); \ - return ERROR(err); \ - } - -/** - * Unconditionally return the specified error. - * - * In debug modes, prints additional information. - */ -#define RETURN_ERROR(err, ...) \ - do { \ - RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ - __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \ - _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ - RAWLOG(3, ": " __VA_ARGS__); \ - RAWLOG(3, "\n"); \ - return ERROR(err); \ - } while(0); - -/** - * If the provided expression evaluates to an error code, returns that error code. - * - * In debug modes, prints additional information. - */ -#define FORWARD_IF_ERROR(err, ...) \ - do { \ - size_t const err_code = (err); \ - if (ERR_isError(err_code)) { \ - RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ - __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \ - _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ - RAWLOG(3, ": " __VA_ARGS__); \ - RAWLOG(3, "\n"); \ - return err_code; \ - } \ - } while(0); - /*-************************************* * Common constants @@ -453,6 +378,51 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus } } +/** + * Computes CTZ on a U64. + * This will be slow on 32-bit mode, and on unsupported compilers. + * If you need this function to be fast (because it is hot) expand + * support. + */ +MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) +{ + if (MEM_64bits()) { +# if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return _tzcnt_u64(val); +# else + unsigned long r = 0; + return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; +# endif +# elif defined(__GNUC__) && (__GNUC__ >= 4) + return __builtin_ctzll((U64)val); +# else + static const int DeBruijnBytePos[64] = { 0, 1, 2, 7, 3, 13, 8, 19, + 4, 25, 14, 28, 9, 34, 20, 56, + 5, 17, 26, 54, 15, 41, 29, 43, + 10, 31, 38, 35, 21, 45, 49, 57, + 63, 6, 12, 18, 24, 27, 33, 55, + 16, 53, 40, 42, 30, 37, 44, 48, + 62, 11, 23, 32, 52, 39, 36, 47, + 61, 22, 51, 46, 60, 50, 59, 58 }; + return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; +# endif + } else { /* 32 bits */ +# if defined(_MSC_VER) + unsigned long r=0; + return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0; +# elif defined(__GNUC__) && (__GNUC__ >= 3) + return (__builtin_ctz((U32)val) >> 3); +# else + static const int DeBruijnBytePos[32] = { 0, 1, 28, 2, 29, 14, 24, 3, + 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, + 26, 12, 18, 6, 11, 5, 10, 9 }; + return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; +# endif + } +} + /* ZSTD_invalidateRepCodes() : * ensures next compression will not use repcodes from previous block. diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 915778eb1..ba296da8d 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -809,6 +809,7 @@ FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int id { size_t const nbBits = HUF_getNbBits(elt); size_t const dirtyBits = nbBits == 0 ? 0 : BIT_highbit32((U32)nbBits) + 1; + (void)dirtyBits; /* Middle bits are 0. */ assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0); /* We didn't overwrite any bits in the bit container. */ diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index f41a02bb5..1dfa4b801 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -22,6 +22,13 @@ #define HUF_STATIC_LINKING_ONLY #include "../common/huf.h" #include "../common/error_private.h" +#include "../common/zstd_internal.h" + +/* ************************************************************** +* Constants +****************************************************************/ + +#define HUF_DECODER_FAST_TABLELOG 11 /* ************************************************************** * Macros @@ -36,6 +43,40 @@ #error "Cannot force the use of the X1 and X2 decoders at the same time!" #endif +/* Only use assembly on Linux / MacOS. + * Disable when MSAN is enabled. + */ +#if defined(__linux__) || defined(__linux) || defined(__APPLE__) +# if ZSTD_MEMORY_SANITIZER +# define HUF_ASM_SUPPORTED 0 +# else +# define HUF_ASM_SUPPORTED 1 +#endif +#else +# define HUF_ASM_SUPPORTED 0 +#endif + +/* HUF_DISABLE_ASM: Disables all ASM implementations. */ +#if !defined(HUF_DISABLE_ASM) && \ + HUF_ASM_SUPPORTED && \ + defined(__x86_64__) && (DYNAMIC_BMI2 || defined(__BMI2__)) +# define HUF_ENABLE_ASM_X86_64_BMI2 1 +#else +# define HUF_ENABLE_ASM_X86_64_BMI2 0 +#endif + +#if HUF_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2 +# define HUF_ASM_X86_64_BMI2_ATTRS TARGET_ATTRIBUTE("bmi2") +#else +# define HUF_ASM_X86_64_BMI2_ATTRS +#endif + +#ifdef __cplusplus +# define HUF_EXTERN_C extern "C" +#else +# define HUF_EXTERN_C +#endif +#define HUF_ASM_DECL HUF_EXTERN_C /* ************************************************************** * Error Management @@ -107,13 +148,146 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) return dtd; } +#if HUF_ENABLE_ASM_X86_64_BMI2 + +static size_t HUF_initDStream(BYTE const* ip) { + BYTE const lastByte = ip[7]; + size_t const bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; + size_t const value = MEM_readLEST(ip) | 1; + assert(bitsConsumed <= 8); + return value << bitsConsumed; +} +typedef struct { + BYTE const* ip[4]; + BYTE* op[4]; + U64 bits[4]; + void const* dt; + BYTE const* ilimit; + BYTE* oend; + BYTE const* iend[4]; +} HUF_DecompressAsmArgs; + +/** + * Initializes args for the asm decoding loop. + * @returns 0 on success + * 1 if the fallback implementation should be used. + * Or an error code on failure. + */ +static size_t HUF_DecompressAsmArgs_init(HUF_DecompressAsmArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable) +{ + void const* dt = DTable + 1; + U32 const dtLog = HUF_getDTableDesc(DTable).tableLog; + + const BYTE* const ilimit = (const BYTE*)src + 6 + 8; + + BYTE* const oend = (BYTE*)dst + dstSize; + + /* We're assuming x86-64 BMI2 - assure that this is the case. */ + assert(MEM_isLittleEndian() && !MEM_32bits()); + + /* strict minimum : jump table + 1 byte per stream */ + if (srcSize < 10) + return ERROR(corruption_detected); + + /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers. + * If table log is not correct at this point, fallback to the old decoder. + * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder. + */ + if (dtLog != HUF_DECODER_FAST_TABLELOG) + return 1; + + /* Read the jump table. */ + { + const BYTE* const istart = (const BYTE*)src; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = srcSize - (length1 + length2 + length3 + 6); + args->iend[0] = istart + 6; /* jumpTable */ + args->iend[1] = args->iend[0] + length1; + args->iend[2] = args->iend[1] + length2; + args->iend[3] = args->iend[2] + length3; + + /* HUF_initDStream() requires this, and this small of an input + * won't benefit from the ASM loop anyways. + * length1 must be >= 16 so that ip[0] >= ilimit before the loop + * starts. + */ + if (length1 < 16 || length2 < 8 || length3 < 8 || length4 < 8) + return 1; + if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */ + } + /* ip[] contains the position that is currently loaded into bits[]. */ + args->ip[0] = args->iend[1] - sizeof(U64); + args->ip[1] = args->iend[2] - sizeof(U64); + args->ip[2] = args->iend[3] - sizeof(U64); + args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64); + + /* op[] contains the output pointers. */ + args->op[0] = (BYTE*)dst; + args->op[1] = args->op[0] + (dstSize+3)/4; + args->op[2] = args->op[1] + (dstSize+3)/4; + args->op[3] = args->op[2] + (dstSize+3)/4; + + /* No point to call the ASM loop for tiny outputs. */ + if (args->op[3] >= oend) + return 1; + + /* bits[] is the bit container. + * It is read from the MSB down to the LSB. + * It is shifted left as it is read, and zeros are + * shifted in. After the lowest valid bit a 1 is + * set, so that CountTrailingZeros(bits[]) can be used + * to count how many bits we've consumed. + */ + args->bits[0] = HUF_initDStream(args->ip[0]); + args->bits[1] = HUF_initDStream(args->ip[1]); + args->bits[2] = HUF_initDStream(args->ip[2]); + args->bits[3] = HUF_initDStream(args->ip[3]); + + /* If ip[] >= ilimit, it is guaranteed to be safe to + * reload bits[]. It may be beyond its section, but is + * guaranteed to be valid (>= istart). + */ + args->ilimit = ilimit; + + args->oend = oend; + args->dt = dt; + + return 0; +} + +static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressAsmArgs const* args, int stream, BYTE* segmentEnd) +{ + /* Validate that we haven't overwritten. */ + if (args->op[stream] > segmentEnd) + return ERROR(corruption_detected); + /* Validate that we haven't read beyond iend[]. + * Note that ip[] may be < iend[] because the MSB is + * the next bit to read, and we may have consumed 100% + * of the stream, so down to iend[i] - 8 is valid. + */ + if (args->ip[stream] < args->iend[stream] - 8) + return ERROR(corruption_detected); + + /* Construct the BIT_DStream_t. */ + bit->bitContainer = MEM_readLE64(args->ip[stream]); + bit->bitsConsumed = ZSTD_countTrailingZeros((size_t)args->bits[stream]); + bit->start = (const char*)args->iend[0]; + bit->limitPtr = bit->start + sizeof(size_t); + bit->ptr = (const char*)args->ip[stream]; + + return 0; +} +#endif + #ifndef HUF_FORCE_DECOMPRESS_X2 /*-***************************/ /* single-symbol decoding */ /*-***************************/ -typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decoding */ +typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */ /** * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at @@ -122,14 +296,44 @@ typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1; /* single-symbol decodi static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) { U64 D4; if (MEM_isLittleEndian()) { - D4 = symbol + (nbBits << 8); - } else { D4 = (symbol << 8) + nbBits; + } else { + D4 = symbol + (nbBits << 8); } D4 *= 0x0001000100010001ULL; return D4; } +/** + * Increase the tableLog to targetTableLog and rescales the stats. + * If tableLog > targetTableLog this is a no-op. + * @returns New tableLog + */ +static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog) +{ + if (tableLog > targetTableLog) + return tableLog; + if (tableLog < targetTableLog) { + U32 const scale = targetTableLog - tableLog; + U32 s; + /* Increase the weight for all non-zero probability symbols by scale. */ + for (s = 0; s < nbSymbols; ++s) { + huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale); + } + /* Update rankVal to reflect the new weights. + * All weights except 0 get moved to weight + scale. + * Weights [1, scale] are empty. + */ + for (s = targetTableLog; s > scale; --s) { + rankVal[s] = rankVal[s - scale]; + } + for (s = scale; s > 0; --s) { + rankVal[s] = 0; + } + } + return targetTableLog; +} + typedef struct { U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1]; @@ -162,8 +366,12 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2); if (HUF_isError(iSize)) return iSize; + /* Table header */ { DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog + 1; + U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG); + tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog); if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ dtd.tableType = 0; dtd.tableLog = (BYTE)tableLog; @@ -445,6 +653,77 @@ HUF_decompress4X1_usingDTable_internal_body( } } +#if DYNAMIC_BMI2 +static TARGET_ATTRIBUTE("bmi2") +size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if HUF_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args); + +static HUF_ASM_X86_64_BMI2_ATTRS +size_t +HUF_decompress4X1_usingDTable_internal_bmi2_asm( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + void const* dt = DTable + 1; + const BYTE* const iend = (const BYTE*)cSrc + 6; + BYTE* const oend = (BYTE*)dst + dstSize; + HUF_DecompressAsmArgs args; + { + size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init asm args"); + if (ret != 0) + return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); + } + + assert(args.ip[0] >= args.ilimit); + HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(&args); + + /* Our loop guarantees that ip[] >= ilimit and that we haven't + * overwritten any op[]. + */ + assert(args.ip[0] >= iend); + assert(args.ip[1] >= iend); + assert(args.ip[2] >= iend); + assert(args.ip[3] >= iend); + assert(args.op[3] <= oend); + (void)iend; + + /* finish bit streams one by one. */ + { + size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + /* Decompress and validate that we've produced exactly the expected length. */ + args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) return ERROR(corruption_detected); + } + } + + /* decoded size */ + return dstSize; +} +#endif /* HUF_ENABLE_ASM_X86_64_BMI2 */ typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize, const void *cSrc, @@ -452,8 +731,28 @@ typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize, const HUF_DTable *DTable); HUF_DGEN(HUF_decompress1X1_usingDTable_internal) -HUF_DGEN(HUF_decompress4X1_usingDTable_internal) +static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { +# if HUF_ENABLE_ASM_X86_64_BMI2 + return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable); +# else + return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); +# endif + } +#else + (void)bmi2; +#endif + +#if HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable); +#else + return HUF_decompress4X1_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable); +#endif +} size_t HUF_decompress1X1_usingDTable( @@ -523,106 +822,226 @@ size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, /* *************************/ typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */ -typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t; +typedef struct { BYTE symbol; } sortedSymbol_t; typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; +/** + * Constructs a HUF_DEltX2 in a U32. + */ +static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + U32 seq; + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3); + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32)); + if (MEM_isLittleEndian()) { + seq = level == 1 ? symbol : (baseSeq + (symbol << 8)); + return seq + (nbBits << 16) + ((U32)level << 24); + } else { + seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol); + return (seq << 16) + (nbBits << 8) + (U32)level; + } +} + +/** + * Constructs a HUF_DEltX2. + */ +static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + HUF_DEltX2 DElt; + U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val)); + ZSTD_memcpy(&DElt, &val, sizeof(val)); + return DElt; +} + +/** + * Constructs 2 HUF_DEltX2s and packs them into a U64. + */ +static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level) +{ + U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + return (U64)DElt + ((U64)DElt << 32); +} + +/** + * Fills the DTable rank with all the symbols from [begin, end) that are each + * nbBits long. + * + * @param DTableRank The start of the rank in the DTable. + * @param begin The first symbol to fill (inclusive). + * @param end The last symbol to fill (exclusive). + * @param nbBits Each symbol is nbBits long. + * @param tableLog The table log. + * @param baseSeq If level == 1 { 0 } else { the first level symbol } + * @param level The level in the table. Must be 1 or 2. + */ +static void HUF_fillDTableX2ForWeight( + HUF_DEltX2* DTableRank, + sortedSymbol_t const* begin, sortedSymbol_t const* end, + U32 nbBits, U32 tableLog, + U16 baseSeq, int const level) +{ + U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */); + const sortedSymbol_t* ptr; + assert(level >= 1 && level <= 2); + switch (length) { + case 1: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + *DTableRank++ = DElt; + } + break; + case 2: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + DTableRank[0] = DElt; + DTableRank[1] = DElt; + DTableRank += 2; + } + break; + case 4: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + DTableRank += 4; + } + break; + case 8: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + DTableRank += 8; + } + break; + default: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + HUF_DEltX2* const DTableRankEnd = DTableRank + length; + for (; DTableRank != DTableRankEnd; DTableRank += 8) { + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + } + } + break; + } +} /* HUF_fillDTableX2Level2() : * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ -static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed, - const U32* rankValOrigin, const int minWeight, - const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, - U32 nbBitsBaseline, U16 baseSeq, U32* wksp, size_t wkspSize) +static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits, + const U32* rankVal, const int minWeight, const int maxWeight1, + const sortedSymbol_t* sortedSymbols, U32 const* rankStart, + U32 nbBitsBaseline, U16 baseSeq) { - HUF_DEltX2 DElt; - U32* rankVal = wksp; - - assert(wkspSize >= HUF_TABLELOG_MAX + 1); - (void)wkspSize; - /* get pre-calculated rankVal */ - ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1)); - - /* fill skipped values */ + /* Fill skipped values (all positions up to rankVal[minWeight]). + * These are positions only get a single symbol because the combined weight + * is too large. + */ if (minWeight>1) { - U32 i, skipSize = rankVal[minWeight]; - MEM_writeLE16(&(DElt.sequence), baseSeq); - DElt.nbBits = (BYTE)(consumed); - DElt.length = 1; - for (i = 0; i < skipSize; i++) - DTable[i] = DElt; + U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */); + U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1); + int const skipSize = rankVal[minWeight]; + assert(length > 1); + assert((U32)skipSize < length); + switch (length) { + case 2: + assert(skipSize == 1); + ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2)); + break; + case 4: + assert(skipSize <= 4); + ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2)); + break; + default: + { + int i; + for (i = 0; i < skipSize; i += 8) { + ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2)); + } + } + } } - /* fill DTable */ - { U32 s; for (s=0; s= 1 */ - - rankVal[weight] += length; - } } + /* Fill each of the second level symbols by weight. */ + { + int w; + for (w = minWeight; w < maxWeight1; ++w) { + int const begin = rankStart[w]; + int const end = rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + U32 const totalBits = nbBits + consumedBits; + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedSymbols + begin, sortedSymbols + end, + totalBits, targetLog, + baseSeq, /* level */ 2); + } + } } - static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, - const sortedSymbol_t* sortedList, const U32 sortedListSize, + const sortedSymbol_t* sortedList, const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight, - const U32 nbBitsBaseline, U32* wksp, size_t wkspSize) + const U32 nbBitsBaseline) { - U32* rankVal = wksp; + U32* const rankVal = rankValOrigin[0]; const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ const U32 minBits = nbBitsBaseline - maxWeight; - U32 s; + int w; + int const wEnd = (int)maxWeight + 1; - assert(wkspSize >= HUF_TABLELOG_MAX + 1); - wksp += HUF_TABLELOG_MAX + 1; - wkspSize -= HUF_TABLELOG_MAX + 1; + /* Fill DTable in order of weight. */ + for (w = 1; w < wEnd; ++w) { + int const begin = (int)rankStart[w]; + int const end = (int)rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; - ZSTD_memcpy(rankVal, rankValOrigin, sizeof(U32) * (HUF_TABLELOG_MAX + 1)); - - /* fill DTable */ - for (s=0; s= minBits) { /* enough room for a second symbol */ - U32 sortedRank; + if (targetLog-nbBits >= minBits) { + /* Enough room for a second symbol. */ + int start = rankVal[w]; + U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */); int minWeight = nbBits + scaleLog; + int s; if (minWeight < 1) minWeight = 1; - sortedRank = rankStart[minWeight]; - HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits, - rankValOrigin[nbBits], minWeight, - sortedList+sortedRank, sortedListSize-sortedRank, - nbBitsBaseline, symbol, wksp, wkspSize); + /* Fill the DTable for every symbol of weight w. + * These symbols get at least 1 second symbol. + */ + for (s = begin; s != end; ++s) { + HUF_fillDTableX2Level2( + DTable + start, targetLog, nbBits, + rankValOrigin[nbBits], minWeight, wEnd, + sortedList, rankStart, + nbBitsBaseline, sortedList[s].symbol); + start += length; + } } else { - HUF_DEltX2 DElt; - MEM_writeLE16(&(DElt.sequence), symbol); - DElt.nbBits = (BYTE)(nbBits); - DElt.length = 1; - { U32 const end = start + length; - U32 u; - for (u = start; u < end; u++) DTable[u] = DElt; - } } - rankVal[weight] += length; + /* Only a single symbol. */ + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedList + begin, sortedList + end, + nbBits, targetLog, + /* baseSeq */ 0, /* level */ 1); + } } } typedef struct { rankValCol_t rankVal[HUF_TABLELOG_MAX]; U32 rankStats[HUF_TABLELOG_MAX + 1]; - U32 rankStart0[HUF_TABLELOG_MAX + 2]; + U32 rankStart0[HUF_TABLELOG_MAX + 3]; sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; @@ -632,9 +1051,16 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) { - U32 tableLog, maxW, sizeOfSort, nbSymbols; + return HUF_readDTableX2_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0); +} + +size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, int bmi2) +{ + U32 tableLog, maxW, nbSymbols; DTableDesc dtd = HUF_getDTableDesc(DTable); - U32 const maxTableLog = dtd.maxTableLog; + U32 maxTableLog = dtd.maxTableLog; size_t iSize; void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; @@ -652,11 +1078,12 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ - iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), /* bmi2 */ 0); + iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), bmi2); if (HUF_isError(iSize)) return iSize; /* check result */ if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG; /* find maxWeight */ for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ @@ -669,7 +1096,7 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, rankStart[w] = curr; } rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ - sizeOfSort = nextRankStart; + rankStart[maxW+1] = nextRankStart; } /* sort symbols by weight */ @@ -678,7 +1105,6 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, U32 const w = wksp->weightList[s]; U32 const r = rankStart[w]++; wksp->sortedSymbol[r].symbol = (BYTE)s; - wksp->sortedSymbol[r].weight = (BYTE)w; } rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */ } @@ -703,10 +1129,9 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, } } } } HUF_fillDTableX2(dt, maxTableLog, - wksp->sortedSymbol, sizeOfSort, + wksp->sortedSymbol, wksp->rankStart0, wksp->rankVal, maxW, - tableLog+1, - wksp->calleeWksp, sizeof(wksp->calleeWksp) / sizeof(U32)); + tableLog+1); dtd.tableLog = (BYTE)maxTableLog; dtd.tableType = 1; @@ -719,7 +1144,7 @@ FORCE_INLINE_TEMPLATE U32 HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) { size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - ZSTD_memcpy(op, dt+val, 2); + ZSTD_memcpy(op, &dt[val].sequence, 2); BIT_skipBits(DStream, dt[val].nbBits); return dt[val].length; } @@ -728,15 +1153,17 @@ FORCE_INLINE_TEMPLATE U32 HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) { size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - ZSTD_memcpy(op, dt+val, 1); - if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits); - else { + ZSTD_memcpy(op, &dt[val].sequence, 1); + if (dt[val].length==1) { + BIT_skipBits(DStream, dt[val].nbBits); + } else { if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { BIT_skipBits(DStream, dt[val].nbBits); if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); - } } + } + } return 1; } @@ -759,11 +1186,23 @@ HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, /* up to 8 symbols at a time */ if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) { - while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { - HUF_DECODE_SYMBOLX2_2(p, bitDPtr); - HUF_DECODE_SYMBOLX2_1(p, bitDPtr); - HUF_DECODE_SYMBOLX2_2(p, bitDPtr); - HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + if (dtLog <= 11 && MEM_64bits()) { + /* up to 10 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) { + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } else { + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } } } @@ -808,7 +1247,6 @@ HUF_decompress1X2_usingDTable_internal_body( /* decoded size */ return dstSize; } - FORCE_INLINE_TEMPLATE size_t HUF_decompress4X2_usingDTable_internal_body( void* dst, size_t dstSize, @@ -927,8 +1365,97 @@ HUF_decompress4X2_usingDTable_internal_body( } } +#if DYNAMIC_BMI2 +static TARGET_ATTRIBUTE("bmi2") +size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if HUF_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args); + +static HUF_ASM_X86_64_BMI2_ATTRS size_t +HUF_decompress4X2_usingDTable_internal_bmi2_asm( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) { + void const* dt = DTable + 1; + const BYTE* const iend = (const BYTE*)cSrc + 6; + BYTE* const oend = (BYTE*)dst + dstSize; + HUF_DecompressAsmArgs args; + { + size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init asm args"); + if (ret != 0) + return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); + } + + assert(args.ip[0] >= args.ilimit); + HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(&args); + + /* note : op4 already verified within main loop */ + assert(args.ip[0] >= iend); + assert(args.ip[1] >= iend); + assert(args.ip[2] >= iend); + assert(args.ip[3] >= iend); + assert(args.op[3] <= oend); + (void)iend; + + /* finish bitStreams one by one */ + { + size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) + return ERROR(corruption_detected); + } + } + + /* decoded size */ + return dstSize; +} +#endif /* HUF_ENABLE_ASM_X86_64_BMI2 */ + +static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { +# if HUF_ENABLE_ASM_X86_64_BMI2 + return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable); +# else + return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); +# endif + } +#else + (void)bmi2; +#endif + +#if HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable); +#else + return HUF_decompress4X2_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable); +#endif +} + HUF_DGEN(HUF_decompress1X2_usingDTable_internal) -HUF_DGEN(HUF_decompress4X2_usingDTable_internal) size_t HUF_decompress1X2_usingDTable( void* dst, size_t dstSize, @@ -1037,25 +1564,25 @@ size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, #if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; -static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = +static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] = { /* single, double, quad */ - {{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */ - {{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */ - {{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */ - {{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */ - {{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */ - {{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */ - {{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */ - {{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */ - {{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */ - {{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */ - {{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */ - {{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */ - {{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */ - {{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */ - {{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */ - {{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */ + {{0,0}, {1,1}}, /* Q==0 : impossible */ + {{0,0}, {1,1}}, /* Q==1 : impossible */ + {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */ + {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */ + {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */ + {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */ + {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */ + {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */ + {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */ + {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */ + {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */ + {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */ + {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */ + {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */ + {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */ + {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */ }; #endif @@ -1082,7 +1609,7 @@ U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) U32 const D256 = (U32)(dstSize >> 8); U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); - DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, to reduce cache eviction */ + DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */ return DTime1 < DTime0; } #endif diff --git a/lib/decompress/huf_decompress_amd64.S b/lib/decompress/huf_decompress_amd64.S new file mode 100644 index 000000000..77a2d8560 --- /dev/null +++ b/lib/decompress/huf_decompress_amd64.S @@ -0,0 +1,561 @@ +# Calling convention: +# +# %rdi contains the first argument: HUF_DecompressAsmArgs*. +# %rbp is'nt maintained (no frame pointer). +# %rsp contains the stack pointer that grows down. +# No red-zone is assumed, only addresses >= %rsp are used. +# All register contents are preserved. +# +# TODO: Support Windows calling convention. + +#if !defined(HUF_DISABLE_ASM) && defined(__x86_64__) +.global HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop +.global HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop +.global _HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop +.global _HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop +.text + +# Sets up register mappings for clarity. +# op[], bits[], dtable & ip[0] each get their own register. +# ip[1,2,3] & olimit alias var[]. +# %rax is a scratch register. + +#define op0 rsi +#define op1 rbx +#define op2 rcx +#define op3 rdi + +#define ip0 r8 +#define ip1 r9 +#define ip2 r10 +#define ip3 r11 + +#define bits0 rbp +#define bits1 rdx +#define bits2 r12 +#define bits3 r13 +#define dtable r14 +#define olimit r15 + +# var[] aliases ip[1,2,3] & olimit +# ip[1,2,3] are saved every iteration. +# olimit is only used in compute_olimit. +#define var0 r15 +#define var1 r9 +#define var2 r10 +#define var3 r11 + +# 32-bit var registers +#define vard0 r15d +#define vard1 r9d +#define vard2 r10d +#define vard3 r11d + +# Helper macro: args if idx != 4. +#define IF_NOT_4_0(...) __VA_ARGS__ +#define IF_NOT_4_1(...) __VA_ARGS__ +#define IF_NOT_4_2(...) __VA_ARGS__ +#define IF_NOT_4_3(...) __VA_ARGS__ +#define IF_NOT_4_4(...) +#define IF_NOT_4_(idx, ...) IF_NOT_4_##idx(__VA_ARGS__) +#define IF_NOT_4(idx, ...) IF_NOT_4_(idx, __VA_ARGS__) + +# Calls X(N) for each stream 0, 1, 2, 3. +#define FOR_EACH_STREAM(X) \ + X(0); \ + X(1); \ + X(2); \ + X(3) + +# Calls X(N, idx) for each stream 0, 1, 2, 3. +#define FOR_EACH_STREAM_WITH_INDEX(X, idx) \ + X(0, idx); \ + X(1, idx); \ + X(2, idx); \ + X(3, idx) + +# Define both _HUF_* & HUF_* symbols because MacOS +# C symbols are prefixed with '_' & Linux symbols aren't. +_HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: +HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: + # Save all registers - even if they are callee saved for simplicity. + push %rax + push %rbx + push %rcx + push %rdx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + + # Read HUF_DecompressAsmArgs* args from %rax + movq %rdi, %rax + movq 0(%rax), %ip0 + movq 8(%rax), %ip1 + movq 16(%rax), %ip2 + movq 24(%rax), %ip3 + movq 32(%rax), %op0 + movq 40(%rax), %op1 + movq 48(%rax), %op2 + movq 56(%rax), %op3 + movq 64(%rax), %bits0 + movq 72(%rax), %bits1 + movq 80(%rax), %bits2 + movq 88(%rax), %bits3 + movq 96(%rax), %dtable + push %rax # argument + push 104(%rax) # ilimit + push 112(%rax) # oend + push %olimit # olimit space + + subq $24, %rsp + +.L_4X1_compute_olimit: + # Computes how many iterations we can do savely + # %r15, %rax may be clobbered + # rbx, rdx must be saved + # op3 & ip0 mustn't be clobbered + movq %rbx, 0(%rsp) + movq %rdx, 8(%rsp) + + movq 32(%rsp), %rax # rax = oend + subq %op3, %rax # rax = oend - op3 + + # r15 = (oend - op3) / 5 + movabsq $-3689348814741910323, %rdx + mulq %rdx + movq %rdx, %r15 + shrq $2, %r15 + + movq %ip0, %rax # rax = ip0 + movq 40(%rsp), %rdx # rdx = ilimit + subq %rdx, %rax # rax = ip0 - ilimit + movq %rax, %rbx # rbx = ip0 - ilimit + + # rdx = (ip0 - ilimit) / 7 + movabsq $2635249153387078803, %rdx + mulq %rdx + subq %rdx, %rbx + shrq %rbx + addq %rbx, %rdx + shrq $2, %rdx + + # r15 = min(%rdx, %r15) + cmpq %rdx, %r15 + cmova %rdx, %r15 + + # r15 = r15 * 5 + leaq (%r15, %r15, 4), %r15 + + # olimit = op3 + r15 + addq %op3, %olimit + + movq 8(%rsp), %rdx + movq 0(%rsp), %rbx + + # If (op3 + 20 > olimit) + movq %op3, %rax # rax = op3 + addq $20, %rax # rax = op3 + 20 + cmpq %rax, %olimit # op3 + 20 > olimit + jb .L_4X1_exit + + # If (ip1 < ip0) go to exit + cmpq %ip0, %ip1 + jb .L_4X1_exit + + # If (ip2 < ip1) go to exit + cmpq %ip1, %ip2 + jb .L_4X1_exit + + # If (ip3 < ip2) go to exit + cmpq %ip2, %ip3 + jb .L_4X1_exit + +# Reads top 11 bits from bits[n] +# Loads dt[bits[n]] into var[n] +#define GET_NEXT_DELT(n) \ + movq $53, %var##n; \ + shrxq %var##n, %bits##n, %var##n; \ + movzwl (%dtable,%var##n,2),%vard##n + +# var[n] must contain the DTable entry computed with GET_NEXT_DELT +# Moves var[n] to %rax +# bits[n] <<= var[n] & 63 +# op[n][idx] = %rax >> 8 +# %ah is a way to access bits [8, 16) of %rax +#define DECODE_FROM_DELT(n, idx) \ + movq %var##n, %rax; \ + shlxq %var##n, %bits##n, %bits##n; \ + movb %ah, idx(%op##n) + +# Assumes GET_NEXT_DELT has been called. +# Calls DECODE_FROM_DELT then GET_NEXT_DELT if n < 4 +#define DECODE(n, idx) \ + DECODE_FROM_DELT(n, idx); \ + IF_NOT_4(idx, GET_NEXT_DELT(n)) + +# // ctz & nbBytes is stored in bits[n] +# // nbBits is stored in %rax +# ctz = CTZ[bits[n]] +# nbBits = ctz & 7 +# nbBytes = ctz >> 3 +# op[n] += 5 +# ip[n] -= nbBytes +# // Note: x86-64 is little-endian ==> no bswap +# bits[n] = MEM_readST(ip[n]) | 1 +# bits[n] <<= nbBits +#define RELOAD_BITS(n) \ + bsfq %bits##n, %bits##n; \ + movq %bits##n, %rax; \ + andq $7, %rax; \ + shrq $3, %bits##n; \ + leaq 5(%op##n), %op##n; \ + subq %bits##n, %ip##n; \ + movq (%ip##n), %bits##n; \ + orq $1, %bits##n; \ + shlx %rax, %bits##n, %bits##n; + + # Store clobbered variables on the stack + movq %olimit, 24(%rsp) + movq %ip1, 0(%rsp) + movq %ip2, 8(%rsp) + movq %ip3, 16(%rsp) + + # Call GET_NEXT_DELT for each stream + FOR_EACH_STREAM(GET_NEXT_DELT) + + .p2align 6 + +.L_4X1_loop_body: +# LLVM-MCA-BEGIN decode-4X1 + # Decode 5 symbols in each of the 4 streams (20 total) + # Must have called GET_NEXT_DELT for each stream + FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) + + # Load ip[1,2,3] from stack (var[] aliases them) + # ip[] is needed for RELOAD_BITS + # Each will be stored back to the stack after RELOAD + movq 0(%rsp), %ip1 + movq 8(%rsp), %ip2 + movq 16(%rsp), %ip3 + + # Reload each stream & fetch the next table entry + # to prepare for the next iteration + RELOAD_BITS(0) + GET_NEXT_DELT(0) + + RELOAD_BITS(1) + movq %ip1, 0(%rsp) + GET_NEXT_DELT(1) + + RELOAD_BITS(2) + movq %ip2, 8(%rsp) + GET_NEXT_DELT(2) + + RELOAD_BITS(3) + movq %ip3, 16(%rsp) + GET_NEXT_DELT(3) + + # If op3 < olimit: continue the loop + cmp %op3, 24(%rsp) + ja .L_4X1_loop_body + + # Reload ip[1,2,3] from stack + movq 0(%rsp), %ip1 + movq 8(%rsp), %ip2 + movq 16(%rsp), %ip3 + + # Re-compute olimit + jmp .L_4X1_compute_olimit + +#undef GET_NEXT_DELT +#undef DECODE_FROM_DELT +#undef DECODE +#undef RELOAD_BITS +# LLVM-MCA-END +.L_4X1_exit: + addq $24, %rsp + + # Restore stack (oend & olimit) + pop %rax # olimit + pop %rax # oend + pop %rax # ilimit + pop %rax # arg + + # Save ip / op / bits + movq %ip0, 0(%rax) + movq %ip1, 8(%rax) + movq %ip2, 16(%rax) + movq %ip3, 24(%rax) + movq %op0, 32(%rax) + movq %op1, 40(%rax) + movq %op2, 48(%rax) + movq %op3, 56(%rax) + movq %bits0, 64(%rax) + movq %bits1, 72(%rax) + movq %bits2, 80(%rax) + movq %bits3, 88(%rax) + + # Restore registers + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rdx + pop %rcx + pop %rbx + pop %rax + ret + +_HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop: +HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop: + # Save all registers - even if they are callee saved for simplicity. + push %rax + push %rbx + push %rcx + push %rdx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + + movq %rdi, %rax + movq 0(%rax), %ip0 + movq 8(%rax), %ip1 + movq 16(%rax), %ip2 + movq 24(%rax), %ip3 + movq 32(%rax), %op0 + movq 40(%rax), %op1 + movq 48(%rax), %op2 + movq 56(%rax), %op3 + movq 64(%rax), %bits0 + movq 72(%rax), %bits1 + movq 80(%rax), %bits2 + movq 88(%rax), %bits3 + movq 96(%rax), %dtable + push %rax # argument + push %rax # olimit + push 104(%rax) # ilimit + + movq 112(%rax), %rax + push %rax # oend3 + + movq %op3, %rax + push %rax # oend2 + + movq %op2, %rax + push %rax # oend1 + + movq %op1, %rax + push %rax # oend0 + + # Scratch space + subq $8, %rsp + +.L_4X2_compute_olimit: + # Computes how many iterations we can do savely + # %r15, %rax may be clobbered + # rdx must be saved + # op[1,2,3,4] & ip0 mustn't be clobbered + movq %rdx, 0(%rsp) + + # We can consume up to 7 input bytes each iteration. + movq %ip0, %rax # rax = ip0 + movq 40(%rsp), %rdx # rdx = ilimit + subq %rdx, %rax # rax = ip0 - ilimit + movq %rax, %r15 # r15 = ip0 - ilimit + + # rdx = rax / 7 + movabsq $2635249153387078803, %rdx + mulq %rdx + subq %rdx, %r15 + shrq %r15 + addq %r15, %rdx + shrq $2, %rdx + + # r15 = (ip0 - ilimit) / 7 + movq %rdx, %r15 + + movabsq $-3689348814741910323, %rdx + movq 8(%rsp), %rax # rax = oend0 + subq %op0, %rax # rax = oend0 - op0 + mulq %rdx + shrq $3, %rdx # rdx = rax / 10 + + # r15 = min(%rdx, %r15) + cmpq %rdx, %r15 + cmova %rdx, %r15 + + movabsq $-3689348814741910323, %rdx + movq 16(%rsp), %rax # rax = oend1 + subq %op1, %rax # rax = oend1 - op1 + mulq %rdx + shrq $3, %rdx # rdx = rax / 10 + + # r15 = min(%rdx, %r15) + cmpq %rdx, %r15 + cmova %rdx, %r15 + + movabsq $-3689348814741910323, %rdx + movq 24(%rsp), %rax # rax = oend2 + subq %op2, %rax # rax = oend2 - op2 + mulq %rdx + shrq $3, %rdx # rdx = rax / 10 + + # r15 = min(%rdx, %r15) + cmpq %rdx, %r15 + cmova %rdx, %r15 + + movabsq $-3689348814741910323, %rdx + movq 32(%rsp), %rax # rax = oend3 + subq %op3, %rax # rax = oend3 - op3 + mulq %rdx + shrq $3, %rdx # rdx = rax / 10 + + # r15 = min(%rdx, %r15) + cmpq %rdx, %r15 + cmova %rdx, %r15 + + # olimit = op3 + 5 * r15 + movq %r15, %rax + leaq (%op3, %rax, 4), %olimit + addq %rax, %olimit + + movq 0(%rsp), %rdx + + # If (op3 + 10 > olimit) + movq %op3, %rax # rax = op3 + addq $10, %rax # rax = op3 + 10 + cmpq %rax, %olimit # op3 + 10 > olimit + jb .L_4X2_exit + + # If (ip1 < ip0) go to exit + cmpq %ip0, %ip1 + jb .L_4X2_exit + + # If (ip2 < ip1) go to exit + cmpq %ip1, %ip2 + jb .L_4X2_exit + + # If (ip3 < ip2) go to exit + cmpq %ip2, %ip3 + jb .L_4X2_exit + +#define DECODE(n, idx) \ + movq %bits##n, %rax; \ + shrq $53, %rax; \ + movzwl 0(%dtable,%rax,4),%r8d; \ + movzbl 2(%dtable,%rax,4),%r15d; \ + movzbl 3(%dtable,%rax,4),%eax; \ + movw %r8w, (%op##n); \ + shlxq %r15, %bits##n, %bits##n; \ + addq %rax, %op##n + +#define RELOAD_BITS(n) \ + bsfq %bits##n, %bits##n; \ + movq %bits##n, %rax; \ + shrq $3, %bits##n; \ + andq $7, %rax; \ + subq %bits##n, %ip##n; \ + movq (%ip##n), %bits##n; \ + orq $1, %bits##n; \ + shlxq %rax, %bits##n, %bits##n; + + + movq %olimit, 48(%rsp) + + .p2align 6 + +.L_4X2_loop_body: +# LLVM-MCA-BEGIN decode-4X2 + + # We clobber r8, so store it on the stack + movq %r8, 0(%rsp) + + # Decode 5 symbols from each of the 4 streams (20 symbols total). + FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) + + # Reload r8 + movq 0(%rsp), %r8 + + FOR_EACH_STREAM(RELOAD_BITS) + + cmp %op3, 48(%rsp) + ja .L_4X2_loop_body + jmp .L_4X2_compute_olimit + +#undef DECODE +#undef RELOAD_BITS +# LLVM-MCA-END +.L_4X2_exit: + addq $8, %rsp + # Restore stack (oend & olimit) + pop %rax # oend0 + pop %rax # oend1 + pop %rax # oend2 + pop %rax # oend3 + pop %rax # ilimit + pop %rax # olimit + pop %rax # arg + + # Save ip / op / bits + movq %ip0, 0(%rax) + movq %ip1, 8(%rax) + movq %ip2, 16(%rax) + movq %ip3, 24(%rax) + movq %op0, 32(%rax) + movq %op1, 40(%rax) + movq %op2, 48(%rax) + movq %op3, 56(%rax) + movq %bits0, 64(%rax) + movq %bits1, 72(%rax) + movq %bits2, 80(%rax) + movq %bits3, 88(%rax) + + # Restore registers + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rdx + pop %rcx + pop %rbx + pop %rax + ret +#endif diff --git a/lib/zstd.h b/lib/zstd.h index ebe2e04b5..90b59475a 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -72,7 +72,7 @@ extern "C" { /*------ Version ------*/ #define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MINOR 5 -#define ZSTD_VERSION_RELEASE 0 +#define ZSTD_VERSION_RELEASE 1 #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) /*! ZSTD_versionNumber() : diff --git a/tests/fuzz/huf_decompress.c b/tests/fuzz/huf_decompress.c index 7ede9ec53..fea09fc93 100644 --- a/tests/fuzz/huf_decompress.c +++ b/tests/fuzz/huf_decompress.c @@ -46,7 +46,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) if (ZSTD_isError(err)) goto _out; } else { - size_t const err = HUF_readDTableX2_wksp(dt, src, size, wksp, wkspSize); + size_t const err = HUF_readDTableX2_wksp_bmi2(dt, src, size, wksp, wkspSize, bmi2); if (ZSTD_isError(err)) goto _out; } From b5c35d7ea33b99d25ceb21057d38eca17c8dc7de Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 20 Sep 2021 09:04:07 -0400 Subject: [PATCH 165/274] Use new paramSwitch enum for LCM, row matchfinder, and block splitter --- lib/compress/zstd_compress.c | 168 ++++++------ lib/compress/zstd_compress_internal.h | 18 +- lib/compress/zstd_ldm.c | 2 +- lib/compress/zstd_ldm.h | 2 +- lib/compress/zstd_opt.c | 2 +- lib/zstd.h | 53 ++-- programs/benchzstd.c | 2 +- programs/benchzstd.h | 2 +- programs/fileio.c | 6 +- programs/fileio.h | 2 +- programs/zstdcli.c | 6 +- tests/fuzz/zstd_helpers.c | 2 +- tests/fuzzer.c | 6 +- tests/regression/config.c | 8 +- tests/regression/levels.h | 2 +- tests/regression/results.csv | 372 +++++++++++++------------- 16 files changed, 329 insertions(+), 324 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e68f7352a..700f4567f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -84,10 +84,10 @@ struct ZSTD_CDict_s { ZSTD_customMem customMem; U32 dictID; int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */ - ZSTD_useRowMatchFinderMode_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use - * row-based matchfinder. Unless the cdict is reloaded, we will use - * the same greedy/lazy matchfinder at compression time. - */ + ZSTD_paramSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use + * row-based matchfinder. Unless the cdict is reloaded, we will use + * the same greedy/lazy matchfinder at compression time. + */ }; /* typedef'd to ZSTD_CDict within "zstd.h" */ ZSTD_CCtx* ZSTD_createCCtx(void) @@ -226,35 +226,42 @@ static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) { /* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder * for this compression. */ -static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_useRowMatchFinderMode_e mode) { - assert(mode != ZSTD_urm_auto); - return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_urm_enableRowMatchFinder); +static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_paramSwitch_e mode) { + assert(mode != ZSTD_ps_auto); + return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable); } -/* Returns row matchfinder usage enum given an initial mode and cParams */ -static ZSTD_useRowMatchFinderMode_e ZSTD_resolveRowMatchFinderMode(ZSTD_useRowMatchFinderMode_e mode, - const ZSTD_compressionParameters* const cParams) { +/* Returns row matchfinder usage given an initial mode and cParams */ +static ZSTD_paramSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_paramSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { #if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON) int const kHasSIMD128 = 1; #else int const kHasSIMD128 = 0; #endif - if (mode != ZSTD_urm_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */ - mode = ZSTD_urm_disableRowMatchFinder; + if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */ + mode = ZSTD_ps_disable; if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode; if (kHasSIMD128) { - if (cParams->windowLog > 14) mode = ZSTD_urm_enableRowMatchFinder; + if (cParams->windowLog > 14) mode = ZSTD_ps_enable; } else { - if (cParams->windowLog > 17) mode = ZSTD_urm_enableRowMatchFinder; + if (cParams->windowLog > 17) mode = ZSTD_ps_enable; } return mode; } +/* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */ +static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + /* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */ static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, - const ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + const ZSTD_paramSwitch_e useRowMatchFinder, const U32 forDDSDict) { - assert(useRowMatchFinder != ZSTD_urm_auto); + assert(useRowMatchFinder != ZSTD_ps_auto); /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate. * We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder. */ @@ -269,14 +276,6 @@ static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27; } -/* Returns 1 if compression parameters are such that we should - * enable blockSplitter (wlog >= 17, strategy >= btopt). - * Returns 0 otherwise. - */ -static U32 ZSTD_CParams_useBlockSplitter(const ZSTD_compressionParameters* const cParams) { - return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17; -} - static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( ZSTD_compressionParameters cParams) { @@ -295,11 +294,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( assert(cctxParams.ldmParams.hashRateLog < 32); } - if (ZSTD_CParams_useBlockSplitter(&cParams)) { - DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including block splitting into cctx params"); - cctxParams.splitBlocks = 1; - } - + cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams); cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); assert(!ZSTD_checkCParams(cParams)); return cctxParams; @@ -360,18 +355,14 @@ static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_par */ cctxParams->compressionLevel = compressionLevel; cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams); - DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d", cctxParams->useRowMatchFinder); + cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, ¶ms->cParams); + DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d", cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter); if (ZSTD_CParams_shouldEnableLdm(¶ms->cParams)) { /* Enable LDM by default for optimal parser and window size >= 128MB */ DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)"); cctxParams->ldmParams.enableLdm = 1; } - - if (ZSTD_CParams_useBlockSplitter(¶ms->cParams)) { - DEBUGLOG(4, "Block splitter enabled by default (window size >= 128K, strategy >= btopt)"); - cctxParams->splitBlocks = 1; - } } size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) @@ -541,9 +532,9 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) return bounds; case ZSTD_c_literalCompressionMode: - ZSTD_STATIC_ASSERT(ZSTD_lcm_auto < ZSTD_lcm_huffman && ZSTD_lcm_huffman < ZSTD_lcm_uncompressed); - bounds.lowerBound = ZSTD_lcm_auto; - bounds.upperBound = ZSTD_lcm_uncompressed; + ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable); + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; return bounds; case ZSTD_c_targetCBlockSize: @@ -572,14 +563,14 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) bounds.upperBound = 1; return bounds; - case ZSTD_c_splitBlocks: - bounds.lowerBound = 0; - bounds.upperBound = 1; + case ZSTD_c_useBlockSplitter: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; return bounds; case ZSTD_c_useRowMatchFinder: - bounds.lowerBound = (int)ZSTD_urm_auto; - bounds.upperBound = (int)ZSTD_urm_enableRowMatchFinder; + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; return bounds; case ZSTD_c_deterministicRefPrefix: @@ -648,7 +639,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) case ZSTD_c_stableOutBuffer: case ZSTD_c_blockDelimiters: case ZSTD_c_validateSequences: - case ZSTD_c_splitBlocks: + case ZSTD_c_useBlockSplitter: case ZSTD_c_useRowMatchFinder: case ZSTD_c_deterministicRefPrefix: default: @@ -703,7 +694,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) case ZSTD_c_stableOutBuffer: case ZSTD_c_blockDelimiters: case ZSTD_c_validateSequences: - case ZSTD_c_splitBlocks: + case ZSTD_c_useBlockSplitter: case ZSTD_c_useRowMatchFinder: case ZSTD_c_deterministicRefPrefix: break; @@ -803,7 +794,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, } case ZSTD_c_literalCompressionMode : { - const ZSTD_literalCompressionMode_e lcm = (ZSTD_literalCompressionMode_e)value; + const ZSTD_paramSwitch_e lcm = (ZSTD_paramSwitch_e)value; BOUNDCHECK(ZSTD_c_literalCompressionMode, lcm); CCtxParams->literalCompressionMode = lcm; return CCtxParams->literalCompressionMode; @@ -917,14 +908,14 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, CCtxParams->validateSequences = value; return CCtxParams->validateSequences; - case ZSTD_c_splitBlocks: - BOUNDCHECK(ZSTD_c_splitBlocks, value); - CCtxParams->splitBlocks = value; - return CCtxParams->splitBlocks; + case ZSTD_c_useBlockSplitter: + BOUNDCHECK(ZSTD_c_useBlockSplitter, value); + CCtxParams->useBlockSplitter = (ZSTD_paramSwitch_e)value; + return CCtxParams->useBlockSplitter; case ZSTD_c_useRowMatchFinder: BOUNDCHECK(ZSTD_c_useRowMatchFinder, value); - CCtxParams->useRowMatchFinder = (ZSTD_useRowMatchFinderMode_e)value; + CCtxParams->useRowMatchFinder = (ZSTD_paramSwitch_e)value; return CCtxParams->useRowMatchFinder; case ZSTD_c_deterministicRefPrefix: @@ -1055,8 +1046,8 @@ size_t ZSTD_CCtxParams_getParameter( case ZSTD_c_validateSequences : *value = (int)CCtxParams->validateSequences; break; - case ZSTD_c_splitBlocks : - *value = (int)CCtxParams->splitBlocks; + case ZSTD_c_useBlockSplitter : + *value = (int)CCtxParams->useBlockSplitter; break; case ZSTD_c_useRowMatchFinder : *value = (int)CCtxParams->useRowMatchFinder; @@ -1430,7 +1421,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( static size_t ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, - const ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + const ZSTD_paramSwitch_e useRowMatchFinder, const U32 enableDedicatedDictSearch, const U32 forCCtx) { @@ -1463,7 +1454,7 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, /* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */ ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4); - assert(useRowMatchFinder != ZSTD_urm_auto); + assert(useRowMatchFinder != ZSTD_ps_auto); DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u", (U32)chainSize, (U32)hSize, (U32)h3Size); @@ -1474,7 +1465,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( const ZSTD_compressionParameters* cParams, const ldmParams_t* ldmParams, const int isStatic, - const ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + const ZSTD_paramSwitch_e useRowMatchFinder, const size_t buffInSize, const size_t buffOutSize, const U64 pledgedSrcSize) @@ -1519,7 +1510,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) { ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); - ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, + ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, &cParams); RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); @@ -1537,9 +1528,9 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */ size_t noRowCCtxSize; size_t rowCCtxSize; - initialParams.useRowMatchFinder = ZSTD_urm_disableRowMatchFinder; + initialParams.useRowMatchFinder = ZSTD_ps_disable; noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); - initialParams.useRowMatchFinder = ZSTD_urm_enableRowMatchFinder; + initialParams.useRowMatchFinder = ZSTD_ps_enable; rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); return MAX(noRowCCtxSize, rowCCtxSize); } else { @@ -1584,7 +1575,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params) size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered) ? ZSTD_compressBound(blockSize) + 1 : 0; - ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams); + ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams); return ZSTD_estimateCCtxSize_usingCCtxParams_internal( &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize, @@ -1599,9 +1590,9 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams) /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */ size_t noRowCCtxSize; size_t rowCCtxSize; - initialParams.useRowMatchFinder = ZSTD_urm_disableRowMatchFinder; + initialParams.useRowMatchFinder = ZSTD_ps_disable; noRowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams); - initialParams.useRowMatchFinder = ZSTD_urm_enableRowMatchFinder; + initialParams.useRowMatchFinder = ZSTD_ps_enable; rowCCtxSize = ZSTD_estimateCStreamSize_usingCCtxParams(&initialParams); return MAX(noRowCCtxSize, rowCCtxSize); } else { @@ -1736,7 +1727,7 @@ static size_t ZSTD_reset_matchState(ZSTD_matchState_t* ms, ZSTD_cwksp* ws, const ZSTD_compressionParameters* cParams, - const ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + const ZSTD_paramSwitch_e useRowMatchFinder, const ZSTD_compResetPolicy_e crp, const ZSTD_indexResetPolicy_e forceResetIndex, const ZSTD_resetTarget_e forWho) @@ -1751,7 +1742,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms, size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset); - assert(useRowMatchFinder != ZSTD_urm_auto); + assert(useRowMatchFinder != ZSTD_ps_auto); if (forceResetIndex == ZSTDirp_reset) { ZSTD_window_init(&ms->window); ZSTD_cwksp_mark_tables_dirty(ws); @@ -1847,8 +1838,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, ZSTD_buffered_policy_e const zbuff) { ZSTD_cwksp* const ws = &zc->workspace; - DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d", - (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder); + DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d", + (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->useBlockSplitter); assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); zc->isFirstBlock = 1; @@ -1859,7 +1850,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->appliedParams = *params; params = &zc->appliedParams; - assert(params->useRowMatchFinder != ZSTD_urm_auto); + assert(params->useRowMatchFinder != ZSTD_ps_auto); + assert(params->useBlockSplitter != ZSTD_ps_auto); if (params->ldmParams.enableLdm) { /* Adjust long distance matching parameters */ ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, ¶ms->cParams); @@ -2138,7 +2130,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, } ZSTD_cwksp_mark_tables_dirty(&cctx->workspace); - assert(params.useRowMatchFinder != ZSTD_urm_auto); + assert(params.useRowMatchFinder != ZSTD_ps_auto); /* copy tables */ { size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */) @@ -2232,8 +2224,10 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, { ZSTD_CCtx_params params = dstCCtx->requestedParams; /* Copy only compression parameters related to tables. */ params.cParams = srcCCtx->appliedParams.cParams; - assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_urm_auto); + assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.useBlockSplitter != ZSTD_ps_auto); params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder; + params.useBlockSplitter = srcCCtx->appliedParams.useBlockSplitter; params.fParams = fParams; ZSTD_resetCCtx_internal(dstCCtx, ¶ms, pledgedSrcSize, /* loadedDictSize */ 0, @@ -2422,11 +2416,13 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) /* ZSTD_blockSplitterEnabled(): * Returns if block splitting param is being used * If used, compression will do best effort to split a block in order to improve compression ratio. + * At the time this function is called, the parameter must be finalized. * Returns 1 if true, 0 otherwise. */ static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams) { - DEBUGLOG(5, "ZSTD_blockSplitterEnabled(splitBlocks=%d)", cctxParams->splitBlocks); - return (cctxParams->splitBlocks != 0); + DEBUGLOG(5, "ZSTD_blockSplitterEnabled (useBlockSplitter=%d)", cctxParams->useBlockSplitter); + assert(cctxParams->useBlockSplitter != ZSTD_ps_auto); + return (cctxParams->useBlockSplitter == ZSTD_ps_enable); } /* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types @@ -2612,7 +2608,7 @@ ZSTD_entropyCompressSeqStore_internal(seqStore_t* seqStorePtr, size_t const cSize = ZSTD_compressLiterals( &prevEntropy->huf, &nextEntropy->huf, cctxParams->cParams.strategy, - ZSTD_disableLiteralsCompression(cctxParams), + ZSTD_literalsCompressionIsDisabled(cctxParams), op, dstCapacity, literals, litSize, entropyWorkspace, entropyWkspSize, @@ -2721,7 +2717,7 @@ ZSTD_entropyCompressSeqStore(seqStore_t* seqStorePtr, /* ZSTD_selectBlockCompressor() : * Not static, but internal use only (used by long distance matcher) * assumption : strat is a valid strategy */ -ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e useRowMatchFinder, ZSTD_dictMode_e dictMode) +ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode) { static const ZSTD_blockCompressor blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { { ZSTD_compressBlock_fast /* default for 0 */, @@ -2786,7 +2782,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRow ZSTD_compressBlock_lazy2_dedicatedDictSearch_row } }; DEBUGLOG(4, "Selecting a row-based matchfinder"); - assert(useRowMatchFinder != ZSTD_urm_auto); + assert(useRowMatchFinder != ZSTD_ps_auto); selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy]; } else { selectedCompressor = blockCompressor[(int)dictMode][(int)strat]; @@ -3055,7 +3051,7 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi const ZSTD_hufCTables_t* prevHuf, ZSTD_hufCTables_t* nextHuf, ZSTD_hufCTablesMetadata_t* hufMetadata, - const int disableLiteralsCompression, + const int literalsCompressionIsDisabled, void* workspace, size_t wkspSize) { BYTE* const wkspStart = (BYTE*)workspace; @@ -3073,7 +3069,7 @@ static size_t ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSi /* Prepare nextEntropy assuming reusing the existing table */ ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); - if (disableLiteralsCompression) { + if (literalsCompressionIsDisabled) { DEBUGLOG(5, "set_basic - disabled"); hufMetadata->hType = set_basic; return 0; @@ -3220,7 +3216,7 @@ size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr, ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize, &prevEntropy->huf, &nextEntropy->huf, &entropyMetadata->hufMetadata, - ZSTD_disableLiteralsCompression(cctxParams), + ZSTD_literalsCompressionIsDisabled(cctxParams), workspace, wkspSize); FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed"); entropyMetadata->fseMetadata.fseTablesSize = @@ -3723,6 +3719,7 @@ static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, U32 nbSeq; size_t cSize; DEBUGLOG(4, "ZSTD_compressBlock_splitBlock"); + assert(zc->appliedParams.useBlockSplitter == ZSTD_ps_enable); { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); @@ -3737,7 +3734,6 @@ static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart); } - assert(zc->appliedParams.splitBlocks == 1); cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq); FORWARD_IF_ERROR(cSize, "Splitting blocks failed!"); return cSize; @@ -4252,8 +4248,8 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, assert(ms->chainTable != NULL); ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, iend-HASH_READ_SIZE); } else { - assert(params->useRowMatchFinder != ZSTD_urm_auto); - if (params->useRowMatchFinder == ZSTD_urm_enableRowMatchFinder) { + assert(params->useRowMatchFinder != ZSTD_ps_auto); + if (params->useRowMatchFinder == ZSTD_ps_enable) { size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog) * sizeof(U16); ZSTD_memset(ms->tagTable, 0, tagTableSize); ZSTD_row_update(ms, iend-HASH_READ_SIZE); @@ -4753,7 +4749,7 @@ size_t ZSTD_estimateCDictSize_advanced( + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) /* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small * in case we are using DDS with row-hash. */ - + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_urm_auto, &cParams), + + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams), /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *)))); @@ -4830,7 +4826,7 @@ static size_t ZSTD_initCDict_internal( static ZSTD_CDict* ZSTD_createCDict_advanced_internal(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_compressionParameters cParams, - ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + ZSTD_paramSwitch_e useRowMatchFinder, U32 enableDedicatedDictSearch, ZSTD_customMem customMem) { @@ -4985,7 +4981,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict( ZSTD_dictContentType_e dictContentType, ZSTD_compressionParameters cParams) { - ZSTD_useRowMatchFinderMode_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_urm_auto, &cParams); + ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams); /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */ size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0); size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) @@ -5568,11 +5564,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, params.ldmParams.enableLdm = 1; } - if (ZSTD_CParams_useBlockSplitter(¶ms.cParams)) { - DEBUGLOG(4, "Block splitter enabled by default (window size >= 128K, strategy >= btopt)"); - params.splitBlocks = 1; - } - + params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, ¶ms.cParams); params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, ¶ms.cParams); #ifdef ZSTD_MULTITHREAD diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index c032d7d18..c168c67e7 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -179,7 +179,7 @@ typedef struct { U32 offCodeSumBasePrice; /* to compare to log2(offreq) */ ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */ const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */ - ZSTD_literalCompressionMode_e literalCompressionMode; + ZSTD_paramSwitch_e literalCompressionMode; } optState_t; typedef struct { @@ -297,7 +297,7 @@ struct ZSTD_CCtx_params_s { * There is no guarantee that hint is close to actual source size */ ZSTD_dictAttachPref_e attachDictPref; - ZSTD_literalCompressionMode_e literalCompressionMode; + ZSTD_paramSwitch_e literalCompressionMode; /* Multithreading: used to pass parameters to mtctx */ int nbWorkers; @@ -320,10 +320,10 @@ struct ZSTD_CCtx_params_s { int validateSequences; /* Block splitting */ - int splitBlocks; + ZSTD_paramSwitch_e useBlockSplitter; /* Param for deciding whether to use row-based matchfinder */ - ZSTD_useRowMatchFinderMode_e useRowMatchFinder; + ZSTD_paramSwitch_e useRowMatchFinder; /* Always load a dictionary in ext-dict mode (not prefix mode)? */ int deterministicRefPrefix; @@ -444,7 +444,7 @@ typedef enum { typedef size_t (*ZSTD_blockCompressor) ( ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize); -ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e rowMatchfinderMode, ZSTD_dictMode_e dictMode); +ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode); MEM_STATIC U32 ZSTD_LLcode(U32 litLength) @@ -551,17 +551,17 @@ MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat) return (srcSize >> minlog) + 2; } -MEM_STATIC int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams) +MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams) { switch (cctxParams->literalCompressionMode) { - case ZSTD_lcm_huffman: + case ZSTD_ps_enable: return 0; - case ZSTD_lcm_uncompressed: + case ZSTD_ps_disable: return 1; default: assert(0 /* impossible: pre-validated */); /* fall-through */ - case ZSTD_lcm_auto: + case ZSTD_ps_auto: return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); } } diff --git a/lib/compress/zstd_ldm.c b/lib/compress/zstd_ldm.c index fa4ebeabd..c97b97a03 100644 --- a/lib/compress/zstd_ldm.c +++ b/lib/compress/zstd_ldm.c @@ -657,7 +657,7 @@ void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) { size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + ZSTD_paramSwitch_e useRowMatchFinder, void const* src, size_t srcSize) { const ZSTD_compressionParameters* const cParams = &ms->cParams; diff --git a/lib/compress/zstd_ldm.h b/lib/compress/zstd_ldm.h index 393466fa9..4e68dbf52 100644 --- a/lib/compress/zstd_ldm.h +++ b/lib/compress/zstd_ldm.h @@ -66,7 +66,7 @@ size_t ZSTD_ldm_generateSequences( */ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - ZSTD_useRowMatchFinderMode_e useRowMatchFinder, + ZSTD_paramSwitch_e useRowMatchFinder, void const* src, size_t srcSize); /** diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 9b4b236c0..40c25daa1 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -65,7 +65,7 @@ MEM_STATIC double ZSTD_fCost(U32 price) static int ZSTD_compressedLiterals(optState_t const* const optPtr) { - return optPtr->literalCompressionMode != ZSTD_lcm_uncompressed; + return optPtr->literalCompressionMode != ZSTD_ps_disable; } static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel) diff --git a/lib/zstd.h b/lib/zstd.h index ebe2e04b5..2cbb1ddf7 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -417,7 +417,7 @@ typedef enum { * ZSTD_c_stableOutBuffer * ZSTD_c_blockDelimiters * ZSTD_c_validateSequences - * ZSTD_c_splitBlocks + * ZSTD_c_useBlockSplitter * ZSTD_c_useRowMatchFinder * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * note : never ever use experimentalParam? names directly; @@ -1299,10 +1299,14 @@ typedef enum { } ZSTD_literalCompressionMode_e; typedef enum { - ZSTD_urm_auto = 0, /* Automatically determine whether or not we use row matchfinder */ - ZSTD_urm_disableRowMatchFinder = 1, /* Never use row matchfinder */ - ZSTD_urm_enableRowMatchFinder = 2 /* Always use row matchfinder when applicable */ -} ZSTD_useRowMatchFinderMode_e; + /* Note: This enum controls features which are conditionally beneficial. Zstd typically will make a final + * decision on whether or not to enable the feature (ZSTD_ps_auto), but setting the switch to ZSTD_ps_enable + * or ZSTD_ps_disable allow for a force enable/disable the feature. + */ + ZSTD_ps_auto = 0, /* Let the library automatically determine whether the feature shall be enabled */ + ZSTD_ps_enable = 1, /* Force-enable the feature */ + ZSTD_ps_disable = 2 /* Do not use the feature */ +} ZSTD_paramSwitch_e; /*************************************** * Frame size functions @@ -1729,9 +1733,15 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre * See the comments on that enum for an explanation of the feature. */ #define ZSTD_c_forceAttachDict ZSTD_c_experimentalParam4 -/* Controls how the literals are compressed (default is auto). - * The value must be of type ZSTD_literalCompressionMode_e. - * See ZSTD_literalCompressionMode_e enum definition for details. +/* Controlled with ZSTD_paramSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never compress literals. + * Set to ZSTD_ps_enable to always compress literals. (Note: uncompressed literals + * may still be emitted if huffman is not beneficial to use.) + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * literals compression based on the compression parameters - specifically, + * negative compression levels do not use literal compression. */ #define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5 @@ -1883,23 +1893,26 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre */ #define ZSTD_c_validateSequences ZSTD_c_experimentalParam12 -/* ZSTD_c_splitBlocks - * Default is 0 == disabled. Set to 1 to enable block splitting. +/* ZSTD_c_useBlockSplitter + * Controlled with ZSTD_paramSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never use block splitter. + * Set to ZSTD_ps_enable to always use block splitter. * - * Will attempt to split blocks in order to improve compression ratio at the cost of speed. + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * block splitting based on the compression parameters. */ -#define ZSTD_c_splitBlocks ZSTD_c_experimentalParam13 +#define ZSTD_c_useBlockSplitter ZSTD_c_experimentalParam13 /* ZSTD_c_useRowMatchFinder - * Default is ZSTD_urm_auto. - * Controlled with ZSTD_useRowMatchFinderMode_e enum. + * Controlled with ZSTD_paramSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never use row-based matchfinder. + * Set to ZSTD_ps_enable to force usage of row-based matchfinder. * - * By default, in ZSTD_urm_auto, when finalizing the compression parameters, the library - * will decide at runtime whether to use the row-based matchfinder based on support for SIMD - * instructions as well as the windowLog. - * - * Set to ZSTD_urm_disableRowMatchFinder to never use row-based matchfinder. - * Set to ZSTD_urm_enableRowMatchFinder to force usage of row-based matchfinder. + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * the row-based matchfinder based on support for SIMD instructions and the window log. + * Note that this only pertains to compression strategies: greedy, lazy, and lazy2 */ #define ZSTD_c_useRowMatchFinder ZSTD_c_experimentalParam14 diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 5cfe624b0..09035ea45 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -131,7 +131,7 @@ BMK_advancedParams_t BMK_initAdvancedParams(void) { 0, /* ldmHashLog */ 0, /* ldmBuckSizeLog */ 0, /* ldmHashRateLog */ - ZSTD_lcm_auto, /* literalCompressionMode */ + ZSTD_ps_auto, /* literalCompressionMode */ 0 /* useRowMatchFinder */ }; return res; diff --git a/programs/benchzstd.h b/programs/benchzstd.h index 9b40dcc29..11ac85da7 100644 --- a/programs/benchzstd.h +++ b/programs/benchzstd.h @@ -116,7 +116,7 @@ typedef struct { int ldmHashLog; int ldmBucketSizeLog; int ldmHashRateLog; - ZSTD_literalCompressionMode_e literalCompressionMode; + ZSTD_paramSwitch_e literalCompressionMode; int useRowMatchFinder; /* use row-based matchfinder if possible */ } BMK_advancedParams_t; diff --git a/programs/fileio.c b/programs/fileio.c index 317ec87e0..db64ecb64 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -320,7 +320,7 @@ struct FIO_prefs_s { size_t targetCBlockSize; int srcSizeHint; int testMode; - ZSTD_literalCompressionMode_e literalCompressionMode; + ZSTD_paramSwitch_e literalCompressionMode; /* IO preferences */ U32 removeSrcFile; @@ -392,7 +392,7 @@ FIO_prefs_t* FIO_createPreferences(void) ret->targetCBlockSize = 0; ret->srcSizeHint = 0; ret->testMode = 0; - ret->literalCompressionMode = ZSTD_lcm_auto; + ret->literalCompressionMode = ZSTD_ps_auto; ret->excludeCompressedFiles = 0; ret->allowBlockDevices = 0; return ret; @@ -510,7 +510,7 @@ void FIO_setTestMode(FIO_prefs_t* const prefs, int testMode) { void FIO_setLiteralCompressionMode( FIO_prefs_t* const prefs, - ZSTD_literalCompressionMode_e mode) { + ZSTD_paramSwitch_e mode) { prefs->literalCompressionMode = mode; } diff --git a/programs/fileio.h b/programs/fileio.h index 9d97ec8bf..82d5bc849 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -100,7 +100,7 @@ void FIO_setSrcSizeHint(FIO_prefs_t* const prefs, size_t srcSizeHint); void FIO_setTestMode(FIO_prefs_t* const prefs, int testMode); void FIO_setLiteralCompressionMode( FIO_prefs_t* const prefs, - ZSTD_literalCompressionMode_e mode); + ZSTD_paramSwitch_e mode); void FIO_setProgressSetting(FIO_progressSetting_e progressSetting); void FIO_setNotificationLevel(int level); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 9178a4bef..7e4f530f8 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -804,7 +804,7 @@ int main(int argCount, const char* argv[]) #ifndef ZSTD_NOBENCH BMK_advancedParams_t benchParams = BMK_initAdvancedParams(); #endif - ZSTD_literalCompressionMode_e literalCompressionMode = ZSTD_lcm_auto; + ZSTD_paramSwitch_e literalCompressionMode = ZSTD_ps_auto; /* init */ @@ -900,8 +900,8 @@ int main(int argCount, const char* argv[]) if (!strcmp(argument, "--format=lz4")) { suffix = LZ4_EXTENSION; FIO_setCompressionType(prefs, FIO_lz4Compression); continue; } #endif if (!strcmp(argument, "--rsyncable")) { rsyncable = 1; continue; } - if (!strcmp(argument, "--compress-literals")) { literalCompressionMode = ZSTD_lcm_huffman; continue; } - if (!strcmp(argument, "--no-compress-literals")) { literalCompressionMode = ZSTD_lcm_uncompressed; continue; } + if (!strcmp(argument, "--compress-literals")) { literalCompressionMode = ZSTD_ps_enable; continue; } + if (!strcmp(argument, "--no-compress-literals")) { literalCompressionMode = ZSTD_ps_disable; continue; } if (!strcmp(argument, "--no-progress")) { FIO_setProgressSetting(FIO_ps_never); continue; } if (!strcmp(argument, "--progress")) { FIO_setProgressSetting(FIO_ps_always); continue; } if (!strcmp(argument, "--exclude-compressed")) { FIO_setExcludeCompressedFile(prefs, 1); continue; } diff --git a/tests/fuzz/zstd_helpers.c b/tests/fuzz/zstd_helpers.c index 4d889deeb..0fbf3bed7 100644 --- a/tests/fuzz/zstd_helpers.c +++ b/tests/fuzz/zstd_helpers.c @@ -96,7 +96,7 @@ void FUZZ_setRandomParameters(ZSTD_CCtx *cctx, size_t srcSize, FUZZ_dataProducer setRand(cctx, ZSTD_c_forceMaxWindow, 0, 1, producer); setRand(cctx, ZSTD_c_literalCompressionMode, 0, 2, producer); setRand(cctx, ZSTD_c_forceAttachDict, 0, 2, producer); - setRand(cctx, ZSTD_c_splitBlocks, 0, 1, producer); + setRand(cctx, ZSTD_c_useBlockSplitter, 0, 2, producer); setRand(cctx, ZSTD_c_deterministicRefPrefix, 0, 1, producer); if (FUZZ_dataProducer_uint32Range(producer, 0, 1) == 0) { setRand(cctx, ZSTD_c_srcSizeHint, ZSTD_SRCSIZEHINT_MIN, 2 * srcSize, producer); diff --git a/tests/fuzzer.c b/tests/fuzzer.c index c4de54247..9be7a38ab 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1718,7 +1718,7 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(3, "test%3i : compress with block splitting : ", testNb++) { ZSTD_CCtx* cctx = ZSTD_createCCtx(); - CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_splitBlocks, 1) ); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_useBlockSplitter, ZSTD_ps_enable) ); cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); CHECK(cSize); ZSTD_freeCCtx(cctx); @@ -1732,7 +1732,7 @@ static int basicUnitTests(U32 const seed, double compressibility) CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 2) ); cSize1 = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); CHECK(cSize1); - CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_literalCompressionMode, ZSTD_lcm_uncompressed) ); + CHECK( ZSTD_CCtx_setParameter(cctx, ZSTD_c_literalCompressionMode, ZSTD_ps_disable) ); cSize2 = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, CNBuffer, CNBuffSize); CHECK(cSize2); CHECK_LT(cSize1, cSize2); @@ -2019,7 +2019,7 @@ static int basicUnitTests(U32 const seed, double compressibility) ZSTD_CCtx* const cctx = ZSTD_createCCtx(); size_t nodict_cSize; ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, l); - ZSTD_CCtx_setParameter(cctx, ZSTD_c_useRowMatchFinder, ZSTD_urm_enableRowMatchFinder); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_useRowMatchFinder, ZSTD_ps_enable); nodict_cSize = ZSTD_compress2(cctx, compressedBuffer, compressedBufferSize, contentStart, contentSize); if (nodict_cSize > target_nodict_cSize[l]) { diff --git a/tests/regression/config.c b/tests/regression/config.c index 4c66dd150..57cd110c6 100644 --- a/tests/regression/config.c +++ b/tests/regression/config.c @@ -215,7 +215,7 @@ static config_t mt_ldm = { static param_value_t mt_advanced_param_values[] = { {.param = ZSTD_c_nbWorkers, .value = 2}, - {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_lcm_uncompressed}, + {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_disable}, }; static config_t mt_advanced = { @@ -258,7 +258,7 @@ static config_t small_clog = { static param_value_t const uncompressed_literals_param_values[] = { {.param = ZSTD_c_compressionLevel, .value = 3}, - {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_lcm_uncompressed}, + {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_disable}, }; static config_t uncompressed_literals = { @@ -269,7 +269,7 @@ static config_t uncompressed_literals = { static param_value_t const uncompressed_literals_opt_param_values[] = { {.param = ZSTD_c_compressionLevel, .value = 19}, - {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_lcm_uncompressed}, + {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_disable}, }; static config_t uncompressed_literals_opt = { @@ -280,7 +280,7 @@ static config_t uncompressed_literals_opt = { static param_value_t const huffman_literals_param_values[] = { {.param = ZSTD_c_compressionLevel, .value = -1}, - {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_lcm_huffman}, + {.param = ZSTD_c_literalCompressionMode, .value = ZSTD_ps_enable}, }; static config_t huffman_literals = { diff --git a/tests/regression/levels.h b/tests/regression/levels.h index 5a933c133..e98209d80 100644 --- a/tests/regression/levels.h +++ b/tests/regression/levels.h @@ -36,7 +36,7 @@ LEVEL(3) LEVEL(4) /* ROW_LEVEL triggers the row hash (force enabled and disabled) with different * dictionary strategies, and 16/32/64 row entries based on the level/searchLog. - * 1 == disabled, 2 == enabled. + * 1 == enabled, 2 == disabled. */ ROW_LEVEL(5, 1) ROW_LEVEL(5, 2) /* 16-entry rows */ diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 9909a15a0..923b4498b 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -235,18 +235,18 @@ silesia, level 0, advanced silesia, level 1, advanced one pass, 5309098 silesia, level 3, advanced one pass, 4849553 silesia, level 4, advanced one pass, 4786968 -silesia, level 5 row 1, advanced one pass, 4640752 -silesia, level 5 row 2, advanced one pass, 4638961 +silesia, level 5 row 1, advanced one pass, 4638961 +silesia, level 5 row 2, advanced one pass, 4640752 silesia, level 5, advanced one pass, 4638961 silesia, level 6, advanced one pass, 4605369 -silesia, level 7 row 1, advanced one pass, 4564868 -silesia, level 7 row 2, advanced one pass, 4567204 +silesia, level 7 row 1, advanced one pass, 4567204 +silesia, level 7 row 2, advanced one pass, 4564868 silesia, level 7, advanced one pass, 4567204 silesia, level 9, advanced one pass, 4543310 -silesia, level 11 row 1, advanced one pass, 4519288 -silesia, level 11 row 2, advanced one pass, 4521399 -silesia, level 12 row 1, advanced one pass, 4503116 -silesia, level 12 row 2, advanced one pass, 4505153 +silesia, level 11 row 1, advanced one pass, 4521399 +silesia, level 11 row 2, advanced one pass, 4519288 +silesia, level 12 row 1, advanced one pass, 4505153 +silesia, level 12 row 2, advanced one pass, 4503116 silesia, level 13, advanced one pass, 4493990 silesia, level 16, advanced one pass, 4359864 silesia, level 19, advanced one pass, 4296880 @@ -269,18 +269,18 @@ silesia.tar, level 0, advanced silesia.tar, level 1, advanced one pass, 5331946 silesia.tar, level 3, advanced one pass, 4861424 silesia.tar, level 4, advanced one pass, 4799632 -silesia.tar, level 5 row 1, advanced one pass, 4652862 -silesia.tar, level 5 row 2, advanced one pass, 4650202 +silesia.tar, level 5 row 1, advanced one pass, 4650202 +silesia.tar, level 5 row 2, advanced one pass, 4652862 silesia.tar, level 5, advanced one pass, 4650202 silesia.tar, level 6, advanced one pass, 4616811 -silesia.tar, level 7 row 1, advanced one pass, 4575393 -silesia.tar, level 7 row 2, advanced one pass, 4576829 +silesia.tar, level 7 row 1, advanced one pass, 4576829 +silesia.tar, level 7 row 2, advanced one pass, 4575393 silesia.tar, level 7, advanced one pass, 4576829 silesia.tar, level 9, advanced one pass, 4552584 -silesia.tar, level 11 row 1, advanced one pass, 4529461 -silesia.tar, level 11 row 2, advanced one pass, 4530256 -silesia.tar, level 12 row 1, advanced one pass, 4513604 -silesia.tar, level 12 row 2, advanced one pass, 4514568 +silesia.tar, level 11 row 1, advanced one pass, 4530256 +silesia.tar, level 11 row 2, advanced one pass, 4529461 +silesia.tar, level 12 row 1, advanced one pass, 4514568 +silesia.tar, level 12 row 2, advanced one pass, 4513604 silesia.tar, level 13, advanced one pass, 4502956 silesia.tar, level 16, advanced one pass, 4360527 silesia.tar, level 19, advanced one pass, 4267266 @@ -326,16 +326,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced one pass, 41251 github, level 4 with dict copy, advanced one pass, 41216 github, level 4 with dict load, advanced one pass, 41159 -github, level 5 row 1, advanced one pass, 135121 -github, level 5 row 1 with dict dms, advanced one pass, 38938 -github, level 5 row 1 with dict dds, advanced one pass, 38732 -github, level 5 row 1 with dict copy, advanced one pass, 38934 -github, level 5 row 1 with dict load, advanced one pass, 40725 -github, level 5 row 2, advanced one pass, 134584 -github, level 5 row 2 with dict dms, advanced one pass, 38758 -github, level 5 row 2 with dict dds, advanced one pass, 38728 -github, level 5 row 2 with dict copy, advanced one pass, 38759 -github, level 5 row 2 with dict load, advanced one pass, 41518 +github, level 5 row 1, advanced one pass, 134584 +github, level 5 row 1 with dict dms, advanced one pass, 38758 +github, level 5 row 1 with dict dds, advanced one pass, 38728 +github, level 5 row 1 with dict copy, advanced one pass, 38759 +github, level 5 row 1 with dict load, advanced one pass, 41518 +github, level 5 row 2, advanced one pass, 135121 +github, level 5 row 2 with dict dms, advanced one pass, 38938 +github, level 5 row 2 with dict dds, advanced one pass, 38732 +github, level 5 row 2 with dict copy, advanced one pass, 38934 +github, level 5 row 2 with dict load, advanced one pass, 40725 github, level 5, advanced one pass, 135121 github, level 5 with dict, advanced one pass, 38758 github, level 5 with dict dms, advanced one pass, 38758 @@ -348,16 +348,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced one pass, 38636 github, level 6 with dict copy, advanced one pass, 38669 github, level 6 with dict load, advanced one pass, 40695 -github, level 7 row 1, advanced one pass, 135122 -github, level 7 row 1 with dict dms, advanced one pass, 38860 -github, level 7 row 1 with dict dds, advanced one pass, 38766 -github, level 7 row 1 with dict copy, advanced one pass, 38834 -github, level 7 row 1 with dict load, advanced one pass, 40695 -github, level 7 row 2, advanced one pass, 134584 -github, level 7 row 2 with dict dms, advanced one pass, 38758 -github, level 7 row 2 with dict dds, advanced one pass, 38745 -github, level 7 row 2 with dict copy, advanced one pass, 38755 -github, level 7 row 2 with dict load, advanced one pass, 43154 +github, level 7 row 1, advanced one pass, 134584 +github, level 7 row 1 with dict dms, advanced one pass, 38758 +github, level 7 row 1 with dict dds, advanced one pass, 38745 +github, level 7 row 1 with dict copy, advanced one pass, 38755 +github, level 7 row 1 with dict load, advanced one pass, 43154 +github, level 7 row 2, advanced one pass, 135122 +github, level 7 row 2 with dict dms, advanced one pass, 38860 +github, level 7 row 2 with dict dds, advanced one pass, 38766 +github, level 7 row 2 with dict copy, advanced one pass, 38834 +github, level 7 row 2 with dict load, advanced one pass, 40695 github, level 7, advanced one pass, 135122 github, level 7 with dict, advanced one pass, 38758 github, level 7 with dict dms, advanced one pass, 38758 @@ -451,16 +451,16 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass, 37954 github.tar, level 4 with dict copy, advanced one pass, 37948 github.tar, level 4 with dict load, advanced one pass, 37927 -github.tar, level 5 row 1, advanced one pass, 38534 -github.tar, level 5 row 1 with dict dms, advanced one pass, 39365 -github.tar, level 5 row 1 with dict dds, advanced one pass, 39233 -github.tar, level 5 row 1 with dict copy, advanced one pass, 39715 -github.tar, level 5 row 1 with dict load, advanced one pass, 38019 -github.tar, level 5 row 2, advanced one pass, 38376 -github.tar, level 5 row 2 with dict dms, advanced one pass, 39024 -github.tar, level 5 row 2 with dict dds, advanced one pass, 39028 -github.tar, level 5 row 2 with dict copy, advanced one pass, 39040 -github.tar, level 5 row 2 with dict load, advanced one pass, 37600 +github.tar, level 5 row 1, advanced one pass, 38376 +github.tar, level 5 row 1 with dict dms, advanced one pass, 39024 +github.tar, level 5 row 1 with dict dds, advanced one pass, 39028 +github.tar, level 5 row 1 with dict copy, advanced one pass, 39040 +github.tar, level 5 row 1 with dict load, advanced one pass, 37600 +github.tar, level 5 row 2, advanced one pass, 38534 +github.tar, level 5 row 2 with dict dms, advanced one pass, 39365 +github.tar, level 5 row 2 with dict dds, advanced one pass, 39233 +github.tar, level 5 row 2 with dict copy, advanced one pass, 39715 +github.tar, level 5 row 2 with dict load, advanced one pass, 38019 github.tar, level 5, advanced one pass, 38376 github.tar, level 5 with dict, advanced one pass, 39040 github.tar, level 5 with dict dms, advanced one pass, 39024 @@ -473,16 +473,16 @@ github.tar, level 6 with dict dms, advanced github.tar, level 6 with dict dds, advanced one pass, 38610 github.tar, level 6 with dict copy, advanced one pass, 38622 github.tar, level 6 with dict load, advanced one pass, 37829 -github.tar, level 7 row 1, advanced one pass, 38077 -github.tar, level 7 row 1 with dict dms, advanced one pass, 38012 -github.tar, level 7 row 1 with dict dds, advanced one pass, 38014 -github.tar, level 7 row 1 with dict copy, advanced one pass, 38101 -github.tar, level 7 row 1 with dict load, advanced one pass, 37402 -github.tar, level 7 row 2, advanced one pass, 38073 -github.tar, level 7 row 2 with dict dms, advanced one pass, 37848 -github.tar, level 7 row 2 with dict dds, advanced one pass, 37869 -github.tar, level 7 row 2 with dict copy, advanced one pass, 37848 -github.tar, level 7 row 2 with dict load, advanced one pass, 37371 +github.tar, level 7 row 1, advanced one pass, 38073 +github.tar, level 7 row 1 with dict dms, advanced one pass, 37848 +github.tar, level 7 row 1 with dict dds, advanced one pass, 37869 +github.tar, level 7 row 1 with dict copy, advanced one pass, 37848 +github.tar, level 7 row 1 with dict load, advanced one pass, 37371 +github.tar, level 7 row 2, advanced one pass, 38077 +github.tar, level 7 row 2 with dict dms, advanced one pass, 38012 +github.tar, level 7 row 2 with dict dds, advanced one pass, 38014 +github.tar, level 7 row 2 with dict copy, advanced one pass, 38101 +github.tar, level 7 row 2 with dict load, advanced one pass, 37402 github.tar, level 7, advanced one pass, 38073 github.tar, level 7 with dict, advanced one pass, 37848 github.tar, level 7 with dict dms, advanced one pass, 37848 @@ -499,22 +499,22 @@ github.tar, level 11 row 1, advanced github.tar, level 11 row 1 with dict dms, advanced one pass, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass, 36419 +github.tar, level 11 row 1 with dict load, advanced one pass, 36424 github.tar, level 11 row 2, advanced one pass, 36435 github.tar, level 11 row 2 with dict dms, advanced one pass, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 2 with dict load, advanced one pass, 36424 -github.tar, level 12 row 1, advanced one pass, 36110 +github.tar, level 11 row 2 with dict load, advanced one pass, 36419 +github.tar, level 12 row 1, advanced one pass, 36105 github.tar, level 12 row 1 with dict dms, advanced one pass, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass, 36459 -github.tar, level 12 row 2, advanced one pass, 36105 +github.tar, level 12 row 1 with dict load, advanced one pass, 36460 +github.tar, level 12 row 2, advanced one pass, 36110 github.tar, level 12 row 2 with dict dms, advanced one pass, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass, 36460 +github.tar, level 12 row 2 with dict load, advanced one pass, 36459 github.tar, level 13, advanced one pass, 35501 github.tar, level 13 with dict, advanced one pass, 37130 github.tar, level 13 with dict dms, advanced one pass, 37267 @@ -553,18 +553,18 @@ silesia, level 0, advanced silesia, level 1, advanced one pass small out, 5309098 silesia, level 3, advanced one pass small out, 4849553 silesia, level 4, advanced one pass small out, 4786968 -silesia, level 5 row 1, advanced one pass small out, 4640752 -silesia, level 5 row 2, advanced one pass small out, 4638961 +silesia, level 5 row 1, advanced one pass small out, 4638961 +silesia, level 5 row 2, advanced one pass small out, 4640752 silesia, level 5, advanced one pass small out, 4638961 silesia, level 6, advanced one pass small out, 4605369 -silesia, level 7 row 1, advanced one pass small out, 4564868 -silesia, level 7 row 2, advanced one pass small out, 4567204 +silesia, level 7 row 1, advanced one pass small out, 4567204 +silesia, level 7 row 2, advanced one pass small out, 4564868 silesia, level 7, advanced one pass small out, 4567204 silesia, level 9, advanced one pass small out, 4543310 -silesia, level 11 row 1, advanced one pass small out, 4519288 -silesia, level 11 row 2, advanced one pass small out, 4521399 -silesia, level 12 row 1, advanced one pass small out, 4503116 -silesia, level 12 row 2, advanced one pass small out, 4505153 +silesia, level 11 row 1, advanced one pass small out, 4521399 +silesia, level 11 row 2, advanced one pass small out, 4519288 +silesia, level 12 row 1, advanced one pass small out, 4505153 +silesia, level 12 row 2, advanced one pass small out, 4503116 silesia, level 13, advanced one pass small out, 4493990 silesia, level 16, advanced one pass small out, 4359864 silesia, level 19, advanced one pass small out, 4296880 @@ -587,18 +587,18 @@ silesia.tar, level 0, advanced silesia.tar, level 1, advanced one pass small out, 5331946 silesia.tar, level 3, advanced one pass small out, 4861424 silesia.tar, level 4, advanced one pass small out, 4799632 -silesia.tar, level 5 row 1, advanced one pass small out, 4652862 -silesia.tar, level 5 row 2, advanced one pass small out, 4650202 +silesia.tar, level 5 row 1, advanced one pass small out, 4650202 +silesia.tar, level 5 row 2, advanced one pass small out, 4652862 silesia.tar, level 5, advanced one pass small out, 4650202 silesia.tar, level 6, advanced one pass small out, 4616811 -silesia.tar, level 7 row 1, advanced one pass small out, 4575393 -silesia.tar, level 7 row 2, advanced one pass small out, 4576829 +silesia.tar, level 7 row 1, advanced one pass small out, 4576829 +silesia.tar, level 7 row 2, advanced one pass small out, 4575393 silesia.tar, level 7, advanced one pass small out, 4576829 silesia.tar, level 9, advanced one pass small out, 4552584 -silesia.tar, level 11 row 1, advanced one pass small out, 4529461 -silesia.tar, level 11 row 2, advanced one pass small out, 4530256 -silesia.tar, level 12 row 1, advanced one pass small out, 4513604 -silesia.tar, level 12 row 2, advanced one pass small out, 4514568 +silesia.tar, level 11 row 1, advanced one pass small out, 4530256 +silesia.tar, level 11 row 2, advanced one pass small out, 4529461 +silesia.tar, level 12 row 1, advanced one pass small out, 4514568 +silesia.tar, level 12 row 2, advanced one pass small out, 4513604 silesia.tar, level 13, advanced one pass small out, 4502956 silesia.tar, level 16, advanced one pass small out, 4360527 silesia.tar, level 19, advanced one pass small out, 4267266 @@ -644,16 +644,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced one pass small out, 41251 github, level 4 with dict copy, advanced one pass small out, 41216 github, level 4 with dict load, advanced one pass small out, 41159 -github, level 5 row 1, advanced one pass small out, 135121 -github, level 5 row 1 with dict dms, advanced one pass small out, 38938 -github, level 5 row 1 with dict dds, advanced one pass small out, 38732 -github, level 5 row 1 with dict copy, advanced one pass small out, 38934 -github, level 5 row 1 with dict load, advanced one pass small out, 40725 -github, level 5 row 2, advanced one pass small out, 134584 -github, level 5 row 2 with dict dms, advanced one pass small out, 38758 -github, level 5 row 2 with dict dds, advanced one pass small out, 38728 -github, level 5 row 2 with dict copy, advanced one pass small out, 38759 -github, level 5 row 2 with dict load, advanced one pass small out, 41518 +github, level 5 row 1, advanced one pass small out, 134584 +github, level 5 row 1 with dict dms, advanced one pass small out, 38758 +github, level 5 row 1 with dict dds, advanced one pass small out, 38728 +github, level 5 row 1 with dict copy, advanced one pass small out, 38759 +github, level 5 row 1 with dict load, advanced one pass small out, 41518 +github, level 5 row 2, advanced one pass small out, 135121 +github, level 5 row 2 with dict dms, advanced one pass small out, 38938 +github, level 5 row 2 with dict dds, advanced one pass small out, 38732 +github, level 5 row 2 with dict copy, advanced one pass small out, 38934 +github, level 5 row 2 with dict load, advanced one pass small out, 40725 github, level 5, advanced one pass small out, 135121 github, level 5 with dict, advanced one pass small out, 38758 github, level 5 with dict dms, advanced one pass small out, 38758 @@ -666,16 +666,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced one pass small out, 38636 github, level 6 with dict copy, advanced one pass small out, 38669 github, level 6 with dict load, advanced one pass small out, 40695 -github, level 7 row 1, advanced one pass small out, 135122 -github, level 7 row 1 with dict dms, advanced one pass small out, 38860 -github, level 7 row 1 with dict dds, advanced one pass small out, 38766 -github, level 7 row 1 with dict copy, advanced one pass small out, 38834 -github, level 7 row 1 with dict load, advanced one pass small out, 40695 -github, level 7 row 2, advanced one pass small out, 134584 -github, level 7 row 2 with dict dms, advanced one pass small out, 38758 -github, level 7 row 2 with dict dds, advanced one pass small out, 38745 -github, level 7 row 2 with dict copy, advanced one pass small out, 38755 -github, level 7 row 2 with dict load, advanced one pass small out, 43154 +github, level 7 row 1, advanced one pass small out, 134584 +github, level 7 row 1 with dict dms, advanced one pass small out, 38758 +github, level 7 row 1 with dict dds, advanced one pass small out, 38745 +github, level 7 row 1 with dict copy, advanced one pass small out, 38755 +github, level 7 row 1 with dict load, advanced one pass small out, 43154 +github, level 7 row 2, advanced one pass small out, 135122 +github, level 7 row 2 with dict dms, advanced one pass small out, 38860 +github, level 7 row 2 with dict dds, advanced one pass small out, 38766 +github, level 7 row 2 with dict copy, advanced one pass small out, 38834 +github, level 7 row 2 with dict load, advanced one pass small out, 40695 github, level 7, advanced one pass small out, 135122 github, level 7 with dict, advanced one pass small out, 38758 github, level 7 with dict dms, advanced one pass small out, 38758 @@ -769,16 +769,16 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass small out, 37954 github.tar, level 4 with dict copy, advanced one pass small out, 37948 github.tar, level 4 with dict load, advanced one pass small out, 37927 -github.tar, level 5 row 1, advanced one pass small out, 38534 -github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39365 -github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39233 -github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39715 -github.tar, level 5 row 1 with dict load, advanced one pass small out, 38019 -github.tar, level 5 row 2, advanced one pass small out, 38376 -github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39024 -github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39028 -github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39040 -github.tar, level 5 row 2 with dict load, advanced one pass small out, 37600 +github.tar, level 5 row 1, advanced one pass small out, 38376 +github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39024 +github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39028 +github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39040 +github.tar, level 5 row 1 with dict load, advanced one pass small out, 37600 +github.tar, level 5 row 2, advanced one pass small out, 38534 +github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39365 +github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39233 +github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39715 +github.tar, level 5 row 2 with dict load, advanced one pass small out, 38019 github.tar, level 5, advanced one pass small out, 38376 github.tar, level 5 with dict, advanced one pass small out, 39040 github.tar, level 5 with dict dms, advanced one pass small out, 39024 @@ -791,16 +791,16 @@ github.tar, level 6 with dict dms, advanced github.tar, level 6 with dict dds, advanced one pass small out, 38610 github.tar, level 6 with dict copy, advanced one pass small out, 38622 github.tar, level 6 with dict load, advanced one pass small out, 37829 -github.tar, level 7 row 1, advanced one pass small out, 38077 -github.tar, level 7 row 1 with dict dms, advanced one pass small out, 38012 -github.tar, level 7 row 1 with dict dds, advanced one pass small out, 38014 -github.tar, level 7 row 1 with dict copy, advanced one pass small out, 38101 -github.tar, level 7 row 1 with dict load, advanced one pass small out, 37402 -github.tar, level 7 row 2, advanced one pass small out, 38073 -github.tar, level 7 row 2 with dict dms, advanced one pass small out, 37848 -github.tar, level 7 row 2 with dict dds, advanced one pass small out, 37869 -github.tar, level 7 row 2 with dict copy, advanced one pass small out, 37848 -github.tar, level 7 row 2 with dict load, advanced one pass small out, 37371 +github.tar, level 7 row 1, advanced one pass small out, 38073 +github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37848 +github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37869 +github.tar, level 7 row 1 with dict copy, advanced one pass small out, 37848 +github.tar, level 7 row 1 with dict load, advanced one pass small out, 37371 +github.tar, level 7 row 2, advanced one pass small out, 38077 +github.tar, level 7 row 2 with dict dms, advanced one pass small out, 38012 +github.tar, level 7 row 2 with dict dds, advanced one pass small out, 38014 +github.tar, level 7 row 2 with dict copy, advanced one pass small out, 38101 +github.tar, level 7 row 2 with dict load, advanced one pass small out, 37402 github.tar, level 7, advanced one pass small out, 38073 github.tar, level 7 with dict, advanced one pass small out, 37848 github.tar, level 7 with dict dms, advanced one pass small out, 37848 @@ -817,22 +817,22 @@ github.tar, level 11 row 1, advanced github.tar, level 11 row 1 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass small out, 36419 +github.tar, level 11 row 1 with dict load, advanced one pass small out, 36424 github.tar, level 11 row 2, advanced one pass small out, 36435 github.tar, level 11 row 2 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 2 with dict load, advanced one pass small out, 36424 -github.tar, level 12 row 1, advanced one pass small out, 36110 +github.tar, level 11 row 2 with dict load, advanced one pass small out, 36419 +github.tar, level 12 row 1, advanced one pass small out, 36105 github.tar, level 12 row 1 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass small out, 36459 -github.tar, level 12 row 2, advanced one pass small out, 36105 +github.tar, level 12 row 1 with dict load, advanced one pass small out, 36460 +github.tar, level 12 row 2, advanced one pass small out, 36110 github.tar, level 12 row 2 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass small out, 36460 +github.tar, level 12 row 2 with dict load, advanced one pass small out, 36459 github.tar, level 13, advanced one pass small out, 35501 github.tar, level 13 with dict, advanced one pass small out, 37130 github.tar, level 13 with dict dms, advanced one pass small out, 37267 @@ -871,18 +871,18 @@ silesia, level 0, advanced silesia, level 1, advanced streaming, 5312694 silesia, level 3, advanced streaming, 4849553 silesia, level 4, advanced streaming, 4786968 -silesia, level 5 row 1, advanced streaming, 4640752 -silesia, level 5 row 2, advanced streaming, 4638961 +silesia, level 5 row 1, advanced streaming, 4638961 +silesia, level 5 row 2, advanced streaming, 4640752 silesia, level 5, advanced streaming, 4638961 silesia, level 6, advanced streaming, 4605369 -silesia, level 7 row 1, advanced streaming, 4564868 -silesia, level 7 row 2, advanced streaming, 4567204 +silesia, level 7 row 1, advanced streaming, 4567204 +silesia, level 7 row 2, advanced streaming, 4564868 silesia, level 7, advanced streaming, 4567204 silesia, level 9, advanced streaming, 4543310 -silesia, level 11 row 1, advanced streaming, 4519288 -silesia, level 11 row 2, advanced streaming, 4521399 -silesia, level 12 row 1, advanced streaming, 4503116 -silesia, level 12 row 2, advanced streaming, 4505153 +silesia, level 11 row 1, advanced streaming, 4521399 +silesia, level 11 row 2, advanced streaming, 4519288 +silesia, level 12 row 1, advanced streaming, 4505153 +silesia, level 12 row 2, advanced streaming, 4503116 silesia, level 13, advanced streaming, 4493990 silesia, level 16, advanced streaming, 4359864 silesia, level 19, advanced streaming, 4296880 @@ -905,18 +905,18 @@ silesia.tar, level 0, advanced silesia.tar, level 1, advanced streaming, 5334890 silesia.tar, level 3, advanced streaming, 4861426 silesia.tar, level 4, advanced streaming, 4799632 -silesia.tar, level 5 row 1, advanced streaming, 4652866 -silesia.tar, level 5 row 2, advanced streaming, 4650207 +silesia.tar, level 5 row 1, advanced streaming, 4650207 +silesia.tar, level 5 row 2, advanced streaming, 4652866 silesia.tar, level 5, advanced streaming, 4650207 silesia.tar, level 6, advanced streaming, 4616816 -silesia.tar, level 7 row 1, advanced streaming, 4575394 -silesia.tar, level 7 row 2, advanced streaming, 4576831 +silesia.tar, level 7 row 1, advanced streaming, 4576831 +silesia.tar, level 7 row 2, advanced streaming, 4575394 silesia.tar, level 7, advanced streaming, 4576831 silesia.tar, level 9, advanced streaming, 4552590 -silesia.tar, level 11 row 1, advanced streaming, 4529461 -silesia.tar, level 11 row 2, advanced streaming, 4530258 -silesia.tar, level 12 row 1, advanced streaming, 4513604 -silesia.tar, level 12 row 2, advanced streaming, 4514569 +silesia.tar, level 11 row 1, advanced streaming, 4530258 +silesia.tar, level 11 row 2, advanced streaming, 4529461 +silesia.tar, level 12 row 1, advanced streaming, 4514569 +silesia.tar, level 12 row 2, advanced streaming, 4513604 silesia.tar, level 13, advanced streaming, 4502956 silesia.tar, level 16, advanced streaming, 4360527 silesia.tar, level 19, advanced streaming, 4267266 @@ -962,16 +962,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced streaming, 41251 github, level 4 with dict copy, advanced streaming, 41216 github, level 4 with dict load, advanced streaming, 41159 -github, level 5 row 1, advanced streaming, 135121 -github, level 5 row 1 with dict dms, advanced streaming, 38938 -github, level 5 row 1 with dict dds, advanced streaming, 38732 -github, level 5 row 1 with dict copy, advanced streaming, 38934 -github, level 5 row 1 with dict load, advanced streaming, 40725 -github, level 5 row 2, advanced streaming, 134584 -github, level 5 row 2 with dict dms, advanced streaming, 38758 -github, level 5 row 2 with dict dds, advanced streaming, 38728 -github, level 5 row 2 with dict copy, advanced streaming, 38759 -github, level 5 row 2 with dict load, advanced streaming, 41518 +github, level 5 row 1, advanced streaming, 134584 +github, level 5 row 1 with dict dms, advanced streaming, 38758 +github, level 5 row 1 with dict dds, advanced streaming, 38728 +github, level 5 row 1 with dict copy, advanced streaming, 38759 +github, level 5 row 1 with dict load, advanced streaming, 41518 +github, level 5 row 2, advanced streaming, 135121 +github, level 5 row 2 with dict dms, advanced streaming, 38938 +github, level 5 row 2 with dict dds, advanced streaming, 38732 +github, level 5 row 2 with dict copy, advanced streaming, 38934 +github, level 5 row 2 with dict load, advanced streaming, 40725 github, level 5, advanced streaming, 135121 github, level 5 with dict, advanced streaming, 38758 github, level 5 with dict dms, advanced streaming, 38758 @@ -984,16 +984,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced streaming, 38636 github, level 6 with dict copy, advanced streaming, 38669 github, level 6 with dict load, advanced streaming, 40695 -github, level 7 row 1, advanced streaming, 135122 -github, level 7 row 1 with dict dms, advanced streaming, 38860 -github, level 7 row 1 with dict dds, advanced streaming, 38766 -github, level 7 row 1 with dict copy, advanced streaming, 38834 -github, level 7 row 1 with dict load, advanced streaming, 40695 -github, level 7 row 2, advanced streaming, 134584 -github, level 7 row 2 with dict dms, advanced streaming, 38758 -github, level 7 row 2 with dict dds, advanced streaming, 38745 -github, level 7 row 2 with dict copy, advanced streaming, 38755 -github, level 7 row 2 with dict load, advanced streaming, 43154 +github, level 7 row 1, advanced streaming, 134584 +github, level 7 row 1 with dict dms, advanced streaming, 38758 +github, level 7 row 1 with dict dds, advanced streaming, 38745 +github, level 7 row 1 with dict copy, advanced streaming, 38755 +github, level 7 row 1 with dict load, advanced streaming, 43154 +github, level 7 row 2, advanced streaming, 135122 +github, level 7 row 2 with dict dms, advanced streaming, 38860 +github, level 7 row 2 with dict dds, advanced streaming, 38766 +github, level 7 row 2 with dict copy, advanced streaming, 38834 +github, level 7 row 2 with dict load, advanced streaming, 40695 github, level 7, advanced streaming, 135122 github, level 7 with dict, advanced streaming, 38758 github, level 7 with dict dms, advanced streaming, 38758 @@ -1087,16 +1087,16 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced streaming, 37954 github.tar, level 4 with dict copy, advanced streaming, 37948 github.tar, level 4 with dict load, advanced streaming, 37927 -github.tar, level 5 row 1, advanced streaming, 38534 -github.tar, level 5 row 1 with dict dms, advanced streaming, 39365 -github.tar, level 5 row 1 with dict dds, advanced streaming, 39233 -github.tar, level 5 row 1 with dict copy, advanced streaming, 39715 -github.tar, level 5 row 1 with dict load, advanced streaming, 38019 -github.tar, level 5 row 2, advanced streaming, 38376 -github.tar, level 5 row 2 with dict dms, advanced streaming, 39024 -github.tar, level 5 row 2 with dict dds, advanced streaming, 39028 -github.tar, level 5 row 2 with dict copy, advanced streaming, 39040 -github.tar, level 5 row 2 with dict load, advanced streaming, 37600 +github.tar, level 5 row 1, advanced streaming, 38376 +github.tar, level 5 row 1 with dict dms, advanced streaming, 39024 +github.tar, level 5 row 1 with dict dds, advanced streaming, 39028 +github.tar, level 5 row 1 with dict copy, advanced streaming, 39040 +github.tar, level 5 row 1 with dict load, advanced streaming, 37600 +github.tar, level 5 row 2, advanced streaming, 38534 +github.tar, level 5 row 2 with dict dms, advanced streaming, 39365 +github.tar, level 5 row 2 with dict dds, advanced streaming, 39233 +github.tar, level 5 row 2 with dict copy, advanced streaming, 39715 +github.tar, level 5 row 2 with dict load, advanced streaming, 38019 github.tar, level 5, advanced streaming, 38376 github.tar, level 5 with dict, advanced streaming, 39040 github.tar, level 5 with dict dms, advanced streaming, 39024 @@ -1109,16 +1109,16 @@ github.tar, level 6 with dict dms, advanced github.tar, level 6 with dict dds, advanced streaming, 38610 github.tar, level 6 with dict copy, advanced streaming, 38622 github.tar, level 6 with dict load, advanced streaming, 37829 -github.tar, level 7 row 1, advanced streaming, 38077 -github.tar, level 7 row 1 with dict dms, advanced streaming, 38012 -github.tar, level 7 row 1 with dict dds, advanced streaming, 38014 -github.tar, level 7 row 1 with dict copy, advanced streaming, 38101 -github.tar, level 7 row 1 with dict load, advanced streaming, 37402 -github.tar, level 7 row 2, advanced streaming, 38073 -github.tar, level 7 row 2 with dict dms, advanced streaming, 37848 -github.tar, level 7 row 2 with dict dds, advanced streaming, 37869 -github.tar, level 7 row 2 with dict copy, advanced streaming, 37848 -github.tar, level 7 row 2 with dict load, advanced streaming, 37371 +github.tar, level 7 row 1, advanced streaming, 38073 +github.tar, level 7 row 1 with dict dms, advanced streaming, 37848 +github.tar, level 7 row 1 with dict dds, advanced streaming, 37869 +github.tar, level 7 row 1 with dict copy, advanced streaming, 37848 +github.tar, level 7 row 1 with dict load, advanced streaming, 37371 +github.tar, level 7 row 2, advanced streaming, 38077 +github.tar, level 7 row 2 with dict dms, advanced streaming, 38012 +github.tar, level 7 row 2 with dict dds, advanced streaming, 38014 +github.tar, level 7 row 2 with dict copy, advanced streaming, 38101 +github.tar, level 7 row 2 with dict load, advanced streaming, 37402 github.tar, level 7, advanced streaming, 38073 github.tar, level 7 with dict, advanced streaming, 37848 github.tar, level 7 with dict dms, advanced streaming, 37848 @@ -1135,22 +1135,22 @@ github.tar, level 11 row 1, advanced github.tar, level 11 row 1 with dict dms, advanced streaming, 36963 github.tar, level 11 row 1 with dict dds, advanced streaming, 36963 github.tar, level 11 row 1 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 1 with dict load, advanced streaming, 36419 +github.tar, level 11 row 1 with dict load, advanced streaming, 36424 github.tar, level 11 row 2, advanced streaming, 36435 github.tar, level 11 row 2 with dict dms, advanced streaming, 36963 github.tar, level 11 row 2 with dict dds, advanced streaming, 36963 github.tar, level 11 row 2 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 2 with dict load, advanced streaming, 36424 -github.tar, level 12 row 1, advanced streaming, 36110 +github.tar, level 11 row 2 with dict load, advanced streaming, 36419 +github.tar, level 12 row 1, advanced streaming, 36105 github.tar, level 12 row 1 with dict dms, advanced streaming, 36986 github.tar, level 12 row 1 with dict dds, advanced streaming, 36986 github.tar, level 12 row 1 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 1 with dict load, advanced streaming, 36459 -github.tar, level 12 row 2, advanced streaming, 36105 +github.tar, level 12 row 1 with dict load, advanced streaming, 36460 +github.tar, level 12 row 2, advanced streaming, 36110 github.tar, level 12 row 2 with dict dms, advanced streaming, 36986 github.tar, level 12 row 2 with dict dds, advanced streaming, 36986 github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 2 with dict load, advanced streaming, 36460 +github.tar, level 12 row 2 with dict load, advanced streaming, 36459 github.tar, level 13, advanced streaming, 35501 github.tar, level 13 with dict, advanced streaming, 37130 github.tar, level 13 with dict dms, advanced streaming, 37267 From 06f42c3bfd1b0d3393c7c8d7a1a53e27e167750b Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 21 Sep 2021 11:56:02 -0400 Subject: [PATCH 166/274] Use new paramSwitch enum for LDM --- lib/compress/zstd_compress.c | 57 ++++++++++++--------------- lib/compress/zstd_compress_internal.h | 2 +- lib/compress/zstd_ldm.c | 4 +- lib/compress/zstdmt_compress.c | 20 +++++----- 4 files changed, 38 insertions(+), 45 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 700f4567f..6ca4784fd 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -272,8 +272,10 @@ static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, * enable long distance matching (wlog >= 27, strategy >= btopt). * Returns 0 otherwise. */ -static U32 ZSTD_CParams_shouldEnableLdm(const ZSTD_compressionParameters* const cParams) { - return cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27; +static ZSTD_paramSwitch_e ZSTD_resolveEnableLdm(ZSTD_paramSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable; } static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( @@ -285,15 +287,12 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( cctxParams.cParams = cParams; /* Adjust advanced params according to cParams */ - if (ZSTD_CParams_shouldEnableLdm(&cParams)) { - DEBUGLOG(4, "ZSTD_makeCCtxParamsFromCParams(): Including LDM into cctx params"); - cctxParams.ldmParams.enableLdm = 1; - /* LDM is enabled by default for optimal parser and window size >= 128MB */ + cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams); + if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) { ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams); assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog); assert(cctxParams.ldmParams.hashRateLog < 32); } - cctxParams.useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.useBlockSplitter, &cParams); cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); assert(!ZSTD_checkCParams(cParams)); @@ -356,13 +355,9 @@ static void ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, ZSTD_par cctxParams->compressionLevel = compressionLevel; cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams); cctxParams->useBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->useBlockSplitter, ¶ms->cParams); - DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d", cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter); - - if (ZSTD_CParams_shouldEnableLdm(¶ms->cParams)) { - /* Enable LDM by default for optimal parser and window size >= 128MB */ - DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)"); - cctxParams->ldmParams.enableLdm = 1; - } + cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, ¶ms->cParams); + DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d", + cctxParams->useRowMatchFinder, cctxParams->useBlockSplitter, cctxParams->ldmParams.enableLdm); } size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) @@ -849,7 +844,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, return CCtxParams->enableDedicatedDictSearch; case ZSTD_c_enableLongDistanceMatching : - CCtxParams->ldmParams.enableLdm = (value!=0); + CCtxParams->ldmParams.enableLdm = (ZSTD_paramSwitch_e)value; return CCtxParams->ldmParams.enableLdm; case ZSTD_c_ldmHashLog : @@ -1412,7 +1407,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( srcSizeHint = CCtxParams->srcSizeHint; } cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode); - if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; + if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; ZSTD_overrideCParams(&cParams, &CCtxParams->cParams); assert(!ZSTD_checkCParams(cParams)); /* srcSizeHint == 0 means 0 */ @@ -1483,7 +1478,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams); size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize); - size_t const ldmSeqSpace = ldmParams->enableLdm ? + size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ? ZSTD_cwksp_aligned_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0; @@ -1852,7 +1847,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, assert(params->useRowMatchFinder != ZSTD_ps_auto); assert(params->useBlockSplitter != ZSTD_ps_auto); - if (params->ldmParams.enableLdm) { + assert(params->ldmParams.enableLdm != ZSTD_ps_auto); + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { /* Adjust long distance matching parameters */ ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, ¶ms->cParams); assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog); @@ -1952,7 +1948,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize); /* ldm bucketOffsets table */ - if (params->ldmParams.enableLdm) { + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { /* TODO: avoid memset? */ size_t const numBuckets = ((size_t)1) << (params->ldmParams.hashLog - @@ -1979,7 +1975,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, ZSTD_resetTarget_CCtx), ""); /* ldm hash table */ - if (params->ldmParams.enableLdm) { + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { /* TODO: avoid memset? */ size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t)); @@ -2226,8 +2222,10 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, params.cParams = srcCCtx->appliedParams.cParams; assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto); assert(srcCCtx->appliedParams.useBlockSplitter != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto); params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder; params.useBlockSplitter = srcCCtx->appliedParams.useBlockSplitter; + params.ldmParams = srcCCtx->appliedParams.ldmParams; params.fParams = fParams; ZSTD_resetCCtx_internal(dstCCtx, ¶ms, pledgedSrcSize, /* loadedDictSize */ 0, @@ -2849,7 +2847,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; } if (zc->externSeqStore.pos < zc->externSeqStore.size) { - assert(!zc->appliedParams.ldmParams.enableLdm); + assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable); /* Updates ldmSeqStore.pos */ lastLLSize = ZSTD_ldm_blockCompress(&zc->externSeqStore, @@ -2858,7 +2856,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) zc->appliedParams.useRowMatchFinder, src, srcSize); assert(zc->externSeqStore.pos <= zc->externSeqStore.size); - } else if (zc->appliedParams.ldmParams.enableLdm) { + } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { rawSeqStore_t ldmSeqStore = kNullRawSeqStore; ldmSeqStore.seq = zc->ldmSequences; @@ -4081,7 +4079,7 @@ size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSe { RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong, "wrong cctx stage"); - RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm, + RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable, parameter_unsupported, "incompatible with ldm"); cctx->externSeqStore.seq = seq; @@ -4122,7 +4120,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, ms->forceNonContiguous = 0; ms->nextToUpdate = ms->window.dictLimit; } - if (cctx->appliedParams.ldmParams.enableLdm) { + if (cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0); } @@ -4191,7 +4189,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, { const BYTE* ip = (const BYTE*) src; const BYTE* const iend = ip + srcSize; - int const loadLdmDict = params->ldmParams.enableLdm && ls != NULL; + int const loadLdmDict = params->ldmParams.enableLdm == ZSTD_ps_enable && ls != NULL; /* Assert that we the ms params match the params we're being given */ ZSTD_assertEqualCParams(params->cParams, ms->cParams); @@ -5557,14 +5555,9 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, ¶ms, cctx->pledgedSrcSizePlusOne-1, dictSize, mode); } - - if (ZSTD_CParams_shouldEnableLdm(¶ms.cParams)) { - /* Enable LDM by default for optimal parser and window size >= 128MB */ - DEBUGLOG(4, "LDM enabled by default (window size >= 128MB, strategy >= btopt)"); - params.ldmParams.enableLdm = 1; - } - + params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, ¶ms.cParams); + params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, ¶ms.cParams); params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, ¶ms.cParams); #ifdef ZSTD_MULTITHREAD diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index c168c67e7..b7772522a 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -266,7 +266,7 @@ typedef struct { } ldmState_t; typedef struct { - U32 enableLdm; /* 1 if enable long distance matching */ + ZSTD_paramSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */ U32 hashLog; /* Log size of hashTable */ U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */ U32 minMatchLength; /* Minimum match length */ diff --git a/lib/compress/zstd_ldm.c b/lib/compress/zstd_ldm.c index c97b97a03..45eebccec 100644 --- a/lib/compress/zstd_ldm.c +++ b/lib/compress/zstd_ldm.c @@ -159,12 +159,12 @@ size_t ZSTD_ldm_getTableSize(ldmParams_t params) size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog); size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize) + ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t)); - return params.enableLdm ? totalSize : 0; + return params.enableLdm == ZSTD_ps_enable ? totalSize : 0; } size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize) { - return params.enableLdm ? (maxChunkSize / params.minMatchLength) : 0; + return params.enableLdm == ZSTD_ps_enable ? (maxChunkSize / params.minMatchLength) : 0; } /** ZSTD_ldm_getBucket() : diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 19e8ce427..2aec41dda 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -467,7 +467,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState, ZSTD_dictContentType_e dictContentType) { /* Adjust parameters */ - if (params.ldmParams.enableLdm) { + if (params.ldmParams.enableLdm == ZSTD_ps_enable) { DEBUGLOG(4, "LDM window size = %u KB", (1U << params.cParams.windowLog) >> 10); ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams); assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog); @@ -478,7 +478,7 @@ ZSTDMT_serialState_reset(serialState_t* serialState, serialState->nextJobID = 0; if (params.fParams.checksumFlag) XXH64_reset(&serialState->xxhState, 0); - if (params.ldmParams.enableLdm) { + if (params.ldmParams.enableLdm == ZSTD_ps_enable) { ZSTD_customMem cMem = params.customMem; unsigned const hashLog = params.ldmParams.hashLog; size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t); @@ -564,7 +564,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState, /* A future job may error and skip our job */ if (serialState->nextJobID == jobID) { /* It is now our turn, do any processing necessary */ - if (serialState->params.ldmParams.enableLdm) { + if (serialState->params.ldmParams.enableLdm == ZSTD_ps_enable) { size_t error; assert(seqStore.seq != NULL && seqStore.pos == 0 && seqStore.size == 0 && seqStore.capacity > 0); @@ -594,7 +594,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState, if (seqStore.size > 0) { size_t const err = ZSTD_referenceExternalSequences( jobCCtx, seqStore.seq, seqStore.size); - assert(serialState->params.ldmParams.enableLdm); + assert(serialState->params.ldmParams.enableLdm == ZSTD_ps_enable); assert(!ZSTD_isError(err)); (void)err; } @@ -672,7 +672,7 @@ static void ZSTDMT_compressionJob(void* jobDescription) if (dstBuff.start==NULL) JOB_ERROR(ERROR(memory_allocation)); job->dstBuff = dstBuff; /* this value can be read in ZSTDMT_flush, when it copies the whole job */ } - if (jobParams.ldmParams.enableLdm && rawSeqStore.seq == NULL) + if (jobParams.ldmParams.enableLdm == ZSTD_ps_enable && rawSeqStore.seq == NULL) JOB_ERROR(ERROR(memory_allocation)); /* Don't compute the checksum for chunks, since we compute it externally, @@ -680,7 +680,7 @@ static void ZSTDMT_compressionJob(void* jobDescription) */ if (job->jobID != 0) jobParams.fParams.checksumFlag = 0; /* Don't run LDM for the chunks, since we handle it externally */ - jobParams.ldmParams.enableLdm = 0; + jobParams.ldmParams.enableLdm = ZSTD_ps_disable; /* Correct nbWorkers to 0. */ jobParams.nbWorkers = 0; @@ -1144,7 +1144,7 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx) static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params) { unsigned jobLog; - if (params->ldmParams.enableLdm) { + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { /* In Long Range Mode, the windowLog is typically oversized. * In which case, it's preferable to determine the jobSize * based on cycleLog instead. */ @@ -1188,7 +1188,7 @@ static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params) int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy); int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog); assert(0 <= overlapRLog && overlapRLog <= 8); - if (params->ldmParams.enableLdm) { + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { /* In Long Range Mode, the windowLog is typically oversized. * In which case, it's preferable to determine the jobSize * based on chainLog instead. @@ -1275,7 +1275,7 @@ size_t ZSTDMT_initCStream_internal( ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(mtctx->targetSectionSize)); { /* If ldm is enabled we need windowSize space. */ - size_t const windowSize = mtctx->params.ldmParams.enableLdm ? (1U << mtctx->params.cParams.windowLog) : 0; + size_t const windowSize = mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable ? (1U << mtctx->params.cParams.windowLog) : 0; /* Two buffers of slack, plus extra space for the overlap * This is the minimum slack that LDM works with. One extra because * flush might waste up to targetSectionSize-1 bytes. Another extra @@ -1587,7 +1587,7 @@ static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window) static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer) { - if (mtctx->params.ldmParams.enableLdm) { + if (mtctx->params.ldmParams.enableLdm == ZSTD_ps_enable) { ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex; DEBUGLOG(5, "ZSTDMT_waitForLdmComplete"); DEBUGLOG(5, "source [0x%zx, 0x%zx)", From 9450876a9df0abe967dd6f0751785b2e4e5981fc Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 21 Sep 2021 16:36:33 -0700 Subject: [PATCH 167/274] [huf] Fix compilation when DYNAMIC_BMI2=0 && BMI2 is supported * Fix compilation issues pointed out in PR #2790. * Add test cases to GitHub actions that test all combinations of `DYNAMIC_BMI2` BMI2 support. --- .github/workflows/dev-short-tests.yml | 12 ++++++++++++ lib/decompress/huf_decompress.c | 20 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 5d7e54b51..056f5cbf1 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -200,6 +200,18 @@ jobs: make clean && make -j all MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" make clean && make check MOREFLAGS="-Werror -DZSTD_NO_INLINE -DZSTD_STRIP_ERROR_STRINGS" + dynamic-bmi2: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: dynamic bmi2 tests + run: | + make clean && make -j check MOREFLAGS="-O0 -Werror -mbmi2" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=1" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=1 -mbmi2" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=0" + make clean && make -j check MOREFLAGS="-O0 -Werror -DDYNAMIC_BMI2=0 -mbmi2" + test-variants: runs-on: ubuntu-latest steps: diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 1dfa4b801..2efca7dd5 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -78,6 +78,18 @@ #endif #define HUF_ASM_DECL HUF_EXTERN_C +#if DYNAMIC_BMI2 || (HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)) +# define HUF_NEED_BMI2_FUNCTION 1 +#else +# define HUF_NEED_BMI2_FUNCTION 0 +#endif + +#if !(HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)) +# define HUF_NEED_DEFAULT_FUNCTION 1 +#else +# define HUF_NEED_DEFAULT_FUNCTION 0 +#endif + /* ************************************************************** * Error Management ****************************************************************/ @@ -653,7 +665,7 @@ HUF_decompress4X1_usingDTable_internal_body( } } -#if DYNAMIC_BMI2 +#if HUF_NEED_BMI2_FUNCTION static TARGET_ATTRIBUTE("bmi2") size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, size_t cSrcSize, HUF_DTable const* DTable) { @@ -661,11 +673,13 @@ size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, vo } #endif +#if HUF_NEED_DEFAULT_FUNCTION static size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, size_t cSrcSize, HUF_DTable const* DTable) { return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); } +#endif #if HUF_ENABLE_ASM_X86_64_BMI2 @@ -1365,7 +1379,7 @@ HUF_decompress4X2_usingDTable_internal_body( } } -#if DYNAMIC_BMI2 +#if HUF_NEED_BMI2_FUNCTION static TARGET_ATTRIBUTE("bmi2") size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, size_t cSrcSize, HUF_DTable const* DTable) { @@ -1373,11 +1387,13 @@ size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, vo } #endif +#if HUF_NEED_DEFAULT_FUNCTION static size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, size_t cSrcSize, HUF_DTable const* DTable) { return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); } +#endif #if HUF_ENABLE_ASM_X86_64_BMI2 From 99b5e7b8c28875d0df998be2a4598d2358e37f23 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 22 Sep 2021 11:27:56 -0400 Subject: [PATCH 168/274] Add test case for FSE over-write --- tests/fuzzer.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/fuzzer.c b/tests/fuzzer.c index fff963176..49f671d17 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -3353,6 +3353,23 @@ static int basicUnitTests(U32 const seed, double compressibility) FSE_normalizeCount(norm, tableLog, count, nbSeq, maxSymbolValue, /* useLowProbCount */ 1); } DISPLAYLEVEL(3, "OK \n"); + + DISPLAYLEVEL(3, "test%3i : testing FSE_writeNCount() PR#2779: ", testNb++); + { + size_t const outBufSize = 9; + short const count[11] = {1, 0, 1, 0, 1, 0, 1, 0, 1, 9, 18}; + unsigned const tableLog = 5; + unsigned const maxSymbolValue = 10; + BYTE* outBuf = (BYTE*)malloc(outBufSize*sizeof(BYTE)); + + /* Ensure that this write doesn't write out of bounds, and that + * FSE_writeNCount_generic() is *not* called with writeIsSafe == 1. + */ + FSE_writeNCount(outBuf, outBufSize, count, maxSymbolValue, tableLog); + free(outBuf); + } + DISPLAYLEVEL(3, "OK \n"); + #ifdef ZSTD_MULTITHREAD DISPLAYLEVEL(3, "test%3i : passing wrong full dict should fail on compressStream2 refPrefix ", testNb++); { ZSTD_CCtx* cctx = ZSTD_createCCtx(); From 2832bbbbdce74325215c0960ae293e27b0aa7df1 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 22 Sep 2021 14:00:20 -0700 Subject: [PATCH 169/274] emphasize usage of -r in documentation notably as a way to overcome shell expansion limitations, notably in a scenario of dictionary training. --- programs/zstd.1.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/programs/zstd.1.md b/programs/zstd.1.md index 066bcb83c..f1c4b5fcd 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -224,7 +224,11 @@ the last one takes effect. keep source file(s) after successful compression or decompression. This is the default behavior. * `-r`: - operate recursively on directories + operate recursively on directories. + It selects all files in the named directory and all its subdirectories. + This can be useful both to reduce command line typing, + and to circumvent shell expansion limitations, + when there are a lot of files and naming breaks the maximum size of a command line. * `--filelist FILE` read a list of files to process as content from `FILE`. Format is compatible with `ls` output, with one file per line. @@ -307,12 +311,14 @@ Compression of small files similar to the sample set will be greatly improved. The training set should contain a lot of small files (> 100), and weight typically 100x the target dictionary size (for example, 10 MB for a 100 KB dictionary). + `--train` can be combined with `-r` to indicate a directory rather than listing all the files, + which can be useful to circumvent shell expansion limits. - Supports multithreading if `zstd` is compiled with threading support. + `--train` supports multithreading if `zstd` is compiled with threading support (default). Additional parameters can be specified with `--train-fastcover`. The legacy dictionary builder can be accessed with `--train-legacy`. - The cover dictionary builder can be accessed with `--train-cover`. - Equivalent to `--train-fastcover=d=8,steps=4`. + The slower cover dictionary builder can be accessed with `--train-cover`. + Default is equivalent to `--train-fastcover=d=8,steps=4`. * `-o file`: Dictionary saved into `file` (default name: dictionary). * `--maxdict=#`: @@ -322,10 +328,10 @@ Compression of small files similar to the sample set will be greatly improved. Will generate statistics more tuned for selected compression level, resulting in a _small_ compression ratio improvement for this level. * `-B#`: - Split input files in blocks of size # (default: no split) + Split input files into blocks of size # (default: no split) * `--dictID=#`: - A dictionary ID is a locally unique ID that a decoder can use to verify it is - using the right dictionary. + A dictionary ID is a locally unique ID + that a decoder can use to verify it is using the right dictionary. By default, zstd will create a 4-bytes random number ID. It's possible to give a precise number instead. Short numbers have an advantage : an ID < 256 will only need 1 byte in the From 999f8778afda7149aa9974e9850a2b9a51a860ff Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 22 Sep 2021 14:18:24 -0700 Subject: [PATCH 170/274] updated man pages using ronn-ng --- programs/zstd.1 | 259 +++++++++----------------------------------- programs/zstdgrep.1 | 23 ---- programs/zstdless.1 | 14 --- 3 files changed, 54 insertions(+), 242 deletions(-) diff --git a/programs/zstd.1 b/programs/zstd.1 index 861f9380b..0810ec999 100644 --- a/programs/zstd.1 +++ b/programs/zstd.1 @@ -1,491 +1,340 @@ -. -.TH "ZSTD" "1" "May 2021" "zstd 1.5.0" "User Commands" -. +.TH "ZSTD" "1" "September 2021" "zstd 1.5.1" "User Commands" .SH "NAME" \fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files -. .SH "SYNOPSIS" -\fBzstd\fR [\fIOPTIONS\fR] [\-|\fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR] -. +.TS +allbox; +\fBzstd\fR [\fIOPTIONS\fR] [\- \fIINPUT\-FILE\fR] [\-o \fIOUTPUT\-FILE\fR] +.TE .P \fBzstdmt\fR is equivalent to \fBzstd \-T0\fR -. .P \fBunzstd\fR is equivalent to \fBzstd \-d\fR -. .P \fBzstdcat\fR is equivalent to \fBzstd \-dcf\fR -. .SH "DESCRIPTION" \fBzstd\fR is a fast lossless compression algorithm and data compression tool, with command line syntax similar to \fBgzip (1)\fR and \fBxz (1)\fR\. It is based on the \fBLZ77\fR family, with further FSE & huff0 entropy stages\. \fBzstd\fR offers highly configurable compression speed, with fast modes at > 200 MB/s per core, and strong modes nearing lzma compression ratios\. It also features a very fast decoder, with speeds > 500 MB/s per core\. -. .P \fBzstd\fR command line syntax is generally similar to gzip, but features the following differences : -. -.IP "\(bu" 4 +.IP "\[ci]" 4 Source files are preserved by default\. It\'s possible to remove them automatically by using the \fB\-\-rm\fR command\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 When compressing a single file, \fBzstd\fR displays progress notifications and result summary by default\. Use \fB\-q\fR to turn them off\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fBzstd\fR does not accept input from console, but it properly accepts \fBstdin\fR when it\'s not the console\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fBzstd\fR displays a short help page when command line is an error\. Use \fB\-q\fR to turn it off\. -. .IP "" 0 -. .P \fBzstd\fR compresses or decompresses each \fIfile\fR according to the selected operation mode\. If no \fIfiles\fR are given or \fIfile\fR is \fB\-\fR, \fBzstd\fR reads from standard input and writes the processed data to standard output\. \fBzstd\fR will refuse to write compressed data to standard output if it is a terminal : it will display an error message and skip the \fIfile\fR\. Similarly, \fBzstd\fR will refuse to read compressed data from standard input if it is a terminal\. -. .P Unless \fB\-\-stdout\fR or \fB\-o\fR is specified, \fIfiles\fR are written to a new file whose name is derived from the source \fIfile\fR name: -. -.IP "\(bu" 4 +.IP "\[ci]" 4 When compressing, the suffix \fB\.zst\fR is appended to the source filename to get the target filename\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 When decompressing, the \fB\.zst\fR suffix is removed from the source filename to get the target filename -. .IP "" 0 -. .SS "Concatenation with \.zst files" It is possible to concatenate \fB\.zst\fR files as is\. \fBzstd\fR will decompress such files as if they were a single \fB\.zst\fR file\. -. .SH "OPTIONS" -. .SS "Integer suffixes and special values" In most places where an integer argument is expected, an optional suffix is supported to easily indicate large integers\. There must be no space between the integer and the suffix\. -. .TP \fBKiB\fR -Multiply the integer by 1,024 (2^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\. -. +Multiply the integer by 1,024 (2\e^10)\. \fBKi\fR, \fBK\fR, and \fBKB\fR are accepted as synonyms for \fBKiB\fR\. .TP \fBMiB\fR -Multiply the integer by 1,048,576 (2^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\. -. +Multiply the integer by 1,048,576 (2\e^20)\. \fBMi\fR, \fBM\fR, and \fBMB\fR are accepted as synonyms for \fBMiB\fR\. .SS "Operation mode" If multiple operation mode options are given, the last one takes effect\. -. .TP \fB\-z\fR, \fB\-\-compress\fR Compress\. This is the default operation mode when no operation mode option is specified and no other operation mode is implied from the command name (for example, \fBunzstd\fR implies \fB\-\-decompress\fR)\. -. .TP \fB\-d\fR, \fB\-\-decompress\fR, \fB\-\-uncompress\fR Decompress\. -. .TP \fB\-t\fR, \fB\-\-test\fR Test the integrity of compressed \fIfiles\fR\. This option is equivalent to \fB\-\-decompress \-\-stdout\fR except that the decompressed data is discarded instead of being written to standard output\. No files are created or removed\. -. .TP \fB\-b#\fR Benchmark file(s) using compression level # -. .TP \fB\-\-train FILEs\fR Use FILEs as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. -. .TP \fB\-l\fR, \fB\-\-list\fR Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command can be augmented with the \fB\-v\fR modifier\. -. .SS "Operation modifiers" -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-#\fR: \fB#\fR compression level [1\-19] (default: 3) -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-ultra\fR: unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-fast[=#]\fR: switch to ultra\-fast compression levels\. If \fB=#\fR is not present, it defaults to \fB1\fR\. The higher the value, the faster the compression speed, at the cost of some compression ratio\. This setting overwrites compression level if one was set previously\. Similarly, if a compression level is set after \fB\-\-fast\fR, it overrides it\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-T#\fR, \fB\-\-threads=#\fR: Compress using \fB#\fR working threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to \fBZSTDMT_NBWORKERS_MAX\fR, which is either 64 in 32\-bit mode, or 256 for 64\-bit environments\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-single\-thread\fR: Does not spawn a thread for compression, use a single thread for both I/O and compression\. In this mode, compression is serialized with I/O, which is slightly slower\. (This is different from \fB\-T1\fR, which spawns 1 compression thread in parallel of I/O)\. This mode is the only one available when multithread support is disabled\. Single\-thread mode features lower memory usage\. Final compressed result is slightly different from \fB\-T1\fR\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 +\fB\-\-auto\-threads={physical,logical} (default: physical)\fR: When using a default amount of threads via \fB\-T0\fR, choose the default based on the number of detected physical or logical cores\. +.IP "\[ci]" 4 \fB\-\-adapt[=min=#,max=#]\fR : \fBzstd\fR will dynamically adapt compression level to perceived I/O conditions\. Compression level adaptation can be observed live by using command \fB\-v\fR\. Adaptation can be constrained between supplied \fBmin\fR and \fBmax\fR levels\. The feature works when combined with multi\-threading and \fB\-\-long\fR mode\. It does not work with \fB\-\-single\-thread\fR\. It sets window size to 8 MB by default (can be changed manually, see \fBwlog\fR)\. Due to the chaotic nature of dynamic adaptation, compressed result is not reproducible\. \fInote\fR : at the time of this writing, \fB\-\-adapt\fR can remain stuck at low speed when combined with multiple worker threads (>=2)\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-long[=#]\fR: enables long distance matching with \fB#\fR \fBwindowLog\fR, if not \fB#\fR is not present it defaults to \fB27\fR\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance\. -. .IP Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-D DICT\fR: use \fBDICT\fR as Dictionary to compress or decompress FILE(s) -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-patch\-from FILE\fR: Specify the file to be used as a reference point for zstd\'s diff engine\. This is effectively dictionary compression with some convenient parameter selection, namely that windowSize > srcSize\. -. .IP Note: cannot use both this and \-D together Note: \fB\-\-long\fR mode will be automatically activated if chainLog < fileLog (fileLog being the windowLog required to cover the whole file)\. You can also manually force it\. Node: for all levels, you can use \-\-patch\-from in \-\-single\-thread mode to improve compression ratio at the cost of speed Note: for level 19, you can get increased compression ratio at the cost of speed by specifying \fB\-\-zstd=targetLength=\fR to be something large (i\.e 4096), and by setting a large \fB\-\-zstd=chainLog=\fR -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-rsyncable\fR : \fBzstd\fR will periodically synchronize the compression state to make the compressed file more rsync\-friendly\. There is a negligible impact to compression ratio, and the faster compression levels will see a small compression speed hit\. This feature does not work with \fB\-\-single\-thread\fR\. You probably don\'t want to use it with long range mode, since it will decrease the effectiveness of the synchronization points, but your milage may vary\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-C\fR, \fB\-\-[no\-]check\fR: add integrity check computed from uncompressed data (default: enabled) -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-[no\-]content\-size\fR: enable / disable whether or not the original size of the file is placed in the header of the compressed file\. The default option is \-\-content\-size (meaning that the original size will be placed in the header)\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-no\-dictID\fR: do not store dictionary ID within frame header (dictionary compression)\. The decoder will have to rely on implicit knowledge about which dictionary to use, it won\'t be able to check if it\'s correct\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-M#\fR, \fB\-\-memory=#\fR: Set a memory usage limit\. By default, Zstandard uses 128 MB for decompression as the maximum amount of memory the decompressor is allowed to use, but you can override this manually if need be in either direction (ie\. you can increase or decrease it)\. -. .IP This is also used during compression when using with \-\-patch\-from=\. In this case, this parameter overrides that maximum size allowed for a dictionary\. (128 MB)\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-stream\-size=#\fR : Sets the pledged source size of input coming from a stream\. This value must be exact, as it will be included in the produced frame header\. Incorrect stream sizes will cause an error\. This information will be used to better optimize compression parameters, resulting in better and potentially faster compression, especially for smaller source sizes\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-size\-hint=#\fR: When handling input from a stream, \fBzstd\fR must guess how large the source size will be when optimizing compression parameters\. If the stream size is relatively small, this guess may be a poor one, resulting in a higher compression ratio than expected\. This feature allows for controlling the guess when needed\. Exact guesses result in better compression ratios\. Overestimates result in slightly degraded compression ratios, while underestimates may result in significant degradation\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-o FILE\fR: save result into \fBFILE\fR -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-rm\fR: remove source file(s) after successful compression or decompression\. If used in combination with \-o, will trigger a confirmation prompt (which can be silenced with \-f), as this is a destructive operation\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-k\fR, \fB\-\-keep\fR: keep source file(s) after successful compression or decompression\. This is the default behavior\. -. -.IP "\(bu" 4 -\fB\-r\fR: operate recursively on directories -. -.IP "\(bu" 4 +.IP "\[ci]" 4 +\fB\-r\fR: operate recursively on directories\. It selects all files in the named directory and all its subdirectories\. This can be useful both to reduce command line typing, and to circumvent shell expansion limitations, when there are a lot of files and naming breaks the maximum size of a command line\. +.IP "\[ci]" 4 \fB\-\-filelist FILE\fR read a list of files to process as content from \fBFILE\fR\. Format is compatible with \fBls\fR output, with one file per line\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-output\-dir\-flat DIR\fR: resulting files are stored into target \fBDIR\fR directory, instead of same directory as origin file\. Be aware that this command can introduce name collision issues, if multiple files, from different directories, end up having the same name\. Collision resolution ensures first file with a given name will be present in \fBDIR\fR, while in combination with \fB\-f\fR, the last file will be present instead\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-output\-dir\-mirror DIR\fR: similar to \fB\-\-output\-dir\-flat\fR, the output files are stored underneath target \fBDIR\fR directory, but this option will replicate input directory hierarchy into output \fBDIR\fR\. -. .IP If input directory contains "\.\.", the files in this directory will be ignored\. If input directory is an absolute directory (i\.e\. "/var/tmp/abc"), it will be stored into the "output\-dir/var/tmp/abc"\. If there are multiple input files or directories, name collision resolution will follow the same rules as \fB\-\-output\-dir\-flat\fR\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-format=FORMAT\fR: compress and decompress in other formats\. If compiled with support, zstd can compress to or decompress from other compression algorithm formats\. Possibly available options are \fBzstd\fR, \fBgzip\fR, \fBxz\fR, \fBlzma\fR, and \fBlz4\fR\. If no such format is provided, \fBzstd\fR is the default\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-h\fR/\fB\-H\fR, \fB\-\-help\fR: display help/long help and exit -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-V\fR, \fB\-\-version\fR: display version number and exit\. Advanced : \fB\-vV\fR also displays supported formats\. \fB\-vvV\fR also displays POSIX support\. \fB\-q\fR will only display the version number, suitable for machine reading\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-v\fR, \fB\-\-verbose\fR: verbose mode, display more information -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-q\fR, \fB\-\-quiet\fR: suppress warnings, interactivity, and notifications\. specify twice to suppress errors too\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-no\-progress\fR: do not display the progress bar, but keep all other messages\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-show\-default\-cparams\fR: Shows the default compression parameters that will be used for a particular src file\. If the provided src file is not a regular file (eg\. named pipe), the cli will just output the default parameters\. That is, the parameters that are used when the src size is unknown\. -. -.IP "\(bu" 4 +.IP "\[ci]" 4 \fB\-\-\fR: All arguments after \fB\-\-\fR are treated as files -. .IP "" 0 -. .SS "Restricted usage of Environment Variables" Using environment variables to set parameters has security implications\. Therefore, this avenue is intentionally restricted\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the compression level and number of threads to use during compression, respectively\. -. .P \fBZSTD_CLEVEL\fR can be used to set the level between 1 and 19 (the "normal" range)\. If the value of \fBZSTD_CLEVEL\fR is not a valid integer, it will be ignored with a warning message\. \fBZSTD_CLEVEL\fR just replaces the default compression level (\fB3\fR)\. -. .P \fBZSTD_NBTHREADS\fR can be used to set the number of threads \fBzstd\fR will attempt to use during compression\. If the value of \fBZSTD_NBTHREADS\fR is not a valid unsigned integer, it will be ignored with a warning message\. \fBZSTD_NBTHREADS\fR has a default value of (\fB1\fR), and is capped at ZSTDMT_NBWORKERS_MAX==200\. \fBzstd\fR must be compiled with multithread support for this to have any effect\. -. .P They can both be overridden by corresponding command line arguments: \fB\-#\fR for compression level and \fB\-T#\fR for number of compression threads\. -. .SH "DICTIONARY BUILDER" \fBzstd\fR offers \fIdictionary\fR compression, which greatly improves efficiency on small files and messages\. It\'s possible to train \fBzstd\fR with a set of samples, the result of which is saved into a file called a \fBdictionary\fR\. Then during compression and decompression, reference the same dictionary, using command \fB\-D dictionaryFileName\fR\. Compression of small files similar to the sample set will be greatly improved\. -. .TP \fB\-\-train FILEs\fR -Use FILEs as training set to create a dictionary\. The training set should contain a lot of small files (> 100), and weight typically 100x the target dictionary size (for example, 10 MB for a 100 KB dictionary)\. -. +Use FILEs as training set to create a dictionary\. The training set should contain a lot of small files (> 100), and weight typically 100x the target dictionary size (for example, 10 MB for a 100 KB dictionary)\. \fB\-\-train\fR can be combined with \fB\-r\fR to indicate a directory rather than listing all the files, which can be useful to circumvent shell expansion limits\. .IP -Supports multithreading if \fBzstd\fR is compiled with threading support\. Additional parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\. -. +\fB\-\-train\fR supports multithreading if \fBzstd\fR is compiled with threading support (default)\. Additional parameters can be specified with \fB\-\-train\-fastcover\fR\. The legacy dictionary builder can be accessed with \fB\-\-train\-legacy\fR\. The slower cover dictionary builder can be accessed with \fB\-\-train\-cover\fR\. Default is equivalent to \fB\-\-train\-fastcover=d=8,steps=4\fR\. .TP \fB\-o file\fR Dictionary saved into \fBfile\fR (default name: dictionary)\. -. .TP \fB\-\-maxdict=#\fR Limit dictionary to specified size (default: 112640)\. -. .TP \fB\-#\fR Use \fB#\fR compression level during training (optional)\. Will generate statistics more tuned for selected compression level, resulting in a \fIsmall\fR compression ratio improvement for this level\. -. .TP \fB\-B#\fR -Split input files in blocks of size # (default: no split) -. +Split input files into blocks of size # (default: no split) .TP \fB\-\-dictID=#\fR A dictionary ID is a locally unique ID that a decoder can use to verify it is using the right dictionary\. By default, zstd will create a 4\-bytes random number ID\. It\'s possible to give a precise number instead\. Short numbers have an advantage : an ID < 256 will only need 1 byte in the compressed frame header, and an ID < 65536 will only need 2 bytes\. This compares favorably to 4 bytes default\. However, it\'s up to the dictionary manager to not assign twice the same ID to 2 different dictionaries\. -. .TP \fB\-\-train\-cover[=k#,d=#,steps=#,split=#,shrink[=#]]\fR Select parameters for the default dictionary builder algorithm named cover\. If \fId\fR is not specified, then it tries \fId\fR = 6 and \fId\fR = 8\. If \fIk\fR is not specified, then it tries \fIsteps\fR values in the range [50, 2000]\. If \fIsteps\fR is not specified, then the default value of 40 is used\. If \fIsplit\fR is not specified or split <= 0, then the default value of 100 is used\. Requires that \fId\fR <= \fIk\fR\. If \fIshrink\fR flag is not used, then the default value for \fIshrinkDict\fR of 0 is used\. If \fIshrink\fR is not specified, then the default value for \fIshrinkDictMaxRegression\fR of 1 is used\. -. .IP Selects segments of size \fIk\fR with highest score to put in the dictionary\. The score of a segment is computed by the sum of the frequencies of all the subsegments of size \fId\fR\. Generally \fId\fR should be in the range [6, 8], occasionally up to 16, but the algorithm will run faster with d <= \fI8\fR\. Good values for \fIk\fR vary widely based on the input data, but a safe range is [2 * \fId\fR, 2000]\. If \fIsplit\fR is 100, all input samples are used for both training and testing to find optimal \fId\fR and \fIk\fR to build dictionary\. Supports multithreading if \fBzstd\fR is compiled with threading support\. Having \fIshrink\fR enabled takes a truncated dictionary of minimum size and doubles in size until compression ratio of the truncated dictionary is at most \fIshrinkDictMaxRegression%\fR worse than the compression ratio of the largest dictionary\. -. .IP Examples: -. .IP \fBzstd \-\-train\-cover FILEs\fR -. .IP \fBzstd \-\-train\-cover=k=50,d=8 FILEs\fR -. .IP \fBzstd \-\-train\-cover=d=8,steps=500 FILEs\fR -. .IP \fBzstd \-\-train\-cover=k=50 FILEs\fR -. .IP \fBzstd \-\-train\-cover=k=50,split=60 FILEs\fR -. .IP \fBzstd \-\-train\-cover=shrink FILEs\fR -. .IP \fBzstd \-\-train\-cover=shrink=2 FILEs\fR -. .TP \fB\-\-train\-fastcover[=k#,d=#,f=#,steps=#,split=#,accel=#]\fR Same as cover but with extra parameters \fIf\fR and \fIaccel\fR and different default value of split If \fIsplit\fR is not specified, then it tries \fIsplit\fR = 75\. If \fIf\fR is not specified, then it tries \fIf\fR = 20\. Requires that 0 < \fIf\fR < 32\. If \fIaccel\fR is not specified, then it tries \fIaccel\fR = 1\. Requires that 0 < \fIaccel\fR <= 10\. Requires that \fId\fR = 6 or \fId\fR = 8\. -. .IP \fIf\fR is log of size of array that keeps track of frequency of subsegments of size \fId\fR\. The subsegment is hashed to an index in the range [0,2^\fIf\fR \- 1]\. It is possible that 2 different subsegments are hashed to the same index, and they are considered as the same subsegment when computing frequency\. Using a higher \fIf\fR reduces collision but takes longer\. -. .IP Examples: -. .IP \fBzstd \-\-train\-fastcover FILEs\fR -. .IP \fBzstd \-\-train\-fastcover=d=8,f=15,accel=2 FILEs\fR -. .TP \fB\-\-train\-legacy[=selectivity=#]\fR Use legacy dictionary builder algorithm with the given dictionary \fIselectivity\fR (default: 9)\. The smaller the \fIselectivity\fR value, the denser the dictionary, improving its efficiency but reducing its possible maximum size\. \fB\-\-train\-legacy=s=#\fR is also accepted\. -. .IP Examples: -. .IP \fBzstd \-\-train\-legacy FILEs\fR -. .IP \fBzstd \-\-train\-legacy=selectivity=8 FILEs\fR -. .SH "BENCHMARK" -. .TP \fB\-b#\fR benchmark file(s) using compression level # -. .TP \fB\-e#\fR benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\fR (inclusive) -. .TP \fB\-i#\fR minimum evaluation time, in seconds (default: 3s), benchmark mode only -. .TP \fB\-B#\fR, \fB\-\-block\-size=#\fR cut file(s) into independent blocks of size # (default: no block) -. .TP \fB\-\-priority=rt\fR set process priority to real\-time -. .P \fBOutput Format:\fR CompressionLevel#Filename : IntputSize \-> OutputSize (CompressionRatio), CompressionSpeed, DecompressionSpeed -. .P \fBMethodology:\fR For both compression and decompression speed, the entire input is compressed/decompressed in\-memory to measure speed\. A run lasts at least 1 sec, so when files are small, they are compressed/decompressed several times per run, in order to improve measurement accuracy\. -. .SH "ADVANCED COMPRESSION OPTIONS" -. -.SS "\-B#:" -Select the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to (slightly) different compressed frames\. -. +### \-B#: Select the size of each compression job\. This parameter is only available when multi\-threading is enabled\. Each compression job is run in parallel, so this value indirectly impacts the nb of active threads\. Default job size varies depending on compression level (generally \fB4 * windowSize\fR)\. \fB\-B#\fR makes it possible to manually select a custom size\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 512 KB, or \fBoverlapSize\fR, whichever is largest\. Different job sizes will lead to (slightly) different compressed frames\. .SS "\-\-zstd[=options]:" \fBzstd\fR provides 22 predefined compression levels\. The selected or default predefined compression level can be changed with advanced compression options\. The \fIoptions\fR are provided as a comma\-separated list\. You may specify only the options you want to change and the rest will be taken from the selected or default compression level\. The list of available \fIoptions\fR: -. .TP \fBstrategy\fR=\fIstrat\fR, \fBstrat\fR=\fIstrat\fR Specify a strategy used by a match finder\. -. .IP There are 9 strategies numbered from 1 to 9, from faster to stronger: 1=ZSTD_fast, 2=ZSTD_dfast, 3=ZSTD_greedy, 4=ZSTD_lazy, 5=ZSTD_lazy2, 6=ZSTD_btlazy2, 7=ZSTD_btopt, 8=ZSTD_btultra, 9=ZSTD_btultra2\. -. .TP \fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR Specify the maximum number of bits for a match distance\. -. .IP The higher number of increases the chance to find a match which usually improves compression ratio\. It also increases memory requirements for the compressor and decompressor\. The minimum \fIwlog\fR is 10 (1 KiB) and the maximum is 30 (1 GiB) on 32\-bit platforms and 31 (2 GiB) on 64\-bit platforms\. -. .IP Note: If \fBwindowLog\fR is set to larger than 27, \fB\-\-long=windowLog\fR or \fB\-\-memory=windowSize\fR needs to be passed to the decompressor\. -. .TP \fBhashLog\fR=\fIhlog\fR, \fBhlog\fR=\fIhlog\fR Specify the maximum number of bits for a hash table\. -. .IP Bigger hash tables cause less collisions which usually makes compression faster, but requires more memory during compression\. -. .IP The minimum \fIhlog\fR is 6 (64 B) and the maximum is 30 (1 GiB)\. -. .TP \fBchainLog\fR=\fIclog\fR, \fBclog\fR=\fIclog\fR Specify the maximum number of bits for a hash chain or a binary tree\. -. .IP Higher numbers of bits increases the chance to find a match which usually improves compression ratio\. It also slows down compression speed and increases memory requirements for compression\. This option is ignored for the ZSTD_fast strategy\. -. .IP The minimum \fIclog\fR is 6 (64 B) and the maximum is 29 (524 Mib) on 32\-bit platforms and 30 (1 Gib) on 64\-bit platforms\. -. .TP \fBsearchLog\fR=\fIslog\fR, \fBslog\fR=\fIslog\fR Specify the maximum number of searches in a hash chain or a binary tree using logarithmic scale\. -. .IP More searches increases the chance to find a match which usually increases compression ratio but decreases compression speed\. -. .IP The minimum \fIslog\fR is 1 and the maximum is \'windowLog\' \- 1\. -. .TP \fBminMatch\fR=\fImml\fR, \fBmml\fR=\fImml\fR Specify the minimum searched length of a match in a hash table\. -. .IP Larger search lengths usually decrease compression ratio but improve decompression speed\. -. .IP The minimum \fImml\fR is 3 and the maximum is 7\. -. .TP \fBtargetLength\fR=\fItlen\fR, \fBtlen\fR=\fItlen\fR The impact of this field vary depending on selected strategy\. -. .IP For ZSTD_btopt, ZSTD_btultra and ZSTD_btultra2, it specifies the minimum match length that causes match finder to stop searching\. A larger \fBtargetLength\fR usually improves compression ratio but decreases compression speed\. t For ZSTD_fast, it triggers ultra\-fast mode when > 0\. The value represents the amount of data skipped between match sampling\. Impact is reversed : a larger \fBtargetLength\fR increases compression speed but decreases compression ratio\. -. .IP For all other strategies, this field has no impact\. -. .IP The minimum \fItlen\fR is 0 and the maximum is 128 Kib\. -. .TP \fBoverlapLog\fR=\fIovlog\fR, \fBovlog\fR=\fIovlog\fR Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This parameter is only available when multithreading is enabled\. Reloading more data improves compression ratio, but decreases speed\. -. .IP The minimum \fIovlog\fR is 0, and the maximum is 9\. 1 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the reloaded amount by a factor 2\. For example, 8 means "windowSize/2", and 6 means "windowSize/8"\. Value 0 is special and means "default" : \fIovlog\fR is automatically determined by \fBzstd\fR\. In which case, \fIovlog\fR will range from 6 to 9, depending on selected \fIstrat\fR\. -. .TP \fBldmHashLog\fR=\fIlhlog\fR, \fBlhlog\fR=\fIlhlog\fR Specify the maximum size for a hash table used for long distance matching\. -. .IP This option is ignored unless long distance matching is enabled\. -. .IP Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\. -. .IP The minimum \fIlhlog\fR is 6 and the maximum is 30 (default: 20)\. -. .TP \fBldmMinMatch\fR=\fIlmml\fR, \fBlmml\fR=\fIlmml\fR Specify the minimum searched length of a match for long distance matching\. -. .IP This option is ignored unless long distance matching is enabled\. -. .IP Larger/very small values usually decrease compression ratio\. -. .IP The minimum \fIlmml\fR is 4 and the maximum is 4096 (default: 64)\. -. .TP \fBldmBucketSizeLog\fR=\fIlblog\fR, \fBlblog\fR=\fIlblog\fR Specify the size of each bucket for the hash table used for long distance matching\. -. .IP This option is ignored unless long distance matching is enabled\. -. .IP Larger bucket sizes improve collision resolution but decrease compression speed\. -. .IP The minimum \fIlblog\fR is 1 and the maximum is 8 (default: 3)\. -. .TP \fBldmHashRateLog\fR=\fIlhrlog\fR, \fBlhrlog\fR=\fIlhrlog\fR Specify the frequency of inserting entries into the long distance matching hash table\. -. .IP This option is ignored unless long distance matching is enabled\. -. .IP Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\. -. .IP The default value is \fBwlog \- lhlog\fR\. -. .SS "Example" The following parameters sets advanced compression options to something similar to predefined level 19 for files bigger than 256 KB: -. .P \fB\-\-zstd\fR=wlog=23,clog=23,hlog=22,slog=6,mml=3,tlen=48,strat=6 -. .SH "BUGS" Report bugs at: https://github\.com/facebook/zstd/issues -. .SH "AUTHOR" Yann Collet diff --git a/programs/zstdgrep.1 b/programs/zstdgrep.1 index bf96185b7..e69de29bb 100644 --- a/programs/zstdgrep.1 +++ b/programs/zstdgrep.1 @@ -1,23 +0,0 @@ -. -.TH "ZSTDGREP" "1" "May 2021" "zstd 1.5.0" "User Commands" -. -.SH "NAME" -\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files -. -.SH "SYNOPSIS" -\fBzstdgrep\fR [\fIgrep\-flags\fR] [\-\-] \fIpattern\fR [\fIfiles\fR \.\.\.] -. -.SH "DESCRIPTION" -\fBzstdgrep\fR runs \fBgrep (1)\fR on files or stdin, if no files argument is given, after decompressing them with \fBzstdcat (1)\fR\. -. -.P -The grep\-flags and pattern arguments are passed on to \fBgrep (1)\fR\. If an \fB\-e\fR flag is found in the \fBgrep\-flags\fR, \fBzstdgrep\fR will not look for a pattern argument\. -. -.SH "EXIT STATUS" -In case of missing arguments or missing pattern, 1 will be returned, otherwise 0\. -. -.SH "SEE ALSO" -\fBzstd (1)\fR -. -.SH "AUTHORS" -Thomas Klausner \fIwiz@NetBSD\.org\fR diff --git a/programs/zstdless.1 b/programs/zstdless.1 index f08bc1921..e69de29bb 100644 --- a/programs/zstdless.1 +++ b/programs/zstdless.1 @@ -1,14 +0,0 @@ -. -.TH "ZSTDLESS" "1" "May 2021" "zstd 1.5.0" "User Commands" -. -.SH "NAME" -\fBzstdless\fR \- view zstandard\-compressed files -. -.SH "SYNOPSIS" -\fBzstdless\fR [\fIflags\fR] [\fIfile\fR \.\.\.] -. -.SH "DESCRIPTION" -\fBzstdless\fR runs \fBless (1)\fR on files or stdin, if no files argument is given, after decompressing them with \fBzstdcat (1)\fR\. -. -.SH "SEE ALSO" -\fBzstd (1)\fR From 70b36c2308441fc6448fc48a365831c7748078b9 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 22 Sep 2021 14:30:06 -0700 Subject: [PATCH 171/274] update zstdgrep doc to mention ripgrep alternative which transparently supports zstd-compressed files. --- programs/zstdgrep.1.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/programs/zstdgrep.1.md b/programs/zstdgrep.1.md index 363ad4f99..35186a4bf 100644 --- a/programs/zstdgrep.1.md +++ b/programs/zstdgrep.1.md @@ -9,10 +9,14 @@ SYNOPSIS DESCRIPTION ----------- -`zstdgrep` runs `grep (1)` on files or stdin, if no files argument is given, after decompressing them with `zstdcat (1)`. +`zstdgrep` runs `grep (1)` on files, or `stdin` if no files argument is given, after decompressing them with `zstdcat (1)`. The grep-flags and pattern arguments are passed on to `grep (1)`. If an `-e` flag is found in the `grep-flags`, `zstdgrep` will not look for a pattern argument. +Note that modern `grep` alternatives such as `ripgrep` (`rg`) support `zstd`-compressed files out of the box, +and can prove better alternatives than `zstdgrep` notably for unsupported complex pattern searches. +Note though that such alternatives may also feature some minor command line differences. + EXIT STATUS ----------- In case of missing arguments or missing pattern, 1 will be returned, otherwise 0. From 3addf2f27781e1abb32551bfdd612295147dd24d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 22 Sep 2021 14:30:59 -0700 Subject: [PATCH 172/274] updated zstdgrep man page --- programs/zstdgrep.1 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/programs/zstdgrep.1 b/programs/zstdgrep.1 index e69de29bb..ae4da3354 100644 --- a/programs/zstdgrep.1 +++ b/programs/zstdgrep.1 @@ -0,0 +1,17 @@ +.TH "ZSTDGREP" "1" "September 2021" "zstd 1.5.1" "User Commands" +.SH "NAME" +\fBzstdgrep\fR \- print lines matching a pattern in zstandard\-compressed files +.SH "SYNOPSIS" +\fBzstdgrep\fR [\fIgrep\-flags\fR] [\-\-] \fIpattern\fR [\fIfiles\fR \|\.\|\.\|\.] +.SH "DESCRIPTION" +\fBzstdgrep\fR runs \fBgrep (1)\fR on files, or \fBstdin\fR if no files argument is given, after decompressing them with \fBzstdcat (1)\fR\. +.P +The grep\-flags and pattern arguments are passed on to \fBgrep (1)\fR\. If an \fB\-e\fR flag is found in the \fBgrep\-flags\fR, \fBzstdgrep\fR will not look for a pattern argument\. +.P +Note that modern \fBgrep\fR alternatives such as \fBripgrep\fR (\fBrg\fR) support \fBzstd\fR\-compressed files out of the box, and can prove better alternatives than \fBzstdgrep\fR notably for unsupported complex pattern searches\. Note though that such alternatives may also feature some minor command line differences\. +.SH "EXIT STATUS" +In case of missing arguments or missing pattern, 1 will be returned, otherwise 0\. +.SH "SEE ALSO" +\fBzstd (1)\fR +.SH "AUTHORS" +Thomas Klausner \fIwiz@NetBSD\.org\fR From 8150891939a7e7bc009ecf372cd0d340508c0b8a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 22 Sep 2021 14:48:51 -0700 Subject: [PATCH 173/274] regenerated zstdless.1 --- programs/zstdless.1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/programs/zstdless.1 b/programs/zstdless.1 index e69de29bb..22354763b 100644 --- a/programs/zstdless.1 +++ b/programs/zstdless.1 @@ -0,0 +1,9 @@ +.TH "ZSTDLESS" "1" "September 2021" "zstd 1.5.1" "User Commands" +.SH "NAME" +\fBzstdless\fR \- view zstandard\-compressed files +.SH "SYNOPSIS" +\fBzstdless\fR [\fIflags\fR] [\fIfile\fR \|\.\|\.\|\.] +.SH "DESCRIPTION" +\fBzstdless\fR runs \fBless (1)\fR on files or stdin, if no files argument is given, after decompressing them with \fBzstdcat (1)\fR\. +.SH "SEE ALSO" +\fBzstd (1)\fR From 4d347a902bd717d0565f797f70b68f159767d364 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 22 Sep 2021 15:06:08 -0700 Subject: [PATCH 174/274] [contrib][linux] Fix up SPDX license identifiers Correctly identify that we are GPL v2+ or BSD 3 clause, as pointed out in issue #2663. --- contrib/linux-kernel/decompress_sources.h | 2 +- contrib/linux-kernel/linux.mk | 2 +- contrib/linux-kernel/linux_zstd.h | 2 +- contrib/linux-kernel/mem.h | 2 +- contrib/linux-kernel/zstd_compress_module.c | 2 +- contrib/linux-kernel/zstd_decompress_module.c | 2 +- contrib/linux-kernel/zstd_deps.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/linux-kernel/decompress_sources.h b/contrib/linux-kernel/decompress_sources.h index aef953c6b..a2aefe8f2 100644 --- a/contrib/linux-kernel/decompress_sources.h +++ b/contrib/linux-kernel/decompress_sources.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* * Copyright (c) Facebook, Inc. * All rights reserved. diff --git a/contrib/linux-kernel/linux.mk b/contrib/linux-kernel/linux.mk index 19485e3cc..65218ec5b 100644 --- a/contrib/linux-kernel/linux.mk +++ b/contrib/linux-kernel/linux.mk @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: GPL-2.0-only +# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause # ################################################################ # Copyright (c) Facebook, Inc. # All rights reserved. diff --git a/contrib/linux-kernel/linux_zstd.h b/contrib/linux-kernel/linux_zstd.h index 446ecabcd..113408eef 100644 --- a/contrib/linux-kernel/linux_zstd.h +++ b/contrib/linux-kernel/linux_zstd.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* * Copyright (c) Yann Collet, Facebook, Inc. * All rights reserved. diff --git a/contrib/linux-kernel/mem.h b/contrib/linux-kernel/mem.h index 4b5db5756..dcdd586a9 100644 --- a/contrib/linux-kernel/mem.h +++ b/contrib/linux-kernel/mem.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* * Copyright (c) Yann Collet, Facebook, Inc. * All rights reserved. diff --git a/contrib/linux-kernel/zstd_compress_module.c b/contrib/linux-kernel/zstd_compress_module.c index 37d08ff43..bb06206f4 100644 --- a/contrib/linux-kernel/zstd_compress_module.c +++ b/contrib/linux-kernel/zstd_compress_module.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * Copyright (c) Facebook, Inc. * All rights reserved. diff --git a/contrib/linux-kernel/zstd_decompress_module.c b/contrib/linux-kernel/zstd_decompress_module.c index 15005cdb9..f4ed952ed 100644 --- a/contrib/linux-kernel/zstd_decompress_module.c +++ b/contrib/linux-kernel/zstd_decompress_module.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* * Copyright (c) Facebook, Inc. * All rights reserved. diff --git a/contrib/linux-kernel/zstd_deps.h b/contrib/linux-kernel/zstd_deps.h index 853b72426..7a5bf4483 100644 --- a/contrib/linux-kernel/zstd_deps.h +++ b/contrib/linux-kernel/zstd_deps.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ /* * Copyright (c) Facebook, Inc. * All rights reserved. From 162491f6015a45f3391584cf64be45304ae91869 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 22 Sep 2021 18:13:02 -0700 Subject: [PATCH 175/274] [contrib][linux] Reduce stack usage by 80 bytes Instead of calling `ZSTD_compress_advanced()` and `ZSTD_initCStream_advanced()`, which each take a `ZSTD_parameters` by value, use the new advanced API. Stack usage went from 2024 -> 1944. --- contrib/linux-kernel/zstd_compress_module.c | 44 +++++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/contrib/linux-kernel/zstd_compress_module.c b/contrib/linux-kernel/zstd_compress_module.c index bb06206f4..65548a4bb 100644 --- a/contrib/linux-kernel/zstd_compress_module.c +++ b/contrib/linux-kernel/zstd_compress_module.c @@ -17,6 +17,43 @@ #include "common/zstd_deps.h" #include "common/zstd_internal.h" +#define ZSTD_FORWARD_IF_ERR(ret) \ + do { \ + size_t const __ret = (ret); \ + if (ZSTD_isError(__ret)) \ + return __ret; \ + } while (0) + +static size_t zstd_cctx_init(zstd_cctx *cctx, const zstd_parameters *parameters, + unsigned long long pledged_src_size) +{ + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_reset( + cctx, ZSTD_reset_session_and_parameters)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setPledgedSrcSize( + cctx, pledged_src_size)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_windowLog, parameters->cParams.windowLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_hashLog, parameters->cParams.hashLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_chainLog, parameters->cParams.chainLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_searchLog, parameters->cParams.searchLog)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_minMatch, parameters->cParams.minMatch)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_targetLength, parameters->cParams.targetLength)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_strategy, parameters->cParams.strategy)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_contentSizeFlag, parameters->fParams.contentSizeFlag)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_checksumFlag, parameters->fParams.checksumFlag)); + ZSTD_FORWARD_IF_ERR(ZSTD_CCtx_setParameter( + cctx, ZSTD_c_dictIDFlag, !parameters->fParams.noDictIDFlag)); + return 0; +} + int zstd_min_clevel(void) { return ZSTD_minCLevel(); @@ -59,7 +96,8 @@ EXPORT_SYMBOL(zstd_init_cctx); size_t zstd_compress_cctx(zstd_cctx *cctx, void *dst, size_t dst_capacity, const void *src, size_t src_size, const zstd_parameters *parameters) { - return ZSTD_compress_advanced(cctx, dst, dst_capacity, src, src_size, NULL, 0, *parameters); + ZSTD_FORWARD_IF_ERR(zstd_cctx_init(cctx, parameters, src_size)); + return ZSTD_compress2(cctx, dst, dst_capacity, src, src_size); } EXPORT_SYMBOL(zstd_compress_cctx); @@ -73,7 +111,6 @@ zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters, unsigned long long pledged_src_size, void *workspace, size_t workspace_size) { zstd_cstream *cstream; - size_t ret; if (workspace == NULL) return NULL; @@ -86,8 +123,7 @@ zstd_cstream *zstd_init_cstream(const zstd_parameters *parameters, if (pledged_src_size == 0) pledged_src_size = ZSTD_CONTENTSIZE_UNKNOWN; - ret = ZSTD_initCStream_advanced(cstream, NULL, 0, *parameters, pledged_src_size); - if (ZSTD_isError(ret)) + if (ZSTD_isError(zstd_cctx_init(cstream, parameters, pledged_src_size))) return NULL; return cstream; From 1d8143c84f287eb54879f752a4200041ed840e25 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 22 Sep 2021 11:16:46 -0400 Subject: [PATCH 176/274] Move block splitter from stack to CCtx --- contrib/linux-kernel/Makefile | 2 +- lib/compress/zstd_compress.c | 62 +++++++++++++-------------- lib/compress/zstd_compress_internal.h | 19 ++++++++ 3 files changed, 51 insertions(+), 32 deletions(-) diff --git a/contrib/linux-kernel/Makefile b/contrib/linux-kernel/Makefile index f85179fc4..c88d137f2 100644 --- a/contrib/linux-kernel/Makefile +++ b/contrib/linux-kernel/Makefile @@ -93,4 +93,4 @@ test: libzstd .PHONY: clean clean: - $(RM) -rf linux + $(RM) -rf linux test/test test/static_test diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6ca4784fd..dc4103667 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1506,7 +1506,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); ZSTD_paramSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, - &cParams); + &cParams); RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); /* estimateCCtxSize is for one-shot compression. So no buffers should @@ -1987,8 +1987,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->ldmState.loadedDictEnd = 0; } - assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace)); DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); + assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace, resizeWorkspace)); zc->initialized = 1; @@ -3341,20 +3341,20 @@ static size_t ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, * * Returns the estimated compressed size of the seqStore, or a zstd error. */ -static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, const ZSTD_CCtx* zc) { - ZSTD_entropyCTablesMetadata_t entropyMetadata; +static size_t ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CCtx* zc) { + ZSTD_entropyCTablesMetadata_t* entropyMetadata = &zc->blockSplitCtx.entropyMetadata; DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()"); FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore, &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, &zc->appliedParams, - &entropyMetadata, + entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), ""); return ZSTD_estimateBlockSize(seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart), seqStore->ofCode, seqStore->llCode, seqStore->mlCode, (size_t)(seqStore->sequences - seqStore->sequencesStart), - &zc->blockState.nextCBlock->entropy, &entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE, - (int)(entropyMetadata.hufMetadata.hType == set_compressed), 1); + &zc->blockState.nextCBlock->entropy, entropyMetadata, zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE, + (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1); } /* Returns literals bytes represented in a seqStore */ @@ -3553,7 +3553,6 @@ typedef struct { } seqStoreSplits; #define MIN_SEQUENCES_BLOCK_SPLITTING 300 -#define MAX_NB_SPLITS 196 /* Helper function to perform the recursive search for block splits. * Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half. @@ -3564,30 +3563,31 @@ typedef struct { * In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING). * In practice, recursion depth usually doesn't go beyond 4. * - * Furthermore, the number of splits is capped by MAX_NB_SPLITS. At MAX_NB_SPLITS == 196 with the current existing blockSize + * Furthermore, the number of splits is capped by ZSTD_MAX_NB_BLOCK_SPLITS. At ZSTD_MAX_NB_BLOCK_SPLITS == 196 with the current existing blockSize * maximum of 128 KB, this value is actually impossible to reach. */ static void ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx, - const ZSTD_CCtx* zc, const seqStore_t* origSeqStore) { - seqStore_t fullSeqStoreChunk; - seqStore_t firstHalfSeqStore; - seqStore_t secondHalfSeqStore; + ZSTD_CCtx* zc, const seqStore_t* origSeqStore) { + seqStore_t* fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk; + seqStore_t* firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore; + seqStore_t* secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore; size_t estimatedOriginalSize; size_t estimatedFirstHalfSize; size_t estimatedSecondHalfSize; size_t midIdx = (startIdx + endIdx)/2; - if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= MAX_NB_SPLITS) { + if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) { DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences"); return; } - ZSTD_deriveSeqStoreChunk(&fullSeqStoreChunk, origSeqStore, startIdx, endIdx); - ZSTD_deriveSeqStoreChunk(&firstHalfSeqStore, origSeqStore, startIdx, midIdx); - ZSTD_deriveSeqStoreChunk(&secondHalfSeqStore, origSeqStore, midIdx, endIdx); - estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&fullSeqStoreChunk, zc); - estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&firstHalfSeqStore, zc); - estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&secondHalfSeqStore, zc); - DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu", + DEBUGLOG(4, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx); + ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx); + ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx); + ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx); + estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(fullSeqStoreChunk, zc); + estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(firstHalfSeqStore, zc); + estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(secondHalfSeqStore, zc); + DEBUGLOG(4, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu", estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize); if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) { return; @@ -3627,12 +3627,12 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s size_t cSize = 0; const BYTE* ip = (const BYTE*)src; BYTE* op = (BYTE*)dst; - U32 partitions[MAX_NB_SPLITS]; size_t i = 0; size_t srcBytesTotal = 0; + U32* partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */ + seqStore_t* nextSeqStore = &zc->blockSplitCtx.nextSeqStore; + seqStore_t* currSeqStore = &zc->blockSplitCtx.currSeqStore; size_t numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq); - seqStore_t nextSeqStore; - seqStore_t currSeqStore; /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history * may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two @@ -3652,7 +3652,7 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s repcodes_t cRep; ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(repcodes_t)); - ZSTD_memset(&nextSeqStore, 0, sizeof(seqStore_t)); + ZSTD_memset(nextSeqStore, 0, sizeof(seqStore_t)); DEBUGLOG(4, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, @@ -3670,36 +3670,36 @@ static size_t ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, void* dst, s return cSizeSingleBlock; } - ZSTD_deriveSeqStoreChunk(&currSeqStore, &zc->seqStore, 0, partitions[0]); + ZSTD_deriveSeqStoreChunk(currSeqStore, &zc->seqStore, 0, partitions[0]); for (i = 0; i <= numSplits; ++i) { size_t srcBytes; size_t cSizeChunk; U32 const lastPartition = (i == numSplits); U32 lastBlockEntireSrc = 0; - srcBytes = ZSTD_countSeqStoreLiteralsBytes(&currSeqStore) + ZSTD_countSeqStoreMatchBytes(&currSeqStore); + srcBytes = ZSTD_countSeqStoreLiteralsBytes(currSeqStore) + ZSTD_countSeqStoreMatchBytes(currSeqStore); srcBytesTotal += srcBytes; if (lastPartition) { /* This is the final partition, need to account for possible last literals */ srcBytes += blockSize - srcBytesTotal; lastBlockEntireSrc = lastBlock; } else { - ZSTD_deriveSeqStoreChunk(&nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]); + ZSTD_deriveSeqStoreChunk(nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]); } - cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, &currSeqStore, + cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, currSeqStore, &dRep, &cRep, op, dstCapacity, ip, srcBytes, lastBlockEntireSrc, 1 /* isPartition */); - DEBUGLOG(5, "Estimated size: %zu actual size: %zu", ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(&currSeqStore, zc), cSizeChunk); + DEBUGLOG(5, "Estimated size: %zu actual size: %zu", ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk); FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!"); ip += srcBytes; op += cSizeChunk; dstCapacity -= cSizeChunk; cSize += cSizeChunk; - currSeqStore = nextSeqStore; + *currSeqStore = *nextSeqStore; assert(cSizeChunk <= ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize); } /* cRep and dRep may have diverged during the compression. If so, we use the dRep repcodes diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index b7772522a..a5c2db4b9 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -345,6 +345,22 @@ typedef enum { ZSTDb_buffered } ZSTD_buffered_policy_e; +/** + * Struct that contains all elements of block splitter that should be allocated + * in a wksp. + */ +#define ZSTD_MAX_NB_BLOCK_SPLITS 196 +typedef struct { + seqStore_t fullSeqStoreChunk; + seqStore_t firstHalfSeqStore; + seqStore_t secondHalfSeqStore; + seqStore_t currSeqStore; + seqStore_t nextSeqStore; + + U32 partitions[ZSTD_MAX_NB_BLOCK_SPLITS]; + ZSTD_entropyCTablesMetadata_t entropyMetadata; +} ZSTD_blockSplitCtx; + struct ZSTD_CCtx_s { ZSTD_compressionStage_e stage; int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */ @@ -410,6 +426,9 @@ struct ZSTD_CCtx_s { #if ZSTD_TRACE ZSTD_TraceCtx traceCtx; #endif + + /* Workspace for block splitter */ + ZSTD_blockSplitCtx blockSplitCtx; }; typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e; From e6d62bbfe12698d67a15dd8b7628ef8f38e4b30b Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Tue, 21 Sep 2021 20:06:49 +0200 Subject: [PATCH 177/274] [contrib][linux] Fix build with CONFIG_WERROR Linux 5.15 introduces a new Kconfig option, CONFIG_WERROR, which forces -Werror for the entire kernel. Current in-kernel ZSTD implementation uses functions deprecated in 1.5.0, and thus fails on -Wdeprecated-declarations. Turn this particular error into warning to be able to build the kernel with CONFIG_WERROR. I'm not disabling them completely to make sure they'll be visible and [hopefully] fixed sooner or later. Signed-off-by: Alexander Lobakin --- contrib/linux-kernel/linux.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/linux-kernel/linux.mk b/contrib/linux-kernel/linux.mk index 65218ec5b..a26bd3325 100644 --- a/contrib/linux-kernel/linux.mk +++ b/contrib/linux-kernel/linux.mk @@ -12,6 +12,7 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o ccflags-y += -O3 +ccflags-y += -Wno-error=deprecated-declarations zstd_compress-y := \ zstd_compress_module.o \ From c45b27abe79f7e9f2b7919bab94e45d7a22c1d6a Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Tue, 21 Sep 2021 20:17:34 +0200 Subject: [PATCH 178/274] [contrib][linux] Add huf_decompress_amd64.o target to Makefile Commit a5f2c4552803 ("Huffman ASM") added a new ASM source file, but it wasn't added to the kernel Makefile despite that it received support for Huffman ASM according to the internal definitions. This leads to undefined references, as huf_decompress.o now calls those ASM functions. Add it to the list of sources when building inside the kernel tree. Kbuild can handle .S files just fine, so none additional rules needed. Fixes: a5f2c4552803 ("Huffman ASM") Signed-off-by: Alexander Lobakin --- contrib/linux-kernel/linux.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/linux-kernel/linux.mk b/contrib/linux-kernel/linux.mk index a26bd3325..9df9c9c6d 100644 --- a/contrib/linux-kernel/linux.mk +++ b/contrib/linux-kernel/linux.mk @@ -42,6 +42,7 @@ zstd_decompress-y := \ common/fse_decompress.o \ common/zstd_common.o \ decompress/huf_decompress.o \ + decompress/huf_decompress_amd64.o \ decompress/zstd_ddict.o \ decompress/zstd_decompress.o \ decompress/zstd_decompress_block.o \ From d8b7fc51c81756a44fb87cbebd8e018652daf730 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Thu, 23 Sep 2021 16:33:24 +0200 Subject: [PATCH 179/274] [contrib][linux] Add contrib/linux-kernel/linux to .gitignore The mentioned path is being created/used by the 'import' rule for generating source files for Linux kernel. Signed-off-by: Alexander Lobakin --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ea574d747..a136ea394 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ dictionary NUL # Build artefacts +contrib/linux-kernel/linux/ projects/ bin/ .buckd/ From fa2a4d77c7a97f7beebc4f3ee268526e5e3a29c0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 23 Sep 2021 08:27:44 -0700 Subject: [PATCH 180/274] constify MatchState* parameter when possible turns out, it's possible to constify MatchState* parameter in some parts of the binary tree algorithm, making it a pure read-only parameter, as opposed to a mutable state. This is supposed to be helpful for both maintenance and the compiler. --- lib/compress/zstd_compress_internal.h | 10 +++++----- lib/compress/zstd_lazy.c | 6 +++--- lib/compress/zstd_opt.c | 20 ++++++++------------ 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index a5c2db4b9..3dab83255 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -1228,15 +1228,15 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window, */ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog) { - U32 const maxDistance = 1U << windowLog; - U32 const lowestValid = ms->window.lowLimit; - U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; - U32 const isDictionary = (ms->loadedDictEnd != 0); + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.lowLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't * valid for the entire block. So this check is sufficient to find the lowest valid match index. */ - U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; return matchLowest; } diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 70319d575..ed50550f3 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -61,7 +61,7 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms, * assumption : curr >= btlow == (curr - btmask) * doesn't fail */ static void -ZSTD_insertDUBT1(ZSTD_matchState_t* ms, +ZSTD_insertDUBT1(const ZSTD_matchState_t* ms, U32 curr, const BYTE* inputEnd, U32 nbCompares, U32 btLow, const ZSTD_dictMode_e dictMode) @@ -151,7 +151,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms, static size_t ZSTD_DUBT_findBetterDictMatch ( - ZSTD_matchState_t* ms, + const ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, size_t* offsetPtr, size_t bestLength, @@ -868,7 +868,7 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( #define ZSTD_ROW_HASH_TAG_OFFSET 16 /* byte offset of hashes in the match state's tagTable from the beginning of a row */ #define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ #define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) -#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ +#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ #define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 40c25daa1..4c765128a 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -366,7 +366,7 @@ MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length) /* Update hashTable3 up to ip (excluded) Assumption : always within prefix (i.e. not within extDict) */ -static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, +static U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_matchState_t* ms, U32* nextToUpdate3, const BYTE* const ip) { @@ -396,7 +396,7 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, * @param target The target of ZSTD_updateTree_internal() - we are filling to this position * @return : nb of positions added */ static U32 ZSTD_insertBt1( - ZSTD_matchState_t* ms, + const ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iend, U32 const target, U32 const mls, const int extDict) @@ -421,8 +421,8 @@ static U32 ZSTD_insertBt1( U32* smallerPtr = bt + 2*(curr&btMask); U32* largerPtr = smallerPtr + 1; U32 dummy32; /* to be nullified at the end */ - /* windowLow is based on target because we're only need positions that will be - * in the window at the end of the tree update. + /* windowLow is based on target because + * we only need positions that will be in the window at the end of the tree update. */ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog); U32 matchEndIdx = curr+8+1; @@ -669,7 +669,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( return 1; } } } /* no dictMatchState lookup: dicts don't have a populated HC3 table */ - } + } /* if (mls == 3) */ hashTable[h] = curr; /* Update Hash Table */ @@ -706,8 +706,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */ break; /* drop, to preserve bt consistency (miss a little bit of compression) */ - } - } + } } if (match[matchLength] < ip[matchLength]) { /* match smaller than current */ @@ -752,8 +751,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( if ( (matchLength > ZSTD_OPT_NUM) | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { break; /* drop, to guarantee consistency (miss a little bit of compression) */ - } - } + } } if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */ if (match[matchLength] < ip[matchLength]) { @@ -763,9 +761,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( /* match is larger than current */ commonLengthLarger = matchLength; dictMatchIndex = nextPtr[0]; - } - } - } + } } } /* if (dictMode == ZSTD_dictMatchState) */ assert(matchEndIdx > curr+8); ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ From 189e87bcbeb1aa527a82f80adfe6e356de6ab555 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 22 Sep 2021 19:56:07 -0700 Subject: [PATCH 181/274] [lib] Make lib compatible with `-Wfall-through` excepting legacy Switch to a macro `ZSTD_FALLTHROUGH;` instead of a comment. On supported compilers this uses an attribute, otherwise it becomes a comment. This is necessary to be compatible with clang's `-Wfall-through`, and gcc's `-Wfall-through=2` which don't support comments. Without this the linux build emits a bunch of warnings. Also add a test to CI to ensure that we don't regress. --- .github/workflows/dev-short-tests.yml | 12 +++++++ contrib/linux-kernel/Makefile | 1 + .../test/include/linux/compiler.h | 2 ++ lib/common/bitstream.h | 12 +++---- lib/common/compiler.h | 33 +++++++++++++++++++ lib/compress/huf_compress.c | 8 ++--- lib/compress/zstd_compress.c | 12 ++++--- lib/compress/zstd_compress_internal.h | 2 +- lib/compress/zstd_double_fast.c | 2 -- lib/decompress/zstd_decompress.c | 19 +++++++---- lib/decompress/zstd_decompress_block.c | 2 +- 11 files changed, 81 insertions(+), 24 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 056f5cbf1..df6b7ed46 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -151,6 +151,18 @@ jobs: make gcc8install CC=gcc-8 CFLAGS="-Werror" make -j all + implicit-fall-through: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: -Wimplicit-fallthrough build + run: | + make clean + CC=gcc MOREFLAGS="-Werror -Wimplicit-fallthrough=2 -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0 + make clean + CC=clang MOREFLAGS="-Werror -Wimplicit-fallthrough -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0 + + visual-2019: runs-on: windows-latest strategy: diff --git a/contrib/linux-kernel/Makefile b/contrib/linux-kernel/Makefile index f85179fc4..d6510aec7 100644 --- a/contrib/linux-kernel/Makefile +++ b/contrib/linux-kernel/Makefile @@ -51,6 +51,7 @@ libzstd: -U_WIN32 \ -RZSTDLIB_VISIBILITY= \ -RZSTDERRORLIB_VISIBILITY= \ + -RZSTD_FALLTHROUGH=fallthrough \ -DZSTD_HAVE_WEAK_SYMBOLS=0 \ -DZSTD_TRACE=0 \ -DZSTD_NO_TRACE diff --git a/contrib/linux-kernel/test/include/linux/compiler.h b/contrib/linux-kernel/test/include/linux/compiler.h index ea3422ee3..de43edb69 100644 --- a/contrib/linux-kernel/test/include/linux/compiler.h +++ b/contrib/linux-kernel/test/include/linux/compiler.h @@ -18,4 +18,6 @@ #define noinline __attribute__((noinline)) #endif +#define fallthrough __attribute__((__fallthrough__)) + #endif diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index 48aad7f3a..72b4f7fa9 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -293,22 +293,22 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si switch(srcSize) { case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); - /* fall-through */ + ZSTD_FALLTHROUGH; case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); - /* fall-through */ + ZSTD_FALLTHROUGH; case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); - /* fall-through */ + ZSTD_FALLTHROUGH; case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; - /* fall-through */ + ZSTD_FALLTHROUGH; case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; - /* fall-through */ + ZSTD_FALLTHROUGH; case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; - /* fall-through */ + ZSTD_FALLTHROUGH; default: break; } diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 9d7d968ce..c630dad70 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -224,6 +224,39 @@ # define __has_feature(x) 0 #endif +/* C-language Attributes are added in C23. */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define ZSTD_HAS_C_ATTRIBUTE(x) 0 +#endif + +/* Only use C++ attributes in C++. Some compilers report support for C++ + * attributes when compiling with C. + */ +#if defined(__cplusplus) && defined(__has_cpp_attribute) +# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute. + * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough + * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * - Else: __attribute__((__fallthrough__)) + */ +#ifndef ZSTD_FALLTHROUGH +# if ZSTD_HAS_C_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif __has_attribute(__fallthrough__) +# define ZSTD_FALLTHROUGH __attribute__((__fallthrough__)) +# else +# define ZSTD_FALLTHROUGH +# endif +#endif + /* detects whether we are being compiled under msan */ #ifndef ZSTD_MEMORY_SANITIZER # if __has_feature(memory_sanitizer) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index ba296da8d..0d2fb6eb8 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -989,12 +989,12 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, case 11: HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0); break; - case 10: - case 9: + case 10: ZSTD_FALLTHROUGH; + case 9: ZSTD_FALLTHROUGH; case 8: HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1); break; - case 7: + case 7: ZSTD_FALLTHROUGH; default: HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1); break; @@ -1016,7 +1016,7 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, case 7: HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0); break; - case 6: + case 6: ZSTD_FALLTHROUGH; default: HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1); break; diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6ca4784fd..ad2605426 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -4023,7 +4023,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, if (!singleSegment) op[pos++] = windowLogByte; switch(dictIDSizeCode) { - default: assert(0); /* impossible */ + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; case 0 : break; case 1 : op[pos] = (BYTE)(dictID); pos++; break; case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break; @@ -4031,7 +4033,9 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, } switch(fcsCode) { - default: assert(0); /* impossible */ + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break; case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break; case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break; @@ -5435,7 +5439,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, zcs->outBuffFlushedSize = 0; zcs->streamStage = zcss_flush; /* pass-through to flush stage */ } - /* fall-through */ + ZSTD_FALLTHROUGH; case zcss_flush: DEBUGLOG(5, "flush stage"); assert(zcs->appliedParams.outBufferMode == ZSTD_bm_buffered); @@ -5555,7 +5559,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx, ¶ms, cctx->pledgedSrcSizePlusOne-1, dictSize, mode); } - + params.useBlockSplitter = ZSTD_resolveBlockSplitterMode(params.useBlockSplitter, ¶ms.cParams); params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, ¶ms.cParams); params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, ¶ms.cParams); diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index b7772522a..64c90fe6f 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -560,7 +560,7 @@ MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxPa return 1; default: assert(0 /* impossible: pre-validated */); - /* fall-through */ + ZSTD_FALLTHROUGH; case ZSTD_ps_auto: return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); } diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index b9e3c5e9f..c17367859 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -244,8 +244,6 @@ _search_next_long: while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ } - /* fall-through */ - _match_found: offset_2 = offset_1; offset_1 = offset; diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index ee707ce6c..88a5ceebb 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -479,7 +479,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s } switch(dictIDSizeCode) { - default: assert(0); /* impossible */ + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; case 0 : break; case 1 : dictID = ip[pos]; pos++; break; case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; @@ -487,7 +489,9 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s } switch(fcsID) { - default: assert(0); /* impossible */ + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; case 0 : if (singleSegment) frameContentSize = ip[pos]; break; case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; case 2 : frameContentSize = MEM_readLE32(ip+pos); break; @@ -1052,7 +1056,7 @@ static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx) switch (dctx->dictUses) { default: assert(0 /* Impossible */); - /* fall-through */ + ZSTD_FALLTHROUGH; case ZSTD_dont_use: ZSTD_clearDict(dctx); return NULL; @@ -1116,7 +1120,9 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { { default: /* should not happen */ assert(0); + ZSTD_FALLTHROUGH; case ZSTDds_getFrameHeaderSize: + ZSTD_FALLTHROUGH; case ZSTDds_decodeFrameHeader: return ZSTDnit_frameHeader; case ZSTDds_decodeBlockHeader: @@ -1128,6 +1134,7 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { case ZSTDds_checkChecksum: return ZSTDnit_checksum; case ZSTDds_decodeSkippableHeader: + ZSTD_FALLTHROUGH; case ZSTDds_skipFrame: return ZSTDnit_skippableFrame; } @@ -1943,7 +1950,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB zds->legacyVersion = 0; zds->hostageByte = 0; zds->expectedOutBuffer = *output; - /* fall-through */ + ZSTD_FALLTHROUGH; case zdss_loadHeader : DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip)); @@ -2081,7 +2088,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB zds->outBuffSize = neededOutBuffSize; } } } zds->streamStage = zdss_read; - /* fall-through */ + ZSTD_FALLTHROUGH; case zdss_read: DEBUGLOG(5, "stage zdss_read"); @@ -2100,7 +2107,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB } } if (ip==iend) { someMoreWork = 0; break; } /* no more input */ zds->streamStage = zdss_load; - /* fall-through */ + ZSTD_FALLTHROUGH; case zdss_load: { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 9acf2f746..169058844 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -90,7 +90,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, case set_repeat: DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block"); RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, ""); - /* fall-through */ + ZSTD_FALLTHROUGH; case set_compressed: RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3"); From 54a888b57b53620ed8352b399d2e3000cf8b81d1 Mon Sep 17 00:00:00 2001 From: Abshar Mohammed Aslam Date: Thu, 23 Sep 2021 21:54:38 +0400 Subject: [PATCH 182/274] Fix typo --- lib/zstd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zstd.h b/lib/zstd.h index f6376bf3d..17fec948a 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -932,7 +932,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); * Advanced dictionary and prefix API (Requires v1.4.0+) * * This API allows dictionaries to be used with ZSTD_compress2(), - * ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and + * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). Dictionaries are sticky, and * only reset with the context is reset with ZSTD_reset_parameters or * ZSTD_reset_session_and_parameters. Prefixes are single-use. ******************************************************************************/ From d7ef97a013b55d04121ed09a8db2457c005fee41 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 23 Sep 2021 11:48:39 -0700 Subject: [PATCH 183/274] [build] Fix oss-fuzz build with the dataflow sanitizer The dataflow sanitizer requires all code to be instrumented. We can't instrument the ASM function, so we have to disable it. --- lib/common/compiler.h | 9 +++++++++ lib/decompress/huf_decompress.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 9d7d968ce..e5292d773 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -233,6 +233,15 @@ # endif #endif +/* detects whether we are being compiled undef dfsan */ +#ifndef ZSTD_DATAFLOW_SANITIZER +# if __has_feature(dataflow_sanitizer) +# define ZSTD_DATAFLOW_SANITIZER 1 +# else +# define ZSTD_DATAFLOW_SANITIZER 0 +# endif +#endif + #if ZSTD_MEMORY_SANITIZER /* Not all platforms that support msan provide sanitizers/msan_interface.h. * We therefore declare the functions we need ourselves, rather than trying to diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 2efca7dd5..128b08019 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -47,7 +47,7 @@ * Disable when MSAN is enabled. */ #if defined(__linux__) || defined(__linux) || defined(__APPLE__) -# if ZSTD_MEMORY_SANITIZER +# if ZSTD_MEMORY_SANITIZER || ZSTD_DATAFLOW_SANITIZER # define HUF_ASM_SUPPORTED 0 # else # define HUF_ASM_SUPPORTED 1 From b10085d97dc9f2acaab776503eb151ee59f7d48c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 24 Sep 2021 14:46:45 -0700 Subject: [PATCH 184/274] [contrib][linux-kernel] Add standard warnings and -Werror to CI Test the kernel build with the standard warnings enabled so that we don't miss issues like fixed in PR #2802. Stacked on top of PR #2802 so CI passes, so it includes the fix. But, I won't merge until it is merged, so @solbjorn gets the credit for the fix. --- contrib/linux-kernel/Makefile | 10 +++- .../linux-kernel/test/include/asm/unaligned.h | 1 + .../linux-kernel/test/include/linux/xxhash.h | 9 ++- contrib/linux-kernel/test/static_test.c | 12 ++-- contrib/linux-kernel/test/test.c | 60 ++++++++++--------- lib/decompress/huf_decompress.c | 4 +- 6 files changed, 57 insertions(+), 39 deletions(-) diff --git a/contrib/linux-kernel/Makefile b/contrib/linux-kernel/Makefile index d4a7e6c69..f79de6792 100644 --- a/contrib/linux-kernel/Makefile +++ b/contrib/linux-kernel/Makefile @@ -39,6 +39,7 @@ libzstd: -DSTATIC_BMI2=0 \ -DZSTD_ADDRESS_SANITIZER=0 \ -DZSTD_MEMORY_SANITIZER=0 \ + -DZSTD_DATAFLOW_SANITIZER=0 \ -DZSTD_COMPRESS_HEAPMODE=1 \ -UZSTD_NO_INLINE \ -UNO_PREFETCH \ @@ -88,9 +89,16 @@ import-upstream: rm $(LINUX)/lib/zstd/common/xxhash.* rm $(LINUX)/lib/zstd/compress/zstdmt_* +DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ + -Wstrict-prototypes -Wundef -Wpointer-arith \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls -Wmissing-prototypes -Wc++-compat \ + -Wimplicit-fallthrough + .PHONY: test test: libzstd - $(MAKE) -C test run-test CFLAGS="-O3 $(CFLAGS)" -j + $(MAKE) -C test run-test CFLAGS="-O3 $(CFLAGS) $(DEBUGFLAGS) -Werror" -j .PHONY: clean clean: diff --git a/contrib/linux-kernel/test/include/asm/unaligned.h b/contrib/linux-kernel/test/include/asm/unaligned.h index 02c2d74f3..86ec4ca38 100644 --- a/contrib/linux-kernel/test/include/asm/unaligned.h +++ b/contrib/linux-kernel/test/include/asm/unaligned.h @@ -20,6 +20,7 @@ static unsigned _isLittleEndian(void) { const union { uint32_t u; uint8_t c[4]; } one = { 1 }; assert(_IS_LITTLE_ENDIAN == one.c[0]); + (void)one; return _IS_LITTLE_ENDIAN; } diff --git a/contrib/linux-kernel/test/include/linux/xxhash.h b/contrib/linux-kernel/test/include/linux/xxhash.h index 0a43bb275..7e92a706e 100644 --- a/contrib/linux-kernel/test/include/linux/xxhash.h +++ b/contrib/linux-kernel/test/include/linux/xxhash.h @@ -124,11 +124,10 @@ XXH_API uint64_t xxh64(const void *input, size_t length, uint64_t seed); static inline unsigned long xxhash(const void *input, size_t length, uint64_t seed) { -#if BITS_PER_LONG == 64 - return xxh64(input, length, seed); -#else - return xxh32(input, length, seed); -#endif + if (sizeof(size_t) == 8) + return xxh64(input, length, seed); + else + return xxh32(input, length, seed); } /*-**************************** diff --git a/contrib/linux-kernel/test/static_test.c b/contrib/linux-kernel/test/static_test.c index 50c594c77..d2b8b5a32 100644 --- a/contrib/linux-kernel/test/static_test.c +++ b/contrib/linux-kernel/test/static_test.c @@ -28,17 +28,19 @@ static const char kEmptyZstdFrame[] = { 0x28, 0xb5, 0x2f, 0xfd, 0x24, 0x00, 0x01, 0x00, 0x00, 0x99, 0xe9, 0xd8, 0x51 }; -static void test_decompress_unzstd() { +static void test_decompress_unzstd(void) { fprintf(stderr, "Testing decompress unzstd... "); { size_t const wkspSize = zstd_dctx_workspace_bound(); void* wksp = malloc(wkspSize); - CONTROL(wksp != NULL); ZSTD_DCtx* dctx = zstd_init_dctx(wksp, wkspSize); + CONTROL(wksp != NULL); CONTROL(dctx != NULL); - size_t const dSize = zstd_decompress_dctx(dctx, NULL, 0, kEmptyZstdFrame, sizeof(kEmptyZstdFrame)); - CONTROL(!zstd_is_error(dSize)); - CONTROL(dSize == 0); + { + size_t const dSize = zstd_decompress_dctx(dctx, NULL, 0, kEmptyZstdFrame, sizeof(kEmptyZstdFrame)); + CONTROL(!zstd_is_error(dSize)); + CONTROL(dSize == 0); + } free(wksp); } fprintf(stderr, "Ok\n"); diff --git a/contrib/linux-kernel/test/test.c b/contrib/linux-kernel/test/test.c index 9064be793..6cd1730bb 100644 --- a/contrib/linux-kernel/test/test.c +++ b/contrib/linux-kernel/test/test.c @@ -30,15 +30,15 @@ typedef struct { size_t compSize; } test_data_t; -test_data_t create_test_data(void) { +static test_data_t create_test_data(void) { test_data_t data; data.dataSize = 128 * 1024; - data.data = malloc(data.dataSize); + data.data = (char*)malloc(data.dataSize); CONTROL(data.data != NULL); - data.data2 = malloc(data.dataSize); + data.data2 = (char*)malloc(data.dataSize); CONTROL(data.data2 != NULL); data.compSize = zstd_compress_bound(data.dataSize); - data.comp = malloc(data.compSize); + data.comp = (char*)malloc(data.compSize); CONTROL(data.comp != NULL); memset(data.data, 0, data.dataSize); return data; @@ -54,26 +54,27 @@ static void free_test_data(test_data_t const *data) { #define MAX(a, b) ((a) > (b) ? (a) : (b)) static void test_btrfs(test_data_t const *data) { - fprintf(stderr, "testing btrfs use cases... "); size_t const size = MIN(data->dataSize, 128 * 1024); + fprintf(stderr, "testing btrfs use cases... "); for (int level = -1; level < 16; ++level) { zstd_parameters params = zstd_get_params(level, size); - CONTROL(params.cParams.windowLog <= 17); size_t const workspaceSize = MAX(zstd_cstream_workspace_bound(¶ms.cParams), zstd_dstream_workspace_bound(size)); void *workspace = malloc(workspaceSize); - CONTROL(workspace != NULL); char const *ip = data->data; char const *iend = ip + size; char *op = data->comp; char *oend = op + data->compSize; + + CONTROL(params.cParams.windowLog <= 17); + CONTROL(workspace != NULL); { zstd_cstream *cctx = zstd_init_cstream(¶ms, size, workspace, workspaceSize); - CONTROL(cctx != NULL); zstd_out_buffer out = {NULL, 0, 0}; zstd_in_buffer in = {NULL, 0, 0}; + CONTROL(cctx != NULL); for (;;) { if (in.pos == in.size) { in.src = ip; @@ -108,9 +109,9 @@ static void test_btrfs(test_data_t const *data) { oend = op + size; { zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cParams.windowLog, workspace, workspaceSize); - CONTROL(dctx != NULL); zstd_out_buffer out = {NULL, 0, 0}; zstd_in_buffer in = {NULL, 0, 0}; + CONTROL(dctx != NULL); for (;;) { if (in.pos == in.size) { in.src = ip; @@ -125,15 +126,16 @@ static void test_btrfs(test_data_t const *data) { out.pos = 0; op += out.size; } - - size_t const ret = zstd_decompress_stream(dctx, &out, &in); - CONTROL(!zstd_is_error(ret)); - if (ret == 0) { - break; + { + size_t const ret = zstd_decompress_stream(dctx, &out, &in); + CONTROL(!zstd_is_error(ret)); + if (ret == 0) { + break; + } } } } - CONTROL(op - data->data2 == data->dataSize); + CONTROL((size_t)(op - data->data2) == data->dataSize); CONTROL(!memcmp(data->data, data->data2, data->dataSize)); free(workspace); } @@ -141,14 +143,14 @@ static void test_btrfs(test_data_t const *data) { } static void test_decompress_unzstd(test_data_t const *data) { - fprintf(stderr, "Testing decompress unzstd... "); size_t cSize; + fprintf(stderr, "Testing decompress unzstd... "); { zstd_parameters params = zstd_get_params(19, 0); size_t const wkspSize = zstd_cctx_workspace_bound(¶ms.cParams); void* wksp = malloc(wkspSize); - CONTROL(wksp != NULL); zstd_cctx* cctx = zstd_init_cctx(wksp, wkspSize); + CONTROL(wksp != NULL); CONTROL(cctx != NULL); cSize = zstd_compress_cctx(cctx, data->comp, data->compSize, data->data, data->dataSize, ¶ms); CONTROL(!zstd_is_error(cSize)); @@ -157,19 +159,21 @@ static void test_decompress_unzstd(test_data_t const *data) { { size_t const wkspSize = zstd_dctx_workspace_bound(); void* wksp = malloc(wkspSize); - CONTROL(wksp != NULL); zstd_dctx* dctx = zstd_init_dctx(wksp, wkspSize); + CONTROL(wksp != NULL); CONTROL(dctx != NULL); - size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize); - CONTROL(!zstd_is_error(dSize)); - CONTROL(dSize == data->dataSize); + { + size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize); + CONTROL(!zstd_is_error(dSize)); + CONTROL(dSize == data->dataSize); + } CONTROL(!memcmp(data->data, data->data2, data->dataSize)); free(wksp); } fprintf(stderr, "Ok\n"); } -static void test_f2fs() { +static void test_f2fs(void) { fprintf(stderr, "testing f2fs uses... "); CONTROL(zstd_min_clevel() < 0); CONTROL(zstd_max_clevel() == 22); @@ -182,7 +186,7 @@ static void __attribute__((noinline)) use(void *x) { asm volatile("" : "+r"(x)); } -static void __attribute__((noinline)) set_stack() { +static void __attribute__((noinline)) set_stack(void) { char stack[8192]; g_stack = stack; @@ -190,14 +194,16 @@ static void __attribute__((noinline)) set_stack() { use(g_stack); } -static void __attribute__((noinline)) check_stack() { +static void __attribute__((noinline)) check_stack(void) { size_t cleanStack = 0; while (cleanStack < 8192 && g_stack[cleanStack] == 0x33) { ++cleanStack; } - size_t const stackSize = 8192 - cleanStack; - fprintf(stderr, "Maximum stack size: %zu\n", stackSize); - CONTROL(stackSize <= 2048 + 512); + { + size_t const stackSize = 8192 - cleanStack; + fprintf(stderr, "Maximum stack size: %zu\n", stackSize); + CONTROL(stackSize <= 2048 + 512); + } } static void test_stack_usage(test_data_t const *data) { diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 128b08019..1a77139ee 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -47,7 +47,9 @@ * Disable when MSAN is enabled. */ #if defined(__linux__) || defined(__linux) || defined(__APPLE__) -# if ZSTD_MEMORY_SANITIZER || ZSTD_DATAFLOW_SANITIZER +# if ZSTD_MEMORY_SANITIZER +# define HUF_ASM_SUPPORTED 0 +# elif ZSTD_DATAFLOW_SANITIZER # define HUF_ASM_SUPPORTED 0 # else # define HUF_ASM_SUPPORTED 1 From cc22042da0819b37cf69175bd92fe26a2975eea7 Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Fri, 24 Sep 2021 08:57:16 +0800 Subject: [PATCH 185/274] Fix a C89 error in msvc Variables (r) must be declared at the beginning of a code block. This causes msvc2012 to fail to compile 64-bit build. --- lib/compress/zstd_lazy.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index ed50550f3..fef28de8d 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -881,8 +881,11 @@ typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 repr static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { assert(val != 0); # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r=0; - return _BitScanForward64(&r, val) ? (U32)r : 0; /* _BitScanForward64 not defined outside of x86/64 */ + { + unsigned long r = 0; + /* _BitScanForward64 is not defined outside of x64 */ + return _BitScanForward64(&r, val) ? (U32)r : 0; + } # elif (defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))) if (sizeof(size_t) == 4) { U32 mostSignificantWord = (U32)(val >> 32); From 95f492ea17834a6fb21013d2db0d03e0f12db025 Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Fri, 24 Sep 2021 19:24:29 +0800 Subject: [PATCH 186/274] Don't initialize the first parameter of _BitScanReverse* functions Like the document example, no need to initialize `r` to 0. https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64 --- lib/common/bitstream.h | 2 +- lib/common/zstd_internal.h | 2 +- lib/compress/zstd_compress_internal.h | 4 ++-- lib/dictBuilder/zdict.c | 10 ++++------ lib/legacy/zstd_v01.c | 3 +-- lib/legacy/zstd_v02.c | 5 ++--- lib/legacy/zstd_v03.c | 5 ++--- lib/legacy/zstd_v04.c | 5 ++--- lib/legacy/zstd_v05.c | 5 ++--- lib/legacy/zstd_v06.c | 5 ++--- lib/legacy/zstd_v07.c | 5 ++--- 11 files changed, 21 insertions(+), 30 deletions(-) diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index 48aad7f3a..cefa1196b 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -145,7 +145,7 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val) # if STATIC_BMI2 == 1 return _lzcnt_u32(val) ^ 31; # else - unsigned long r = 0; + unsigned long r; return _BitScanReverse(&r, val) ? (unsigned)r : 0; # endif # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index aaf7d4665..ba1b7bbc8 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -358,7 +358,7 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus # if STATIC_BMI2 == 1 return _lzcnt_u32(val)^31; # else - unsigned long r=0; + unsigned long r; return _BitScanReverse(&r, val) ? (unsigned)r : 0; # endif # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 3dab83255..6821c9df8 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -708,7 +708,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # if STATIC_BMI2 return _lzcnt_u64(val) >> 3; # else - unsigned long r = 0; + unsigned long r; return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0; # endif # elif defined(__GNUC__) && (__GNUC__ >= 4) @@ -723,7 +723,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r = 0; + unsigned long r; return _BitScanReverse( &r, (unsigned long)val ) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (__builtin_clz((U32)val) >> 3); diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index 9edc77fe8..2421f40f3 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -159,9 +159,8 @@ static unsigned ZDICT_NbCommonBytes (size_t val) } else { /* Big Endian CPU */ if (MEM_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r = 0; - _BitScanReverse64( &r, val ); - return (unsigned)(r>>3); + unsigned long r; + return _BitScanReverse64(&r, val) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_clzll(val) >> 3); # else @@ -174,9 +173,8 @@ static unsigned ZDICT_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r = 0; - _BitScanReverse( &r, (unsigned long)val ); - return (unsigned)(r>>3); + unsigned long r; + return _BitScanReverse(&r, (unsigned long)val) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_clz((U32)val) >> 3); # else diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 7ab554797..6be9c8105 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -343,8 +343,7 @@ FORCE_INLINE unsigned FSE_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ unsigned long r; - _BitScanReverse ( &r, val ); - return (unsigned) r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (GCC_VERSION >= 304) /* GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index 89fdc7169..f26b99bc8 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -353,9 +353,8 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); MEM_STATIC unsigned BIT_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 5262d515a..744bde515 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -356,9 +356,8 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); MEM_STATIC unsigned BIT_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index bee1b99dd..4d336b59f 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -627,9 +627,8 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); MEM_STATIC unsigned BIT_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index eb8966bb4..bc293661e 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -756,9 +756,8 @@ MEM_STATIC size_t BITv05_readBitsFast(BITv05_DStream_t* bitD, unsigned nbBits); MEM_STATIC unsigned BITv05_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index fcb16d4d8..7d6a35922 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -860,9 +860,8 @@ MEM_STATIC size_t BITv06_readBitsFast(BITv06_DStream_t* bitD, unsigned nbBits); MEM_STATIC unsigned BITv06_highbit32 ( U32 val) { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 0d0e46609..1449ef3ab 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -530,9 +530,8 @@ MEM_STATIC size_t BITv07_readBitsFast(BITv07_DStream_t* bitD, unsigned nbBits); MEM_STATIC unsigned BITv07_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; - _BitScanReverse ( &r, val ); - return (unsigned) r; + unsigned long r; + return _BitScanReverse(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; # else /* Software version */ From e5ba858270929080f03be821c53c93b8a05a42e0 Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Fri, 24 Sep 2021 19:40:24 +0800 Subject: [PATCH 187/274] Don't initialize the first parameter of _BitScanForward* functions Like the document example, no need to initialize `r` to 0. https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64 --- lib/common/entropy_common.c | 2 +- lib/common/zstd_internal.h | 4 ++-- lib/compress/zstd_compress_internal.h | 4 ++-- lib/compress/zstd_lazy.c | 2 +- lib/dictBuilder/zdict.c | 10 ++++------ 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index 6ba1f2209..dd80b2ccc 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -43,7 +43,7 @@ static U32 FSE_ctz(U32 val) assert(val != 0); { # if defined(_MSC_VER) /* Visual */ - unsigned long r=0; + unsigned long r; return _BitScanForward(&r, val) ? (unsigned)r : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ return __builtin_ctz(val); diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index ba1b7bbc8..246022c5f 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -391,7 +391,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) # if STATIC_BMI2 return _tzcnt_u64(val); # else - unsigned long r = 0; + unsigned long r; return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; # endif # elif defined(__GNUC__) && (__GNUC__ >= 4) @@ -409,7 +409,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r=0; + unsigned long r; return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (__builtin_ctz((U32)val) >> 3); diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 6821c9df8..bc30daa75 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -672,7 +672,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # if STATIC_BMI2 return _tzcnt_u64(val) >> 3; # else - unsigned long r = 0; + unsigned long r; return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; # endif # elif defined(__GNUC__) && (__GNUC__ >= 4) @@ -690,7 +690,7 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r=0; + unsigned long r; return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (__builtin_ctz((U32)val) >> 3); diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index fef28de8d..ac84b479f 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -882,7 +882,7 @@ static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { assert(val != 0); # if defined(_MSC_VER) && defined(_WIN64) { - unsigned long r = 0; + unsigned long r; /* _BitScanForward64 is not defined outside of x64 */ return _BitScanForward64(&r, val) ? (U32)r : 0; } diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index 2421f40f3..ea00eafc7 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -135,9 +135,8 @@ static unsigned ZDICT_NbCommonBytes (size_t val) if (MEM_isLittleEndian()) { if (MEM_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r = 0; - _BitScanForward64( &r, (U64)val ); - return (unsigned)(r>>3); + unsigned long r; + return _BitScanForward64(&r, (U64)val) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_ctzll((U64)val) >> 3); # else @@ -146,9 +145,8 @@ static unsigned ZDICT_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r=0; - _BitScanForward( &r, (U32)val ); - return (unsigned)(r>>3); + unsigned long r; + return _BitScanForward(&r, (U32)val) ? (unsigned)(r >> 3) : 0; # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_ctz((U32)val) >> 3); # else From 71526e6f296c4d31b21ba93862698405809ba2c6 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Fri, 24 Sep 2021 21:50:37 +0200 Subject: [PATCH 188/274] [contrib][linux] Fix -Wundef inside Linux kernel tree Commit d7ef97a013b5 ("[build] Fix oss-fuzz build with the dataflow sanitizer") broke build inside Linux-kernel after 'import', as it no longer can conditionally remove ZSTD_MEMORY_SANITIZER definition from the #if DEF_A || DEF_B block. This emits -Wundef warning which can be treated as error. Split this preprocessor condition into two separate conditions to fix this. Fixes: d7ef97a013b5 ("[build] Fix oss-fuzz build with the dataflow sanitizer") Signed-off-by: Alexander Lobakin --- lib/decompress/huf_decompress.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 128b08019..9f711f39e 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -47,11 +47,13 @@ * Disable when MSAN is enabled. */ #if defined(__linux__) || defined(__linux) || defined(__APPLE__) -# if ZSTD_MEMORY_SANITIZER || ZSTD_DATAFLOW_SANITIZER +# if ZSTD_MEMORY_SANITIZER +# define HUF_ASM_SUPPORTED 0 +# elif ZSTD_DATAFLOW_SANITIZER # define HUF_ASM_SUPPORTED 0 # else # define HUF_ASM_SUPPORTED 1 -#endif +# endif #else # define HUF_ASM_SUPPORTED 0 #endif From 02296cac8293bdc68cd39f998dbba05a301461f3 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Sat, 25 Sep 2021 01:19:11 +0200 Subject: [PATCH 189/274] decompress: conditionally remove legacy members from context Remove the then unneeded variables from the struct, and all accesses to them. --- lib/decompress/zstd_decompress.c | 4 ++++ lib/decompress/zstd_decompress_internal.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 88a5ceebb..bcf36b911 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -255,8 +255,10 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) dctx->inBuffSize = 0; dctx->outBuffSize = 0; dctx->streamStage = zdss_init; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) dctx->legacyContext = NULL; dctx->previousLegacyVersion = 0; +#endif dctx->noForwardProgress = 0; dctx->oversizedDuration = 0; dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); @@ -1947,7 +1949,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB DEBUGLOG(5, "stage zdss_init => transparent reset "); zds->streamStage = zdss_loadHeader; zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) zds->legacyVersion = 0; +#endif zds->hostageByte = 0; zds->expectedOutBuffer = *output; ZSTD_FALLTHROUGH; diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index ebda0c903..cb43539ad 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -158,9 +158,11 @@ struct ZSTD_DCtx_s size_t outStart; size_t outEnd; size_t lhSize; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) void* legacyContext; U32 previousLegacyVersion; U32 legacyVersion; +#endif U32 hostageByte; int noForwardProgress; ZSTD_bufferMode_e outBufferMode; From 0d455406950cbd5c2ab737e0a9d03a5d86c8e603 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Sun, 26 Sep 2021 11:14:35 +0200 Subject: [PATCH 190/274] decompress: conditionally remove bmi2 from context Use an helper function, which will just return 0 in case the feature is disabled. Allows constant propagation and removal of dead code. --- lib/decompress/zstd_decompress.c | 4 +++- lib/decompress/zstd_decompress_block.c | 18 +++++++++--------- lib/decompress/zstd_decompress_internal.h | 10 ++++++++++ tests/fullbench.c | 2 +- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index bcf36b911..377c87d26 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -261,7 +261,9 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) #endif dctx->noForwardProgress = 0; dctx->oversizedDuration = 0; - dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); +#if DYNAMIC_BMI2 + dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()) +#endif dctx->ddictSet = NULL; ZSTD_DCtx_resetParameters(dctx); #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 169058844..054e62526 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -133,11 +133,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, if (singleStream) { hufSuccess = HUF_decompress1X_usingDTable_bmi2( dctx->litBuffer, litSize, istart+lhSize, litCSize, - dctx->HUFptr, dctx->bmi2); + dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx)); } else { hufSuccess = HUF_decompress4X_usingDTable_bmi2( dctx->litBuffer, litSize, istart+lhSize, litCSize, - dctx->HUFptr, dctx->bmi2); + dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx)); } } else { if (singleStream) { @@ -150,13 +150,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, hufSuccess = HUF_decompress1X1_DCtx_wksp_bmi2( dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->workspace, - sizeof(dctx->workspace), dctx->bmi2); + sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx)); #endif } else { hufSuccess = HUF_decompress4X_hufOnly_wksp_bmi2( dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->workspace, - sizeof(dctx->workspace), dctx->bmi2); + sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx)); } } @@ -620,7 +620,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, LL_defaultDTable, dctx->fseEntropy, dctx->ddictIsCold, nbSeq, dctx->workspace, sizeof(dctx->workspace), - dctx->bmi2); + ZSTD_DCtx_get_bmi2(dctx)); RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed"); ip += llhSize; } @@ -632,7 +632,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, OF_defaultDTable, dctx->fseEntropy, dctx->ddictIsCold, nbSeq, dctx->workspace, sizeof(dctx->workspace), - dctx->bmi2); + ZSTD_DCtx_get_bmi2(dctx)); RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed"); ip += ofhSize; } @@ -644,7 +644,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, ML_defaultDTable, dctx->fseEntropy, dctx->ddictIsCold, nbSeq, dctx->workspace, sizeof(dctx->workspace), - dctx->bmi2); + ZSTD_DCtx_get_bmi2(dctx)); RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed"); ip += mlhSize; } @@ -1379,7 +1379,7 @@ ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, { DEBUGLOG(5, "ZSTD_decompressSequences"); #if DYNAMIC_BMI2 - if (dctx->bmi2) { + if (ZSTD_DCtx_get_bmi2(dctx)) { return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } #endif @@ -1403,7 +1403,7 @@ ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, { DEBUGLOG(5, "ZSTD_decompressSequencesLong"); #if DYNAMIC_BMI2 - if (dctx->bmi2) { + if (ZSTD_DCtx_get_bmi2(dctx)) { return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } #endif diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index cb43539ad..2a15bd874 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -136,7 +136,9 @@ struct ZSTD_DCtx_s size_t litSize; size_t rleSize; size_t staticSize; +#if DYNAMIC_BMI2 != 0 int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ +#endif /* dictionary */ ZSTD_DDict* ddictLocal; @@ -185,6 +187,14 @@ struct ZSTD_DCtx_s #endif }; /* typedef'd to ZSTD_DCtx within "zstd.h" */ +MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) { +#if DYNAMIC_BMI2 != 0 + return dctx->bmi2; +#else + (void)dctx; + return 0; +#endif +} /*-******************************************************* * Shared internal functions diff --git a/tests/fullbench.c b/tests/fullbench.c index a71117e09..dc20b837b 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -177,7 +177,7 @@ FORCE_NOINLINE size_t ZSTD_decodeLiteralsHeader(ZSTD_DCtx* dctx, void const* src dctx->entropy.hufTable, istart+lhSize, litCSize, dctx->workspace, sizeof(dctx->workspace), - dctx->bmi2); + ZSTD_DCtx_get_bmi2(dctx)); #else return HUF_readDTableX2_wksp( dctx->entropy.hufTable, From 6763f403318034372b8d52de73a23066d04ec750 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Sun, 26 Sep 2021 10:59:05 +0200 Subject: [PATCH 191/274] zstd_decompress: use a helper function for context create Multiple ZSTD_createDCtx* functions call other (public) ZSTD_createDCtx* functions, this makes it harder for humans and compilers to throw out code that is not used. This farms out the logic into a static function, if a program only uses a single ZSTD_createDCtx variant, all others can be easily dropped and the remaining implementation can be specialized. --- lib/decompress/zstd_decompress.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 377c87d26..4a4b3f72a 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -262,7 +262,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) dctx->noForwardProgress = 0; dctx->oversizedDuration = 0; #if DYNAMIC_BMI2 - dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()) + dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); #endif dctx->ddictSet = NULL; ZSTD_DCtx_resetParameters(dctx); @@ -284,8 +284,7 @@ ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) return dctx; } -ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) -{ +static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) { if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem); @@ -296,10 +295,15 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) } } +ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDCtx_internal(customMem); +} + ZSTD_DCtx* ZSTD_createDCtx(void) { DEBUGLOG(3, "ZSTD_createDCtx"); - return ZSTD_createDCtx_advanced(ZSTD_defaultCMem); + return ZSTD_createDCtx_internal(ZSTD_defaultCMem); } static void ZSTD_clearDict(ZSTD_DCtx* dctx) @@ -1082,7 +1086,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr { #if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1) size_t regenSize; - ZSTD_DCtx* const dctx = ZSTD_createDCtx(); + ZSTD_DCtx* const dctx = ZSTD_createDCtx_internal(ZSTD_defaultCMem); RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!"); regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize); ZSTD_freeDCtx(dctx); @@ -1547,7 +1551,7 @@ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, ZSTD_DStream* ZSTD_createDStream(void) { DEBUGLOG(3, "ZSTD_createDStream"); - return ZSTD_createDStream_advanced(ZSTD_defaultCMem); + return ZSTD_createDCtx_internal(ZSTD_defaultCMem); } ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize) @@ -1557,7 +1561,7 @@ ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize) ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem) { - return ZSTD_createDCtx_advanced(customMem); + return ZSTD_createDCtx_internal(customMem); } size_t ZSTD_freeDStream(ZSTD_DStream* zds) From 70a80b6be8d88c7a2cda611e0fcd8c2a8096c3b8 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 26 Sep 2021 06:48:52 -0700 Subject: [PATCH 192/274] minor : makes the "stable" property of Zstandard format more prominent --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2ab80998..09683a66f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ __Zstandard__, or `zstd` as short version, is a fast lossless compression algori targeting real-time compression scenarios at zlib-level and better compression ratios. It's backed by a very fast entropy stage, provided by [Huff0 and FSE library](https://github.com/Cyan4973/FiniteStateEntropy). -The project is provided as an open-source dual [BSD](LICENSE) and [GPLv2](COPYING) licensed **C** library, +Zstandard's format is stable and documented in RFC8878. Several independent implementations are already available. +This repository represents the reference implementation, provided as an open-source dual [BSD](LICENSE) and [GPLv2](COPYING) licensed **C** library, and a command line utility producing and decoding `.zst`, `.gz`, `.xz` and `.lz4` files. Should your project require another programming language, a list of known ports and bindings is provided on [Zstandard homepage](http://www.zstd.net/#other-languages). From ecb2daeaa98bbe1774162f7a3f8185029d493588 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 26 Sep 2021 06:58:10 -0700 Subject: [PATCH 193/274] added link to RFC --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 09683a66f..44cce47ee 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ __Zstandard__, or `zstd` as short version, is a fast lossless compression algori targeting real-time compression scenarios at zlib-level and better compression ratios. It's backed by a very fast entropy stage, provided by [Huff0 and FSE library](https://github.com/Cyan4973/FiniteStateEntropy). -Zstandard's format is stable and documented in RFC8878. Several independent implementations are already available. +Zstandard's format is stable and documented in [RFC8878](https://datatracker.ietf.org/doc/html/rfc8878). Multiple independent implementations are already available. This repository represents the reference implementation, provided as an open-source dual [BSD](LICENSE) and [GPLv2](COPYING) licensed **C** library, and a command line utility producing and decoding `.zst`, `.gz`, `.xz` and `.lz4` files. Should your project require another programming language, From 2ed14c2476a59a105a13fc05e6127122c07e6caa Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 26 Sep 2021 08:44:18 -0700 Subject: [PATCH 194/274] minor : fix comment provide correct reasons to include zstd_internal.h --- lib/decompress/zstd_decompress_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index ebda0c903..0b1bf426f 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -20,7 +20,7 @@ * Dependencies *********************************************************/ #include "../common/mem.h" /* BYTE, U16, U32 */ -#include "../common/zstd_internal.h" /* ZSTD_seqSymbol */ +#include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */ From ae986fcdb861c44ee4267fc4b3dcf0a4cd2ee724 Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Sun, 26 Sep 2021 10:41:39 +0800 Subject: [PATCH 195/274] Use __assume(0) for unreachable code path in msvc msvc will optimize away the condition check. --- lib/common/bitstream.h | 12 ++++++-- lib/common/entropy_common.c | 10 +++++-- lib/common/zstd_internal.h | 30 ++++++++++++++++---- lib/compress/zstd_compress_internal.h | 40 +++++++++++++++++++++------ lib/compress/zstd_lazy.c | 13 +++++---- lib/dictBuilder/zdict.c | 40 +++++++++++++++++++++------ 6 files changed, 113 insertions(+), 32 deletions(-) diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index cefa1196b..696719eaf 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -143,10 +143,16 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val) { # if defined(_MSC_VER) /* Visual */ # if STATIC_BMI2 == 1 - return _lzcnt_u32(val) ^ 31; + return _lzcnt_u32(val) ^ 31; # else - unsigned long r; - return _BitScanReverse(&r, val) ? (unsigned)r : 0; + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, val); + return (unsigned)r; + } else { + /* Should not reach this code path */ + __assume(0); + } # endif # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ return __builtin_clz (val) ^ 31; diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index dd80b2ccc..3ac00255f 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -43,8 +43,14 @@ static U32 FSE_ctz(U32 val) assert(val != 0); { # if defined(_MSC_VER) /* Visual */ - unsigned long r; - return _BitScanForward(&r, val) ? (unsigned)r : 0; + if (val != 0) { + unsigned long r; + _BitScanForward(&r, val); + return (unsigned)r; + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ return __builtin_ctz(val); # elif defined(__ICCARM__) /* IAR Intrinsic */ diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 246022c5f..4db5b00a7 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -358,8 +358,14 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus # if STATIC_BMI2 == 1 return _lzcnt_u32(val)^31; # else - unsigned long r; - return _BitScanReverse(&r, val) ? (unsigned)r : 0; + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, val); + return (unsigned)r; + } else { + /* Should not reach this code path */ + __assume(0); + } # endif # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */ return __builtin_clz (val) ^ 31; @@ -391,8 +397,14 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) # if STATIC_BMI2 return _tzcnt_u64(val); # else - unsigned long r; - return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, (U64)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # endif # elif defined(__GNUC__) && (__GNUC__ >= 4) return __builtin_ctzll((U64)val); @@ -409,8 +421,14 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r; - return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanForward(&r, (U32)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (__builtin_ctz((U32)val) >> 3); # else diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index bc30daa75..cf0b8061a 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -672,8 +672,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # if STATIC_BMI2 return _tzcnt_u64(val) >> 3; # else - unsigned long r; - return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, (U64)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # endif # elif defined(__GNUC__) && (__GNUC__ >= 4) return (__builtin_ctzll((U64)val) >> 3); @@ -690,8 +696,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r; - return _BitScanForward( &r, (U32)val ) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanForward(&r, (U32)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (__builtin_ctz((U32)val) >> 3); # else @@ -708,8 +720,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # if STATIC_BMI2 return _lzcnt_u64(val) >> 3; # else - unsigned long r; - return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanReverse64(&r, (U64)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # endif # elif defined(__GNUC__) && (__GNUC__ >= 4) return (__builtin_clzll(val) >> 3); @@ -723,8 +741,14 @@ static unsigned ZSTD_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r; - return _BitScanReverse( &r, (unsigned long)val ) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, (unsigned long)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (__builtin_clz((U32)val) >> 3); # else diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index ac84b479f..cbac712a5 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -881,11 +881,14 @@ typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 repr static U32 ZSTD_VecMask_next(ZSTD_VecMask val) { assert(val != 0); # if defined(_MSC_VER) && defined(_WIN64) - { - unsigned long r; - /* _BitScanForward64 is not defined outside of x64 */ - return _BitScanForward64(&r, val) ? (U32)r : 0; - } + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, val); + return (U32)(r); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif (defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))) if (sizeof(size_t) == 4) { U32 mostSignificantWord = (U32)(val >> 32); diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index ea00eafc7..d93b202e7 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -135,8 +135,14 @@ static unsigned ZDICT_NbCommonBytes (size_t val) if (MEM_isLittleEndian()) { if (MEM_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r; - return _BitScanForward64(&r, (U64)val) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, (U64)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_ctzll((U64)val) >> 3); # else @@ -145,8 +151,14 @@ static unsigned ZDICT_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r; - return _BitScanForward(&r, (U32)val) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanForward(&r, (U32)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_ctz((U32)val) >> 3); # else @@ -157,8 +169,14 @@ static unsigned ZDICT_NbCommonBytes (size_t val) } else { /* Big Endian CPU */ if (MEM_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) - unsigned long r; - return _BitScanReverse64(&r, val) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanReverse64(&r, val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_clzll(val) >> 3); # else @@ -171,8 +189,14 @@ static unsigned ZDICT_NbCommonBytes (size_t val) # endif } else { /* 32 bits */ # if defined(_MSC_VER) - unsigned long r; - return _BitScanReverse(&r, (unsigned long)val) ? (unsigned)(r >> 3) : 0; + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, (unsigned long)val); + return (unsigned)(r >> 3); + } else { + /* Should not reach this code path */ + __assume(0); + } # elif defined(__GNUC__) && (__GNUC__ >= 3) return (unsigned)(__builtin_clz((U32)val) >> 3); # else From a07ddb47f7d43529dde4922786516f7ec14754cb Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 27 Sep 2021 13:56:07 -0700 Subject: [PATCH 196/274] [huf] Fix OSS-Fuzz assert PR #2784 introduced a bug in the decompressor that caused some valid inputs to fail to decompress. The bitstream isn't reloaded after the 4X* loop if the number of elements remaining is small enough, causing us to read more bits than are available in the bitcontainer. This was caught by the MSAN fuzzer in OSS-Fuzz because the assembly implementation isn't used in the MSAN build. Credit to OSS-Fuzz. --- lib/decompress/huf_decompress.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 128b08019..7529034ef 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -531,6 +531,8 @@ HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, cons HUF_DECODE_SYMBOLX1_2(p, bitDPtr); HUF_DECODE_SYMBOLX1_0(p, bitDPtr); } + } else { + BIT_reloadDStream(bitDPtr); } /* [0-3] symbols remaining */ @@ -1218,6 +1220,8 @@ HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, HUF_DECODE_SYMBOLX2_0(p, bitDPtr); } } + } else { + BIT_reloadDStream(bitDPtr); } /* closer to end : up to 2 symbols at a time */ From b8fd6bf30cd0c25b660b95aac7aacad55c03dc9a Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Wed, 18 Aug 2021 06:52:17 -0700 Subject: [PATCH 197/274] Skip most long matches in lazy hash table update --- lib/compress/zstd_lazy.c | 17 +- tests/regression/results.csv | 1580 +++++++++++++++++----------------- 2 files changed, 804 insertions(+), 793 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index ed50550f3..e9ee6ebd4 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -971,7 +971,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, U16 const* ta * Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries, * but not beyond iLimit. */ -static void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base, +FORCE_INLINE_TEMPLATE void ZSTD_row_fillHashCache(ZSTD_matchState_t* ms, const BYTE* base, U32 const rowLog, U32 const mls, U32 idx, const BYTE* const iLimit) { @@ -1022,9 +1022,20 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const U32* const hashTable = ms->hashTable; U16* const tagTable = ms->tagTable; U32 const hashLog = ms->rowHashLog; + U32 idx = ms->nextToUpdate; const BYTE* const base = ms->window.base; const U32 target = (U32)(ip - base); - U32 idx = ms->nextToUpdate; + const U32 kMaxPositionsToUpdate = 256; + + assert(target >= idx); + if (useCache) { + /* Only skip positions when using hash cache, i.e. + if we are loading a dict, don't skip anything */ + if (UNLIKELY(target - idx > kMaxPositionsToUpdate)) { + idx = target - kMaxPositionsToUpdate; + ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); + } + } DEBUGLOG(6, "ZSTD_row_update_internal(): nextToUpdate=%u, current=%u", idx, target); for (; idx < target; ++idx) { @@ -1037,7 +1048,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); assert(hash == ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls)); - ((BYTE*)tagRow)[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; + tagRow[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; row[pos] = idx; } ms->nextToUpdate = target; diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 923b4498b..66be6cb5b 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -1,72 +1,72 @@ Data, Config, Method, Total compressed size -silesia.tar, level -5, compress simple, 7359401 -silesia.tar, level -3, compress simple, 6901672 -silesia.tar, level -1, compress simple, 6182241 -silesia.tar, level 0, compress simple, 4861424 -silesia.tar, level 1, compress simple, 5331946 -silesia.tar, level 3, compress simple, 4861424 +silesia.tar, level -5, compress simple, 6738593 +silesia.tar, level -3, compress simple, 6446372 +silesia.tar, level -1, compress simple, 6186042 +silesia.tar, level 0, compress simple, 4861423 +silesia.tar, level 1, compress simple, 5334885 +silesia.tar, level 3, compress simple, 4861423 silesia.tar, level 4, compress simple, 4799632 -silesia.tar, level 5, compress simple, 4650202 -silesia.tar, level 6, compress simple, 4616811 -silesia.tar, level 7, compress simple, 4576829 -silesia.tar, level 9, compress simple, 4552584 -silesia.tar, level 13, compress simple, 4502956 -silesia.tar, level 16, compress simple, 4360527 -silesia.tar, level 19, compress simple, 4267266 -silesia.tar, uncompressed literals, compress simple, 4861424 -silesia.tar, uncompressed literals optimal, compress simple, 4267266 -silesia.tar, huffman literals, compress simple, 6182241 -github.tar, level -5, compress simple, 66914 -github.tar, level -3, compress simple, 52127 -github.tar, level -1, compress simple, 42560 +silesia.tar, level 5, compress simple, 4650387 +silesia.tar, level 6, compress simple, 4617089 +silesia.tar, level 7, compress simple, 4576951 +silesia.tar, level 9, compress simple, 4552638 +silesia.tar, level 13, compress simple, 4491768 +silesia.tar, level 16, compress simple, 4356834 +silesia.tar, level 19, compress simple, 4264388 +silesia.tar, uncompressed literals, compress simple, 4861423 +silesia.tar, uncompressed literals optimal, compress simple, 4264388 +silesia.tar, huffman literals, compress simple, 6186042 +github.tar, level -5, compress simple, 46856 +github.tar, level -3, compress simple, 43754 +github.tar, level -1, compress simple, 42490 github.tar, level 0, compress simple, 38441 -github.tar, level 1, compress simple, 39200 +github.tar, level 1, compress simple, 39265 github.tar, level 3, compress simple, 38441 github.tar, level 4, compress simple, 38467 -github.tar, level 5, compress simple, 38376 -github.tar, level 6, compress simple, 38610 -github.tar, level 7, compress simple, 38073 -github.tar, level 9, compress simple, 36767 -github.tar, level 13, compress simple, 35501 -github.tar, level 16, compress simple, 40471 -github.tar, level 19, compress simple, 32134 +github.tar, level 5, compress simple, 38394 +github.tar, level 6, compress simple, 38669 +github.tar, level 7, compress simple, 38153 +github.tar, level 9, compress simple, 36768 +github.tar, level 13, compress simple, 35621 +github.tar, level 16, compress simple, 40255 +github.tar, level 19, compress simple, 32837 github.tar, uncompressed literals, compress simple, 38441 -github.tar, uncompressed literals optimal, compress simple, 32134 -github.tar, huffman literals, compress simple, 42560 -silesia, level -5, compress cctx, 7354675 -silesia, level -3, compress cctx, 6902374 -silesia, level -1, compress cctx, 6177565 -silesia, level 0, compress cctx, 4849553 -silesia, level 1, compress cctx, 5309098 -silesia, level 3, compress cctx, 4849553 -silesia, level 4, compress cctx, 4786968 -silesia, level 5, compress cctx, 4638961 -silesia, level 6, compress cctx, 4605369 -silesia, level 7, compress cctx, 4567204 -silesia, level 9, compress cctx, 4543310 -silesia, level 13, compress cctx, 4493990 -silesia, level 16, compress cctx, 4359864 -silesia, level 19, compress cctx, 4296880 -silesia, long distance mode, compress cctx, 4849553 -silesia, multithreaded, compress cctx, 4849553 -silesia, multithreaded long distance mode, compress cctx, 4849553 +github.tar, uncompressed literals optimal, compress simple, 32837 +github.tar, huffman literals, compress simple, 42490 +silesia, level -5, compress cctx, 6737607 +silesia, level -3, compress cctx, 6444677 +silesia, level -1, compress cctx, 6178460 +silesia, level 0, compress cctx, 4849551 +silesia, level 1, compress cctx, 5313202 +silesia, level 3, compress cctx, 4849551 +silesia, level 4, compress cctx, 4786969 +silesia, level 5, compress cctx, 4639132 +silesia, level 6, compress cctx, 4605629 +silesia, level 7, compress cctx, 4567307 +silesia, level 9, compress cctx, 4543330 +silesia, level 13, compress cctx, 4482131 +silesia, level 16, compress cctx, 4360251 +silesia, level 19, compress cctx, 4283236 +silesia, long distance mode, compress cctx, 4849551 +silesia, multithreaded, compress cctx, 4849551 +silesia, multithreaded long distance mode, compress cctx, 4849551 silesia, small window log, compress cctx, 7084179 silesia, small hash log, compress cctx, 6526141 -silesia, small chain log, compress cctx, 4912197 -silesia, explicit params, compress cctx, 4794481 -silesia, uncompressed literals, compress cctx, 4849553 -silesia, uncompressed literals optimal, compress cctx, 4296880 -silesia, huffman literals, compress cctx, 6177565 -silesia, multithreaded with advanced params, compress cctx, 4849553 -github, level -5, compress cctx, 232315 +silesia, small chain log, compress cctx, 4912199 +silesia, explicit params, compress cctx, 4794917 +silesia, uncompressed literals, compress cctx, 4849551 +silesia, uncompressed literals optimal, compress cctx, 4283236 +silesia, huffman literals, compress cctx, 6178460 +silesia, multithreaded with advanced params, compress cctx, 4849551 +github, level -5, compress cctx, 205285 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 220760 +github, level -3, compress cctx, 190643 github, level -3 with dict, compress cctx, 48047 -github, level -1, compress cctx, 175468 +github, level -1, compress cctx, 175568 github, level -1 with dict, compress cctx, 43527 github, level 0, compress cctx, 136335 github, level 0 with dict, compress cctx, 41534 -github, level 1, compress cctx, 142365 +github, level 1, compress cctx, 142465 github, level 1 with dict, compress cctx, 42157 github, level 3, compress cctx, 136335 github, level 3 with dict, compress cctx, 41534 @@ -95,68 +95,68 @@ github, small chain log, compress github, explicit params, compress cctx, 140932 github, uncompressed literals, compress cctx, 136335 github, uncompressed literals optimal, compress cctx, 134064 -github, huffman literals, compress cctx, 175468 +github, huffman literals, compress cctx, 175568 github, multithreaded with advanced params, compress cctx, 141102 -silesia, level -5, zstdcli, 7354723 -silesia, level -3, zstdcli, 6902422 -silesia, level -1, zstdcli, 6177613 -silesia, level 0, zstdcli, 4849601 -silesia, level 1, zstdcli, 5309146 -silesia, level 3, zstdcli, 4849601 -silesia, level 4, zstdcli, 4787016 -silesia, level 5, zstdcli, 4639009 -silesia, level 6, zstdcli, 4605417 -silesia, level 7, zstdcli, 4567252 -silesia, level 9, zstdcli, 4543358 -silesia, level 13, zstdcli, 4494038 -silesia, level 16, zstdcli, 4359912 -silesia, level 19, zstdcli, 4296928 +silesia, level -5, zstdcli, 6737655 +silesia, level -3, zstdcli, 6444725 +silesia, level -1, zstdcli, 6178508 +silesia, level 0, zstdcli, 4849599 +silesia, level 1, zstdcli, 5313250 +silesia, level 3, zstdcli, 4849599 +silesia, level 4, zstdcli, 4787017 +silesia, level 5, zstdcli, 4639180 +silesia, level 6, zstdcli, 4605677 +silesia, level 7, zstdcli, 4567355 +silesia, level 9, zstdcli, 4543378 +silesia, level 13, zstdcli, 4482179 +silesia, level 16, zstdcli, 4360299 +silesia, level 19, zstdcli, 4283284 silesia, long distance mode, zstdcli, 4840807 -silesia, multithreaded, zstdcli, 4849601 +silesia, multithreaded, zstdcli, 4849599 silesia, multithreaded long distance mode, zstdcli, 4840807 silesia, small window log, zstdcli, 7095967 silesia, small hash log, zstdcli, 6526189 -silesia, small chain log, zstdcli, 4912245 -silesia, explicit params, zstdcli, 4795856 +silesia, small chain log, zstdcli, 4912247 +silesia, explicit params, zstdcli, 4796282 silesia, uncompressed literals, zstdcli, 5128030 -silesia, uncompressed literals optimal, zstdcli, 4319566 -silesia, huffman literals, zstdcli, 5326394 +silesia, uncompressed literals optimal, zstdcli, 4317944 +silesia, huffman literals, zstdcli, 5326317 silesia, multithreaded with advanced params, zstdcli, 5128030 -silesia.tar, level -5, zstdcli, 7363866 -silesia.tar, level -3, zstdcli, 6902158 -silesia.tar, level -1, zstdcli, 6182939 -silesia.tar, level 0, zstdcli, 4861512 -silesia.tar, level 1, zstdcli, 5333183 -silesia.tar, level 3, zstdcli, 4861512 -silesia.tar, level 4, zstdcli, 4800528 -silesia.tar, level 5, zstdcli, 4651160 -silesia.tar, level 6, zstdcli, 4618402 -silesia.tar, level 7, zstdcli, 4578884 -silesia.tar, level 9, zstdcli, 4553499 -silesia.tar, level 13, zstdcli, 4502960 -silesia.tar, level 16, zstdcli, 4360531 -silesia.tar, level 19, zstdcli, 4267270 -silesia.tar, no source size, zstdcli, 4861508 +silesia.tar, level -5, zstdcli, 6738934 +silesia.tar, level -3, zstdcli, 6448419 +silesia.tar, level -1, zstdcli, 6186912 +silesia.tar, level 0, zstdcli, 4861511 +silesia.tar, level 1, zstdcli, 5336318 +silesia.tar, level 3, zstdcli, 4861511 +silesia.tar, level 4, zstdcli, 4800529 +silesia.tar, level 5, zstdcli, 4651342 +silesia.tar, level 6, zstdcli, 4618674 +silesia.tar, level 7, zstdcli, 4579009 +silesia.tar, level 9, zstdcli, 4553551 +silesia.tar, level 13, zstdcli, 4491772 +silesia.tar, level 16, zstdcli, 4356838 +silesia.tar, level 19, zstdcli, 4264392 +silesia.tar, no source size, zstdcli, 4861507 silesia.tar, long distance mode, zstdcli, 4853225 -silesia.tar, multithreaded, zstdcli, 4861512 +silesia.tar, multithreaded, zstdcli, 4861511 silesia.tar, multithreaded long distance mode, zstdcli, 4853225 silesia.tar, small window log, zstdcli, 7101576 -silesia.tar, small hash log, zstdcli, 6529289 -silesia.tar, small chain log, zstdcli, 4917022 -silesia.tar, explicit params, zstdcli, 4821274 +silesia.tar, small hash log, zstdcli, 6529286 +silesia.tar, small chain log, zstdcli, 4917020 +silesia.tar, explicit params, zstdcli, 4821593 silesia.tar, uncompressed literals, zstdcli, 5129559 -silesia.tar, uncompressed literals optimal, zstdcli, 4310145 -silesia.tar, huffman literals, zstdcli, 5344915 +silesia.tar, uncompressed literals optimal, zstdcli, 4307404 +silesia.tar, huffman literals, zstdcli, 5347610 silesia.tar, multithreaded with advanced params, zstdcli, 5129559 -github, level -5, zstdcli, 234315 +github, level -5, zstdcli, 207285 github, level -5 with dict, zstdcli, 48718 -github, level -3, zstdcli, 222760 +github, level -3, zstdcli, 192643 github, level -3 with dict, zstdcli, 47395 -github, level -1, zstdcli, 177468 +github, level -1, zstdcli, 177568 github, level -1 with dict, zstdcli, 45170 github, level 0, zstdcli, 138335 github, level 0 with dict, zstdcli, 43148 -github, level 1, zstdcli, 144365 +github, level 1, zstdcli, 144465 github, level 1 with dict, zstdcli, 43682 github, level 3, zstdcli, 138335 github, level 3 with dict, zstdcli, 43148 @@ -185,36 +185,36 @@ github, small chain log, zstdcli, github, explicit params, zstdcli, 136197 github, uncompressed literals, zstdcli, 167915 github, uncompressed literals optimal, zstdcli, 159227 -github, huffman literals, zstdcli, 144365 +github, huffman literals, zstdcli, 144465 github, multithreaded with advanced params, zstdcli, 167915 -github.tar, level -5, zstdcli, 66918 -github.tar, level -5 with dict, zstdcli, 51529 -github.tar, level -3, zstdcli, 52131 -github.tar, level -3 with dict, zstdcli, 44246 -github.tar, level -1, zstdcli, 42564 -github.tar, level -1 with dict, zstdcli, 41140 +github.tar, level -5, zstdcli, 46860 +github.tar, level -5 with dict, zstdcli, 44575 +github.tar, level -3, zstdcli, 43758 +github.tar, level -3 with dict, zstdcli, 41451 +github.tar, level -1, zstdcli, 42494 +github.tar, level -1 with dict, zstdcli, 41135 github.tar, level 0, zstdcli, 38445 github.tar, level 0 with dict, zstdcli, 37999 -github.tar, level 1, zstdcli, 39204 -github.tar, level 1 with dict, zstdcli, 38288 +github.tar, level 1, zstdcli, 39269 +github.tar, level 1 with dict, zstdcli, 38284 github.tar, level 3, zstdcli, 38445 github.tar, level 3 with dict, zstdcli, 37999 github.tar, level 4, zstdcli, 38471 github.tar, level 4 with dict, zstdcli, 37952 -github.tar, level 5, zstdcli, 38380 -github.tar, level 5 with dict, zstdcli, 39032 -github.tar, level 6, zstdcli, 38614 -github.tar, level 6 with dict, zstdcli, 38614 -github.tar, level 7, zstdcli, 38077 -github.tar, level 7 with dict, zstdcli, 37873 -github.tar, level 9, zstdcli, 36771 -github.tar, level 9 with dict, zstdcli, 36623 -github.tar, level 13, zstdcli, 35505 -github.tar, level 13 with dict, zstdcli, 37134 -github.tar, level 16, zstdcli, 40475 -github.tar, level 16 with dict, zstdcli, 33382 -github.tar, level 19, zstdcli, 32138 -github.tar, level 19 with dict, zstdcli, 32713 +github.tar, level 5, zstdcli, 38398 +github.tar, level 5 with dict, zstdcli, 39048 +github.tar, level 6, zstdcli, 38673 +github.tar, level 6 with dict, zstdcli, 38660 +github.tar, level 7, zstdcli, 38157 +github.tar, level 7 with dict, zstdcli, 37914 +github.tar, level 9, zstdcli, 36772 +github.tar, level 9 with dict, zstdcli, 36650 +github.tar, level 13, zstdcli, 35625 +github.tar, level 13 with dict, zstdcli, 38730 +github.tar, level 16, zstdcli, 40259 +github.tar, level 16 with dict, zstdcli, 33643 +github.tar, level 19, zstdcli, 32841 +github.tar, level 19 with dict, zstdcli, 32899 github.tar, no source size, zstdcli, 38442 github.tar, no source size with dict, zstdcli, 38004 github.tar, long distance mode, zstdcli, 39730 @@ -223,84 +223,84 @@ github.tar, multithreaded long distance mode, zstdcli, github.tar, small window log, zstdcli, 198544 github.tar, small hash log, zstdcli, 129874 github.tar, small chain log, zstdcli, 41673 -github.tar, explicit params, zstdcli, 41227 +github.tar, explicit params, zstdcli, 41350 github.tar, uncompressed literals, zstdcli, 41126 -github.tar, uncompressed literals optimal, zstdcli, 35401 -github.tar, huffman literals, zstdcli, 38857 +github.tar, uncompressed literals optimal, zstdcli, 35392 +github.tar, huffman literals, zstdcli, 38781 github.tar, multithreaded with advanced params, zstdcli, 41126 -silesia, level -5, advanced one pass, 7354675 -silesia, level -3, advanced one pass, 6902374 -silesia, level -1, advanced one pass, 6177565 -silesia, level 0, advanced one pass, 4849553 -silesia, level 1, advanced one pass, 5309098 -silesia, level 3, advanced one pass, 4849553 -silesia, level 4, advanced one pass, 4786968 -silesia, level 5 row 1, advanced one pass, 4638961 -silesia, level 5 row 2, advanced one pass, 4640752 -silesia, level 5, advanced one pass, 4638961 -silesia, level 6, advanced one pass, 4605369 -silesia, level 7 row 1, advanced one pass, 4567204 -silesia, level 7 row 2, advanced one pass, 4564868 -silesia, level 7, advanced one pass, 4567204 -silesia, level 9, advanced one pass, 4543310 -silesia, level 11 row 1, advanced one pass, 4521399 -silesia, level 11 row 2, advanced one pass, 4519288 -silesia, level 12 row 1, advanced one pass, 4505153 -silesia, level 12 row 2, advanced one pass, 4503116 -silesia, level 13, advanced one pass, 4493990 -silesia, level 16, advanced one pass, 4359864 -silesia, level 19, advanced one pass, 4296880 -silesia, no source size, advanced one pass, 4849553 -silesia, long distance mode, advanced one pass, 4840737 -silesia, multithreaded, advanced one pass, 4849553 +silesia, level -5, advanced one pass, 6737607 +silesia, level -3, advanced one pass, 6444677 +silesia, level -1, advanced one pass, 6178460 +silesia, level 0, advanced one pass, 4849551 +silesia, level 1, advanced one pass, 5313202 +silesia, level 3, advanced one pass, 4849551 +silesia, level 4, advanced one pass, 4786969 +silesia, level 5 row 1, advanced one pass, 4640753 +silesia, level 5 row 2, advanced one pass, 4639132 +silesia, level 5, advanced one pass, 4639132 +silesia, level 6, advanced one pass, 4605629 +silesia, level 7 row 1, advanced one pass, 4564870 +silesia, level 7 row 2, advanced one pass, 4567307 +silesia, level 7, advanced one pass, 4567307 +silesia, level 9, advanced one pass, 4543330 +silesia, level 11 row 1, advanced one pass, 4519288 +silesia, level 11 row 2, advanced one pass, 4521524 +silesia, level 12 row 1, advanced one pass, 4503117 +silesia, level 12 row 2, advanced one pass, 4505093 +silesia, level 13, advanced one pass, 4482131 +silesia, level 16, advanced one pass, 4360251 +silesia, level 19, advanced one pass, 4283236 +silesia, no source size, advanced one pass, 4849551 +silesia, long distance mode, advanced one pass, 4840738 +silesia, multithreaded, advanced one pass, 4849551 silesia, multithreaded long distance mode, advanced one pass, 4840759 silesia, small window log, advanced one pass, 7095919 silesia, small hash log, advanced one pass, 6526141 -silesia, small chain log, advanced one pass, 4912197 -silesia, explicit params, advanced one pass, 4795856 +silesia, small chain log, advanced one pass, 4912199 +silesia, explicit params, advanced one pass, 4796282 silesia, uncompressed literals, advanced one pass, 5127982 -silesia, uncompressed literals optimal, advanced one pass, 4319518 -silesia, huffman literals, advanced one pass, 5326346 +silesia, uncompressed literals optimal, advanced one pass, 4317896 +silesia, huffman literals, advanced one pass, 5326269 silesia, multithreaded with advanced params, advanced one pass, 5127982 -silesia.tar, level -5, advanced one pass, 7359401 -silesia.tar, level -3, advanced one pass, 6901672 -silesia.tar, level -1, advanced one pass, 6182241 -silesia.tar, level 0, advanced one pass, 4861424 -silesia.tar, level 1, advanced one pass, 5331946 -silesia.tar, level 3, advanced one pass, 4861424 +silesia.tar, level -5, advanced one pass, 6738593 +silesia.tar, level -3, advanced one pass, 6446372 +silesia.tar, level -1, advanced one pass, 6186042 +silesia.tar, level 0, advanced one pass, 4861423 +silesia.tar, level 1, advanced one pass, 5334885 +silesia.tar, level 3, advanced one pass, 4861423 silesia.tar, level 4, advanced one pass, 4799632 -silesia.tar, level 5 row 1, advanced one pass, 4650202 -silesia.tar, level 5 row 2, advanced one pass, 4652862 -silesia.tar, level 5, advanced one pass, 4650202 -silesia.tar, level 6, advanced one pass, 4616811 -silesia.tar, level 7 row 1, advanced one pass, 4576829 -silesia.tar, level 7 row 2, advanced one pass, 4575393 -silesia.tar, level 7, advanced one pass, 4576829 -silesia.tar, level 9, advanced one pass, 4552584 -silesia.tar, level 11 row 1, advanced one pass, 4530256 -silesia.tar, level 11 row 2, advanced one pass, 4529461 -silesia.tar, level 12 row 1, advanced one pass, 4514568 -silesia.tar, level 12 row 2, advanced one pass, 4513604 -silesia.tar, level 13, advanced one pass, 4502956 -silesia.tar, level 16, advanced one pass, 4360527 -silesia.tar, level 19, advanced one pass, 4267266 -silesia.tar, no source size, advanced one pass, 4861424 -silesia.tar, long distance mode, advanced one pass, 4847752 -silesia.tar, multithreaded, advanced one pass, 4861508 +silesia.tar, level 5 row 1, advanced one pass, 4652862 +silesia.tar, level 5 row 2, advanced one pass, 4650387 +silesia.tar, level 5, advanced one pass, 4650387 +silesia.tar, level 6, advanced one pass, 4617089 +silesia.tar, level 7 row 1, advanced one pass, 4575392 +silesia.tar, level 7 row 2, advanced one pass, 4576951 +silesia.tar, level 7, advanced one pass, 4576951 +silesia.tar, level 9, advanced one pass, 4552638 +silesia.tar, level 11 row 1, advanced one pass, 4529458 +silesia.tar, level 11 row 2, advanced one pass, 4530416 +silesia.tar, level 12 row 1, advanced one pass, 4513603 +silesia.tar, level 12 row 2, advanced one pass, 4514499 +silesia.tar, level 13, advanced one pass, 4491768 +silesia.tar, level 16, advanced one pass, 4356834 +silesia.tar, level 19, advanced one pass, 4264388 +silesia.tar, no source size, advanced one pass, 4861423 +silesia.tar, long distance mode, advanced one pass, 4847753 +silesia.tar, multithreaded, advanced one pass, 4861507 silesia.tar, multithreaded long distance mode, advanced one pass, 4853221 silesia.tar, small window log, advanced one pass, 7101530 -silesia.tar, small hash log, advanced one pass, 6529231 -silesia.tar, small chain log, advanced one pass, 4917041 -silesia.tar, explicit params, advanced one pass, 4807381 +silesia.tar, small hash log, advanced one pass, 6529228 +silesia.tar, small chain log, advanced one pass, 4917039 +silesia.tar, explicit params, advanced one pass, 4807675 silesia.tar, uncompressed literals, advanced one pass, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass, 4310141 -silesia.tar, huffman literals, advanced one pass, 5344545 +silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 +silesia.tar, huffman literals, advanced one pass, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 -github, level -5, advanced one pass, 232315 +github, level -5, advanced one pass, 205285 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 220760 +github, level -3, advanced one pass, 190643 github, level -3 with dict, advanced one pass, 45395 -github, level -1, advanced one pass, 175468 +github, level -1, advanced one pass, 175568 github, level -1 with dict, advanced one pass, 43170 github, level 0, advanced one pass, 136335 github, level 0 with dict, advanced one pass, 41148 @@ -308,7 +308,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced one pass, 41148 github, level 0 with dict copy, advanced one pass, 41124 github, level 0 with dict load, advanced one pass, 42252 -github, level 1, advanced one pass, 142365 +github, level 1, advanced one pass, 142465 github, level 1 with dict, advanced one pass, 41682 github, level 1 with dict dms, advanced one pass, 41682 github, level 1 with dict dds, advanced one pass, 41682 @@ -326,16 +326,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced one pass, 41251 github, level 4 with dict copy, advanced one pass, 41216 github, level 4 with dict load, advanced one pass, 41159 -github, level 5 row 1, advanced one pass, 134584 -github, level 5 row 1 with dict dms, advanced one pass, 38758 -github, level 5 row 1 with dict dds, advanced one pass, 38728 -github, level 5 row 1 with dict copy, advanced one pass, 38759 -github, level 5 row 1 with dict load, advanced one pass, 41518 -github, level 5 row 2, advanced one pass, 135121 -github, level 5 row 2 with dict dms, advanced one pass, 38938 -github, level 5 row 2 with dict dds, advanced one pass, 38732 -github, level 5 row 2 with dict copy, advanced one pass, 38934 -github, level 5 row 2 with dict load, advanced one pass, 40725 +github, level 5 row 1, advanced one pass, 135121 +github, level 5 row 1 with dict dms, advanced one pass, 38938 +github, level 5 row 1 with dict dds, advanced one pass, 38732 +github, level 5 row 1 with dict copy, advanced one pass, 38934 +github, level 5 row 1 with dict load, advanced one pass, 40725 +github, level 5 row 2, advanced one pass, 134584 +github, level 5 row 2 with dict dms, advanced one pass, 38758 +github, level 5 row 2 with dict dds, advanced one pass, 38728 +github, level 5 row 2 with dict copy, advanced one pass, 38759 +github, level 5 row 2 with dict load, advanced one pass, 41518 github, level 5, advanced one pass, 135121 github, level 5 with dict, advanced one pass, 38758 github, level 5 with dict dms, advanced one pass, 38758 @@ -348,16 +348,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced one pass, 38636 github, level 6 with dict copy, advanced one pass, 38669 github, level 6 with dict load, advanced one pass, 40695 -github, level 7 row 1, advanced one pass, 134584 -github, level 7 row 1 with dict dms, advanced one pass, 38758 -github, level 7 row 1 with dict dds, advanced one pass, 38745 -github, level 7 row 1 with dict copy, advanced one pass, 38755 -github, level 7 row 1 with dict load, advanced one pass, 43154 -github, level 7 row 2, advanced one pass, 135122 -github, level 7 row 2 with dict dms, advanced one pass, 38860 -github, level 7 row 2 with dict dds, advanced one pass, 38766 -github, level 7 row 2 with dict copy, advanced one pass, 38834 -github, level 7 row 2 with dict load, advanced one pass, 40695 +github, level 7 row 1, advanced one pass, 135122 +github, level 7 row 1 with dict dms, advanced one pass, 38860 +github, level 7 row 1 with dict dds, advanced one pass, 38766 +github, level 7 row 1 with dict copy, advanced one pass, 38834 +github, level 7 row 1 with dict load, advanced one pass, 40695 +github, level 7 row 2, advanced one pass, 134584 +github, level 7 row 2 with dict dms, advanced one pass, 38758 +github, level 7 row 2 with dict dds, advanced one pass, 38745 +github, level 7 row 2 with dict copy, advanced one pass, 38755 +github, level 7 row 2 with dict load, advanced one pass, 43154 github, level 7, advanced one pass, 135122 github, level 7 with dict, advanced one pass, 38758 github, level 7 with dict dms, advanced one pass, 38758 @@ -419,26 +419,26 @@ github, small chain log, advanced github, explicit params, advanced one pass, 137727 github, uncompressed literals, advanced one pass, 165915 github, uncompressed literals optimal, advanced one pass, 157227 -github, huffman literals, advanced one pass, 142365 +github, huffman literals, advanced one pass, 142465 github, multithreaded with advanced params, advanced one pass, 165915 -github.tar, level -5, advanced one pass, 66914 -github.tar, level -5 with dict, advanced one pass, 51525 -github.tar, level -3, advanced one pass, 52127 -github.tar, level -3 with dict, advanced one pass, 44242 -github.tar, level -1, advanced one pass, 42560 -github.tar, level -1 with dict, advanced one pass, 41136 +github.tar, level -5, advanced one pass, 46856 +github.tar, level -5 with dict, advanced one pass, 44571 +github.tar, level -3, advanced one pass, 43754 +github.tar, level -3 with dict, advanced one pass, 41447 +github.tar, level -1, advanced one pass, 42490 +github.tar, level -1 with dict, advanced one pass, 41131 github.tar, level 0, advanced one pass, 38441 github.tar, level 0 with dict, advanced one pass, 37995 github.tar, level 0 with dict dms, advanced one pass, 38003 github.tar, level 0 with dict dds, advanced one pass, 38003 github.tar, level 0 with dict copy, advanced one pass, 37995 github.tar, level 0 with dict load, advanced one pass, 37956 -github.tar, level 1, advanced one pass, 39200 -github.tar, level 1 with dict, advanced one pass, 38284 -github.tar, level 1 with dict dms, advanced one pass, 38294 -github.tar, level 1 with dict dds, advanced one pass, 38294 -github.tar, level 1 with dict copy, advanced one pass, 38284 -github.tar, level 1 with dict load, advanced one pass, 38724 +github.tar, level 1, advanced one pass, 39265 +github.tar, level 1 with dict, advanced one pass, 38280 +github.tar, level 1 with dict dms, advanced one pass, 38290 +github.tar, level 1 with dict dds, advanced one pass, 38290 +github.tar, level 1 with dict copy, advanced one pass, 38280 +github.tar, level 1 with dict load, advanced one pass, 38729 github.tar, level 3, advanced one pass, 38441 github.tar, level 3 with dict, advanced one pass, 37995 github.tar, level 3 with dict dms, advanced one pass, 38003 @@ -451,88 +451,88 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass, 37954 github.tar, level 4 with dict copy, advanced one pass, 37948 github.tar, level 4 with dict load, advanced one pass, 37927 -github.tar, level 5 row 1, advanced one pass, 38376 -github.tar, level 5 row 1 with dict dms, advanced one pass, 39024 -github.tar, level 5 row 1 with dict dds, advanced one pass, 39028 -github.tar, level 5 row 1 with dict copy, advanced one pass, 39040 -github.tar, level 5 row 1 with dict load, advanced one pass, 37600 -github.tar, level 5 row 2, advanced one pass, 38534 -github.tar, level 5 row 2 with dict dms, advanced one pass, 39365 -github.tar, level 5 row 2 with dict dds, advanced one pass, 39233 -github.tar, level 5 row 2 with dict copy, advanced one pass, 39715 -github.tar, level 5 row 2 with dict load, advanced one pass, 38019 -github.tar, level 5, advanced one pass, 38376 -github.tar, level 5 with dict, advanced one pass, 39040 -github.tar, level 5 with dict dms, advanced one pass, 39024 -github.tar, level 5 with dict dds, advanced one pass, 39028 -github.tar, level 5 with dict copy, advanced one pass, 39040 -github.tar, level 5 with dict load, advanced one pass, 37600 -github.tar, level 6, advanced one pass, 38610 -github.tar, level 6 with dict, advanced one pass, 38622 -github.tar, level 6 with dict dms, advanced one pass, 38608 -github.tar, level 6 with dict dds, advanced one pass, 38610 -github.tar, level 6 with dict copy, advanced one pass, 38622 -github.tar, level 6 with dict load, advanced one pass, 37829 -github.tar, level 7 row 1, advanced one pass, 38073 -github.tar, level 7 row 1 with dict dms, advanced one pass, 37848 -github.tar, level 7 row 1 with dict dds, advanced one pass, 37869 -github.tar, level 7 row 1 with dict copy, advanced one pass, 37848 -github.tar, level 7 row 1 with dict load, advanced one pass, 37371 -github.tar, level 7 row 2, advanced one pass, 38077 -github.tar, level 7 row 2 with dict dms, advanced one pass, 38012 -github.tar, level 7 row 2 with dict dds, advanced one pass, 38014 -github.tar, level 7 row 2 with dict copy, advanced one pass, 38101 -github.tar, level 7 row 2 with dict load, advanced one pass, 37402 -github.tar, level 7, advanced one pass, 38073 -github.tar, level 7 with dict, advanced one pass, 37848 -github.tar, level 7 with dict dms, advanced one pass, 37848 -github.tar, level 7 with dict dds, advanced one pass, 37869 -github.tar, level 7 with dict copy, advanced one pass, 37848 -github.tar, level 7 with dict load, advanced one pass, 37371 -github.tar, level 9, advanced one pass, 36767 -github.tar, level 9 with dict, advanced one pass, 36457 -github.tar, level 9 with dict dms, advanced one pass, 36549 -github.tar, level 9 with dict dds, advanced one pass, 36619 -github.tar, level 9 with dict copy, advanced one pass, 36457 -github.tar, level 9 with dict load, advanced one pass, 36352 +github.tar, level 5 row 1, advanced one pass, 38534 +github.tar, level 5 row 1 with dict dms, advanced one pass, 39365 +github.tar, level 5 row 1 with dict dds, advanced one pass, 39233 +github.tar, level 5 row 1 with dict copy, advanced one pass, 39715 +github.tar, level 5 row 1 with dict load, advanced one pass, 38019 +github.tar, level 5 row 2, advanced one pass, 38394 +github.tar, level 5 row 2 with dict dms, advanced one pass, 39048 +github.tar, level 5 row 2 with dict dds, advanced one pass, 39044 +github.tar, level 5 row 2 with dict copy, advanced one pass, 39074 +github.tar, level 5 row 2 with dict load, advanced one pass, 37665 +github.tar, level 5, advanced one pass, 38394 +github.tar, level 5 with dict, advanced one pass, 39074 +github.tar, level 5 with dict dms, advanced one pass, 39048 +github.tar, level 5 with dict dds, advanced one pass, 39044 +github.tar, level 5 with dict copy, advanced one pass, 39074 +github.tar, level 5 with dict load, advanced one pass, 37665 +github.tar, level 6, advanced one pass, 38669 +github.tar, level 6 with dict, advanced one pass, 38660 +github.tar, level 6 with dict dms, advanced one pass, 38654 +github.tar, level 6 with dict dds, advanced one pass, 38656 +github.tar, level 6 with dict copy, advanced one pass, 38660 +github.tar, level 6 with dict load, advanced one pass, 37889 +github.tar, level 7 row 1, advanced one pass, 38077 +github.tar, level 7 row 1 with dict dms, advanced one pass, 38012 +github.tar, level 7 row 1 with dict dds, advanced one pass, 38014 +github.tar, level 7 row 1 with dict copy, advanced one pass, 38101 +github.tar, level 7 row 1 with dict load, advanced one pass, 37402 +github.tar, level 7 row 2, advanced one pass, 38153 +github.tar, level 7 row 2 with dict dms, advanced one pass, 37888 +github.tar, level 7 row 2 with dict dds, advanced one pass, 37910 +github.tar, level 7 row 2 with dict copy, advanced one pass, 37892 +github.tar, level 7 row 2 with dict load, advanced one pass, 37457 +github.tar, level 7, advanced one pass, 38153 +github.tar, level 7 with dict, advanced one pass, 37892 +github.tar, level 7 with dict dms, advanced one pass, 37888 +github.tar, level 7 with dict dds, advanced one pass, 37910 +github.tar, level 7 with dict copy, advanced one pass, 37892 +github.tar, level 7 with dict load, advanced one pass, 37457 +github.tar, level 9, advanced one pass, 36768 +github.tar, level 9 with dict, advanced one pass, 36510 +github.tar, level 9 with dict dms, advanced one pass, 36584 +github.tar, level 9 with dict dds, advanced one pass, 36646 +github.tar, level 9 with dict copy, advanced one pass, 36510 +github.tar, level 9 with dict load, advanced one pass, 36383 github.tar, level 11 row 1, advanced one pass, 36435 github.tar, level 11 row 1 with dict dms, advanced one pass, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass, 36424 -github.tar, level 11 row 2, advanced one pass, 36435 +github.tar, level 11 row 1 with dict load, advanced one pass, 36419 +github.tar, level 11 row 2, advanced one pass, 36412 github.tar, level 11 row 2 with dict dms, advanced one pass, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 2 with dict load, advanced one pass, 36419 -github.tar, level 12 row 1, advanced one pass, 36105 +github.tar, level 11 row 2 with dict load, advanced one pass, 36439 +github.tar, level 12 row 1, advanced one pass, 36110 github.tar, level 12 row 1 with dict dms, advanced one pass, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass, 36460 -github.tar, level 12 row 2, advanced one pass, 36110 +github.tar, level 12 row 1 with dict load, advanced one pass, 36459 +github.tar, level 12 row 2, advanced one pass, 36062 github.tar, level 12 row 2 with dict dms, advanced one pass, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass, 36459 -github.tar, level 13, advanced one pass, 35501 -github.tar, level 13 with dict, advanced one pass, 37130 -github.tar, level 13 with dict dms, advanced one pass, 37267 -github.tar, level 13 with dict dds, advanced one pass, 37267 -github.tar, level 13 with dict copy, advanced one pass, 37130 -github.tar, level 13 with dict load, advanced one pass, 36010 -github.tar, level 16, advanced one pass, 40471 -github.tar, level 16 with dict, advanced one pass, 33378 -github.tar, level 16 with dict dms, advanced one pass, 33213 -github.tar, level 16 with dict dds, advanced one pass, 33213 -github.tar, level 16 with dict copy, advanced one pass, 33378 -github.tar, level 16 with dict load, advanced one pass, 39081 -github.tar, level 19, advanced one pass, 32134 -github.tar, level 19 with dict, advanced one pass, 32709 -github.tar, level 19 with dict dms, advanced one pass, 32553 -github.tar, level 19 with dict dds, advanced one pass, 32553 -github.tar, level 19 with dict copy, advanced one pass, 32709 -github.tar, level 19 with dict load, advanced one pass, 32474 +github.tar, level 12 row 2 with dict load, advanced one pass, 36392 +github.tar, level 13, advanced one pass, 35621 +github.tar, level 13 with dict, advanced one pass, 38726 +github.tar, level 13 with dict dms, advanced one pass, 38903 +github.tar, level 13 with dict dds, advanced one pass, 38903 +github.tar, level 13 with dict copy, advanced one pass, 38726 +github.tar, level 13 with dict load, advanced one pass, 36372 +github.tar, level 16, advanced one pass, 40255 +github.tar, level 16 with dict, advanced one pass, 33639 +github.tar, level 16 with dict dms, advanced one pass, 33544 +github.tar, level 16 with dict dds, advanced one pass, 33544 +github.tar, level 16 with dict copy, advanced one pass, 33639 +github.tar, level 16 with dict load, advanced one pass, 39353 +github.tar, level 19, advanced one pass, 32837 +github.tar, level 19 with dict, advanced one pass, 32895 +github.tar, level 19 with dict dms, advanced one pass, 32672 +github.tar, level 19 with dict dds, advanced one pass, 32672 +github.tar, level 19 with dict copy, advanced one pass, 32895 +github.tar, level 19 with dict load, advanced one pass, 32676 github.tar, no source size, advanced one pass, 38441 github.tar, no source size with dict, advanced one pass, 37995 github.tar, long distance mode, advanced one pass, 39757 @@ -541,84 +541,84 @@ github.tar, multithreaded long distance mode, advanced github.tar, small window log, advanced one pass, 198540 github.tar, small hash log, advanced one pass, 129870 github.tar, small chain log, advanced one pass, 41669 -github.tar, explicit params, advanced one pass, 41227 +github.tar, explicit params, advanced one pass, 41350 github.tar, uncompressed literals, advanced one pass, 41122 -github.tar, uncompressed literals optimal, advanced one pass, 35397 -github.tar, huffman literals, advanced one pass, 38853 +github.tar, uncompressed literals optimal, advanced one pass, 35388 +github.tar, huffman literals, advanced one pass, 38777 github.tar, multithreaded with advanced params, advanced one pass, 41122 -silesia, level -5, advanced one pass small out, 7354675 -silesia, level -3, advanced one pass small out, 6902374 -silesia, level -1, advanced one pass small out, 6177565 -silesia, level 0, advanced one pass small out, 4849553 -silesia, level 1, advanced one pass small out, 5309098 -silesia, level 3, advanced one pass small out, 4849553 -silesia, level 4, advanced one pass small out, 4786968 -silesia, level 5 row 1, advanced one pass small out, 4638961 -silesia, level 5 row 2, advanced one pass small out, 4640752 -silesia, level 5, advanced one pass small out, 4638961 -silesia, level 6, advanced one pass small out, 4605369 -silesia, level 7 row 1, advanced one pass small out, 4567204 -silesia, level 7 row 2, advanced one pass small out, 4564868 -silesia, level 7, advanced one pass small out, 4567204 -silesia, level 9, advanced one pass small out, 4543310 -silesia, level 11 row 1, advanced one pass small out, 4521399 -silesia, level 11 row 2, advanced one pass small out, 4519288 -silesia, level 12 row 1, advanced one pass small out, 4505153 -silesia, level 12 row 2, advanced one pass small out, 4503116 -silesia, level 13, advanced one pass small out, 4493990 -silesia, level 16, advanced one pass small out, 4359864 -silesia, level 19, advanced one pass small out, 4296880 -silesia, no source size, advanced one pass small out, 4849553 -silesia, long distance mode, advanced one pass small out, 4840737 -silesia, multithreaded, advanced one pass small out, 4849553 +silesia, level -5, advanced one pass small out, 6737607 +silesia, level -3, advanced one pass small out, 6444677 +silesia, level -1, advanced one pass small out, 6178460 +silesia, level 0, advanced one pass small out, 4849551 +silesia, level 1, advanced one pass small out, 5313202 +silesia, level 3, advanced one pass small out, 4849551 +silesia, level 4, advanced one pass small out, 4786969 +silesia, level 5 row 1, advanced one pass small out, 4640753 +silesia, level 5 row 2, advanced one pass small out, 4639132 +silesia, level 5, advanced one pass small out, 4639132 +silesia, level 6, advanced one pass small out, 4605629 +silesia, level 7 row 1, advanced one pass small out, 4564870 +silesia, level 7 row 2, advanced one pass small out, 4567307 +silesia, level 7, advanced one pass small out, 4567307 +silesia, level 9, advanced one pass small out, 4543330 +silesia, level 11 row 1, advanced one pass small out, 4519288 +silesia, level 11 row 2, advanced one pass small out, 4521524 +silesia, level 12 row 1, advanced one pass small out, 4503117 +silesia, level 12 row 2, advanced one pass small out, 4505093 +silesia, level 13, advanced one pass small out, 4482131 +silesia, level 16, advanced one pass small out, 4360251 +silesia, level 19, advanced one pass small out, 4283236 +silesia, no source size, advanced one pass small out, 4849551 +silesia, long distance mode, advanced one pass small out, 4840738 +silesia, multithreaded, advanced one pass small out, 4849551 silesia, multithreaded long distance mode, advanced one pass small out, 4840759 silesia, small window log, advanced one pass small out, 7095919 silesia, small hash log, advanced one pass small out, 6526141 -silesia, small chain log, advanced one pass small out, 4912197 -silesia, explicit params, advanced one pass small out, 4795856 +silesia, small chain log, advanced one pass small out, 4912199 +silesia, explicit params, advanced one pass small out, 4796282 silesia, uncompressed literals, advanced one pass small out, 5127982 -silesia, uncompressed literals optimal, advanced one pass small out, 4319518 -silesia, huffman literals, advanced one pass small out, 5326346 +silesia, uncompressed literals optimal, advanced one pass small out, 4317896 +silesia, huffman literals, advanced one pass small out, 5326269 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 -silesia.tar, level -5, advanced one pass small out, 7359401 -silesia.tar, level -3, advanced one pass small out, 6901672 -silesia.tar, level -1, advanced one pass small out, 6182241 -silesia.tar, level 0, advanced one pass small out, 4861424 -silesia.tar, level 1, advanced one pass small out, 5331946 -silesia.tar, level 3, advanced one pass small out, 4861424 +silesia.tar, level -5, advanced one pass small out, 6738593 +silesia.tar, level -3, advanced one pass small out, 6446372 +silesia.tar, level -1, advanced one pass small out, 6186042 +silesia.tar, level 0, advanced one pass small out, 4861423 +silesia.tar, level 1, advanced one pass small out, 5334885 +silesia.tar, level 3, advanced one pass small out, 4861423 silesia.tar, level 4, advanced one pass small out, 4799632 -silesia.tar, level 5 row 1, advanced one pass small out, 4650202 -silesia.tar, level 5 row 2, advanced one pass small out, 4652862 -silesia.tar, level 5, advanced one pass small out, 4650202 -silesia.tar, level 6, advanced one pass small out, 4616811 -silesia.tar, level 7 row 1, advanced one pass small out, 4576829 -silesia.tar, level 7 row 2, advanced one pass small out, 4575393 -silesia.tar, level 7, advanced one pass small out, 4576829 -silesia.tar, level 9, advanced one pass small out, 4552584 -silesia.tar, level 11 row 1, advanced one pass small out, 4530256 -silesia.tar, level 11 row 2, advanced one pass small out, 4529461 -silesia.tar, level 12 row 1, advanced one pass small out, 4514568 -silesia.tar, level 12 row 2, advanced one pass small out, 4513604 -silesia.tar, level 13, advanced one pass small out, 4502956 -silesia.tar, level 16, advanced one pass small out, 4360527 -silesia.tar, level 19, advanced one pass small out, 4267266 -silesia.tar, no source size, advanced one pass small out, 4861424 -silesia.tar, long distance mode, advanced one pass small out, 4847752 -silesia.tar, multithreaded, advanced one pass small out, 4861508 +silesia.tar, level 5 row 1, advanced one pass small out, 4652862 +silesia.tar, level 5 row 2, advanced one pass small out, 4650387 +silesia.tar, level 5, advanced one pass small out, 4650387 +silesia.tar, level 6, advanced one pass small out, 4617089 +silesia.tar, level 7 row 1, advanced one pass small out, 4575392 +silesia.tar, level 7 row 2, advanced one pass small out, 4576951 +silesia.tar, level 7, advanced one pass small out, 4576951 +silesia.tar, level 9, advanced one pass small out, 4552638 +silesia.tar, level 11 row 1, advanced one pass small out, 4529458 +silesia.tar, level 11 row 2, advanced one pass small out, 4530416 +silesia.tar, level 12 row 1, advanced one pass small out, 4513603 +silesia.tar, level 12 row 2, advanced one pass small out, 4514499 +silesia.tar, level 13, advanced one pass small out, 4491768 +silesia.tar, level 16, advanced one pass small out, 4356834 +silesia.tar, level 19, advanced one pass small out, 4264388 +silesia.tar, no source size, advanced one pass small out, 4861423 +silesia.tar, long distance mode, advanced one pass small out, 4847753 +silesia.tar, multithreaded, advanced one pass small out, 4861507 silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853221 silesia.tar, small window log, advanced one pass small out, 7101530 -silesia.tar, small hash log, advanced one pass small out, 6529231 -silesia.tar, small chain log, advanced one pass small out, 4917041 -silesia.tar, explicit params, advanced one pass small out, 4807381 +silesia.tar, small hash log, advanced one pass small out, 6529228 +silesia.tar, small chain log, advanced one pass small out, 4917039 +silesia.tar, explicit params, advanced one pass small out, 4807675 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass small out, 4310141 -silesia.tar, huffman literals, advanced one pass small out, 5344545 +silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 +silesia.tar, huffman literals, advanced one pass small out, 5347335 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 -github, level -5, advanced one pass small out, 232315 +github, level -5, advanced one pass small out, 205285 github, level -5 with dict, advanced one pass small out, 46718 -github, level -3, advanced one pass small out, 220760 +github, level -3, advanced one pass small out, 190643 github, level -3 with dict, advanced one pass small out, 45395 -github, level -1, advanced one pass small out, 175468 +github, level -1, advanced one pass small out, 175568 github, level -1 with dict, advanced one pass small out, 43170 github, level 0, advanced one pass small out, 136335 github, level 0 with dict, advanced one pass small out, 41148 @@ -626,7 +626,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced one pass small out, 41148 github, level 0 with dict copy, advanced one pass small out, 41124 github, level 0 with dict load, advanced one pass small out, 42252 -github, level 1, advanced one pass small out, 142365 +github, level 1, advanced one pass small out, 142465 github, level 1 with dict, advanced one pass small out, 41682 github, level 1 with dict dms, advanced one pass small out, 41682 github, level 1 with dict dds, advanced one pass small out, 41682 @@ -644,16 +644,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced one pass small out, 41251 github, level 4 with dict copy, advanced one pass small out, 41216 github, level 4 with dict load, advanced one pass small out, 41159 -github, level 5 row 1, advanced one pass small out, 134584 -github, level 5 row 1 with dict dms, advanced one pass small out, 38758 -github, level 5 row 1 with dict dds, advanced one pass small out, 38728 -github, level 5 row 1 with dict copy, advanced one pass small out, 38759 -github, level 5 row 1 with dict load, advanced one pass small out, 41518 -github, level 5 row 2, advanced one pass small out, 135121 -github, level 5 row 2 with dict dms, advanced one pass small out, 38938 -github, level 5 row 2 with dict dds, advanced one pass small out, 38732 -github, level 5 row 2 with dict copy, advanced one pass small out, 38934 -github, level 5 row 2 with dict load, advanced one pass small out, 40725 +github, level 5 row 1, advanced one pass small out, 135121 +github, level 5 row 1 with dict dms, advanced one pass small out, 38938 +github, level 5 row 1 with dict dds, advanced one pass small out, 38732 +github, level 5 row 1 with dict copy, advanced one pass small out, 38934 +github, level 5 row 1 with dict load, advanced one pass small out, 40725 +github, level 5 row 2, advanced one pass small out, 134584 +github, level 5 row 2 with dict dms, advanced one pass small out, 38758 +github, level 5 row 2 with dict dds, advanced one pass small out, 38728 +github, level 5 row 2 with dict copy, advanced one pass small out, 38759 +github, level 5 row 2 with dict load, advanced one pass small out, 41518 github, level 5, advanced one pass small out, 135121 github, level 5 with dict, advanced one pass small out, 38758 github, level 5 with dict dms, advanced one pass small out, 38758 @@ -666,16 +666,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced one pass small out, 38636 github, level 6 with dict copy, advanced one pass small out, 38669 github, level 6 with dict load, advanced one pass small out, 40695 -github, level 7 row 1, advanced one pass small out, 134584 -github, level 7 row 1 with dict dms, advanced one pass small out, 38758 -github, level 7 row 1 with dict dds, advanced one pass small out, 38745 -github, level 7 row 1 with dict copy, advanced one pass small out, 38755 -github, level 7 row 1 with dict load, advanced one pass small out, 43154 -github, level 7 row 2, advanced one pass small out, 135122 -github, level 7 row 2 with dict dms, advanced one pass small out, 38860 -github, level 7 row 2 with dict dds, advanced one pass small out, 38766 -github, level 7 row 2 with dict copy, advanced one pass small out, 38834 -github, level 7 row 2 with dict load, advanced one pass small out, 40695 +github, level 7 row 1, advanced one pass small out, 135122 +github, level 7 row 1 with dict dms, advanced one pass small out, 38860 +github, level 7 row 1 with dict dds, advanced one pass small out, 38766 +github, level 7 row 1 with dict copy, advanced one pass small out, 38834 +github, level 7 row 1 with dict load, advanced one pass small out, 40695 +github, level 7 row 2, advanced one pass small out, 134584 +github, level 7 row 2 with dict dms, advanced one pass small out, 38758 +github, level 7 row 2 with dict dds, advanced one pass small out, 38745 +github, level 7 row 2 with dict copy, advanced one pass small out, 38755 +github, level 7 row 2 with dict load, advanced one pass small out, 43154 github, level 7, advanced one pass small out, 135122 github, level 7 with dict, advanced one pass small out, 38758 github, level 7 with dict dms, advanced one pass small out, 38758 @@ -737,26 +737,26 @@ github, small chain log, advanced github, explicit params, advanced one pass small out, 137727 github, uncompressed literals, advanced one pass small out, 165915 github, uncompressed literals optimal, advanced one pass small out, 157227 -github, huffman literals, advanced one pass small out, 142365 +github, huffman literals, advanced one pass small out, 142465 github, multithreaded with advanced params, advanced one pass small out, 165915 -github.tar, level -5, advanced one pass small out, 66914 -github.tar, level -5 with dict, advanced one pass small out, 51525 -github.tar, level -3, advanced one pass small out, 52127 -github.tar, level -3 with dict, advanced one pass small out, 44242 -github.tar, level -1, advanced one pass small out, 42560 -github.tar, level -1 with dict, advanced one pass small out, 41136 +github.tar, level -5, advanced one pass small out, 46856 +github.tar, level -5 with dict, advanced one pass small out, 44571 +github.tar, level -3, advanced one pass small out, 43754 +github.tar, level -3 with dict, advanced one pass small out, 41447 +github.tar, level -1, advanced one pass small out, 42490 +github.tar, level -1 with dict, advanced one pass small out, 41131 github.tar, level 0, advanced one pass small out, 38441 github.tar, level 0 with dict, advanced one pass small out, 37995 github.tar, level 0 with dict dms, advanced one pass small out, 38003 github.tar, level 0 with dict dds, advanced one pass small out, 38003 github.tar, level 0 with dict copy, advanced one pass small out, 37995 github.tar, level 0 with dict load, advanced one pass small out, 37956 -github.tar, level 1, advanced one pass small out, 39200 -github.tar, level 1 with dict, advanced one pass small out, 38284 -github.tar, level 1 with dict dms, advanced one pass small out, 38294 -github.tar, level 1 with dict dds, advanced one pass small out, 38294 -github.tar, level 1 with dict copy, advanced one pass small out, 38284 -github.tar, level 1 with dict load, advanced one pass small out, 38724 +github.tar, level 1, advanced one pass small out, 39265 +github.tar, level 1 with dict, advanced one pass small out, 38280 +github.tar, level 1 with dict dms, advanced one pass small out, 38290 +github.tar, level 1 with dict dds, advanced one pass small out, 38290 +github.tar, level 1 with dict copy, advanced one pass small out, 38280 +github.tar, level 1 with dict load, advanced one pass small out, 38729 github.tar, level 3, advanced one pass small out, 38441 github.tar, level 3 with dict, advanced one pass small out, 37995 github.tar, level 3 with dict dms, advanced one pass small out, 38003 @@ -769,88 +769,88 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass small out, 37954 github.tar, level 4 with dict copy, advanced one pass small out, 37948 github.tar, level 4 with dict load, advanced one pass small out, 37927 -github.tar, level 5 row 1, advanced one pass small out, 38376 -github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39024 -github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39028 -github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39040 -github.tar, level 5 row 1 with dict load, advanced one pass small out, 37600 -github.tar, level 5 row 2, advanced one pass small out, 38534 -github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39365 -github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39233 -github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39715 -github.tar, level 5 row 2 with dict load, advanced one pass small out, 38019 -github.tar, level 5, advanced one pass small out, 38376 -github.tar, level 5 with dict, advanced one pass small out, 39040 -github.tar, level 5 with dict dms, advanced one pass small out, 39024 -github.tar, level 5 with dict dds, advanced one pass small out, 39028 -github.tar, level 5 with dict copy, advanced one pass small out, 39040 -github.tar, level 5 with dict load, advanced one pass small out, 37600 -github.tar, level 6, advanced one pass small out, 38610 -github.tar, level 6 with dict, advanced one pass small out, 38622 -github.tar, level 6 with dict dms, advanced one pass small out, 38608 -github.tar, level 6 with dict dds, advanced one pass small out, 38610 -github.tar, level 6 with dict copy, advanced one pass small out, 38622 -github.tar, level 6 with dict load, advanced one pass small out, 37829 -github.tar, level 7 row 1, advanced one pass small out, 38073 -github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37848 -github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37869 -github.tar, level 7 row 1 with dict copy, advanced one pass small out, 37848 -github.tar, level 7 row 1 with dict load, advanced one pass small out, 37371 -github.tar, level 7 row 2, advanced one pass small out, 38077 -github.tar, level 7 row 2 with dict dms, advanced one pass small out, 38012 -github.tar, level 7 row 2 with dict dds, advanced one pass small out, 38014 -github.tar, level 7 row 2 with dict copy, advanced one pass small out, 38101 -github.tar, level 7 row 2 with dict load, advanced one pass small out, 37402 -github.tar, level 7, advanced one pass small out, 38073 -github.tar, level 7 with dict, advanced one pass small out, 37848 -github.tar, level 7 with dict dms, advanced one pass small out, 37848 -github.tar, level 7 with dict dds, advanced one pass small out, 37869 -github.tar, level 7 with dict copy, advanced one pass small out, 37848 -github.tar, level 7 with dict load, advanced one pass small out, 37371 -github.tar, level 9, advanced one pass small out, 36767 -github.tar, level 9 with dict, advanced one pass small out, 36457 -github.tar, level 9 with dict dms, advanced one pass small out, 36549 -github.tar, level 9 with dict dds, advanced one pass small out, 36619 -github.tar, level 9 with dict copy, advanced one pass small out, 36457 -github.tar, level 9 with dict load, advanced one pass small out, 36352 +github.tar, level 5 row 1, advanced one pass small out, 38534 +github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39365 +github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39233 +github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39715 +github.tar, level 5 row 1 with dict load, advanced one pass small out, 38019 +github.tar, level 5 row 2, advanced one pass small out, 38394 +github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39048 +github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39044 +github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39074 +github.tar, level 5 row 2 with dict load, advanced one pass small out, 37665 +github.tar, level 5, advanced one pass small out, 38394 +github.tar, level 5 with dict, advanced one pass small out, 39074 +github.tar, level 5 with dict dms, advanced one pass small out, 39048 +github.tar, level 5 with dict dds, advanced one pass small out, 39044 +github.tar, level 5 with dict copy, advanced one pass small out, 39074 +github.tar, level 5 with dict load, advanced one pass small out, 37665 +github.tar, level 6, advanced one pass small out, 38669 +github.tar, level 6 with dict, advanced one pass small out, 38660 +github.tar, level 6 with dict dms, advanced one pass small out, 38654 +github.tar, level 6 with dict dds, advanced one pass small out, 38656 +github.tar, level 6 with dict copy, advanced one pass small out, 38660 +github.tar, level 6 with dict load, advanced one pass small out, 37889 +github.tar, level 7 row 1, advanced one pass small out, 38077 +github.tar, level 7 row 1 with dict dms, advanced one pass small out, 38012 +github.tar, level 7 row 1 with dict dds, advanced one pass small out, 38014 +github.tar, level 7 row 1 with dict copy, advanced one pass small out, 38101 +github.tar, level 7 row 1 with dict load, advanced one pass small out, 37402 +github.tar, level 7 row 2, advanced one pass small out, 38153 +github.tar, level 7 row 2 with dict dms, advanced one pass small out, 37888 +github.tar, level 7 row 2 with dict dds, advanced one pass small out, 37910 +github.tar, level 7 row 2 with dict copy, advanced one pass small out, 37892 +github.tar, level 7 row 2 with dict load, advanced one pass small out, 37457 +github.tar, level 7, advanced one pass small out, 38153 +github.tar, level 7 with dict, advanced one pass small out, 37892 +github.tar, level 7 with dict dms, advanced one pass small out, 37888 +github.tar, level 7 with dict dds, advanced one pass small out, 37910 +github.tar, level 7 with dict copy, advanced one pass small out, 37892 +github.tar, level 7 with dict load, advanced one pass small out, 37457 +github.tar, level 9, advanced one pass small out, 36768 +github.tar, level 9 with dict, advanced one pass small out, 36510 +github.tar, level 9 with dict dms, advanced one pass small out, 36584 +github.tar, level 9 with dict dds, advanced one pass small out, 36646 +github.tar, level 9 with dict copy, advanced one pass small out, 36510 +github.tar, level 9 with dict load, advanced one pass small out, 36383 github.tar, level 11 row 1, advanced one pass small out, 36435 github.tar, level 11 row 1 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass small out, 36424 -github.tar, level 11 row 2, advanced one pass small out, 36435 +github.tar, level 11 row 1 with dict load, advanced one pass small out, 36419 +github.tar, level 11 row 2, advanced one pass small out, 36412 github.tar, level 11 row 2 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 2 with dict load, advanced one pass small out, 36419 -github.tar, level 12 row 1, advanced one pass small out, 36105 +github.tar, level 11 row 2 with dict load, advanced one pass small out, 36439 +github.tar, level 12 row 1, advanced one pass small out, 36110 github.tar, level 12 row 1 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass small out, 36460 -github.tar, level 12 row 2, advanced one pass small out, 36110 +github.tar, level 12 row 1 with dict load, advanced one pass small out, 36459 +github.tar, level 12 row 2, advanced one pass small out, 36062 github.tar, level 12 row 2 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass small out, 36459 -github.tar, level 13, advanced one pass small out, 35501 -github.tar, level 13 with dict, advanced one pass small out, 37130 -github.tar, level 13 with dict dms, advanced one pass small out, 37267 -github.tar, level 13 with dict dds, advanced one pass small out, 37267 -github.tar, level 13 with dict copy, advanced one pass small out, 37130 -github.tar, level 13 with dict load, advanced one pass small out, 36010 -github.tar, level 16, advanced one pass small out, 40471 -github.tar, level 16 with dict, advanced one pass small out, 33378 -github.tar, level 16 with dict dms, advanced one pass small out, 33213 -github.tar, level 16 with dict dds, advanced one pass small out, 33213 -github.tar, level 16 with dict copy, advanced one pass small out, 33378 -github.tar, level 16 with dict load, advanced one pass small out, 39081 -github.tar, level 19, advanced one pass small out, 32134 -github.tar, level 19 with dict, advanced one pass small out, 32709 -github.tar, level 19 with dict dms, advanced one pass small out, 32553 -github.tar, level 19 with dict dds, advanced one pass small out, 32553 -github.tar, level 19 with dict copy, advanced one pass small out, 32709 -github.tar, level 19 with dict load, advanced one pass small out, 32474 +github.tar, level 12 row 2 with dict load, advanced one pass small out, 36392 +github.tar, level 13, advanced one pass small out, 35621 +github.tar, level 13 with dict, advanced one pass small out, 38726 +github.tar, level 13 with dict dms, advanced one pass small out, 38903 +github.tar, level 13 with dict dds, advanced one pass small out, 38903 +github.tar, level 13 with dict copy, advanced one pass small out, 38726 +github.tar, level 13 with dict load, advanced one pass small out, 36372 +github.tar, level 16, advanced one pass small out, 40255 +github.tar, level 16 with dict, advanced one pass small out, 33639 +github.tar, level 16 with dict dms, advanced one pass small out, 33544 +github.tar, level 16 with dict dds, advanced one pass small out, 33544 +github.tar, level 16 with dict copy, advanced one pass small out, 33639 +github.tar, level 16 with dict load, advanced one pass small out, 39353 +github.tar, level 19, advanced one pass small out, 32837 +github.tar, level 19 with dict, advanced one pass small out, 32895 +github.tar, level 19 with dict dms, advanced one pass small out, 32672 +github.tar, level 19 with dict dds, advanced one pass small out, 32672 +github.tar, level 19 with dict copy, advanced one pass small out, 32895 +github.tar, level 19 with dict load, advanced one pass small out, 32676 github.tar, no source size, advanced one pass small out, 38441 github.tar, no source size with dict, advanced one pass small out, 37995 github.tar, long distance mode, advanced one pass small out, 39757 @@ -859,84 +859,84 @@ github.tar, multithreaded long distance mode, advanced github.tar, small window log, advanced one pass small out, 198540 github.tar, small hash log, advanced one pass small out, 129870 github.tar, small chain log, advanced one pass small out, 41669 -github.tar, explicit params, advanced one pass small out, 41227 +github.tar, explicit params, advanced one pass small out, 41350 github.tar, uncompressed literals, advanced one pass small out, 41122 -github.tar, uncompressed literals optimal, advanced one pass small out, 35397 -github.tar, huffman literals, advanced one pass small out, 38853 +github.tar, uncompressed literals optimal, advanced one pass small out, 35388 +github.tar, huffman literals, advanced one pass small out, 38777 github.tar, multithreaded with advanced params, advanced one pass small out, 41122 -silesia, level -5, advanced streaming, 7292053 -silesia, level -3, advanced streaming, 6867875 -silesia, level -1, advanced streaming, 6183923 -silesia, level 0, advanced streaming, 4849553 -silesia, level 1, advanced streaming, 5312694 -silesia, level 3, advanced streaming, 4849553 -silesia, level 4, advanced streaming, 4786968 -silesia, level 5 row 1, advanced streaming, 4638961 -silesia, level 5 row 2, advanced streaming, 4640752 -silesia, level 5, advanced streaming, 4638961 -silesia, level 6, advanced streaming, 4605369 -silesia, level 7 row 1, advanced streaming, 4567204 -silesia, level 7 row 2, advanced streaming, 4564868 -silesia, level 7, advanced streaming, 4567204 -silesia, level 9, advanced streaming, 4543310 -silesia, level 11 row 1, advanced streaming, 4521399 -silesia, level 11 row 2, advanced streaming, 4519288 -silesia, level 12 row 1, advanced streaming, 4505153 -silesia, level 12 row 2, advanced streaming, 4503116 -silesia, level 13, advanced streaming, 4493990 -silesia, level 16, advanced streaming, 4359864 -silesia, level 19, advanced streaming, 4296880 -silesia, no source size, advanced streaming, 4849517 -silesia, long distance mode, advanced streaming, 4840737 -silesia, multithreaded, advanced streaming, 4849553 +silesia, level -5, advanced streaming, 6882505 +silesia, level -3, advanced streaming, 6568376 +silesia, level -1, advanced streaming, 6183403 +silesia, level 0, advanced streaming, 4849551 +silesia, level 1, advanced streaming, 5314161 +silesia, level 3, advanced streaming, 4849551 +silesia, level 4, advanced streaming, 4786969 +silesia, level 5 row 1, advanced streaming, 4640753 +silesia, level 5 row 2, advanced streaming, 4639132 +silesia, level 5, advanced streaming, 4639132 +silesia, level 6, advanced streaming, 4605629 +silesia, level 7 row 1, advanced streaming, 4564870 +silesia, level 7 row 2, advanced streaming, 4567307 +silesia, level 7, advanced streaming, 4567307 +silesia, level 9, advanced streaming, 4543330 +silesia, level 11 row 1, advanced streaming, 4519288 +silesia, level 11 row 2, advanced streaming, 4521524 +silesia, level 12 row 1, advanced streaming, 4503117 +silesia, level 12 row 2, advanced streaming, 4505093 +silesia, level 13, advanced streaming, 4482131 +silesia, level 16, advanced streaming, 4360251 +silesia, level 19, advanced streaming, 4283236 +silesia, no source size, advanced streaming, 4849515 +silesia, long distance mode, advanced streaming, 4840738 +silesia, multithreaded, advanced streaming, 4849551 silesia, multithreaded long distance mode, advanced streaming, 4840759 silesia, small window log, advanced streaming, 7112062 silesia, small hash log, advanced streaming, 6526141 -silesia, small chain log, advanced streaming, 4912197 -silesia, explicit params, advanced streaming, 4795883 +silesia, small chain log, advanced streaming, 4912199 +silesia, explicit params, advanced streaming, 4796309 silesia, uncompressed literals, advanced streaming, 5127982 -silesia, uncompressed literals optimal, advanced streaming, 4319518 -silesia, huffman literals, advanced streaming, 5332234 +silesia, uncompressed literals optimal, advanced streaming, 4317896 +silesia, huffman literals, advanced streaming, 5331171 silesia, multithreaded with advanced params, advanced streaming, 5127982 -silesia.tar, level -5, advanced streaming, 7260007 -silesia.tar, level -3, advanced streaming, 6845151 -silesia.tar, level -1, advanced streaming, 6187938 -silesia.tar, level 0, advanced streaming, 4861426 -silesia.tar, level 1, advanced streaming, 5334890 -silesia.tar, level 3, advanced streaming, 4861426 +silesia.tar, level -5, advanced streaming, 6982759 +silesia.tar, level -3, advanced streaming, 6641283 +silesia.tar, level -1, advanced streaming, 6190795 +silesia.tar, level 0, advanced streaming, 4861425 +silesia.tar, level 1, advanced streaming, 5336941 +silesia.tar, level 3, advanced streaming, 4861425 silesia.tar, level 4, advanced streaming, 4799632 -silesia.tar, level 5 row 1, advanced streaming, 4650207 -silesia.tar, level 5 row 2, advanced streaming, 4652866 -silesia.tar, level 5, advanced streaming, 4650207 -silesia.tar, level 6, advanced streaming, 4616816 -silesia.tar, level 7 row 1, advanced streaming, 4576831 -silesia.tar, level 7 row 2, advanced streaming, 4575394 -silesia.tar, level 7, advanced streaming, 4576831 -silesia.tar, level 9, advanced streaming, 4552590 -silesia.tar, level 11 row 1, advanced streaming, 4530258 -silesia.tar, level 11 row 2, advanced streaming, 4529461 -silesia.tar, level 12 row 1, advanced streaming, 4514569 -silesia.tar, level 12 row 2, advanced streaming, 4513604 -silesia.tar, level 13, advanced streaming, 4502956 -silesia.tar, level 16, advanced streaming, 4360527 -silesia.tar, level 19, advanced streaming, 4267266 -silesia.tar, no source size, advanced streaming, 4861422 -silesia.tar, long distance mode, advanced streaming, 4847752 -silesia.tar, multithreaded, advanced streaming, 4861508 +silesia.tar, level 5 row 1, advanced streaming, 4652866 +silesia.tar, level 5 row 2, advanced streaming, 4650392 +silesia.tar, level 5, advanced streaming, 4650392 +silesia.tar, level 6, advanced streaming, 4617097 +silesia.tar, level 7 row 1, advanced streaming, 4575393 +silesia.tar, level 7 row 2, advanced streaming, 4576953 +silesia.tar, level 7, advanced streaming, 4576953 +silesia.tar, level 9, advanced streaming, 4552646 +silesia.tar, level 11 row 1, advanced streaming, 4529458 +silesia.tar, level 11 row 2, advanced streaming, 4530417 +silesia.tar, level 12 row 1, advanced streaming, 4513603 +silesia.tar, level 12 row 2, advanced streaming, 4514500 +silesia.tar, level 13, advanced streaming, 4491769 +silesia.tar, level 16, advanced streaming, 4356834 +silesia.tar, level 19, advanced streaming, 4264388 +silesia.tar, no source size, advanced streaming, 4861421 +silesia.tar, long distance mode, advanced streaming, 4847753 +silesia.tar, multithreaded, advanced streaming, 4861507 silesia.tar, multithreaded long distance mode, advanced streaming, 4853221 silesia.tar, small window log, advanced streaming, 7118769 -silesia.tar, small hash log, advanced streaming, 6529234 -silesia.tar, small chain log, advanced streaming, 4917021 -silesia.tar, explicit params, advanced streaming, 4807401 +silesia.tar, small hash log, advanced streaming, 6529231 +silesia.tar, small chain log, advanced streaming, 4917019 +silesia.tar, explicit params, advanced streaming, 4807688 silesia.tar, uncompressed literals, advanced streaming, 5129461 -silesia.tar, uncompressed literals optimal, advanced streaming, 4310141 -silesia.tar, huffman literals, advanced streaming, 5350519 +silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 +silesia.tar, huffman literals, advanced streaming, 5352360 silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 -github, level -5, advanced streaming, 232315 +github, level -5, advanced streaming, 205285 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 220760 +github, level -3, advanced streaming, 190643 github, level -3 with dict, advanced streaming, 45395 -github, level -1, advanced streaming, 175468 +github, level -1, advanced streaming, 175568 github, level -1 with dict, advanced streaming, 43170 github, level 0, advanced streaming, 136335 github, level 0 with dict, advanced streaming, 41148 @@ -944,7 +944,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced streaming, 41148 github, level 0 with dict copy, advanced streaming, 41124 github, level 0 with dict load, advanced streaming, 42252 -github, level 1, advanced streaming, 142365 +github, level 1, advanced streaming, 142465 github, level 1 with dict, advanced streaming, 41682 github, level 1 with dict dms, advanced streaming, 41682 github, level 1 with dict dds, advanced streaming, 41682 @@ -962,16 +962,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced streaming, 41251 github, level 4 with dict copy, advanced streaming, 41216 github, level 4 with dict load, advanced streaming, 41159 -github, level 5 row 1, advanced streaming, 134584 -github, level 5 row 1 with dict dms, advanced streaming, 38758 -github, level 5 row 1 with dict dds, advanced streaming, 38728 -github, level 5 row 1 with dict copy, advanced streaming, 38759 -github, level 5 row 1 with dict load, advanced streaming, 41518 -github, level 5 row 2, advanced streaming, 135121 -github, level 5 row 2 with dict dms, advanced streaming, 38938 -github, level 5 row 2 with dict dds, advanced streaming, 38732 -github, level 5 row 2 with dict copy, advanced streaming, 38934 -github, level 5 row 2 with dict load, advanced streaming, 40725 +github, level 5 row 1, advanced streaming, 135121 +github, level 5 row 1 with dict dms, advanced streaming, 38938 +github, level 5 row 1 with dict dds, advanced streaming, 38732 +github, level 5 row 1 with dict copy, advanced streaming, 38934 +github, level 5 row 1 with dict load, advanced streaming, 40725 +github, level 5 row 2, advanced streaming, 134584 +github, level 5 row 2 with dict dms, advanced streaming, 38758 +github, level 5 row 2 with dict dds, advanced streaming, 38728 +github, level 5 row 2 with dict copy, advanced streaming, 38759 +github, level 5 row 2 with dict load, advanced streaming, 41518 github, level 5, advanced streaming, 135121 github, level 5 with dict, advanced streaming, 38758 github, level 5 with dict dms, advanced streaming, 38758 @@ -984,16 +984,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced streaming, 38636 github, level 6 with dict copy, advanced streaming, 38669 github, level 6 with dict load, advanced streaming, 40695 -github, level 7 row 1, advanced streaming, 134584 -github, level 7 row 1 with dict dms, advanced streaming, 38758 -github, level 7 row 1 with dict dds, advanced streaming, 38745 -github, level 7 row 1 with dict copy, advanced streaming, 38755 -github, level 7 row 1 with dict load, advanced streaming, 43154 -github, level 7 row 2, advanced streaming, 135122 -github, level 7 row 2 with dict dms, advanced streaming, 38860 -github, level 7 row 2 with dict dds, advanced streaming, 38766 -github, level 7 row 2 with dict copy, advanced streaming, 38834 -github, level 7 row 2 with dict load, advanced streaming, 40695 +github, level 7 row 1, advanced streaming, 135122 +github, level 7 row 1 with dict dms, advanced streaming, 38860 +github, level 7 row 1 with dict dds, advanced streaming, 38766 +github, level 7 row 1 with dict copy, advanced streaming, 38834 +github, level 7 row 1 with dict load, advanced streaming, 40695 +github, level 7 row 2, advanced streaming, 134584 +github, level 7 row 2 with dict dms, advanced streaming, 38758 +github, level 7 row 2 with dict dds, advanced streaming, 38745 +github, level 7 row 2 with dict copy, advanced streaming, 38755 +github, level 7 row 2 with dict load, advanced streaming, 43154 github, level 7, advanced streaming, 135122 github, level 7 with dict, advanced streaming, 38758 github, level 7 with dict dms, advanced streaming, 38758 @@ -1055,26 +1055,26 @@ github, small chain log, advanced github, explicit params, advanced streaming, 137727 github, uncompressed literals, advanced streaming, 165915 github, uncompressed literals optimal, advanced streaming, 157227 -github, huffman literals, advanced streaming, 142365 +github, huffman literals, advanced streaming, 142465 github, multithreaded with advanced params, advanced streaming, 165915 -github.tar, level -5, advanced streaming, 64132 -github.tar, level -5 with dict, advanced streaming, 48642 -github.tar, level -3, advanced streaming, 50964 -github.tar, level -3 with dict, advanced streaming, 42750 -github.tar, level -1, advanced streaming, 42536 -github.tar, level -1 with dict, advanced streaming, 41198 +github.tar, level -5, advanced streaming, 46747 +github.tar, level -5 with dict, advanced streaming, 44440 +github.tar, level -3, advanced streaming, 43537 +github.tar, level -3 with dict, advanced streaming, 41112 +github.tar, level -1, advanced streaming, 42465 +github.tar, level -1 with dict, advanced streaming, 41196 github.tar, level 0, advanced streaming, 38441 github.tar, level 0 with dict, advanced streaming, 37995 github.tar, level 0 with dict dms, advanced streaming, 38003 github.tar, level 0 with dict dds, advanced streaming, 38003 github.tar, level 0 with dict copy, advanced streaming, 37995 github.tar, level 0 with dict load, advanced streaming, 37956 -github.tar, level 1, advanced streaming, 39270 -github.tar, level 1 with dict, advanced streaming, 38316 -github.tar, level 1 with dict dms, advanced streaming, 38326 -github.tar, level 1 with dict dds, advanced streaming, 38326 -github.tar, level 1 with dict copy, advanced streaming, 38316 -github.tar, level 1 with dict load, advanced streaming, 38761 +github.tar, level 1, advanced streaming, 39342 +github.tar, level 1 with dict, advanced streaming, 38293 +github.tar, level 1 with dict dms, advanced streaming, 38303 +github.tar, level 1 with dict dds, advanced streaming, 38303 +github.tar, level 1 with dict copy, advanced streaming, 38293 +github.tar, level 1 with dict load, advanced streaming, 38766 github.tar, level 3, advanced streaming, 38441 github.tar, level 3 with dict, advanced streaming, 37995 github.tar, level 3 with dict dms, advanced streaming, 38003 @@ -1087,88 +1087,88 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced streaming, 37954 github.tar, level 4 with dict copy, advanced streaming, 37948 github.tar, level 4 with dict load, advanced streaming, 37927 -github.tar, level 5 row 1, advanced streaming, 38376 -github.tar, level 5 row 1 with dict dms, advanced streaming, 39024 -github.tar, level 5 row 1 with dict dds, advanced streaming, 39028 -github.tar, level 5 row 1 with dict copy, advanced streaming, 39040 -github.tar, level 5 row 1 with dict load, advanced streaming, 37600 -github.tar, level 5 row 2, advanced streaming, 38534 -github.tar, level 5 row 2 with dict dms, advanced streaming, 39365 -github.tar, level 5 row 2 with dict dds, advanced streaming, 39233 -github.tar, level 5 row 2 with dict copy, advanced streaming, 39715 -github.tar, level 5 row 2 with dict load, advanced streaming, 38019 -github.tar, level 5, advanced streaming, 38376 -github.tar, level 5 with dict, advanced streaming, 39040 -github.tar, level 5 with dict dms, advanced streaming, 39024 -github.tar, level 5 with dict dds, advanced streaming, 39028 -github.tar, level 5 with dict copy, advanced streaming, 39040 -github.tar, level 5 with dict load, advanced streaming, 37600 -github.tar, level 6, advanced streaming, 38610 -github.tar, level 6 with dict, advanced streaming, 38622 -github.tar, level 6 with dict dms, advanced streaming, 38608 -github.tar, level 6 with dict dds, advanced streaming, 38610 -github.tar, level 6 with dict copy, advanced streaming, 38622 -github.tar, level 6 with dict load, advanced streaming, 37829 -github.tar, level 7 row 1, advanced streaming, 38073 -github.tar, level 7 row 1 with dict dms, advanced streaming, 37848 -github.tar, level 7 row 1 with dict dds, advanced streaming, 37869 -github.tar, level 7 row 1 with dict copy, advanced streaming, 37848 -github.tar, level 7 row 1 with dict load, advanced streaming, 37371 -github.tar, level 7 row 2, advanced streaming, 38077 -github.tar, level 7 row 2 with dict dms, advanced streaming, 38012 -github.tar, level 7 row 2 with dict dds, advanced streaming, 38014 -github.tar, level 7 row 2 with dict copy, advanced streaming, 38101 -github.tar, level 7 row 2 with dict load, advanced streaming, 37402 -github.tar, level 7, advanced streaming, 38073 -github.tar, level 7 with dict, advanced streaming, 37848 -github.tar, level 7 with dict dms, advanced streaming, 37848 -github.tar, level 7 with dict dds, advanced streaming, 37869 -github.tar, level 7 with dict copy, advanced streaming, 37848 -github.tar, level 7 with dict load, advanced streaming, 37371 -github.tar, level 9, advanced streaming, 36767 -github.tar, level 9 with dict, advanced streaming, 36457 -github.tar, level 9 with dict dms, advanced streaming, 36549 -github.tar, level 9 with dict dds, advanced streaming, 36619 -github.tar, level 9 with dict copy, advanced streaming, 36457 -github.tar, level 9 with dict load, advanced streaming, 36352 +github.tar, level 5 row 1, advanced streaming, 38534 +github.tar, level 5 row 1 with dict dms, advanced streaming, 39365 +github.tar, level 5 row 1 with dict dds, advanced streaming, 39233 +github.tar, level 5 row 1 with dict copy, advanced streaming, 39715 +github.tar, level 5 row 1 with dict load, advanced streaming, 38019 +github.tar, level 5 row 2, advanced streaming, 38394 +github.tar, level 5 row 2 with dict dms, advanced streaming, 39048 +github.tar, level 5 row 2 with dict dds, advanced streaming, 39044 +github.tar, level 5 row 2 with dict copy, advanced streaming, 39074 +github.tar, level 5 row 2 with dict load, advanced streaming, 37665 +github.tar, level 5, advanced streaming, 38394 +github.tar, level 5 with dict, advanced streaming, 39074 +github.tar, level 5 with dict dms, advanced streaming, 39048 +github.tar, level 5 with dict dds, advanced streaming, 39044 +github.tar, level 5 with dict copy, advanced streaming, 39074 +github.tar, level 5 with dict load, advanced streaming, 37665 +github.tar, level 6, advanced streaming, 38669 +github.tar, level 6 with dict, advanced streaming, 38660 +github.tar, level 6 with dict dms, advanced streaming, 38654 +github.tar, level 6 with dict dds, advanced streaming, 38656 +github.tar, level 6 with dict copy, advanced streaming, 38660 +github.tar, level 6 with dict load, advanced streaming, 37889 +github.tar, level 7 row 1, advanced streaming, 38077 +github.tar, level 7 row 1 with dict dms, advanced streaming, 38012 +github.tar, level 7 row 1 with dict dds, advanced streaming, 38014 +github.tar, level 7 row 1 with dict copy, advanced streaming, 38101 +github.tar, level 7 row 1 with dict load, advanced streaming, 37402 +github.tar, level 7 row 2, advanced streaming, 38153 +github.tar, level 7 row 2 with dict dms, advanced streaming, 37888 +github.tar, level 7 row 2 with dict dds, advanced streaming, 37910 +github.tar, level 7 row 2 with dict copy, advanced streaming, 37892 +github.tar, level 7 row 2 with dict load, advanced streaming, 37457 +github.tar, level 7, advanced streaming, 38153 +github.tar, level 7 with dict, advanced streaming, 37892 +github.tar, level 7 with dict dms, advanced streaming, 37888 +github.tar, level 7 with dict dds, advanced streaming, 37910 +github.tar, level 7 with dict copy, advanced streaming, 37892 +github.tar, level 7 with dict load, advanced streaming, 37457 +github.tar, level 9, advanced streaming, 36768 +github.tar, level 9 with dict, advanced streaming, 36510 +github.tar, level 9 with dict dms, advanced streaming, 36584 +github.tar, level 9 with dict dds, advanced streaming, 36646 +github.tar, level 9 with dict copy, advanced streaming, 36510 +github.tar, level 9 with dict load, advanced streaming, 36383 github.tar, level 11 row 1, advanced streaming, 36435 github.tar, level 11 row 1 with dict dms, advanced streaming, 36963 github.tar, level 11 row 1 with dict dds, advanced streaming, 36963 github.tar, level 11 row 1 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 1 with dict load, advanced streaming, 36424 -github.tar, level 11 row 2, advanced streaming, 36435 +github.tar, level 11 row 1 with dict load, advanced streaming, 36419 +github.tar, level 11 row 2, advanced streaming, 36412 github.tar, level 11 row 2 with dict dms, advanced streaming, 36963 github.tar, level 11 row 2 with dict dds, advanced streaming, 36963 github.tar, level 11 row 2 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 2 with dict load, advanced streaming, 36419 -github.tar, level 12 row 1, advanced streaming, 36105 +github.tar, level 11 row 2 with dict load, advanced streaming, 36439 +github.tar, level 12 row 1, advanced streaming, 36110 github.tar, level 12 row 1 with dict dms, advanced streaming, 36986 github.tar, level 12 row 1 with dict dds, advanced streaming, 36986 github.tar, level 12 row 1 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 1 with dict load, advanced streaming, 36460 -github.tar, level 12 row 2, advanced streaming, 36110 +github.tar, level 12 row 1 with dict load, advanced streaming, 36459 +github.tar, level 12 row 2, advanced streaming, 36062 github.tar, level 12 row 2 with dict dms, advanced streaming, 36986 github.tar, level 12 row 2 with dict dds, advanced streaming, 36986 github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 2 with dict load, advanced streaming, 36459 -github.tar, level 13, advanced streaming, 35501 -github.tar, level 13 with dict, advanced streaming, 37130 -github.tar, level 13 with dict dms, advanced streaming, 37267 -github.tar, level 13 with dict dds, advanced streaming, 37267 -github.tar, level 13 with dict copy, advanced streaming, 37130 -github.tar, level 13 with dict load, advanced streaming, 36010 -github.tar, level 16, advanced streaming, 40471 -github.tar, level 16 with dict, advanced streaming, 33378 -github.tar, level 16 with dict dms, advanced streaming, 33213 -github.tar, level 16 with dict dds, advanced streaming, 33213 -github.tar, level 16 with dict copy, advanced streaming, 33378 -github.tar, level 16 with dict load, advanced streaming, 39081 -github.tar, level 19, advanced streaming, 32134 -github.tar, level 19 with dict, advanced streaming, 32709 -github.tar, level 19 with dict dms, advanced streaming, 32553 -github.tar, level 19 with dict dds, advanced streaming, 32553 -github.tar, level 19 with dict copy, advanced streaming, 32709 -github.tar, level 19 with dict load, advanced streaming, 32474 +github.tar, level 12 row 2 with dict load, advanced streaming, 36392 +github.tar, level 13, advanced streaming, 35621 +github.tar, level 13 with dict, advanced streaming, 38726 +github.tar, level 13 with dict dms, advanced streaming, 38903 +github.tar, level 13 with dict dds, advanced streaming, 38903 +github.tar, level 13 with dict copy, advanced streaming, 38726 +github.tar, level 13 with dict load, advanced streaming, 36372 +github.tar, level 16, advanced streaming, 40255 +github.tar, level 16 with dict, advanced streaming, 33639 +github.tar, level 16 with dict dms, advanced streaming, 33544 +github.tar, level 16 with dict dds, advanced streaming, 33544 +github.tar, level 16 with dict copy, advanced streaming, 33639 +github.tar, level 16 with dict load, advanced streaming, 39353 +github.tar, level 19, advanced streaming, 32837 +github.tar, level 19 with dict, advanced streaming, 32895 +github.tar, level 19 with dict dms, advanced streaming, 32672 +github.tar, level 19 with dict dds, advanced streaming, 32672 +github.tar, level 19 with dict copy, advanced streaming, 32895 +github.tar, level 19 with dict load, advanced streaming, 32676 github.tar, no source size, advanced streaming, 38438 github.tar, no source size with dict, advanced streaming, 38000 github.tar, long distance mode, advanced streaming, 39757 @@ -1177,56 +1177,56 @@ github.tar, multithreaded long distance mode, advanced github.tar, small window log, advanced streaming, 199558 github.tar, small hash log, advanced streaming, 129870 github.tar, small chain log, advanced streaming, 41669 -github.tar, explicit params, advanced streaming, 41227 +github.tar, explicit params, advanced streaming, 41351 github.tar, uncompressed literals, advanced streaming, 41122 -github.tar, uncompressed literals optimal, advanced streaming, 35397 -github.tar, huffman literals, advanced streaming, 38874 +github.tar, uncompressed literals optimal, advanced streaming, 35388 +github.tar, huffman literals, advanced streaming, 38800 github.tar, multithreaded with advanced params, advanced streaming, 41122 -silesia, level -5, old streaming, 7292053 -silesia, level -3, old streaming, 6867875 -silesia, level -1, old streaming, 6183923 -silesia, level 0, old streaming, 4849553 -silesia, level 1, old streaming, 5312694 -silesia, level 3, old streaming, 4849553 -silesia, level 4, old streaming, 4786968 -silesia, level 5, old streaming, 4638961 -silesia, level 6, old streaming, 4605369 -silesia, level 7, old streaming, 4567204 -silesia, level 9, old streaming, 4543310 -silesia, level 13, old streaming, 4493990 -silesia, level 16, old streaming, 4359864 -silesia, level 19, old streaming, 4296880 -silesia, no source size, old streaming, 4849517 -silesia, uncompressed literals, old streaming, 4849553 -silesia, uncompressed literals optimal, old streaming, 4296880 -silesia, huffman literals, old streaming, 6183923 -silesia.tar, level -5, old streaming, 7260007 -silesia.tar, level -3, old streaming, 6845151 -silesia.tar, level -1, old streaming, 6187938 -silesia.tar, level 0, old streaming, 4861426 -silesia.tar, level 1, old streaming, 5334890 -silesia.tar, level 3, old streaming, 4861426 +silesia, level -5, old streaming, 6882505 +silesia, level -3, old streaming, 6568376 +silesia, level -1, old streaming, 6183403 +silesia, level 0, old streaming, 4849551 +silesia, level 1, old streaming, 5314161 +silesia, level 3, old streaming, 4849551 +silesia, level 4, old streaming, 4786969 +silesia, level 5, old streaming, 4639132 +silesia, level 6, old streaming, 4605629 +silesia, level 7, old streaming, 4567307 +silesia, level 9, old streaming, 4543330 +silesia, level 13, old streaming, 4482131 +silesia, level 16, old streaming, 4360251 +silesia, level 19, old streaming, 4283236 +silesia, no source size, old streaming, 4849515 +silesia, uncompressed literals, old streaming, 4849551 +silesia, uncompressed literals optimal, old streaming, 4283236 +silesia, huffman literals, old streaming, 6183403 +silesia.tar, level -5, old streaming, 6982759 +silesia.tar, level -3, old streaming, 6641283 +silesia.tar, level -1, old streaming, 6190795 +silesia.tar, level 0, old streaming, 4861425 +silesia.tar, level 1, old streaming, 5336941 +silesia.tar, level 3, old streaming, 4861425 silesia.tar, level 4, old streaming, 4799632 -silesia.tar, level 5, old streaming, 4650207 -silesia.tar, level 6, old streaming, 4616816 -silesia.tar, level 7, old streaming, 4576831 -silesia.tar, level 9, old streaming, 4552590 -silesia.tar, level 13, old streaming, 4502956 -silesia.tar, level 16, old streaming, 4360527 -silesia.tar, level 19, old streaming, 4267266 -silesia.tar, no source size, old streaming, 4861422 -silesia.tar, uncompressed literals, old streaming, 4861426 -silesia.tar, uncompressed literals optimal, old streaming, 4267266 -silesia.tar, huffman literals, old streaming, 6187938 -github, level -5, old streaming, 232315 +silesia.tar, level 5, old streaming, 4650392 +silesia.tar, level 6, old streaming, 4617097 +silesia.tar, level 7, old streaming, 4576953 +silesia.tar, level 9, old streaming, 4552646 +silesia.tar, level 13, old streaming, 4491769 +silesia.tar, level 16, old streaming, 4356834 +silesia.tar, level 19, old streaming, 4264388 +silesia.tar, no source size, old streaming, 4861421 +silesia.tar, uncompressed literals, old streaming, 4861425 +silesia.tar, uncompressed literals optimal, old streaming, 4264388 +silesia.tar, huffman literals, old streaming, 6190795 +github, level -5, old streaming, 205285 github, level -5 with dict, old streaming, 46718 -github, level -3, old streaming, 220760 +github, level -3, old streaming, 190643 github, level -3 with dict, old streaming, 45395 -github, level -1, old streaming, 175468 +github, level -1, old streaming, 175568 github, level -1 with dict, old streaming, 43170 github, level 0, old streaming, 136335 github, level 0 with dict, old streaming, 41148 -github, level 1, old streaming, 142365 +github, level 1, old streaming, 142465 github, level 1 with dict, old streaming, 41682 github, level 3, old streaming, 136335 github, level 3 with dict, old streaming, 41148 @@ -1250,101 +1250,101 @@ github, no source size, old stre github, no source size with dict, old streaming, 40654 github, uncompressed literals, old streaming, 136335 github, uncompressed literals optimal, old streaming, 134064 -github, huffman literals, old streaming, 175468 -github.tar, level -5, old streaming, 64132 -github.tar, level -5 with dict, old streaming, 48642 -github.tar, level -3, old streaming, 50964 -github.tar, level -3 with dict, old streaming, 42750 -github.tar, level -1, old streaming, 42536 -github.tar, level -1 with dict, old streaming, 41198 +github, huffman literals, old streaming, 175568 +github.tar, level -5, old streaming, 46747 +github.tar, level -5 with dict, old streaming, 44440 +github.tar, level -3, old streaming, 43537 +github.tar, level -3 with dict, old streaming, 41112 +github.tar, level -1, old streaming, 42465 +github.tar, level -1 with dict, old streaming, 41196 github.tar, level 0, old streaming, 38441 github.tar, level 0 with dict, old streaming, 37995 -github.tar, level 1, old streaming, 39270 -github.tar, level 1 with dict, old streaming, 38316 +github.tar, level 1, old streaming, 39342 +github.tar, level 1 with dict, old streaming, 38293 github.tar, level 3, old streaming, 38441 github.tar, level 3 with dict, old streaming, 37995 github.tar, level 4, old streaming, 38467 github.tar, level 4 with dict, old streaming, 37948 -github.tar, level 5, old streaming, 38376 -github.tar, level 5 with dict, old streaming, 39040 -github.tar, level 6, old streaming, 38610 -github.tar, level 6 with dict, old streaming, 38622 -github.tar, level 7, old streaming, 38073 -github.tar, level 7 with dict, old streaming, 37848 -github.tar, level 9, old streaming, 36767 -github.tar, level 9 with dict, old streaming, 36457 -github.tar, level 13, old streaming, 35501 -github.tar, level 13 with dict, old streaming, 37130 -github.tar, level 16, old streaming, 40471 -github.tar, level 16 with dict, old streaming, 33378 -github.tar, level 19, old streaming, 32134 -github.tar, level 19 with dict, old streaming, 32709 +github.tar, level 5, old streaming, 38394 +github.tar, level 5 with dict, old streaming, 39074 +github.tar, level 6, old streaming, 38669 +github.tar, level 6 with dict, old streaming, 38660 +github.tar, level 7, old streaming, 38153 +github.tar, level 7 with dict, old streaming, 37892 +github.tar, level 9, old streaming, 36768 +github.tar, level 9 with dict, old streaming, 36510 +github.tar, level 13, old streaming, 35621 +github.tar, level 13 with dict, old streaming, 38726 +github.tar, level 16, old streaming, 40255 +github.tar, level 16 with dict, old streaming, 33639 +github.tar, level 19, old streaming, 32837 +github.tar, level 19 with dict, old streaming, 32895 github.tar, no source size, old streaming, 38438 github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38441 -github.tar, uncompressed literals optimal, old streaming, 32134 -github.tar, huffman literals, old streaming, 42536 -silesia, level -5, old streaming advanced, 7292053 -silesia, level -3, old streaming advanced, 6867875 -silesia, level -1, old streaming advanced, 6183923 -silesia, level 0, old streaming advanced, 4849553 -silesia, level 1, old streaming advanced, 5312694 -silesia, level 3, old streaming advanced, 4849553 -silesia, level 4, old streaming advanced, 4786968 -silesia, level 5, old streaming advanced, 4638961 -silesia, level 6, old streaming advanced, 4605369 -silesia, level 7, old streaming advanced, 4567204 -silesia, level 9, old streaming advanced, 4543310 -silesia, level 13, old streaming advanced, 4493990 -silesia, level 16, old streaming advanced, 4359864 -silesia, level 19, old streaming advanced, 4296880 -silesia, no source size, old streaming advanced, 4849517 -silesia, long distance mode, old streaming advanced, 4849553 -silesia, multithreaded, old streaming advanced, 4849553 -silesia, multithreaded long distance mode, old streaming advanced, 4849553 +github.tar, uncompressed literals optimal, old streaming, 32837 +github.tar, huffman literals, old streaming, 42465 +silesia, level -5, old streaming advanced, 6882505 +silesia, level -3, old streaming advanced, 6568376 +silesia, level -1, old streaming advanced, 6183403 +silesia, level 0, old streaming advanced, 4849551 +silesia, level 1, old streaming advanced, 5314161 +silesia, level 3, old streaming advanced, 4849551 +silesia, level 4, old streaming advanced, 4786969 +silesia, level 5, old streaming advanced, 4639132 +silesia, level 6, old streaming advanced, 4605629 +silesia, level 7, old streaming advanced, 4567307 +silesia, level 9, old streaming advanced, 4543330 +silesia, level 13, old streaming advanced, 4482131 +silesia, level 16, old streaming advanced, 4360251 +silesia, level 19, old streaming advanced, 4283236 +silesia, no source size, old streaming advanced, 4849515 +silesia, long distance mode, old streaming advanced, 4849551 +silesia, multithreaded, old streaming advanced, 4849551 +silesia, multithreaded long distance mode, old streaming advanced, 4849551 silesia, small window log, old streaming advanced, 7112062 silesia, small hash log, old streaming advanced, 6526141 -silesia, small chain log, old streaming advanced, 4912197 -silesia, explicit params, old streaming advanced, 4795883 -silesia, uncompressed literals, old streaming advanced, 4849553 -silesia, uncompressed literals optimal, old streaming advanced, 4296880 -silesia, huffman literals, old streaming advanced, 6183923 -silesia, multithreaded with advanced params, old streaming advanced, 4849553 -silesia.tar, level -5, old streaming advanced, 7260007 -silesia.tar, level -3, old streaming advanced, 6845151 -silesia.tar, level -1, old streaming advanced, 6187938 -silesia.tar, level 0, old streaming advanced, 4861426 -silesia.tar, level 1, old streaming advanced, 5334890 -silesia.tar, level 3, old streaming advanced, 4861426 +silesia, small chain log, old streaming advanced, 4912199 +silesia, explicit params, old streaming advanced, 4796309 +silesia, uncompressed literals, old streaming advanced, 4849551 +silesia, uncompressed literals optimal, old streaming advanced, 4283236 +silesia, huffman literals, old streaming advanced, 6183403 +silesia, multithreaded with advanced params, old streaming advanced, 4849551 +silesia.tar, level -5, old streaming advanced, 6982759 +silesia.tar, level -3, old streaming advanced, 6641283 +silesia.tar, level -1, old streaming advanced, 6190795 +silesia.tar, level 0, old streaming advanced, 4861425 +silesia.tar, level 1, old streaming advanced, 5336941 +silesia.tar, level 3, old streaming advanced, 4861425 silesia.tar, level 4, old streaming advanced, 4799632 -silesia.tar, level 5, old streaming advanced, 4650207 -silesia.tar, level 6, old streaming advanced, 4616816 -silesia.tar, level 7, old streaming advanced, 4576831 -silesia.tar, level 9, old streaming advanced, 4552590 -silesia.tar, level 13, old streaming advanced, 4502956 -silesia.tar, level 16, old streaming advanced, 4360527 -silesia.tar, level 19, old streaming advanced, 4267266 -silesia.tar, no source size, old streaming advanced, 4861422 -silesia.tar, long distance mode, old streaming advanced, 4861426 -silesia.tar, multithreaded, old streaming advanced, 4861426 -silesia.tar, multithreaded long distance mode, old streaming advanced, 4861426 +silesia.tar, level 5, old streaming advanced, 4650392 +silesia.tar, level 6, old streaming advanced, 4617097 +silesia.tar, level 7, old streaming advanced, 4576953 +silesia.tar, level 9, old streaming advanced, 4552646 +silesia.tar, level 13, old streaming advanced, 4491769 +silesia.tar, level 16, old streaming advanced, 4356834 +silesia.tar, level 19, old streaming advanced, 4264388 +silesia.tar, no source size, old streaming advanced, 4861421 +silesia.tar, long distance mode, old streaming advanced, 4861425 +silesia.tar, multithreaded, old streaming advanced, 4861425 +silesia.tar, multithreaded long distance mode, old streaming advanced, 4861425 silesia.tar, small window log, old streaming advanced, 7118772 -silesia.tar, small hash log, old streaming advanced, 6529234 -silesia.tar, small chain log, old streaming advanced, 4917021 -silesia.tar, explicit params, old streaming advanced, 4807401 -silesia.tar, uncompressed literals, old streaming advanced, 4861426 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4267266 -silesia.tar, huffman literals, old streaming advanced, 6187938 -silesia.tar, multithreaded with advanced params, old streaming advanced, 4861426 -github, level -5, old streaming advanced, 241214 +silesia.tar, small hash log, old streaming advanced, 6529231 +silesia.tar, small chain log, old streaming advanced, 4917019 +silesia.tar, explicit params, old streaming advanced, 4807688 +silesia.tar, uncompressed literals, old streaming advanced, 4861425 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4264388 +silesia.tar, huffman literals, old streaming advanced, 6190795 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 +github, level -5, old streaming advanced, 216734 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 222937 +github, level -3, old streaming advanced, 192160 github, level -3 with dict, old streaming advanced, 44956 -github, level -1, old streaming advanced, 181107 +github, level -1, old streaming advanced, 181108 github, level -1 with dict, old streaming advanced, 42383 github, level 0, old streaming advanced, 141104 github, level 0 with dict, old streaming advanced, 41113 -github, level 1, old streaming advanced, 143693 +github, level 1, old streaming advanced, 143692 github, level 1 with dict, old streaming advanced, 42430 github, level 3, old streaming advanced, 141104 github, level 3 with dict, old streaming advanced, 41113 @@ -1359,7 +1359,7 @@ github, level 7 with dict, old stre github, level 9, old streaming advanced, 138676 github, level 9 with dict, old streaming advanced, 38981 github, level 13, old streaming advanced, 138676 -github, level 13 with dict, old streaming advanced, 39721 +github, level 13 with dict, old streaming advanced, 39731 github, level 16, old streaming advanced, 138676 github, level 16 with dict, old streaming advanced, 40789 github, level 19, old streaming advanced, 134064 @@ -1375,36 +1375,36 @@ github, small chain log, old stre github, explicit params, old streaming advanced, 140937 github, uncompressed literals, old streaming advanced, 141104 github, uncompressed literals optimal, old streaming advanced, 134064 -github, huffman literals, old streaming advanced, 181107 +github, huffman literals, old streaming advanced, 181108 github, multithreaded with advanced params, old streaming advanced, 141104 -github.tar, level -5, old streaming advanced, 64132 -github.tar, level -5 with dict, old streaming advanced, 48982 -github.tar, level -3, old streaming advanced, 50964 -github.tar, level -3 with dict, old streaming advanced, 43357 -github.tar, level -1, old streaming advanced, 42536 -github.tar, level -1 with dict, old streaming advanced, 41494 +github.tar, level -5, old streaming advanced, 46747 +github.tar, level -5 with dict, old streaming advanced, 44824 +github.tar, level -3, old streaming advanced, 43537 +github.tar, level -3 with dict, old streaming advanced, 41800 +github.tar, level -1, old streaming advanced, 42465 +github.tar, level -1 with dict, old streaming advanced, 41471 github.tar, level 0, old streaming advanced, 38441 github.tar, level 0 with dict, old streaming advanced, 38013 -github.tar, level 1, old streaming advanced, 39270 -github.tar, level 1 with dict, old streaming advanced, 38934 +github.tar, level 1, old streaming advanced, 39342 +github.tar, level 1 with dict, old streaming advanced, 38940 github.tar, level 3, old streaming advanced, 38441 github.tar, level 3 with dict, old streaming advanced, 38013 github.tar, level 4, old streaming advanced, 38467 github.tar, level 4 with dict, old streaming advanced, 38063 -github.tar, level 5, old streaming advanced, 38376 -github.tar, level 5 with dict, old streaming advanced, 37677 -github.tar, level 6, old streaming advanced, 38610 -github.tar, level 6 with dict, old streaming advanced, 37786 -github.tar, level 7, old streaming advanced, 38073 -github.tar, level 7 with dict, old streaming advanced, 37322 -github.tar, level 9, old streaming advanced, 36767 -github.tar, level 9 with dict, old streaming advanced, 36233 -github.tar, level 13, old streaming advanced, 35501 -github.tar, level 13 with dict, old streaming advanced, 35807 -github.tar, level 16, old streaming advanced, 40471 -github.tar, level 16 with dict, old streaming advanced, 38578 -github.tar, level 19, old streaming advanced, 32134 -github.tar, level 19 with dict, old streaming advanced, 32702 +github.tar, level 5, old streaming advanced, 38394 +github.tar, level 5 with dict, old streaming advanced, 37763 +github.tar, level 6, old streaming advanced, 38669 +github.tar, level 6 with dict, old streaming advanced, 37851 +github.tar, level 7, old streaming advanced, 38153 +github.tar, level 7 with dict, old streaming advanced, 37406 +github.tar, level 9, old streaming advanced, 36768 +github.tar, level 9 with dict, old streaming advanced, 36304 +github.tar, level 13, old streaming advanced, 35621 +github.tar, level 13 with dict, old streaming advanced, 36035 +github.tar, level 16, old streaming advanced, 40255 +github.tar, level 16 with dict, old streaming advanced, 38736 +github.tar, level 19, old streaming advanced, 32837 +github.tar, level 19 with dict, old streaming advanced, 32876 github.tar, no source size, old streaming advanced, 38438 github.tar, no source size with dict, old streaming advanced, 38015 github.tar, long distance mode, old streaming advanced, 38441 @@ -1413,10 +1413,10 @@ github.tar, multithreaded long distance mode, old stre github.tar, small window log, old streaming advanced, 199561 github.tar, small hash log, old streaming advanced, 129870 github.tar, small chain log, old streaming advanced, 41669 -github.tar, explicit params, old streaming advanced, 41227 +github.tar, explicit params, old streaming advanced, 41351 github.tar, uncompressed literals, old streaming advanced, 38441 -github.tar, uncompressed literals optimal, old streaming advanced, 32134 -github.tar, huffman literals, old streaming advanced, 42536 +github.tar, uncompressed literals optimal, old streaming advanced, 32837 +github.tar, huffman literals, old streaming advanced, 42465 github.tar, multithreaded with advanced params, old streaming advanced, 38441 github, level -5 with dict, old streaming cdict, 46718 github, level -3 with dict, old streaming cdict, 45395 @@ -1433,20 +1433,20 @@ github, level 13 with dict, old stre github, level 16 with dict, old streaming cdict, 37577 github, level 19 with dict, old streaming cdict, 37576 github, no source size with dict, old streaming cdict, 40654 -github.tar, level -5 with dict, old streaming cdict, 49146 -github.tar, level -3 with dict, old streaming cdict, 43468 -github.tar, level -1 with dict, old streaming cdict, 41662 +github.tar, level -5 with dict, old streaming cdict, 45018 +github.tar, level -3 with dict, old streaming cdict, 41886 +github.tar, level -1 with dict, old streaming cdict, 41636 github.tar, level 0 with dict, old streaming cdict, 37956 -github.tar, level 1 with dict, old streaming cdict, 38761 +github.tar, level 1 with dict, old streaming cdict, 38766 github.tar, level 3 with dict, old streaming cdict, 37956 github.tar, level 4 with dict, old streaming cdict, 37927 -github.tar, level 5 with dict, old streaming cdict, 37600 -github.tar, level 6 with dict, old streaming cdict, 37829 -github.tar, level 7 with dict, old streaming cdict, 37371 -github.tar, level 9 with dict, old streaming cdict, 36352 -github.tar, level 13 with dict, old streaming cdict, 36010 -github.tar, level 16 with dict, old streaming cdict, 39081 -github.tar, level 19 with dict, old streaming cdict, 32474 +github.tar, level 5 with dict, old streaming cdict, 37665 +github.tar, level 6 with dict, old streaming cdict, 37889 +github.tar, level 7 with dict, old streaming cdict, 37457 +github.tar, level 9 with dict, old streaming cdict, 36383 +github.tar, level 13 with dict, old streaming cdict, 36372 +github.tar, level 16 with dict, old streaming cdict, 39353 +github.tar, level 19 with dict, old streaming cdict, 32676 github.tar, no source size with dict, old streaming cdict, 38000 github, level -5 with dict, old streaming advanced cdict, 49562 github, level -3 with dict, old streaming advanced cdict, 44956 @@ -1459,7 +1459,7 @@ github, level 5 with dict, old stre github, level 6 with dict, old streaming advanced cdict, 39363 github, level 7 with dict, old streaming advanced cdict, 38924 github, level 9 with dict, old streaming advanced cdict, 38981 -github, level 13 with dict, old streaming advanced cdict, 39721 +github, level 13 with dict, old streaming advanced cdict, 39731 github, level 16 with dict, old streaming advanced cdict, 40789 github, level 19 with dict, old streaming advanced cdict, 37576 github, no source size with dict, old streaming advanced cdict, 40608 @@ -1470,11 +1470,11 @@ github.tar, level 0 with dict, old stre github.tar, level 1 with dict, old streaming advanced cdict, 39002 github.tar, level 3 with dict, old streaming advanced cdict, 38013 github.tar, level 4 with dict, old streaming advanced cdict, 38063 -github.tar, level 5 with dict, old streaming advanced cdict, 37677 -github.tar, level 6 with dict, old streaming advanced cdict, 37786 -github.tar, level 7 with dict, old streaming advanced cdict, 37322 -github.tar, level 9 with dict, old streaming advanced cdict, 36233 -github.tar, level 13 with dict, old streaming advanced cdict, 35807 -github.tar, level 16 with dict, old streaming advanced cdict, 38578 -github.tar, level 19 with dict, old streaming advanced cdict, 32702 +github.tar, level 5 with dict, old streaming advanced cdict, 37763 +github.tar, level 6 with dict, old streaming advanced cdict, 37851 +github.tar, level 7 with dict, old streaming advanced cdict, 37406 +github.tar, level 9 with dict, old streaming advanced cdict, 36304 +github.tar, level 13 with dict, old streaming advanced cdict, 36035 +github.tar, level 16 with dict, old streaming advanced cdict, 38736 +github.tar, level 19 with dict, old streaming advanced cdict, 32876 github.tar, no source size with dict, old streaming advanced cdict, 38015 From ccdcbf46214186db78779290f025158bb1eee627 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Thu, 23 Sep 2021 07:08:56 -0700 Subject: [PATCH 198/274] Try beginning and end of match --- lib/compress/zstd_lazy.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index e9ee6ebd4..c94a663be 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1025,14 +1025,29 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const U32 idx = ms->nextToUpdate; const BYTE* const base = ms->window.base; const U32 target = (U32)(ip - base); - const U32 kMaxPositionsToUpdate = 256; + const U32 kMaxPositionsToUpdate = 128; assert(target >= idx); if (useCache) { /* Only skip positions when using hash cache, i.e. - if we are loading a dict, don't skip anything */ + * if we are loading a dict, don't skip anything. + */ if (UNLIKELY(target - idx > kMaxPositionsToUpdate)) { - idx = target - kMaxPositionsToUpdate; + U32 const bound = idx + 3*kMaxPositionsToUpdate/4; + for (; idx < bound; ++idx) { + U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, idx, hashLog, rowLog, mls) + : (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32* const row = hashTable + relRow; + BYTE* tagRow = (BYTE*)(tagTable + relRow); /* Though tagTable is laid out as a table of U16, each tag is only 1 byte. + Explicit cast allows us to get exact desired position within each row */ + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + + assert(hash == ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls)); + tagRow[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; + row[pos] = idx; + } + idx = target - kMaxPositionsToUpdate/4; ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); } } From 4b7f45cb04d624d5ae2cc5bbaf234fe450ad8c09 Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Tue, 28 Sep 2021 07:48:56 -0700 Subject: [PATCH 199/274] Pull hot loop into its own function --- lib/compress/zstd_lazy.c | 86 +++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index c94a663be..c76fa840f 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1011,61 +1011,65 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTab } } -/* ZSTD_row_update_internal(): - * Inserts the byte at ip into the appropriate position in the hash table. - * Determines the relative row, and the position within the {16, 32} entry row to insert at. +/* ZSTD_row_update_internalImpl(): + * Updates the hash table with positions starting from updateStartIdx until updateEndIdx. */ -FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip, - U32 const mls, U32 const rowLog, - U32 const rowMask, U32 const useCache) +FORCE_INLINE_TEMPLATE void ZSTD_row_update_internalImpl(ZSTD_matchState_t* ms, + U32 updateStartIdx, U32 const updateEndIdx, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) { U32* const hashTable = ms->hashTable; U16* const tagTable = ms->tagTable; U32 const hashLog = ms->rowHashLog; - U32 idx = ms->nextToUpdate; const BYTE* const base = ms->window.base; - const U32 target = (U32)(ip - base); - const U32 kMaxPositionsToUpdate = 128; - assert(target >= idx); - if (useCache) { - /* Only skip positions when using hash cache, i.e. - * if we are loading a dict, don't skip anything. - */ - if (UNLIKELY(target - idx > kMaxPositionsToUpdate)) { - U32 const bound = idx + 3*kMaxPositionsToUpdate/4; - for (; idx < bound; ++idx) { - U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, idx, hashLog, rowLog, mls) - : (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); - U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; - U32* const row = hashTable + relRow; - BYTE* tagRow = (BYTE*)(tagTable + relRow); /* Though tagTable is laid out as a table of U16, each tag is only 1 byte. - Explicit cast allows us to get exact desired position within each row */ - U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); - - assert(hash == ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls)); - tagRow[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; - row[pos] = idx; - } - idx = target - kMaxPositionsToUpdate/4; - ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); - } - } - - DEBUGLOG(6, "ZSTD_row_update_internal(): nextToUpdate=%u, current=%u", idx, target); - for (; idx < target; ++idx) { - U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, idx, hashLog, rowLog, mls) - : (U32)ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx); + for (; updateStartIdx < updateEndIdx; ++updateStartIdx) { + U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls) + : (U32)ZSTD_hashPtr(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls); U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; U32* const row = hashTable + relRow; BYTE* tagRow = (BYTE*)(tagTable + relRow); /* Though tagTable is laid out as a table of U16, each tag is only 1 byte. Explicit cast allows us to get exact desired position within each row */ U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); - assert(hash == ZSTD_hashPtr(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls)); - tagRow[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; - row[pos] = idx; + assert(hash == ZSTD_hashPtr(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls)); + ((BYTE*)tagRow)[pos + ZSTD_ROW_HASH_TAG_OFFSET] = hash & ZSTD_ROW_HASH_TAG_MASK; + row[pos] = updateStartIdx; } +} + +/* ZSTD_row_update_internal(): + * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate. + * Skips sections of long matches as is necessary. + */ +FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const BYTE* ip, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32 idx = ms->nextToUpdate; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + const U32 kSkipThreshold = 384; + const U32 kMaxMatchStartPositionsToUpdate = 96; + const U32 kMaxMatchEndPositionsToUpdate = 32; + + if (useCache) { + /* Only skip positions when using hash cache, i.e. + * if we are loading a dict, don't skip anything. + * If we decide to skip, then we only update a set number + * of positions at the beginning and end of the match. + */ + if (UNLIKELY(target - idx > kSkipThreshold)) { + U32 const bound = idx + kMaxMatchStartPositionsToUpdate; + ZSTD_row_update_internalImpl(ms, idx, bound, mls, rowLog, rowMask, useCache); + idx = target - kMaxMatchEndPositionsToUpdate; + ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); + } + } + assert(target >= idx); + ZSTD_row_update_internalImpl(ms, idx, target, mls, rowLog, rowMask, useCache); ms->nextToUpdate = target; } From 93603673718d6063a86d483e9d09ac2fdf8ca00d Mon Sep 17 00:00:00 2001 From: Sen Huang Date: Tue, 28 Sep 2021 08:29:11 -0700 Subject: [PATCH 200/274] Update regression test --- tests/regression/results.csv | 1586 +++++++++++++++++----------------- 1 file changed, 793 insertions(+), 793 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 66be6cb5b..2538728c8 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -1,72 +1,72 @@ Data, Config, Method, Total compressed size -silesia.tar, level -5, compress simple, 6738593 -silesia.tar, level -3, compress simple, 6446372 -silesia.tar, level -1, compress simple, 6186042 -silesia.tar, level 0, compress simple, 4861423 -silesia.tar, level 1, compress simple, 5334885 -silesia.tar, level 3, compress simple, 4861423 +silesia.tar, level -5, compress simple, 7359401 +silesia.tar, level -3, compress simple, 6901672 +silesia.tar, level -1, compress simple, 6182241 +silesia.tar, level 0, compress simple, 4861424 +silesia.tar, level 1, compress simple, 5331946 +silesia.tar, level 3, compress simple, 4861424 silesia.tar, level 4, compress simple, 4799632 -silesia.tar, level 5, compress simple, 4650387 -silesia.tar, level 6, compress simple, 4617089 -silesia.tar, level 7, compress simple, 4576951 -silesia.tar, level 9, compress simple, 4552638 -silesia.tar, level 13, compress simple, 4491768 -silesia.tar, level 16, compress simple, 4356834 -silesia.tar, level 19, compress simple, 4264388 -silesia.tar, uncompressed literals, compress simple, 4861423 -silesia.tar, uncompressed literals optimal, compress simple, 4264388 -silesia.tar, huffman literals, compress simple, 6186042 -github.tar, level -5, compress simple, 46856 -github.tar, level -3, compress simple, 43754 -github.tar, level -1, compress simple, 42490 +silesia.tar, level 5, compress simple, 4649987 +silesia.tar, level 6, compress simple, 4616797 +silesia.tar, level 7, compress simple, 4576661 +silesia.tar, level 9, compress simple, 4552381 +silesia.tar, level 13, compress simple, 4502956 +silesia.tar, level 16, compress simple, 4360527 +silesia.tar, level 19, compress simple, 4267266 +silesia.tar, uncompressed literals, compress simple, 4861424 +silesia.tar, uncompressed literals optimal, compress simple, 4267266 +silesia.tar, huffman literals, compress simple, 6182241 +github.tar, level -5, compress simple, 66914 +github.tar, level -3, compress simple, 52127 +github.tar, level -1, compress simple, 42560 github.tar, level 0, compress simple, 38441 -github.tar, level 1, compress simple, 39265 +github.tar, level 1, compress simple, 39200 github.tar, level 3, compress simple, 38441 github.tar, level 4, compress simple, 38467 -github.tar, level 5, compress simple, 38394 -github.tar, level 6, compress simple, 38669 -github.tar, level 7, compress simple, 38153 -github.tar, level 9, compress simple, 36768 -github.tar, level 13, compress simple, 35621 -github.tar, level 16, compress simple, 40255 -github.tar, level 19, compress simple, 32837 +github.tar, level 5, compress simple, 38366 +github.tar, level 6, compress simple, 38648 +github.tar, level 7, compress simple, 38110 +github.tar, level 9, compress simple, 36760 +github.tar, level 13, compress simple, 35501 +github.tar, level 16, compress simple, 40471 +github.tar, level 19, compress simple, 32134 github.tar, uncompressed literals, compress simple, 38441 -github.tar, uncompressed literals optimal, compress simple, 32837 -github.tar, huffman literals, compress simple, 42490 -silesia, level -5, compress cctx, 6737607 -silesia, level -3, compress cctx, 6444677 -silesia, level -1, compress cctx, 6178460 -silesia, level 0, compress cctx, 4849551 -silesia, level 1, compress cctx, 5313202 -silesia, level 3, compress cctx, 4849551 -silesia, level 4, compress cctx, 4786969 -silesia, level 5, compress cctx, 4639132 -silesia, level 6, compress cctx, 4605629 -silesia, level 7, compress cctx, 4567307 -silesia, level 9, compress cctx, 4543330 -silesia, level 13, compress cctx, 4482131 -silesia, level 16, compress cctx, 4360251 -silesia, level 19, compress cctx, 4283236 -silesia, long distance mode, compress cctx, 4849551 -silesia, multithreaded, compress cctx, 4849551 -silesia, multithreaded long distance mode, compress cctx, 4849551 +github.tar, uncompressed literals optimal, compress simple, 32134 +github.tar, huffman literals, compress simple, 42560 +silesia, level -5, compress cctx, 7354675 +silesia, level -3, compress cctx, 6902374 +silesia, level -1, compress cctx, 6177565 +silesia, level 0, compress cctx, 4849553 +silesia, level 1, compress cctx, 5309098 +silesia, level 3, compress cctx, 4849553 +silesia, level 4, compress cctx, 4786968 +silesia, level 5, compress cctx, 4638691 +silesia, level 6, compress cctx, 4605296 +silesia, level 7, compress cctx, 4566984 +silesia, level 9, compress cctx, 4543018 +silesia, level 13, compress cctx, 4493990 +silesia, level 16, compress cctx, 4359864 +silesia, level 19, compress cctx, 4296880 +silesia, long distance mode, compress cctx, 4849553 +silesia, multithreaded, compress cctx, 4849553 +silesia, multithreaded long distance mode, compress cctx, 4849553 silesia, small window log, compress cctx, 7084179 silesia, small hash log, compress cctx, 6526141 -silesia, small chain log, compress cctx, 4912199 -silesia, explicit params, compress cctx, 4794917 -silesia, uncompressed literals, compress cctx, 4849551 -silesia, uncompressed literals optimal, compress cctx, 4283236 -silesia, huffman literals, compress cctx, 6178460 -silesia, multithreaded with advanced params, compress cctx, 4849551 -github, level -5, compress cctx, 205285 +silesia, small chain log, compress cctx, 4912197 +silesia, explicit params, compress cctx, 4794052 +silesia, uncompressed literals, compress cctx, 4849553 +silesia, uncompressed literals optimal, compress cctx, 4296880 +silesia, huffman literals, compress cctx, 6177565 +silesia, multithreaded with advanced params, compress cctx, 4849553 +github, level -5, compress cctx, 232315 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 190643 +github, level -3, compress cctx, 220760 github, level -3 with dict, compress cctx, 48047 -github, level -1, compress cctx, 175568 +github, level -1, compress cctx, 175468 github, level -1 with dict, compress cctx, 43527 github, level 0, compress cctx, 136335 github, level 0 with dict, compress cctx, 41534 -github, level 1, compress cctx, 142465 +github, level 1, compress cctx, 142365 github, level 1 with dict, compress cctx, 42157 github, level 3, compress cctx, 136335 github, level 3 with dict, compress cctx, 41534 @@ -95,68 +95,68 @@ github, small chain log, compress github, explicit params, compress cctx, 140932 github, uncompressed literals, compress cctx, 136335 github, uncompressed literals optimal, compress cctx, 134064 -github, huffman literals, compress cctx, 175568 +github, huffman literals, compress cctx, 175468 github, multithreaded with advanced params, compress cctx, 141102 -silesia, level -5, zstdcli, 6737655 -silesia, level -3, zstdcli, 6444725 -silesia, level -1, zstdcli, 6178508 -silesia, level 0, zstdcli, 4849599 -silesia, level 1, zstdcli, 5313250 -silesia, level 3, zstdcli, 4849599 -silesia, level 4, zstdcli, 4787017 -silesia, level 5, zstdcli, 4639180 -silesia, level 6, zstdcli, 4605677 -silesia, level 7, zstdcli, 4567355 -silesia, level 9, zstdcli, 4543378 -silesia, level 13, zstdcli, 4482179 -silesia, level 16, zstdcli, 4360299 -silesia, level 19, zstdcli, 4283284 +silesia, level -5, zstdcli, 7354723 +silesia, level -3, zstdcli, 6902422 +silesia, level -1, zstdcli, 6177613 +silesia, level 0, zstdcli, 4849601 +silesia, level 1, zstdcli, 5309146 +silesia, level 3, zstdcli, 4849601 +silesia, level 4, zstdcli, 4787016 +silesia, level 5, zstdcli, 4638739 +silesia, level 6, zstdcli, 4605344 +silesia, level 7, zstdcli, 4567032 +silesia, level 9, zstdcli, 4543066 +silesia, level 13, zstdcli, 4494038 +silesia, level 16, zstdcli, 4359912 +silesia, level 19, zstdcli, 4296928 silesia, long distance mode, zstdcli, 4840807 -silesia, multithreaded, zstdcli, 4849599 +silesia, multithreaded, zstdcli, 4849601 silesia, multithreaded long distance mode, zstdcli, 4840807 silesia, small window log, zstdcli, 7095967 silesia, small hash log, zstdcli, 6526189 -silesia, small chain log, zstdcli, 4912247 -silesia, explicit params, zstdcli, 4796282 +silesia, small chain log, zstdcli, 4912245 +silesia, explicit params, zstdcli, 4795432 silesia, uncompressed literals, zstdcli, 5128030 -silesia, uncompressed literals optimal, zstdcli, 4317944 -silesia, huffman literals, zstdcli, 5326317 +silesia, uncompressed literals optimal, zstdcli, 4319566 +silesia, huffman literals, zstdcli, 5326394 silesia, multithreaded with advanced params, zstdcli, 5128030 -silesia.tar, level -5, zstdcli, 6738934 -silesia.tar, level -3, zstdcli, 6448419 -silesia.tar, level -1, zstdcli, 6186912 -silesia.tar, level 0, zstdcli, 4861511 -silesia.tar, level 1, zstdcli, 5336318 -silesia.tar, level 3, zstdcli, 4861511 -silesia.tar, level 4, zstdcli, 4800529 -silesia.tar, level 5, zstdcli, 4651342 -silesia.tar, level 6, zstdcli, 4618674 -silesia.tar, level 7, zstdcli, 4579009 -silesia.tar, level 9, zstdcli, 4553551 -silesia.tar, level 13, zstdcli, 4491772 -silesia.tar, level 16, zstdcli, 4356838 -silesia.tar, level 19, zstdcli, 4264392 -silesia.tar, no source size, zstdcli, 4861507 +silesia.tar, level -5, zstdcli, 7363866 +silesia.tar, level -3, zstdcli, 6902158 +silesia.tar, level -1, zstdcli, 6182939 +silesia.tar, level 0, zstdcli, 4861512 +silesia.tar, level 1, zstdcli, 5333183 +silesia.tar, level 3, zstdcli, 4861512 +silesia.tar, level 4, zstdcli, 4800528 +silesia.tar, level 5, zstdcli, 4650946 +silesia.tar, level 6, zstdcli, 4618390 +silesia.tar, level 7, zstdcli, 4578719 +silesia.tar, level 9, zstdcli, 4553299 +silesia.tar, level 13, zstdcli, 4502960 +silesia.tar, level 16, zstdcli, 4360531 +silesia.tar, level 19, zstdcli, 4267270 +silesia.tar, no source size, zstdcli, 4861508 silesia.tar, long distance mode, zstdcli, 4853225 -silesia.tar, multithreaded, zstdcli, 4861511 +silesia.tar, multithreaded, zstdcli, 4861512 silesia.tar, multithreaded long distance mode, zstdcli, 4853225 silesia.tar, small window log, zstdcli, 7101576 -silesia.tar, small hash log, zstdcli, 6529286 -silesia.tar, small chain log, zstdcli, 4917020 -silesia.tar, explicit params, zstdcli, 4821593 +silesia.tar, small hash log, zstdcli, 6529289 +silesia.tar, small chain log, zstdcli, 4917022 +silesia.tar, explicit params, zstdcli, 4820713 silesia.tar, uncompressed literals, zstdcli, 5129559 -silesia.tar, uncompressed literals optimal, zstdcli, 4307404 -silesia.tar, huffman literals, zstdcli, 5347610 +silesia.tar, uncompressed literals optimal, zstdcli, 4310145 +silesia.tar, huffman literals, zstdcli, 5344915 silesia.tar, multithreaded with advanced params, zstdcli, 5129559 -github, level -5, zstdcli, 207285 +github, level -5, zstdcli, 234315 github, level -5 with dict, zstdcli, 48718 -github, level -3, zstdcli, 192643 +github, level -3, zstdcli, 222760 github, level -3 with dict, zstdcli, 47395 -github, level -1, zstdcli, 177568 +github, level -1, zstdcli, 177468 github, level -1 with dict, zstdcli, 45170 github, level 0, zstdcli, 138335 github, level 0 with dict, zstdcli, 43148 -github, level 1, zstdcli, 144465 +github, level 1, zstdcli, 144365 github, level 1 with dict, zstdcli, 43682 github, level 3, zstdcli, 138335 github, level 3 with dict, zstdcli, 43148 @@ -185,36 +185,36 @@ github, small chain log, zstdcli, github, explicit params, zstdcli, 136197 github, uncompressed literals, zstdcli, 167915 github, uncompressed literals optimal, zstdcli, 159227 -github, huffman literals, zstdcli, 144465 +github, huffman literals, zstdcli, 144365 github, multithreaded with advanced params, zstdcli, 167915 -github.tar, level -5, zstdcli, 46860 -github.tar, level -5 with dict, zstdcli, 44575 -github.tar, level -3, zstdcli, 43758 -github.tar, level -3 with dict, zstdcli, 41451 -github.tar, level -1, zstdcli, 42494 -github.tar, level -1 with dict, zstdcli, 41135 +github.tar, level -5, zstdcli, 66918 +github.tar, level -5 with dict, zstdcli, 51529 +github.tar, level -3, zstdcli, 52131 +github.tar, level -3 with dict, zstdcli, 44246 +github.tar, level -1, zstdcli, 42564 +github.tar, level -1 with dict, zstdcli, 41140 github.tar, level 0, zstdcli, 38445 github.tar, level 0 with dict, zstdcli, 37999 -github.tar, level 1, zstdcli, 39269 -github.tar, level 1 with dict, zstdcli, 38284 +github.tar, level 1, zstdcli, 39204 +github.tar, level 1 with dict, zstdcli, 38288 github.tar, level 3, zstdcli, 38445 github.tar, level 3 with dict, zstdcli, 37999 github.tar, level 4, zstdcli, 38471 github.tar, level 4 with dict, zstdcli, 37952 -github.tar, level 5, zstdcli, 38398 -github.tar, level 5 with dict, zstdcli, 39048 -github.tar, level 6, zstdcli, 38673 -github.tar, level 6 with dict, zstdcli, 38660 -github.tar, level 7, zstdcli, 38157 -github.tar, level 7 with dict, zstdcli, 37914 -github.tar, level 9, zstdcli, 36772 -github.tar, level 9 with dict, zstdcli, 36650 -github.tar, level 13, zstdcli, 35625 -github.tar, level 13 with dict, zstdcli, 38730 -github.tar, level 16, zstdcli, 40259 -github.tar, level 16 with dict, zstdcli, 33643 -github.tar, level 19, zstdcli, 32841 -github.tar, level 19 with dict, zstdcli, 32899 +github.tar, level 5, zstdcli, 38370 +github.tar, level 5 with dict, zstdcli, 39071 +github.tar, level 6, zstdcli, 38652 +github.tar, level 6 with dict, zstdcli, 38638 +github.tar, level 7, zstdcli, 38114 +github.tar, level 7 with dict, zstdcli, 37886 +github.tar, level 9, zstdcli, 36764 +github.tar, level 9 with dict, zstdcli, 36632 +github.tar, level 13, zstdcli, 35505 +github.tar, level 13 with dict, zstdcli, 37134 +github.tar, level 16, zstdcli, 40475 +github.tar, level 16 with dict, zstdcli, 33382 +github.tar, level 19, zstdcli, 32138 +github.tar, level 19 with dict, zstdcli, 32713 github.tar, no source size, zstdcli, 38442 github.tar, no source size with dict, zstdcli, 38004 github.tar, long distance mode, zstdcli, 39730 @@ -223,84 +223,84 @@ github.tar, multithreaded long distance mode, zstdcli, github.tar, small window log, zstdcli, 198544 github.tar, small hash log, zstdcli, 129874 github.tar, small chain log, zstdcli, 41673 -github.tar, explicit params, zstdcli, 41350 +github.tar, explicit params, zstdcli, 41385 github.tar, uncompressed literals, zstdcli, 41126 -github.tar, uncompressed literals optimal, zstdcli, 35392 -github.tar, huffman literals, zstdcli, 38781 +github.tar, uncompressed literals optimal, zstdcli, 35401 +github.tar, huffman literals, zstdcli, 38857 github.tar, multithreaded with advanced params, zstdcli, 41126 -silesia, level -5, advanced one pass, 6737607 -silesia, level -3, advanced one pass, 6444677 -silesia, level -1, advanced one pass, 6178460 -silesia, level 0, advanced one pass, 4849551 -silesia, level 1, advanced one pass, 5313202 -silesia, level 3, advanced one pass, 4849551 -silesia, level 4, advanced one pass, 4786969 -silesia, level 5 row 1, advanced one pass, 4640753 -silesia, level 5 row 2, advanced one pass, 4639132 -silesia, level 5, advanced one pass, 4639132 -silesia, level 6, advanced one pass, 4605629 -silesia, level 7 row 1, advanced one pass, 4564870 -silesia, level 7 row 2, advanced one pass, 4567307 -silesia, level 7, advanced one pass, 4567307 -silesia, level 9, advanced one pass, 4543330 -silesia, level 11 row 1, advanced one pass, 4519288 -silesia, level 11 row 2, advanced one pass, 4521524 -silesia, level 12 row 1, advanced one pass, 4503117 -silesia, level 12 row 2, advanced one pass, 4505093 -silesia, level 13, advanced one pass, 4482131 -silesia, level 16, advanced one pass, 4360251 -silesia, level 19, advanced one pass, 4283236 -silesia, no source size, advanced one pass, 4849551 -silesia, long distance mode, advanced one pass, 4840738 -silesia, multithreaded, advanced one pass, 4849551 +silesia, level -5, advanced one pass, 7354675 +silesia, level -3, advanced one pass, 6902374 +silesia, level -1, advanced one pass, 6177565 +silesia, level 0, advanced one pass, 4849553 +silesia, level 1, advanced one pass, 5309098 +silesia, level 3, advanced one pass, 4849553 +silesia, level 4, advanced one pass, 4786968 +silesia, level 5 row 1, advanced one pass, 4638691 +silesia, level 5 row 2, advanced one pass, 4640752 +silesia, level 5, advanced one pass, 4638691 +silesia, level 6, advanced one pass, 4605296 +silesia, level 7 row 1, advanced one pass, 4566984 +silesia, level 7 row 2, advanced one pass, 4564868 +silesia, level 7, advanced one pass, 4566984 +silesia, level 9, advanced one pass, 4543018 +silesia, level 11 row 1, advanced one pass, 4521323 +silesia, level 11 row 2, advanced one pass, 4519288 +silesia, level 12 row 1, advanced one pass, 4505046 +silesia, level 12 row 2, advanced one pass, 4503116 +silesia, level 13, advanced one pass, 4493990 +silesia, level 16, advanced one pass, 4359864 +silesia, level 19, advanced one pass, 4296880 +silesia, no source size, advanced one pass, 4849553 +silesia, long distance mode, advanced one pass, 4840737 +silesia, multithreaded, advanced one pass, 4849553 silesia, multithreaded long distance mode, advanced one pass, 4840759 silesia, small window log, advanced one pass, 7095919 silesia, small hash log, advanced one pass, 6526141 -silesia, small chain log, advanced one pass, 4912199 -silesia, explicit params, advanced one pass, 4796282 +silesia, small chain log, advanced one pass, 4912197 +silesia, explicit params, advanced one pass, 4795432 silesia, uncompressed literals, advanced one pass, 5127982 -silesia, uncompressed literals optimal, advanced one pass, 4317896 -silesia, huffman literals, advanced one pass, 5326269 +silesia, uncompressed literals optimal, advanced one pass, 4319518 +silesia, huffman literals, advanced one pass, 5326346 silesia, multithreaded with advanced params, advanced one pass, 5127982 -silesia.tar, level -5, advanced one pass, 6738593 -silesia.tar, level -3, advanced one pass, 6446372 -silesia.tar, level -1, advanced one pass, 6186042 -silesia.tar, level 0, advanced one pass, 4861423 -silesia.tar, level 1, advanced one pass, 5334885 -silesia.tar, level 3, advanced one pass, 4861423 +silesia.tar, level -5, advanced one pass, 7359401 +silesia.tar, level -3, advanced one pass, 6901672 +silesia.tar, level -1, advanced one pass, 6182241 +silesia.tar, level 0, advanced one pass, 4861424 +silesia.tar, level 1, advanced one pass, 5331946 +silesia.tar, level 3, advanced one pass, 4861424 silesia.tar, level 4, advanced one pass, 4799632 -silesia.tar, level 5 row 1, advanced one pass, 4652862 -silesia.tar, level 5 row 2, advanced one pass, 4650387 -silesia.tar, level 5, advanced one pass, 4650387 -silesia.tar, level 6, advanced one pass, 4617089 -silesia.tar, level 7 row 1, advanced one pass, 4575392 -silesia.tar, level 7 row 2, advanced one pass, 4576951 -silesia.tar, level 7, advanced one pass, 4576951 -silesia.tar, level 9, advanced one pass, 4552638 -silesia.tar, level 11 row 1, advanced one pass, 4529458 -silesia.tar, level 11 row 2, advanced one pass, 4530416 -silesia.tar, level 12 row 1, advanced one pass, 4513603 -silesia.tar, level 12 row 2, advanced one pass, 4514499 -silesia.tar, level 13, advanced one pass, 4491768 -silesia.tar, level 16, advanced one pass, 4356834 -silesia.tar, level 19, advanced one pass, 4264388 -silesia.tar, no source size, advanced one pass, 4861423 -silesia.tar, long distance mode, advanced one pass, 4847753 -silesia.tar, multithreaded, advanced one pass, 4861507 +silesia.tar, level 5 row 1, advanced one pass, 4649987 +silesia.tar, level 5 row 2, advanced one pass, 4652862 +silesia.tar, level 5, advanced one pass, 4649987 +silesia.tar, level 6, advanced one pass, 4616797 +silesia.tar, level 7 row 1, advanced one pass, 4576661 +silesia.tar, level 7 row 2, advanced one pass, 4575393 +silesia.tar, level 7, advanced one pass, 4576661 +silesia.tar, level 9, advanced one pass, 4552381 +silesia.tar, level 11 row 1, advanced one pass, 4530241 +silesia.tar, level 11 row 2, advanced one pass, 4529461 +silesia.tar, level 12 row 1, advanced one pass, 4514432 +silesia.tar, level 12 row 2, advanced one pass, 4513604 +silesia.tar, level 13, advanced one pass, 4502956 +silesia.tar, level 16, advanced one pass, 4360527 +silesia.tar, level 19, advanced one pass, 4267266 +silesia.tar, no source size, advanced one pass, 4861424 +silesia.tar, long distance mode, advanced one pass, 4847752 +silesia.tar, multithreaded, advanced one pass, 4861508 silesia.tar, multithreaded long distance mode, advanced one pass, 4853221 silesia.tar, small window log, advanced one pass, 7101530 -silesia.tar, small hash log, advanced one pass, 6529228 -silesia.tar, small chain log, advanced one pass, 4917039 -silesia.tar, explicit params, advanced one pass, 4807675 +silesia.tar, small hash log, advanced one pass, 6529231 +silesia.tar, small chain log, advanced one pass, 4917041 +silesia.tar, explicit params, advanced one pass, 4806855 silesia.tar, uncompressed literals, advanced one pass, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass, 4307400 -silesia.tar, huffman literals, advanced one pass, 5347335 +silesia.tar, uncompressed literals optimal, advanced one pass, 4310141 +silesia.tar, huffman literals, advanced one pass, 5344545 silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 -github, level -5, advanced one pass, 205285 +github, level -5, advanced one pass, 232315 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 190643 +github, level -3, advanced one pass, 220760 github, level -3 with dict, advanced one pass, 45395 -github, level -1, advanced one pass, 175568 +github, level -1, advanced one pass, 175468 github, level -1 with dict, advanced one pass, 43170 github, level 0, advanced one pass, 136335 github, level 0 with dict, advanced one pass, 41148 @@ -308,7 +308,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced one pass, 41148 github, level 0 with dict copy, advanced one pass, 41124 github, level 0 with dict load, advanced one pass, 42252 -github, level 1, advanced one pass, 142465 +github, level 1, advanced one pass, 142365 github, level 1 with dict, advanced one pass, 41682 github, level 1 with dict dms, advanced one pass, 41682 github, level 1 with dict dds, advanced one pass, 41682 @@ -326,16 +326,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced one pass, 41251 github, level 4 with dict copy, advanced one pass, 41216 github, level 4 with dict load, advanced one pass, 41159 -github, level 5 row 1, advanced one pass, 135121 -github, level 5 row 1 with dict dms, advanced one pass, 38938 -github, level 5 row 1 with dict dds, advanced one pass, 38732 -github, level 5 row 1 with dict copy, advanced one pass, 38934 -github, level 5 row 1 with dict load, advanced one pass, 40725 -github, level 5 row 2, advanced one pass, 134584 -github, level 5 row 2 with dict dms, advanced one pass, 38758 -github, level 5 row 2 with dict dds, advanced one pass, 38728 -github, level 5 row 2 with dict copy, advanced one pass, 38759 -github, level 5 row 2 with dict load, advanced one pass, 41518 +github, level 5 row 1, advanced one pass, 134584 +github, level 5 row 1 with dict dms, advanced one pass, 38758 +github, level 5 row 1 with dict dds, advanced one pass, 38728 +github, level 5 row 1 with dict copy, advanced one pass, 38759 +github, level 5 row 1 with dict load, advanced one pass, 41518 +github, level 5 row 2, advanced one pass, 135121 +github, level 5 row 2 with dict dms, advanced one pass, 38938 +github, level 5 row 2 with dict dds, advanced one pass, 38732 +github, level 5 row 2 with dict copy, advanced one pass, 38934 +github, level 5 row 2 with dict load, advanced one pass, 40725 github, level 5, advanced one pass, 135121 github, level 5 with dict, advanced one pass, 38758 github, level 5 with dict dms, advanced one pass, 38758 @@ -348,16 +348,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced one pass, 38636 github, level 6 with dict copy, advanced one pass, 38669 github, level 6 with dict load, advanced one pass, 40695 -github, level 7 row 1, advanced one pass, 135122 -github, level 7 row 1 with dict dms, advanced one pass, 38860 -github, level 7 row 1 with dict dds, advanced one pass, 38766 -github, level 7 row 1 with dict copy, advanced one pass, 38834 -github, level 7 row 1 with dict load, advanced one pass, 40695 -github, level 7 row 2, advanced one pass, 134584 -github, level 7 row 2 with dict dms, advanced one pass, 38758 -github, level 7 row 2 with dict dds, advanced one pass, 38745 -github, level 7 row 2 with dict copy, advanced one pass, 38755 -github, level 7 row 2 with dict load, advanced one pass, 43154 +github, level 7 row 1, advanced one pass, 134584 +github, level 7 row 1 with dict dms, advanced one pass, 38758 +github, level 7 row 1 with dict dds, advanced one pass, 38745 +github, level 7 row 1 with dict copy, advanced one pass, 38755 +github, level 7 row 1 with dict load, advanced one pass, 43154 +github, level 7 row 2, advanced one pass, 135122 +github, level 7 row 2 with dict dms, advanced one pass, 38860 +github, level 7 row 2 with dict dds, advanced one pass, 38766 +github, level 7 row 2 with dict copy, advanced one pass, 38834 +github, level 7 row 2 with dict load, advanced one pass, 40695 github, level 7, advanced one pass, 135122 github, level 7 with dict, advanced one pass, 38758 github, level 7 with dict dms, advanced one pass, 38758 @@ -419,26 +419,26 @@ github, small chain log, advanced github, explicit params, advanced one pass, 137727 github, uncompressed literals, advanced one pass, 165915 github, uncompressed literals optimal, advanced one pass, 157227 -github, huffman literals, advanced one pass, 142465 +github, huffman literals, advanced one pass, 142365 github, multithreaded with advanced params, advanced one pass, 165915 -github.tar, level -5, advanced one pass, 46856 -github.tar, level -5 with dict, advanced one pass, 44571 -github.tar, level -3, advanced one pass, 43754 -github.tar, level -3 with dict, advanced one pass, 41447 -github.tar, level -1, advanced one pass, 42490 -github.tar, level -1 with dict, advanced one pass, 41131 +github.tar, level -5, advanced one pass, 66914 +github.tar, level -5 with dict, advanced one pass, 51525 +github.tar, level -3, advanced one pass, 52127 +github.tar, level -3 with dict, advanced one pass, 44242 +github.tar, level -1, advanced one pass, 42560 +github.tar, level -1 with dict, advanced one pass, 41136 github.tar, level 0, advanced one pass, 38441 github.tar, level 0 with dict, advanced one pass, 37995 github.tar, level 0 with dict dms, advanced one pass, 38003 github.tar, level 0 with dict dds, advanced one pass, 38003 github.tar, level 0 with dict copy, advanced one pass, 37995 github.tar, level 0 with dict load, advanced one pass, 37956 -github.tar, level 1, advanced one pass, 39265 -github.tar, level 1 with dict, advanced one pass, 38280 -github.tar, level 1 with dict dms, advanced one pass, 38290 -github.tar, level 1 with dict dds, advanced one pass, 38290 -github.tar, level 1 with dict copy, advanced one pass, 38280 -github.tar, level 1 with dict load, advanced one pass, 38729 +github.tar, level 1, advanced one pass, 39200 +github.tar, level 1 with dict, advanced one pass, 38284 +github.tar, level 1 with dict dms, advanced one pass, 38294 +github.tar, level 1 with dict dds, advanced one pass, 38294 +github.tar, level 1 with dict copy, advanced one pass, 38284 +github.tar, level 1 with dict load, advanced one pass, 38724 github.tar, level 3, advanced one pass, 38441 github.tar, level 3 with dict, advanced one pass, 37995 github.tar, level 3 with dict dms, advanced one pass, 38003 @@ -451,88 +451,88 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass, 37954 github.tar, level 4 with dict copy, advanced one pass, 37948 github.tar, level 4 with dict load, advanced one pass, 37927 -github.tar, level 5 row 1, advanced one pass, 38534 -github.tar, level 5 row 1 with dict dms, advanced one pass, 39365 -github.tar, level 5 row 1 with dict dds, advanced one pass, 39233 -github.tar, level 5 row 1 with dict copy, advanced one pass, 39715 -github.tar, level 5 row 1 with dict load, advanced one pass, 38019 -github.tar, level 5 row 2, advanced one pass, 38394 -github.tar, level 5 row 2 with dict dms, advanced one pass, 39048 -github.tar, level 5 row 2 with dict dds, advanced one pass, 39044 -github.tar, level 5 row 2 with dict copy, advanced one pass, 39074 -github.tar, level 5 row 2 with dict load, advanced one pass, 37665 -github.tar, level 5, advanced one pass, 38394 -github.tar, level 5 with dict, advanced one pass, 39074 -github.tar, level 5 with dict dms, advanced one pass, 39048 -github.tar, level 5 with dict dds, advanced one pass, 39044 -github.tar, level 5 with dict copy, advanced one pass, 39074 -github.tar, level 5 with dict load, advanced one pass, 37665 -github.tar, level 6, advanced one pass, 38669 -github.tar, level 6 with dict, advanced one pass, 38660 -github.tar, level 6 with dict dms, advanced one pass, 38654 -github.tar, level 6 with dict dds, advanced one pass, 38656 -github.tar, level 6 with dict copy, advanced one pass, 38660 -github.tar, level 6 with dict load, advanced one pass, 37889 -github.tar, level 7 row 1, advanced one pass, 38077 -github.tar, level 7 row 1 with dict dms, advanced one pass, 38012 -github.tar, level 7 row 1 with dict dds, advanced one pass, 38014 -github.tar, level 7 row 1 with dict copy, advanced one pass, 38101 -github.tar, level 7 row 1 with dict load, advanced one pass, 37402 -github.tar, level 7 row 2, advanced one pass, 38153 -github.tar, level 7 row 2 with dict dms, advanced one pass, 37888 -github.tar, level 7 row 2 with dict dds, advanced one pass, 37910 -github.tar, level 7 row 2 with dict copy, advanced one pass, 37892 -github.tar, level 7 row 2 with dict load, advanced one pass, 37457 -github.tar, level 7, advanced one pass, 38153 -github.tar, level 7 with dict, advanced one pass, 37892 -github.tar, level 7 with dict dms, advanced one pass, 37888 -github.tar, level 7 with dict dds, advanced one pass, 37910 -github.tar, level 7 with dict copy, advanced one pass, 37892 -github.tar, level 7 with dict load, advanced one pass, 37457 -github.tar, level 9, advanced one pass, 36768 -github.tar, level 9 with dict, advanced one pass, 36510 -github.tar, level 9 with dict dms, advanced one pass, 36584 -github.tar, level 9 with dict dds, advanced one pass, 36646 -github.tar, level 9 with dict copy, advanced one pass, 36510 -github.tar, level 9 with dict load, advanced one pass, 36383 -github.tar, level 11 row 1, advanced one pass, 36435 +github.tar, level 5 row 1, advanced one pass, 38366 +github.tar, level 5 row 1 with dict dms, advanced one pass, 39059 +github.tar, level 5 row 1 with dict dds, advanced one pass, 39067 +github.tar, level 5 row 1 with dict copy, advanced one pass, 39082 +github.tar, level 5 row 1 with dict load, advanced one pass, 37656 +github.tar, level 5 row 2, advanced one pass, 38534 +github.tar, level 5 row 2 with dict dms, advanced one pass, 39365 +github.tar, level 5 row 2 with dict dds, advanced one pass, 39233 +github.tar, level 5 row 2 with dict copy, advanced one pass, 39715 +github.tar, level 5 row 2 with dict load, advanced one pass, 38019 +github.tar, level 5, advanced one pass, 38366 +github.tar, level 5 with dict, advanced one pass, 39082 +github.tar, level 5 with dict dms, advanced one pass, 39059 +github.tar, level 5 with dict dds, advanced one pass, 39067 +github.tar, level 5 with dict copy, advanced one pass, 39082 +github.tar, level 5 with dict load, advanced one pass, 37656 +github.tar, level 6, advanced one pass, 38648 +github.tar, level 6 with dict, advanced one pass, 38656 +github.tar, level 6 with dict dms, advanced one pass, 38636 +github.tar, level 6 with dict dds, advanced one pass, 38634 +github.tar, level 6 with dict copy, advanced one pass, 38656 +github.tar, level 6 with dict load, advanced one pass, 37865 +github.tar, level 7 row 1, advanced one pass, 38110 +github.tar, level 7 row 1 with dict dms, advanced one pass, 37858 +github.tar, level 7 row 1 with dict dds, advanced one pass, 37882 +github.tar, level 7 row 1 with dict copy, advanced one pass, 37865 +github.tar, level 7 row 1 with dict load, advanced one pass, 37436 +github.tar, level 7 row 2, advanced one pass, 38077 +github.tar, level 7 row 2 with dict dms, advanced one pass, 38012 +github.tar, level 7 row 2 with dict dds, advanced one pass, 38014 +github.tar, level 7 row 2 with dict copy, advanced one pass, 38101 +github.tar, level 7 row 2 with dict load, advanced one pass, 37402 +github.tar, level 7, advanced one pass, 38110 +github.tar, level 7 with dict, advanced one pass, 37865 +github.tar, level 7 with dict dms, advanced one pass, 37858 +github.tar, level 7 with dict dds, advanced one pass, 37882 +github.tar, level 7 with dict copy, advanced one pass, 37865 +github.tar, level 7 with dict load, advanced one pass, 37436 +github.tar, level 9, advanced one pass, 36760 +github.tar, level 9 with dict, advanced one pass, 36484 +github.tar, level 9 with dict dms, advanced one pass, 36567 +github.tar, level 9 with dict dds, advanced one pass, 36628 +github.tar, level 9 with dict copy, advanced one pass, 36484 +github.tar, level 9 with dict load, advanced one pass, 36401 +github.tar, level 11 row 1, advanced one pass, 36452 github.tar, level 11 row 1 with dict dms, advanced one pass, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass, 36419 -github.tar, level 11 row 2, advanced one pass, 36412 +github.tar, level 11 row 1 with dict load, advanced one pass, 36455 +github.tar, level 11 row 2, advanced one pass, 36435 github.tar, level 11 row 2 with dict dms, advanced one pass, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass, 36557 -github.tar, level 11 row 2 with dict load, advanced one pass, 36439 -github.tar, level 12 row 1, advanced one pass, 36110 +github.tar, level 11 row 2 with dict load, advanced one pass, 36419 +github.tar, level 12 row 1, advanced one pass, 36081 github.tar, level 12 row 1 with dict dms, advanced one pass, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass, 36459 -github.tar, level 12 row 2, advanced one pass, 36062 +github.tar, level 12 row 1 with dict load, advanced one pass, 36434 +github.tar, level 12 row 2, advanced one pass, 36110 github.tar, level 12 row 2 with dict dms, advanced one pass, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass, 36392 -github.tar, level 13, advanced one pass, 35621 -github.tar, level 13 with dict, advanced one pass, 38726 -github.tar, level 13 with dict dms, advanced one pass, 38903 -github.tar, level 13 with dict dds, advanced one pass, 38903 -github.tar, level 13 with dict copy, advanced one pass, 38726 -github.tar, level 13 with dict load, advanced one pass, 36372 -github.tar, level 16, advanced one pass, 40255 -github.tar, level 16 with dict, advanced one pass, 33639 -github.tar, level 16 with dict dms, advanced one pass, 33544 -github.tar, level 16 with dict dds, advanced one pass, 33544 -github.tar, level 16 with dict copy, advanced one pass, 33639 -github.tar, level 16 with dict load, advanced one pass, 39353 -github.tar, level 19, advanced one pass, 32837 -github.tar, level 19 with dict, advanced one pass, 32895 -github.tar, level 19 with dict dms, advanced one pass, 32672 -github.tar, level 19 with dict dds, advanced one pass, 32672 -github.tar, level 19 with dict copy, advanced one pass, 32895 -github.tar, level 19 with dict load, advanced one pass, 32676 +github.tar, level 12 row 2 with dict load, advanced one pass, 36459 +github.tar, level 13, advanced one pass, 35501 +github.tar, level 13 with dict, advanced one pass, 37130 +github.tar, level 13 with dict dms, advanced one pass, 37267 +github.tar, level 13 with dict dds, advanced one pass, 37267 +github.tar, level 13 with dict copy, advanced one pass, 37130 +github.tar, level 13 with dict load, advanced one pass, 36010 +github.tar, level 16, advanced one pass, 40471 +github.tar, level 16 with dict, advanced one pass, 33378 +github.tar, level 16 with dict dms, advanced one pass, 33213 +github.tar, level 16 with dict dds, advanced one pass, 33213 +github.tar, level 16 with dict copy, advanced one pass, 33378 +github.tar, level 16 with dict load, advanced one pass, 39081 +github.tar, level 19, advanced one pass, 32134 +github.tar, level 19 with dict, advanced one pass, 32709 +github.tar, level 19 with dict dms, advanced one pass, 32553 +github.tar, level 19 with dict dds, advanced one pass, 32553 +github.tar, level 19 with dict copy, advanced one pass, 32709 +github.tar, level 19 with dict load, advanced one pass, 32474 github.tar, no source size, advanced one pass, 38441 github.tar, no source size with dict, advanced one pass, 37995 github.tar, long distance mode, advanced one pass, 39757 @@ -541,84 +541,84 @@ github.tar, multithreaded long distance mode, advanced github.tar, small window log, advanced one pass, 198540 github.tar, small hash log, advanced one pass, 129870 github.tar, small chain log, advanced one pass, 41669 -github.tar, explicit params, advanced one pass, 41350 +github.tar, explicit params, advanced one pass, 41385 github.tar, uncompressed literals, advanced one pass, 41122 -github.tar, uncompressed literals optimal, advanced one pass, 35388 -github.tar, huffman literals, advanced one pass, 38777 +github.tar, uncompressed literals optimal, advanced one pass, 35397 +github.tar, huffman literals, advanced one pass, 38853 github.tar, multithreaded with advanced params, advanced one pass, 41122 -silesia, level -5, advanced one pass small out, 6737607 -silesia, level -3, advanced one pass small out, 6444677 -silesia, level -1, advanced one pass small out, 6178460 -silesia, level 0, advanced one pass small out, 4849551 -silesia, level 1, advanced one pass small out, 5313202 -silesia, level 3, advanced one pass small out, 4849551 -silesia, level 4, advanced one pass small out, 4786969 -silesia, level 5 row 1, advanced one pass small out, 4640753 -silesia, level 5 row 2, advanced one pass small out, 4639132 -silesia, level 5, advanced one pass small out, 4639132 -silesia, level 6, advanced one pass small out, 4605629 -silesia, level 7 row 1, advanced one pass small out, 4564870 -silesia, level 7 row 2, advanced one pass small out, 4567307 -silesia, level 7, advanced one pass small out, 4567307 -silesia, level 9, advanced one pass small out, 4543330 -silesia, level 11 row 1, advanced one pass small out, 4519288 -silesia, level 11 row 2, advanced one pass small out, 4521524 -silesia, level 12 row 1, advanced one pass small out, 4503117 -silesia, level 12 row 2, advanced one pass small out, 4505093 -silesia, level 13, advanced one pass small out, 4482131 -silesia, level 16, advanced one pass small out, 4360251 -silesia, level 19, advanced one pass small out, 4283236 -silesia, no source size, advanced one pass small out, 4849551 -silesia, long distance mode, advanced one pass small out, 4840738 -silesia, multithreaded, advanced one pass small out, 4849551 +silesia, level -5, advanced one pass small out, 7354675 +silesia, level -3, advanced one pass small out, 6902374 +silesia, level -1, advanced one pass small out, 6177565 +silesia, level 0, advanced one pass small out, 4849553 +silesia, level 1, advanced one pass small out, 5309098 +silesia, level 3, advanced one pass small out, 4849553 +silesia, level 4, advanced one pass small out, 4786968 +silesia, level 5 row 1, advanced one pass small out, 4638691 +silesia, level 5 row 2, advanced one pass small out, 4640752 +silesia, level 5, advanced one pass small out, 4638691 +silesia, level 6, advanced one pass small out, 4605296 +silesia, level 7 row 1, advanced one pass small out, 4566984 +silesia, level 7 row 2, advanced one pass small out, 4564868 +silesia, level 7, advanced one pass small out, 4566984 +silesia, level 9, advanced one pass small out, 4543018 +silesia, level 11 row 1, advanced one pass small out, 4521323 +silesia, level 11 row 2, advanced one pass small out, 4519288 +silesia, level 12 row 1, advanced one pass small out, 4505046 +silesia, level 12 row 2, advanced one pass small out, 4503116 +silesia, level 13, advanced one pass small out, 4493990 +silesia, level 16, advanced one pass small out, 4359864 +silesia, level 19, advanced one pass small out, 4296880 +silesia, no source size, advanced one pass small out, 4849553 +silesia, long distance mode, advanced one pass small out, 4840737 +silesia, multithreaded, advanced one pass small out, 4849553 silesia, multithreaded long distance mode, advanced one pass small out, 4840759 silesia, small window log, advanced one pass small out, 7095919 silesia, small hash log, advanced one pass small out, 6526141 -silesia, small chain log, advanced one pass small out, 4912199 -silesia, explicit params, advanced one pass small out, 4796282 +silesia, small chain log, advanced one pass small out, 4912197 +silesia, explicit params, advanced one pass small out, 4795432 silesia, uncompressed literals, advanced one pass small out, 5127982 -silesia, uncompressed literals optimal, advanced one pass small out, 4317896 -silesia, huffman literals, advanced one pass small out, 5326269 +silesia, uncompressed literals optimal, advanced one pass small out, 4319518 +silesia, huffman literals, advanced one pass small out, 5326346 silesia, multithreaded with advanced params, advanced one pass small out, 5127982 -silesia.tar, level -5, advanced one pass small out, 6738593 -silesia.tar, level -3, advanced one pass small out, 6446372 -silesia.tar, level -1, advanced one pass small out, 6186042 -silesia.tar, level 0, advanced one pass small out, 4861423 -silesia.tar, level 1, advanced one pass small out, 5334885 -silesia.tar, level 3, advanced one pass small out, 4861423 +silesia.tar, level -5, advanced one pass small out, 7359401 +silesia.tar, level -3, advanced one pass small out, 6901672 +silesia.tar, level -1, advanced one pass small out, 6182241 +silesia.tar, level 0, advanced one pass small out, 4861424 +silesia.tar, level 1, advanced one pass small out, 5331946 +silesia.tar, level 3, advanced one pass small out, 4861424 silesia.tar, level 4, advanced one pass small out, 4799632 -silesia.tar, level 5 row 1, advanced one pass small out, 4652862 -silesia.tar, level 5 row 2, advanced one pass small out, 4650387 -silesia.tar, level 5, advanced one pass small out, 4650387 -silesia.tar, level 6, advanced one pass small out, 4617089 -silesia.tar, level 7 row 1, advanced one pass small out, 4575392 -silesia.tar, level 7 row 2, advanced one pass small out, 4576951 -silesia.tar, level 7, advanced one pass small out, 4576951 -silesia.tar, level 9, advanced one pass small out, 4552638 -silesia.tar, level 11 row 1, advanced one pass small out, 4529458 -silesia.tar, level 11 row 2, advanced one pass small out, 4530416 -silesia.tar, level 12 row 1, advanced one pass small out, 4513603 -silesia.tar, level 12 row 2, advanced one pass small out, 4514499 -silesia.tar, level 13, advanced one pass small out, 4491768 -silesia.tar, level 16, advanced one pass small out, 4356834 -silesia.tar, level 19, advanced one pass small out, 4264388 -silesia.tar, no source size, advanced one pass small out, 4861423 -silesia.tar, long distance mode, advanced one pass small out, 4847753 -silesia.tar, multithreaded, advanced one pass small out, 4861507 +silesia.tar, level 5 row 1, advanced one pass small out, 4649987 +silesia.tar, level 5 row 2, advanced one pass small out, 4652862 +silesia.tar, level 5, advanced one pass small out, 4649987 +silesia.tar, level 6, advanced one pass small out, 4616797 +silesia.tar, level 7 row 1, advanced one pass small out, 4576661 +silesia.tar, level 7 row 2, advanced one pass small out, 4575393 +silesia.tar, level 7, advanced one pass small out, 4576661 +silesia.tar, level 9, advanced one pass small out, 4552381 +silesia.tar, level 11 row 1, advanced one pass small out, 4530241 +silesia.tar, level 11 row 2, advanced one pass small out, 4529461 +silesia.tar, level 12 row 1, advanced one pass small out, 4514432 +silesia.tar, level 12 row 2, advanced one pass small out, 4513604 +silesia.tar, level 13, advanced one pass small out, 4502956 +silesia.tar, level 16, advanced one pass small out, 4360527 +silesia.tar, level 19, advanced one pass small out, 4267266 +silesia.tar, no source size, advanced one pass small out, 4861424 +silesia.tar, long distance mode, advanced one pass small out, 4847752 +silesia.tar, multithreaded, advanced one pass small out, 4861508 silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853221 silesia.tar, small window log, advanced one pass small out, 7101530 -silesia.tar, small hash log, advanced one pass small out, 6529228 -silesia.tar, small chain log, advanced one pass small out, 4917039 -silesia.tar, explicit params, advanced one pass small out, 4807675 +silesia.tar, small hash log, advanced one pass small out, 6529231 +silesia.tar, small chain log, advanced one pass small out, 4917041 +silesia.tar, explicit params, advanced one pass small out, 4806855 silesia.tar, uncompressed literals, advanced one pass small out, 5129458 -silesia.tar, uncompressed literals optimal, advanced one pass small out, 4307400 -silesia.tar, huffman literals, advanced one pass small out, 5347335 +silesia.tar, uncompressed literals optimal, advanced one pass small out, 4310141 +silesia.tar, huffman literals, advanced one pass small out, 5344545 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 -github, level -5, advanced one pass small out, 205285 +github, level -5, advanced one pass small out, 232315 github, level -5 with dict, advanced one pass small out, 46718 -github, level -3, advanced one pass small out, 190643 +github, level -3, advanced one pass small out, 220760 github, level -3 with dict, advanced one pass small out, 45395 -github, level -1, advanced one pass small out, 175568 +github, level -1, advanced one pass small out, 175468 github, level -1 with dict, advanced one pass small out, 43170 github, level 0, advanced one pass small out, 136335 github, level 0 with dict, advanced one pass small out, 41148 @@ -626,7 +626,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced one pass small out, 41148 github, level 0 with dict copy, advanced one pass small out, 41124 github, level 0 with dict load, advanced one pass small out, 42252 -github, level 1, advanced one pass small out, 142465 +github, level 1, advanced one pass small out, 142365 github, level 1 with dict, advanced one pass small out, 41682 github, level 1 with dict dms, advanced one pass small out, 41682 github, level 1 with dict dds, advanced one pass small out, 41682 @@ -644,16 +644,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced one pass small out, 41251 github, level 4 with dict copy, advanced one pass small out, 41216 github, level 4 with dict load, advanced one pass small out, 41159 -github, level 5 row 1, advanced one pass small out, 135121 -github, level 5 row 1 with dict dms, advanced one pass small out, 38938 -github, level 5 row 1 with dict dds, advanced one pass small out, 38732 -github, level 5 row 1 with dict copy, advanced one pass small out, 38934 -github, level 5 row 1 with dict load, advanced one pass small out, 40725 -github, level 5 row 2, advanced one pass small out, 134584 -github, level 5 row 2 with dict dms, advanced one pass small out, 38758 -github, level 5 row 2 with dict dds, advanced one pass small out, 38728 -github, level 5 row 2 with dict copy, advanced one pass small out, 38759 -github, level 5 row 2 with dict load, advanced one pass small out, 41518 +github, level 5 row 1, advanced one pass small out, 134584 +github, level 5 row 1 with dict dms, advanced one pass small out, 38758 +github, level 5 row 1 with dict dds, advanced one pass small out, 38728 +github, level 5 row 1 with dict copy, advanced one pass small out, 38759 +github, level 5 row 1 with dict load, advanced one pass small out, 41518 +github, level 5 row 2, advanced one pass small out, 135121 +github, level 5 row 2 with dict dms, advanced one pass small out, 38938 +github, level 5 row 2 with dict dds, advanced one pass small out, 38732 +github, level 5 row 2 with dict copy, advanced one pass small out, 38934 +github, level 5 row 2 with dict load, advanced one pass small out, 40725 github, level 5, advanced one pass small out, 135121 github, level 5 with dict, advanced one pass small out, 38758 github, level 5 with dict dms, advanced one pass small out, 38758 @@ -666,16 +666,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced one pass small out, 38636 github, level 6 with dict copy, advanced one pass small out, 38669 github, level 6 with dict load, advanced one pass small out, 40695 -github, level 7 row 1, advanced one pass small out, 135122 -github, level 7 row 1 with dict dms, advanced one pass small out, 38860 -github, level 7 row 1 with dict dds, advanced one pass small out, 38766 -github, level 7 row 1 with dict copy, advanced one pass small out, 38834 -github, level 7 row 1 with dict load, advanced one pass small out, 40695 -github, level 7 row 2, advanced one pass small out, 134584 -github, level 7 row 2 with dict dms, advanced one pass small out, 38758 -github, level 7 row 2 with dict dds, advanced one pass small out, 38745 -github, level 7 row 2 with dict copy, advanced one pass small out, 38755 -github, level 7 row 2 with dict load, advanced one pass small out, 43154 +github, level 7 row 1, advanced one pass small out, 134584 +github, level 7 row 1 with dict dms, advanced one pass small out, 38758 +github, level 7 row 1 with dict dds, advanced one pass small out, 38745 +github, level 7 row 1 with dict copy, advanced one pass small out, 38755 +github, level 7 row 1 with dict load, advanced one pass small out, 43154 +github, level 7 row 2, advanced one pass small out, 135122 +github, level 7 row 2 with dict dms, advanced one pass small out, 38860 +github, level 7 row 2 with dict dds, advanced one pass small out, 38766 +github, level 7 row 2 with dict copy, advanced one pass small out, 38834 +github, level 7 row 2 with dict load, advanced one pass small out, 40695 github, level 7, advanced one pass small out, 135122 github, level 7 with dict, advanced one pass small out, 38758 github, level 7 with dict dms, advanced one pass small out, 38758 @@ -737,26 +737,26 @@ github, small chain log, advanced github, explicit params, advanced one pass small out, 137727 github, uncompressed literals, advanced one pass small out, 165915 github, uncompressed literals optimal, advanced one pass small out, 157227 -github, huffman literals, advanced one pass small out, 142465 +github, huffman literals, advanced one pass small out, 142365 github, multithreaded with advanced params, advanced one pass small out, 165915 -github.tar, level -5, advanced one pass small out, 46856 -github.tar, level -5 with dict, advanced one pass small out, 44571 -github.tar, level -3, advanced one pass small out, 43754 -github.tar, level -3 with dict, advanced one pass small out, 41447 -github.tar, level -1, advanced one pass small out, 42490 -github.tar, level -1 with dict, advanced one pass small out, 41131 +github.tar, level -5, advanced one pass small out, 66914 +github.tar, level -5 with dict, advanced one pass small out, 51525 +github.tar, level -3, advanced one pass small out, 52127 +github.tar, level -3 with dict, advanced one pass small out, 44242 +github.tar, level -1, advanced one pass small out, 42560 +github.tar, level -1 with dict, advanced one pass small out, 41136 github.tar, level 0, advanced one pass small out, 38441 github.tar, level 0 with dict, advanced one pass small out, 37995 github.tar, level 0 with dict dms, advanced one pass small out, 38003 github.tar, level 0 with dict dds, advanced one pass small out, 38003 github.tar, level 0 with dict copy, advanced one pass small out, 37995 github.tar, level 0 with dict load, advanced one pass small out, 37956 -github.tar, level 1, advanced one pass small out, 39265 -github.tar, level 1 with dict, advanced one pass small out, 38280 -github.tar, level 1 with dict dms, advanced one pass small out, 38290 -github.tar, level 1 with dict dds, advanced one pass small out, 38290 -github.tar, level 1 with dict copy, advanced one pass small out, 38280 -github.tar, level 1 with dict load, advanced one pass small out, 38729 +github.tar, level 1, advanced one pass small out, 39200 +github.tar, level 1 with dict, advanced one pass small out, 38284 +github.tar, level 1 with dict dms, advanced one pass small out, 38294 +github.tar, level 1 with dict dds, advanced one pass small out, 38294 +github.tar, level 1 with dict copy, advanced one pass small out, 38284 +github.tar, level 1 with dict load, advanced one pass small out, 38724 github.tar, level 3, advanced one pass small out, 38441 github.tar, level 3 with dict, advanced one pass small out, 37995 github.tar, level 3 with dict dms, advanced one pass small out, 38003 @@ -769,88 +769,88 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced one pass small out, 37954 github.tar, level 4 with dict copy, advanced one pass small out, 37948 github.tar, level 4 with dict load, advanced one pass small out, 37927 -github.tar, level 5 row 1, advanced one pass small out, 38534 -github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39365 -github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39233 -github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39715 -github.tar, level 5 row 1 with dict load, advanced one pass small out, 38019 -github.tar, level 5 row 2, advanced one pass small out, 38394 -github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39048 -github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39044 -github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39074 -github.tar, level 5 row 2 with dict load, advanced one pass small out, 37665 -github.tar, level 5, advanced one pass small out, 38394 -github.tar, level 5 with dict, advanced one pass small out, 39074 -github.tar, level 5 with dict dms, advanced one pass small out, 39048 -github.tar, level 5 with dict dds, advanced one pass small out, 39044 -github.tar, level 5 with dict copy, advanced one pass small out, 39074 -github.tar, level 5 with dict load, advanced one pass small out, 37665 -github.tar, level 6, advanced one pass small out, 38669 -github.tar, level 6 with dict, advanced one pass small out, 38660 -github.tar, level 6 with dict dms, advanced one pass small out, 38654 -github.tar, level 6 with dict dds, advanced one pass small out, 38656 -github.tar, level 6 with dict copy, advanced one pass small out, 38660 -github.tar, level 6 with dict load, advanced one pass small out, 37889 -github.tar, level 7 row 1, advanced one pass small out, 38077 -github.tar, level 7 row 1 with dict dms, advanced one pass small out, 38012 -github.tar, level 7 row 1 with dict dds, advanced one pass small out, 38014 -github.tar, level 7 row 1 with dict copy, advanced one pass small out, 38101 -github.tar, level 7 row 1 with dict load, advanced one pass small out, 37402 -github.tar, level 7 row 2, advanced one pass small out, 38153 -github.tar, level 7 row 2 with dict dms, advanced one pass small out, 37888 -github.tar, level 7 row 2 with dict dds, advanced one pass small out, 37910 -github.tar, level 7 row 2 with dict copy, advanced one pass small out, 37892 -github.tar, level 7 row 2 with dict load, advanced one pass small out, 37457 -github.tar, level 7, advanced one pass small out, 38153 -github.tar, level 7 with dict, advanced one pass small out, 37892 -github.tar, level 7 with dict dms, advanced one pass small out, 37888 -github.tar, level 7 with dict dds, advanced one pass small out, 37910 -github.tar, level 7 with dict copy, advanced one pass small out, 37892 -github.tar, level 7 with dict load, advanced one pass small out, 37457 -github.tar, level 9, advanced one pass small out, 36768 -github.tar, level 9 with dict, advanced one pass small out, 36510 -github.tar, level 9 with dict dms, advanced one pass small out, 36584 -github.tar, level 9 with dict dds, advanced one pass small out, 36646 -github.tar, level 9 with dict copy, advanced one pass small out, 36510 -github.tar, level 9 with dict load, advanced one pass small out, 36383 -github.tar, level 11 row 1, advanced one pass small out, 36435 +github.tar, level 5 row 1, advanced one pass small out, 38366 +github.tar, level 5 row 1 with dict dms, advanced one pass small out, 39059 +github.tar, level 5 row 1 with dict dds, advanced one pass small out, 39067 +github.tar, level 5 row 1 with dict copy, advanced one pass small out, 39082 +github.tar, level 5 row 1 with dict load, advanced one pass small out, 37656 +github.tar, level 5 row 2, advanced one pass small out, 38534 +github.tar, level 5 row 2 with dict dms, advanced one pass small out, 39365 +github.tar, level 5 row 2 with dict dds, advanced one pass small out, 39233 +github.tar, level 5 row 2 with dict copy, advanced one pass small out, 39715 +github.tar, level 5 row 2 with dict load, advanced one pass small out, 38019 +github.tar, level 5, advanced one pass small out, 38366 +github.tar, level 5 with dict, advanced one pass small out, 39082 +github.tar, level 5 with dict dms, advanced one pass small out, 39059 +github.tar, level 5 with dict dds, advanced one pass small out, 39067 +github.tar, level 5 with dict copy, advanced one pass small out, 39082 +github.tar, level 5 with dict load, advanced one pass small out, 37656 +github.tar, level 6, advanced one pass small out, 38648 +github.tar, level 6 with dict, advanced one pass small out, 38656 +github.tar, level 6 with dict dms, advanced one pass small out, 38636 +github.tar, level 6 with dict dds, advanced one pass small out, 38634 +github.tar, level 6 with dict copy, advanced one pass small out, 38656 +github.tar, level 6 with dict load, advanced one pass small out, 37865 +github.tar, level 7 row 1, advanced one pass small out, 38110 +github.tar, level 7 row 1 with dict dms, advanced one pass small out, 37858 +github.tar, level 7 row 1 with dict dds, advanced one pass small out, 37882 +github.tar, level 7 row 1 with dict copy, advanced one pass small out, 37865 +github.tar, level 7 row 1 with dict load, advanced one pass small out, 37436 +github.tar, level 7 row 2, advanced one pass small out, 38077 +github.tar, level 7 row 2 with dict dms, advanced one pass small out, 38012 +github.tar, level 7 row 2 with dict dds, advanced one pass small out, 38014 +github.tar, level 7 row 2 with dict copy, advanced one pass small out, 38101 +github.tar, level 7 row 2 with dict load, advanced one pass small out, 37402 +github.tar, level 7, advanced one pass small out, 38110 +github.tar, level 7 with dict, advanced one pass small out, 37865 +github.tar, level 7 with dict dms, advanced one pass small out, 37858 +github.tar, level 7 with dict dds, advanced one pass small out, 37882 +github.tar, level 7 with dict copy, advanced one pass small out, 37865 +github.tar, level 7 with dict load, advanced one pass small out, 37436 +github.tar, level 9, advanced one pass small out, 36760 +github.tar, level 9 with dict, advanced one pass small out, 36484 +github.tar, level 9 with dict dms, advanced one pass small out, 36567 +github.tar, level 9 with dict dds, advanced one pass small out, 36628 +github.tar, level 9 with dict copy, advanced one pass small out, 36484 +github.tar, level 9 with dict load, advanced one pass small out, 36401 +github.tar, level 11 row 1, advanced one pass small out, 36452 github.tar, level 11 row 1 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 1 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 1 with dict load, advanced one pass small out, 36419 -github.tar, level 11 row 2, advanced one pass small out, 36412 +github.tar, level 11 row 1 with dict load, advanced one pass small out, 36455 +github.tar, level 11 row 2, advanced one pass small out, 36435 github.tar, level 11 row 2 with dict dms, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict dds, advanced one pass small out, 36963 github.tar, level 11 row 2 with dict copy, advanced one pass small out, 36557 -github.tar, level 11 row 2 with dict load, advanced one pass small out, 36439 -github.tar, level 12 row 1, advanced one pass small out, 36110 +github.tar, level 11 row 2 with dict load, advanced one pass small out, 36419 +github.tar, level 12 row 1, advanced one pass small out, 36081 github.tar, level 12 row 1 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 1 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 1 with dict load, advanced one pass small out, 36459 -github.tar, level 12 row 2, advanced one pass small out, 36062 +github.tar, level 12 row 1 with dict load, advanced one pass small out, 36434 +github.tar, level 12 row 2, advanced one pass small out, 36110 github.tar, level 12 row 2 with dict dms, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict dds, advanced one pass small out, 36986 github.tar, level 12 row 2 with dict copy, advanced one pass small out, 36609 -github.tar, level 12 row 2 with dict load, advanced one pass small out, 36392 -github.tar, level 13, advanced one pass small out, 35621 -github.tar, level 13 with dict, advanced one pass small out, 38726 -github.tar, level 13 with dict dms, advanced one pass small out, 38903 -github.tar, level 13 with dict dds, advanced one pass small out, 38903 -github.tar, level 13 with dict copy, advanced one pass small out, 38726 -github.tar, level 13 with dict load, advanced one pass small out, 36372 -github.tar, level 16, advanced one pass small out, 40255 -github.tar, level 16 with dict, advanced one pass small out, 33639 -github.tar, level 16 with dict dms, advanced one pass small out, 33544 -github.tar, level 16 with dict dds, advanced one pass small out, 33544 -github.tar, level 16 with dict copy, advanced one pass small out, 33639 -github.tar, level 16 with dict load, advanced one pass small out, 39353 -github.tar, level 19, advanced one pass small out, 32837 -github.tar, level 19 with dict, advanced one pass small out, 32895 -github.tar, level 19 with dict dms, advanced one pass small out, 32672 -github.tar, level 19 with dict dds, advanced one pass small out, 32672 -github.tar, level 19 with dict copy, advanced one pass small out, 32895 -github.tar, level 19 with dict load, advanced one pass small out, 32676 +github.tar, level 12 row 2 with dict load, advanced one pass small out, 36459 +github.tar, level 13, advanced one pass small out, 35501 +github.tar, level 13 with dict, advanced one pass small out, 37130 +github.tar, level 13 with dict dms, advanced one pass small out, 37267 +github.tar, level 13 with dict dds, advanced one pass small out, 37267 +github.tar, level 13 with dict copy, advanced one pass small out, 37130 +github.tar, level 13 with dict load, advanced one pass small out, 36010 +github.tar, level 16, advanced one pass small out, 40471 +github.tar, level 16 with dict, advanced one pass small out, 33378 +github.tar, level 16 with dict dms, advanced one pass small out, 33213 +github.tar, level 16 with dict dds, advanced one pass small out, 33213 +github.tar, level 16 with dict copy, advanced one pass small out, 33378 +github.tar, level 16 with dict load, advanced one pass small out, 39081 +github.tar, level 19, advanced one pass small out, 32134 +github.tar, level 19 with dict, advanced one pass small out, 32709 +github.tar, level 19 with dict dms, advanced one pass small out, 32553 +github.tar, level 19 with dict dds, advanced one pass small out, 32553 +github.tar, level 19 with dict copy, advanced one pass small out, 32709 +github.tar, level 19 with dict load, advanced one pass small out, 32474 github.tar, no source size, advanced one pass small out, 38441 github.tar, no source size with dict, advanced one pass small out, 37995 github.tar, long distance mode, advanced one pass small out, 39757 @@ -859,84 +859,84 @@ github.tar, multithreaded long distance mode, advanced github.tar, small window log, advanced one pass small out, 198540 github.tar, small hash log, advanced one pass small out, 129870 github.tar, small chain log, advanced one pass small out, 41669 -github.tar, explicit params, advanced one pass small out, 41350 +github.tar, explicit params, advanced one pass small out, 41385 github.tar, uncompressed literals, advanced one pass small out, 41122 -github.tar, uncompressed literals optimal, advanced one pass small out, 35388 -github.tar, huffman literals, advanced one pass small out, 38777 +github.tar, uncompressed literals optimal, advanced one pass small out, 35397 +github.tar, huffman literals, advanced one pass small out, 38853 github.tar, multithreaded with advanced params, advanced one pass small out, 41122 -silesia, level -5, advanced streaming, 6882505 -silesia, level -3, advanced streaming, 6568376 -silesia, level -1, advanced streaming, 6183403 -silesia, level 0, advanced streaming, 4849551 -silesia, level 1, advanced streaming, 5314161 -silesia, level 3, advanced streaming, 4849551 -silesia, level 4, advanced streaming, 4786969 -silesia, level 5 row 1, advanced streaming, 4640753 -silesia, level 5 row 2, advanced streaming, 4639132 -silesia, level 5, advanced streaming, 4639132 -silesia, level 6, advanced streaming, 4605629 -silesia, level 7 row 1, advanced streaming, 4564870 -silesia, level 7 row 2, advanced streaming, 4567307 -silesia, level 7, advanced streaming, 4567307 -silesia, level 9, advanced streaming, 4543330 -silesia, level 11 row 1, advanced streaming, 4519288 -silesia, level 11 row 2, advanced streaming, 4521524 -silesia, level 12 row 1, advanced streaming, 4503117 -silesia, level 12 row 2, advanced streaming, 4505093 -silesia, level 13, advanced streaming, 4482131 -silesia, level 16, advanced streaming, 4360251 -silesia, level 19, advanced streaming, 4283236 -silesia, no source size, advanced streaming, 4849515 -silesia, long distance mode, advanced streaming, 4840738 -silesia, multithreaded, advanced streaming, 4849551 +silesia, level -5, advanced streaming, 7292053 +silesia, level -3, advanced streaming, 6867875 +silesia, level -1, advanced streaming, 6183923 +silesia, level 0, advanced streaming, 4849553 +silesia, level 1, advanced streaming, 5312694 +silesia, level 3, advanced streaming, 4849553 +silesia, level 4, advanced streaming, 4786968 +silesia, level 5 row 1, advanced streaming, 4638691 +silesia, level 5 row 2, advanced streaming, 4640752 +silesia, level 5, advanced streaming, 4638691 +silesia, level 6, advanced streaming, 4605296 +silesia, level 7 row 1, advanced streaming, 4566984 +silesia, level 7 row 2, advanced streaming, 4564868 +silesia, level 7, advanced streaming, 4566984 +silesia, level 9, advanced streaming, 4543018 +silesia, level 11 row 1, advanced streaming, 4521323 +silesia, level 11 row 2, advanced streaming, 4519288 +silesia, level 12 row 1, advanced streaming, 4505046 +silesia, level 12 row 2, advanced streaming, 4503116 +silesia, level 13, advanced streaming, 4493990 +silesia, level 16, advanced streaming, 4359864 +silesia, level 19, advanced streaming, 4296880 +silesia, no source size, advanced streaming, 4849517 +silesia, long distance mode, advanced streaming, 4840737 +silesia, multithreaded, advanced streaming, 4849553 silesia, multithreaded long distance mode, advanced streaming, 4840759 silesia, small window log, advanced streaming, 7112062 silesia, small hash log, advanced streaming, 6526141 -silesia, small chain log, advanced streaming, 4912199 -silesia, explicit params, advanced streaming, 4796309 +silesia, small chain log, advanced streaming, 4912197 +silesia, explicit params, advanced streaming, 4795452 silesia, uncompressed literals, advanced streaming, 5127982 -silesia, uncompressed literals optimal, advanced streaming, 4317896 -silesia, huffman literals, advanced streaming, 5331171 +silesia, uncompressed literals optimal, advanced streaming, 4319518 +silesia, huffman literals, advanced streaming, 5332234 silesia, multithreaded with advanced params, advanced streaming, 5127982 -silesia.tar, level -5, advanced streaming, 6982759 -silesia.tar, level -3, advanced streaming, 6641283 -silesia.tar, level -1, advanced streaming, 6190795 -silesia.tar, level 0, advanced streaming, 4861425 -silesia.tar, level 1, advanced streaming, 5336941 -silesia.tar, level 3, advanced streaming, 4861425 +silesia.tar, level -5, advanced streaming, 7260007 +silesia.tar, level -3, advanced streaming, 6845151 +silesia.tar, level -1, advanced streaming, 6187938 +silesia.tar, level 0, advanced streaming, 4861426 +silesia.tar, level 1, advanced streaming, 5334890 +silesia.tar, level 3, advanced streaming, 4861426 silesia.tar, level 4, advanced streaming, 4799632 -silesia.tar, level 5 row 1, advanced streaming, 4652866 -silesia.tar, level 5 row 2, advanced streaming, 4650392 -silesia.tar, level 5, advanced streaming, 4650392 -silesia.tar, level 6, advanced streaming, 4617097 -silesia.tar, level 7 row 1, advanced streaming, 4575393 -silesia.tar, level 7 row 2, advanced streaming, 4576953 -silesia.tar, level 7, advanced streaming, 4576953 -silesia.tar, level 9, advanced streaming, 4552646 -silesia.tar, level 11 row 1, advanced streaming, 4529458 -silesia.tar, level 11 row 2, advanced streaming, 4530417 -silesia.tar, level 12 row 1, advanced streaming, 4513603 -silesia.tar, level 12 row 2, advanced streaming, 4514500 -silesia.tar, level 13, advanced streaming, 4491769 -silesia.tar, level 16, advanced streaming, 4356834 -silesia.tar, level 19, advanced streaming, 4264388 -silesia.tar, no source size, advanced streaming, 4861421 -silesia.tar, long distance mode, advanced streaming, 4847753 -silesia.tar, multithreaded, advanced streaming, 4861507 +silesia.tar, level 5 row 1, advanced streaming, 4649992 +silesia.tar, level 5 row 2, advanced streaming, 4652866 +silesia.tar, level 5, advanced streaming, 4649992 +silesia.tar, level 6, advanced streaming, 4616803 +silesia.tar, level 7 row 1, advanced streaming, 4576664 +silesia.tar, level 7 row 2, advanced streaming, 4575394 +silesia.tar, level 7, advanced streaming, 4576664 +silesia.tar, level 9, advanced streaming, 4552386 +silesia.tar, level 11 row 1, advanced streaming, 4530243 +silesia.tar, level 11 row 2, advanced streaming, 4529461 +silesia.tar, level 12 row 1, advanced streaming, 4514433 +silesia.tar, level 12 row 2, advanced streaming, 4513604 +silesia.tar, level 13, advanced streaming, 4502956 +silesia.tar, level 16, advanced streaming, 4360527 +silesia.tar, level 19, advanced streaming, 4267266 +silesia.tar, no source size, advanced streaming, 4861422 +silesia.tar, long distance mode, advanced streaming, 4847752 +silesia.tar, multithreaded, advanced streaming, 4861508 silesia.tar, multithreaded long distance mode, advanced streaming, 4853221 silesia.tar, small window log, advanced streaming, 7118769 -silesia.tar, small hash log, advanced streaming, 6529231 -silesia.tar, small chain log, advanced streaming, 4917019 -silesia.tar, explicit params, advanced streaming, 4807688 +silesia.tar, small hash log, advanced streaming, 6529234 +silesia.tar, small chain log, advanced streaming, 4917021 +silesia.tar, explicit params, advanced streaming, 4806873 silesia.tar, uncompressed literals, advanced streaming, 5129461 -silesia.tar, uncompressed literals optimal, advanced streaming, 4307400 -silesia.tar, huffman literals, advanced streaming, 5352360 +silesia.tar, uncompressed literals optimal, advanced streaming, 4310141 +silesia.tar, huffman literals, advanced streaming, 5350519 silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 -github, level -5, advanced streaming, 205285 +github, level -5, advanced streaming, 232315 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 190643 +github, level -3, advanced streaming, 220760 github, level -3 with dict, advanced streaming, 45395 -github, level -1, advanced streaming, 175568 +github, level -1, advanced streaming, 175468 github, level -1 with dict, advanced streaming, 43170 github, level 0, advanced streaming, 136335 github, level 0 with dict, advanced streaming, 41148 @@ -944,7 +944,7 @@ github, level 0 with dict dms, advanced github, level 0 with dict dds, advanced streaming, 41148 github, level 0 with dict copy, advanced streaming, 41124 github, level 0 with dict load, advanced streaming, 42252 -github, level 1, advanced streaming, 142465 +github, level 1, advanced streaming, 142365 github, level 1 with dict, advanced streaming, 41682 github, level 1 with dict dms, advanced streaming, 41682 github, level 1 with dict dds, advanced streaming, 41682 @@ -962,16 +962,16 @@ github, level 4 with dict dms, advanced github, level 4 with dict dds, advanced streaming, 41251 github, level 4 with dict copy, advanced streaming, 41216 github, level 4 with dict load, advanced streaming, 41159 -github, level 5 row 1, advanced streaming, 135121 -github, level 5 row 1 with dict dms, advanced streaming, 38938 -github, level 5 row 1 with dict dds, advanced streaming, 38732 -github, level 5 row 1 with dict copy, advanced streaming, 38934 -github, level 5 row 1 with dict load, advanced streaming, 40725 -github, level 5 row 2, advanced streaming, 134584 -github, level 5 row 2 with dict dms, advanced streaming, 38758 -github, level 5 row 2 with dict dds, advanced streaming, 38728 -github, level 5 row 2 with dict copy, advanced streaming, 38759 -github, level 5 row 2 with dict load, advanced streaming, 41518 +github, level 5 row 1, advanced streaming, 134584 +github, level 5 row 1 with dict dms, advanced streaming, 38758 +github, level 5 row 1 with dict dds, advanced streaming, 38728 +github, level 5 row 1 with dict copy, advanced streaming, 38759 +github, level 5 row 1 with dict load, advanced streaming, 41518 +github, level 5 row 2, advanced streaming, 135121 +github, level 5 row 2 with dict dms, advanced streaming, 38938 +github, level 5 row 2 with dict dds, advanced streaming, 38732 +github, level 5 row 2 with dict copy, advanced streaming, 38934 +github, level 5 row 2 with dict load, advanced streaming, 40725 github, level 5, advanced streaming, 135121 github, level 5 with dict, advanced streaming, 38758 github, level 5 with dict dms, advanced streaming, 38758 @@ -984,16 +984,16 @@ github, level 6 with dict dms, advanced github, level 6 with dict dds, advanced streaming, 38636 github, level 6 with dict copy, advanced streaming, 38669 github, level 6 with dict load, advanced streaming, 40695 -github, level 7 row 1, advanced streaming, 135122 -github, level 7 row 1 with dict dms, advanced streaming, 38860 -github, level 7 row 1 with dict dds, advanced streaming, 38766 -github, level 7 row 1 with dict copy, advanced streaming, 38834 -github, level 7 row 1 with dict load, advanced streaming, 40695 -github, level 7 row 2, advanced streaming, 134584 -github, level 7 row 2 with dict dms, advanced streaming, 38758 -github, level 7 row 2 with dict dds, advanced streaming, 38745 -github, level 7 row 2 with dict copy, advanced streaming, 38755 -github, level 7 row 2 with dict load, advanced streaming, 43154 +github, level 7 row 1, advanced streaming, 134584 +github, level 7 row 1 with dict dms, advanced streaming, 38758 +github, level 7 row 1 with dict dds, advanced streaming, 38745 +github, level 7 row 1 with dict copy, advanced streaming, 38755 +github, level 7 row 1 with dict load, advanced streaming, 43154 +github, level 7 row 2, advanced streaming, 135122 +github, level 7 row 2 with dict dms, advanced streaming, 38860 +github, level 7 row 2 with dict dds, advanced streaming, 38766 +github, level 7 row 2 with dict copy, advanced streaming, 38834 +github, level 7 row 2 with dict load, advanced streaming, 40695 github, level 7, advanced streaming, 135122 github, level 7 with dict, advanced streaming, 38758 github, level 7 with dict dms, advanced streaming, 38758 @@ -1055,26 +1055,26 @@ github, small chain log, advanced github, explicit params, advanced streaming, 137727 github, uncompressed literals, advanced streaming, 165915 github, uncompressed literals optimal, advanced streaming, 157227 -github, huffman literals, advanced streaming, 142465 +github, huffman literals, advanced streaming, 142365 github, multithreaded with advanced params, advanced streaming, 165915 -github.tar, level -5, advanced streaming, 46747 -github.tar, level -5 with dict, advanced streaming, 44440 -github.tar, level -3, advanced streaming, 43537 -github.tar, level -3 with dict, advanced streaming, 41112 -github.tar, level -1, advanced streaming, 42465 -github.tar, level -1 with dict, advanced streaming, 41196 +github.tar, level -5, advanced streaming, 64132 +github.tar, level -5 with dict, advanced streaming, 48642 +github.tar, level -3, advanced streaming, 50964 +github.tar, level -3 with dict, advanced streaming, 42750 +github.tar, level -1, advanced streaming, 42536 +github.tar, level -1 with dict, advanced streaming, 41198 github.tar, level 0, advanced streaming, 38441 github.tar, level 0 with dict, advanced streaming, 37995 github.tar, level 0 with dict dms, advanced streaming, 38003 github.tar, level 0 with dict dds, advanced streaming, 38003 github.tar, level 0 with dict copy, advanced streaming, 37995 github.tar, level 0 with dict load, advanced streaming, 37956 -github.tar, level 1, advanced streaming, 39342 -github.tar, level 1 with dict, advanced streaming, 38293 -github.tar, level 1 with dict dms, advanced streaming, 38303 -github.tar, level 1 with dict dds, advanced streaming, 38303 -github.tar, level 1 with dict copy, advanced streaming, 38293 -github.tar, level 1 with dict load, advanced streaming, 38766 +github.tar, level 1, advanced streaming, 39270 +github.tar, level 1 with dict, advanced streaming, 38316 +github.tar, level 1 with dict dms, advanced streaming, 38326 +github.tar, level 1 with dict dds, advanced streaming, 38326 +github.tar, level 1 with dict copy, advanced streaming, 38316 +github.tar, level 1 with dict load, advanced streaming, 38761 github.tar, level 3, advanced streaming, 38441 github.tar, level 3 with dict, advanced streaming, 37995 github.tar, level 3 with dict dms, advanced streaming, 38003 @@ -1087,88 +1087,88 @@ github.tar, level 4 with dict dms, advanced github.tar, level 4 with dict dds, advanced streaming, 37954 github.tar, level 4 with dict copy, advanced streaming, 37948 github.tar, level 4 with dict load, advanced streaming, 37927 -github.tar, level 5 row 1, advanced streaming, 38534 -github.tar, level 5 row 1 with dict dms, advanced streaming, 39365 -github.tar, level 5 row 1 with dict dds, advanced streaming, 39233 -github.tar, level 5 row 1 with dict copy, advanced streaming, 39715 -github.tar, level 5 row 1 with dict load, advanced streaming, 38019 -github.tar, level 5 row 2, advanced streaming, 38394 -github.tar, level 5 row 2 with dict dms, advanced streaming, 39048 -github.tar, level 5 row 2 with dict dds, advanced streaming, 39044 -github.tar, level 5 row 2 with dict copy, advanced streaming, 39074 -github.tar, level 5 row 2 with dict load, advanced streaming, 37665 -github.tar, level 5, advanced streaming, 38394 -github.tar, level 5 with dict, advanced streaming, 39074 -github.tar, level 5 with dict dms, advanced streaming, 39048 -github.tar, level 5 with dict dds, advanced streaming, 39044 -github.tar, level 5 with dict copy, advanced streaming, 39074 -github.tar, level 5 with dict load, advanced streaming, 37665 -github.tar, level 6, advanced streaming, 38669 -github.tar, level 6 with dict, advanced streaming, 38660 -github.tar, level 6 with dict dms, advanced streaming, 38654 -github.tar, level 6 with dict dds, advanced streaming, 38656 -github.tar, level 6 with dict copy, advanced streaming, 38660 -github.tar, level 6 with dict load, advanced streaming, 37889 -github.tar, level 7 row 1, advanced streaming, 38077 -github.tar, level 7 row 1 with dict dms, advanced streaming, 38012 -github.tar, level 7 row 1 with dict dds, advanced streaming, 38014 -github.tar, level 7 row 1 with dict copy, advanced streaming, 38101 -github.tar, level 7 row 1 with dict load, advanced streaming, 37402 -github.tar, level 7 row 2, advanced streaming, 38153 -github.tar, level 7 row 2 with dict dms, advanced streaming, 37888 -github.tar, level 7 row 2 with dict dds, advanced streaming, 37910 -github.tar, level 7 row 2 with dict copy, advanced streaming, 37892 -github.tar, level 7 row 2 with dict load, advanced streaming, 37457 -github.tar, level 7, advanced streaming, 38153 -github.tar, level 7 with dict, advanced streaming, 37892 -github.tar, level 7 with dict dms, advanced streaming, 37888 -github.tar, level 7 with dict dds, advanced streaming, 37910 -github.tar, level 7 with dict copy, advanced streaming, 37892 -github.tar, level 7 with dict load, advanced streaming, 37457 -github.tar, level 9, advanced streaming, 36768 -github.tar, level 9 with dict, advanced streaming, 36510 -github.tar, level 9 with dict dms, advanced streaming, 36584 -github.tar, level 9 with dict dds, advanced streaming, 36646 -github.tar, level 9 with dict copy, advanced streaming, 36510 -github.tar, level 9 with dict load, advanced streaming, 36383 -github.tar, level 11 row 1, advanced streaming, 36435 +github.tar, level 5 row 1, advanced streaming, 38366 +github.tar, level 5 row 1 with dict dms, advanced streaming, 39059 +github.tar, level 5 row 1 with dict dds, advanced streaming, 39067 +github.tar, level 5 row 1 with dict copy, advanced streaming, 39082 +github.tar, level 5 row 1 with dict load, advanced streaming, 37656 +github.tar, level 5 row 2, advanced streaming, 38534 +github.tar, level 5 row 2 with dict dms, advanced streaming, 39365 +github.tar, level 5 row 2 with dict dds, advanced streaming, 39233 +github.tar, level 5 row 2 with dict copy, advanced streaming, 39715 +github.tar, level 5 row 2 with dict load, advanced streaming, 38019 +github.tar, level 5, advanced streaming, 38366 +github.tar, level 5 with dict, advanced streaming, 39082 +github.tar, level 5 with dict dms, advanced streaming, 39059 +github.tar, level 5 with dict dds, advanced streaming, 39067 +github.tar, level 5 with dict copy, advanced streaming, 39082 +github.tar, level 5 with dict load, advanced streaming, 37656 +github.tar, level 6, advanced streaming, 38648 +github.tar, level 6 with dict, advanced streaming, 38656 +github.tar, level 6 with dict dms, advanced streaming, 38636 +github.tar, level 6 with dict dds, advanced streaming, 38634 +github.tar, level 6 with dict copy, advanced streaming, 38656 +github.tar, level 6 with dict load, advanced streaming, 37865 +github.tar, level 7 row 1, advanced streaming, 38110 +github.tar, level 7 row 1 with dict dms, advanced streaming, 37858 +github.tar, level 7 row 1 with dict dds, advanced streaming, 37882 +github.tar, level 7 row 1 with dict copy, advanced streaming, 37865 +github.tar, level 7 row 1 with dict load, advanced streaming, 37436 +github.tar, level 7 row 2, advanced streaming, 38077 +github.tar, level 7 row 2 with dict dms, advanced streaming, 38012 +github.tar, level 7 row 2 with dict dds, advanced streaming, 38014 +github.tar, level 7 row 2 with dict copy, advanced streaming, 38101 +github.tar, level 7 row 2 with dict load, advanced streaming, 37402 +github.tar, level 7, advanced streaming, 38110 +github.tar, level 7 with dict, advanced streaming, 37865 +github.tar, level 7 with dict dms, advanced streaming, 37858 +github.tar, level 7 with dict dds, advanced streaming, 37882 +github.tar, level 7 with dict copy, advanced streaming, 37865 +github.tar, level 7 with dict load, advanced streaming, 37436 +github.tar, level 9, advanced streaming, 36760 +github.tar, level 9 with dict, advanced streaming, 36484 +github.tar, level 9 with dict dms, advanced streaming, 36567 +github.tar, level 9 with dict dds, advanced streaming, 36628 +github.tar, level 9 with dict copy, advanced streaming, 36484 +github.tar, level 9 with dict load, advanced streaming, 36401 +github.tar, level 11 row 1, advanced streaming, 36452 github.tar, level 11 row 1 with dict dms, advanced streaming, 36963 github.tar, level 11 row 1 with dict dds, advanced streaming, 36963 github.tar, level 11 row 1 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 1 with dict load, advanced streaming, 36419 -github.tar, level 11 row 2, advanced streaming, 36412 +github.tar, level 11 row 1 with dict load, advanced streaming, 36455 +github.tar, level 11 row 2, advanced streaming, 36435 github.tar, level 11 row 2 with dict dms, advanced streaming, 36963 github.tar, level 11 row 2 with dict dds, advanced streaming, 36963 github.tar, level 11 row 2 with dict copy, advanced streaming, 36557 -github.tar, level 11 row 2 with dict load, advanced streaming, 36439 -github.tar, level 12 row 1, advanced streaming, 36110 +github.tar, level 11 row 2 with dict load, advanced streaming, 36419 +github.tar, level 12 row 1, advanced streaming, 36081 github.tar, level 12 row 1 with dict dms, advanced streaming, 36986 github.tar, level 12 row 1 with dict dds, advanced streaming, 36986 github.tar, level 12 row 1 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 1 with dict load, advanced streaming, 36459 -github.tar, level 12 row 2, advanced streaming, 36062 +github.tar, level 12 row 1 with dict load, advanced streaming, 36434 +github.tar, level 12 row 2, advanced streaming, 36110 github.tar, level 12 row 2 with dict dms, advanced streaming, 36986 github.tar, level 12 row 2 with dict dds, advanced streaming, 36986 github.tar, level 12 row 2 with dict copy, advanced streaming, 36609 -github.tar, level 12 row 2 with dict load, advanced streaming, 36392 -github.tar, level 13, advanced streaming, 35621 -github.tar, level 13 with dict, advanced streaming, 38726 -github.tar, level 13 with dict dms, advanced streaming, 38903 -github.tar, level 13 with dict dds, advanced streaming, 38903 -github.tar, level 13 with dict copy, advanced streaming, 38726 -github.tar, level 13 with dict load, advanced streaming, 36372 -github.tar, level 16, advanced streaming, 40255 -github.tar, level 16 with dict, advanced streaming, 33639 -github.tar, level 16 with dict dms, advanced streaming, 33544 -github.tar, level 16 with dict dds, advanced streaming, 33544 -github.tar, level 16 with dict copy, advanced streaming, 33639 -github.tar, level 16 with dict load, advanced streaming, 39353 -github.tar, level 19, advanced streaming, 32837 -github.tar, level 19 with dict, advanced streaming, 32895 -github.tar, level 19 with dict dms, advanced streaming, 32672 -github.tar, level 19 with dict dds, advanced streaming, 32672 -github.tar, level 19 with dict copy, advanced streaming, 32895 -github.tar, level 19 with dict load, advanced streaming, 32676 +github.tar, level 12 row 2 with dict load, advanced streaming, 36459 +github.tar, level 13, advanced streaming, 35501 +github.tar, level 13 with dict, advanced streaming, 37130 +github.tar, level 13 with dict dms, advanced streaming, 37267 +github.tar, level 13 with dict dds, advanced streaming, 37267 +github.tar, level 13 with dict copy, advanced streaming, 37130 +github.tar, level 13 with dict load, advanced streaming, 36010 +github.tar, level 16, advanced streaming, 40471 +github.tar, level 16 with dict, advanced streaming, 33378 +github.tar, level 16 with dict dms, advanced streaming, 33213 +github.tar, level 16 with dict dds, advanced streaming, 33213 +github.tar, level 16 with dict copy, advanced streaming, 33378 +github.tar, level 16 with dict load, advanced streaming, 39081 +github.tar, level 19, advanced streaming, 32134 +github.tar, level 19 with dict, advanced streaming, 32709 +github.tar, level 19 with dict dms, advanced streaming, 32553 +github.tar, level 19 with dict dds, advanced streaming, 32553 +github.tar, level 19 with dict copy, advanced streaming, 32709 +github.tar, level 19 with dict load, advanced streaming, 32474 github.tar, no source size, advanced streaming, 38438 github.tar, no source size with dict, advanced streaming, 38000 github.tar, long distance mode, advanced streaming, 39757 @@ -1177,56 +1177,56 @@ github.tar, multithreaded long distance mode, advanced github.tar, small window log, advanced streaming, 199558 github.tar, small hash log, advanced streaming, 129870 github.tar, small chain log, advanced streaming, 41669 -github.tar, explicit params, advanced streaming, 41351 +github.tar, explicit params, advanced streaming, 41385 github.tar, uncompressed literals, advanced streaming, 41122 -github.tar, uncompressed literals optimal, advanced streaming, 35388 -github.tar, huffman literals, advanced streaming, 38800 +github.tar, uncompressed literals optimal, advanced streaming, 35397 +github.tar, huffman literals, advanced streaming, 38874 github.tar, multithreaded with advanced params, advanced streaming, 41122 -silesia, level -5, old streaming, 6882505 -silesia, level -3, old streaming, 6568376 -silesia, level -1, old streaming, 6183403 -silesia, level 0, old streaming, 4849551 -silesia, level 1, old streaming, 5314161 -silesia, level 3, old streaming, 4849551 -silesia, level 4, old streaming, 4786969 -silesia, level 5, old streaming, 4639132 -silesia, level 6, old streaming, 4605629 -silesia, level 7, old streaming, 4567307 -silesia, level 9, old streaming, 4543330 -silesia, level 13, old streaming, 4482131 -silesia, level 16, old streaming, 4360251 -silesia, level 19, old streaming, 4283236 -silesia, no source size, old streaming, 4849515 -silesia, uncompressed literals, old streaming, 4849551 -silesia, uncompressed literals optimal, old streaming, 4283236 -silesia, huffman literals, old streaming, 6183403 -silesia.tar, level -5, old streaming, 6982759 -silesia.tar, level -3, old streaming, 6641283 -silesia.tar, level -1, old streaming, 6190795 -silesia.tar, level 0, old streaming, 4861425 -silesia.tar, level 1, old streaming, 5336941 -silesia.tar, level 3, old streaming, 4861425 +silesia, level -5, old streaming, 7292053 +silesia, level -3, old streaming, 6867875 +silesia, level -1, old streaming, 6183923 +silesia, level 0, old streaming, 4849553 +silesia, level 1, old streaming, 5312694 +silesia, level 3, old streaming, 4849553 +silesia, level 4, old streaming, 4786968 +silesia, level 5, old streaming, 4638691 +silesia, level 6, old streaming, 4605296 +silesia, level 7, old streaming, 4566984 +silesia, level 9, old streaming, 4543018 +silesia, level 13, old streaming, 4493990 +silesia, level 16, old streaming, 4359864 +silesia, level 19, old streaming, 4296880 +silesia, no source size, old streaming, 4849517 +silesia, uncompressed literals, old streaming, 4849553 +silesia, uncompressed literals optimal, old streaming, 4296880 +silesia, huffman literals, old streaming, 6183923 +silesia.tar, level -5, old streaming, 7260007 +silesia.tar, level -3, old streaming, 6845151 +silesia.tar, level -1, old streaming, 6187938 +silesia.tar, level 0, old streaming, 4861426 +silesia.tar, level 1, old streaming, 5334890 +silesia.tar, level 3, old streaming, 4861426 silesia.tar, level 4, old streaming, 4799632 -silesia.tar, level 5, old streaming, 4650392 -silesia.tar, level 6, old streaming, 4617097 -silesia.tar, level 7, old streaming, 4576953 -silesia.tar, level 9, old streaming, 4552646 -silesia.tar, level 13, old streaming, 4491769 -silesia.tar, level 16, old streaming, 4356834 -silesia.tar, level 19, old streaming, 4264388 -silesia.tar, no source size, old streaming, 4861421 -silesia.tar, uncompressed literals, old streaming, 4861425 -silesia.tar, uncompressed literals optimal, old streaming, 4264388 -silesia.tar, huffman literals, old streaming, 6190795 -github, level -5, old streaming, 205285 +silesia.tar, level 5, old streaming, 4649992 +silesia.tar, level 6, old streaming, 4616803 +silesia.tar, level 7, old streaming, 4576664 +silesia.tar, level 9, old streaming, 4552386 +silesia.tar, level 13, old streaming, 4502956 +silesia.tar, level 16, old streaming, 4360527 +silesia.tar, level 19, old streaming, 4267266 +silesia.tar, no source size, old streaming, 4861422 +silesia.tar, uncompressed literals, old streaming, 4861426 +silesia.tar, uncompressed literals optimal, old streaming, 4267266 +silesia.tar, huffman literals, old streaming, 6187938 +github, level -5, old streaming, 232315 github, level -5 with dict, old streaming, 46718 -github, level -3, old streaming, 190643 +github, level -3, old streaming, 220760 github, level -3 with dict, old streaming, 45395 -github, level -1, old streaming, 175568 +github, level -1, old streaming, 175468 github, level -1 with dict, old streaming, 43170 github, level 0, old streaming, 136335 github, level 0 with dict, old streaming, 41148 -github, level 1, old streaming, 142465 +github, level 1, old streaming, 142365 github, level 1 with dict, old streaming, 41682 github, level 3, old streaming, 136335 github, level 3 with dict, old streaming, 41148 @@ -1250,101 +1250,101 @@ github, no source size, old stre github, no source size with dict, old streaming, 40654 github, uncompressed literals, old streaming, 136335 github, uncompressed literals optimal, old streaming, 134064 -github, huffman literals, old streaming, 175568 -github.tar, level -5, old streaming, 46747 -github.tar, level -5 with dict, old streaming, 44440 -github.tar, level -3, old streaming, 43537 -github.tar, level -3 with dict, old streaming, 41112 -github.tar, level -1, old streaming, 42465 -github.tar, level -1 with dict, old streaming, 41196 +github, huffman literals, old streaming, 175468 +github.tar, level -5, old streaming, 64132 +github.tar, level -5 with dict, old streaming, 48642 +github.tar, level -3, old streaming, 50964 +github.tar, level -3 with dict, old streaming, 42750 +github.tar, level -1, old streaming, 42536 +github.tar, level -1 with dict, old streaming, 41198 github.tar, level 0, old streaming, 38441 github.tar, level 0 with dict, old streaming, 37995 -github.tar, level 1, old streaming, 39342 -github.tar, level 1 with dict, old streaming, 38293 +github.tar, level 1, old streaming, 39270 +github.tar, level 1 with dict, old streaming, 38316 github.tar, level 3, old streaming, 38441 github.tar, level 3 with dict, old streaming, 37995 github.tar, level 4, old streaming, 38467 github.tar, level 4 with dict, old streaming, 37948 -github.tar, level 5, old streaming, 38394 -github.tar, level 5 with dict, old streaming, 39074 -github.tar, level 6, old streaming, 38669 -github.tar, level 6 with dict, old streaming, 38660 -github.tar, level 7, old streaming, 38153 -github.tar, level 7 with dict, old streaming, 37892 -github.tar, level 9, old streaming, 36768 -github.tar, level 9 with dict, old streaming, 36510 -github.tar, level 13, old streaming, 35621 -github.tar, level 13 with dict, old streaming, 38726 -github.tar, level 16, old streaming, 40255 -github.tar, level 16 with dict, old streaming, 33639 -github.tar, level 19, old streaming, 32837 -github.tar, level 19 with dict, old streaming, 32895 +github.tar, level 5, old streaming, 38366 +github.tar, level 5 with dict, old streaming, 39082 +github.tar, level 6, old streaming, 38648 +github.tar, level 6 with dict, old streaming, 38656 +github.tar, level 7, old streaming, 38110 +github.tar, level 7 with dict, old streaming, 37865 +github.tar, level 9, old streaming, 36760 +github.tar, level 9 with dict, old streaming, 36484 +github.tar, level 13, old streaming, 35501 +github.tar, level 13 with dict, old streaming, 37130 +github.tar, level 16, old streaming, 40471 +github.tar, level 16 with dict, old streaming, 33378 +github.tar, level 19, old streaming, 32134 +github.tar, level 19 with dict, old streaming, 32709 github.tar, no source size, old streaming, 38438 github.tar, no source size with dict, old streaming, 38000 github.tar, uncompressed literals, old streaming, 38441 -github.tar, uncompressed literals optimal, old streaming, 32837 -github.tar, huffman literals, old streaming, 42465 -silesia, level -5, old streaming advanced, 6882505 -silesia, level -3, old streaming advanced, 6568376 -silesia, level -1, old streaming advanced, 6183403 -silesia, level 0, old streaming advanced, 4849551 -silesia, level 1, old streaming advanced, 5314161 -silesia, level 3, old streaming advanced, 4849551 -silesia, level 4, old streaming advanced, 4786969 -silesia, level 5, old streaming advanced, 4639132 -silesia, level 6, old streaming advanced, 4605629 -silesia, level 7, old streaming advanced, 4567307 -silesia, level 9, old streaming advanced, 4543330 -silesia, level 13, old streaming advanced, 4482131 -silesia, level 16, old streaming advanced, 4360251 -silesia, level 19, old streaming advanced, 4283236 -silesia, no source size, old streaming advanced, 4849515 -silesia, long distance mode, old streaming advanced, 4849551 -silesia, multithreaded, old streaming advanced, 4849551 -silesia, multithreaded long distance mode, old streaming advanced, 4849551 +github.tar, uncompressed literals optimal, old streaming, 32134 +github.tar, huffman literals, old streaming, 42536 +silesia, level -5, old streaming advanced, 7292053 +silesia, level -3, old streaming advanced, 6867875 +silesia, level -1, old streaming advanced, 6183923 +silesia, level 0, old streaming advanced, 4849553 +silesia, level 1, old streaming advanced, 5312694 +silesia, level 3, old streaming advanced, 4849553 +silesia, level 4, old streaming advanced, 4786968 +silesia, level 5, old streaming advanced, 4638691 +silesia, level 6, old streaming advanced, 4605296 +silesia, level 7, old streaming advanced, 4566984 +silesia, level 9, old streaming advanced, 4543018 +silesia, level 13, old streaming advanced, 4493990 +silesia, level 16, old streaming advanced, 4359864 +silesia, level 19, old streaming advanced, 4296880 +silesia, no source size, old streaming advanced, 4849517 +silesia, long distance mode, old streaming advanced, 4849553 +silesia, multithreaded, old streaming advanced, 4849553 +silesia, multithreaded long distance mode, old streaming advanced, 4849553 silesia, small window log, old streaming advanced, 7112062 silesia, small hash log, old streaming advanced, 6526141 -silesia, small chain log, old streaming advanced, 4912199 -silesia, explicit params, old streaming advanced, 4796309 -silesia, uncompressed literals, old streaming advanced, 4849551 -silesia, uncompressed literals optimal, old streaming advanced, 4283236 -silesia, huffman literals, old streaming advanced, 6183403 -silesia, multithreaded with advanced params, old streaming advanced, 4849551 -silesia.tar, level -5, old streaming advanced, 6982759 -silesia.tar, level -3, old streaming advanced, 6641283 -silesia.tar, level -1, old streaming advanced, 6190795 -silesia.tar, level 0, old streaming advanced, 4861425 -silesia.tar, level 1, old streaming advanced, 5336941 -silesia.tar, level 3, old streaming advanced, 4861425 +silesia, small chain log, old streaming advanced, 4912197 +silesia, explicit params, old streaming advanced, 4795452 +silesia, uncompressed literals, old streaming advanced, 4849553 +silesia, uncompressed literals optimal, old streaming advanced, 4296880 +silesia, huffman literals, old streaming advanced, 6183923 +silesia, multithreaded with advanced params, old streaming advanced, 4849553 +silesia.tar, level -5, old streaming advanced, 7260007 +silesia.tar, level -3, old streaming advanced, 6845151 +silesia.tar, level -1, old streaming advanced, 6187938 +silesia.tar, level 0, old streaming advanced, 4861426 +silesia.tar, level 1, old streaming advanced, 5334890 +silesia.tar, level 3, old streaming advanced, 4861426 silesia.tar, level 4, old streaming advanced, 4799632 -silesia.tar, level 5, old streaming advanced, 4650392 -silesia.tar, level 6, old streaming advanced, 4617097 -silesia.tar, level 7, old streaming advanced, 4576953 -silesia.tar, level 9, old streaming advanced, 4552646 -silesia.tar, level 13, old streaming advanced, 4491769 -silesia.tar, level 16, old streaming advanced, 4356834 -silesia.tar, level 19, old streaming advanced, 4264388 -silesia.tar, no source size, old streaming advanced, 4861421 -silesia.tar, long distance mode, old streaming advanced, 4861425 -silesia.tar, multithreaded, old streaming advanced, 4861425 -silesia.tar, multithreaded long distance mode, old streaming advanced, 4861425 +silesia.tar, level 5, old streaming advanced, 4649992 +silesia.tar, level 6, old streaming advanced, 4616803 +silesia.tar, level 7, old streaming advanced, 4576664 +silesia.tar, level 9, old streaming advanced, 4552386 +silesia.tar, level 13, old streaming advanced, 4502956 +silesia.tar, level 16, old streaming advanced, 4360527 +silesia.tar, level 19, old streaming advanced, 4267266 +silesia.tar, no source size, old streaming advanced, 4861422 +silesia.tar, long distance mode, old streaming advanced, 4861426 +silesia.tar, multithreaded, old streaming advanced, 4861426 +silesia.tar, multithreaded long distance mode, old streaming advanced, 4861426 silesia.tar, small window log, old streaming advanced, 7118772 -silesia.tar, small hash log, old streaming advanced, 6529231 -silesia.tar, small chain log, old streaming advanced, 4917019 -silesia.tar, explicit params, old streaming advanced, 4807688 -silesia.tar, uncompressed literals, old streaming advanced, 4861425 -silesia.tar, uncompressed literals optimal, old streaming advanced, 4264388 -silesia.tar, huffman literals, old streaming advanced, 6190795 -silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 -github, level -5, old streaming advanced, 216734 +silesia.tar, small hash log, old streaming advanced, 6529234 +silesia.tar, small chain log, old streaming advanced, 4917021 +silesia.tar, explicit params, old streaming advanced, 4806873 +silesia.tar, uncompressed literals, old streaming advanced, 4861426 +silesia.tar, uncompressed literals optimal, old streaming advanced, 4267266 +silesia.tar, huffman literals, old streaming advanced, 6187938 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4861426 +github, level -5, old streaming advanced, 241214 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 192160 +github, level -3, old streaming advanced, 222937 github, level -3 with dict, old streaming advanced, 44956 -github, level -1, old streaming advanced, 181108 +github, level -1, old streaming advanced, 181107 github, level -1 with dict, old streaming advanced, 42383 github, level 0, old streaming advanced, 141104 github, level 0 with dict, old streaming advanced, 41113 -github, level 1, old streaming advanced, 143692 +github, level 1, old streaming advanced, 143693 github, level 1 with dict, old streaming advanced, 42430 github, level 3, old streaming advanced, 141104 github, level 3 with dict, old streaming advanced, 41113 @@ -1359,7 +1359,7 @@ github, level 7 with dict, old stre github, level 9, old streaming advanced, 138676 github, level 9 with dict, old streaming advanced, 38981 github, level 13, old streaming advanced, 138676 -github, level 13 with dict, old streaming advanced, 39731 +github, level 13 with dict, old streaming advanced, 39721 github, level 16, old streaming advanced, 138676 github, level 16 with dict, old streaming advanced, 40789 github, level 19, old streaming advanced, 134064 @@ -1375,36 +1375,36 @@ github, small chain log, old stre github, explicit params, old streaming advanced, 140937 github, uncompressed literals, old streaming advanced, 141104 github, uncompressed literals optimal, old streaming advanced, 134064 -github, huffman literals, old streaming advanced, 181108 +github, huffman literals, old streaming advanced, 181107 github, multithreaded with advanced params, old streaming advanced, 141104 -github.tar, level -5, old streaming advanced, 46747 -github.tar, level -5 with dict, old streaming advanced, 44824 -github.tar, level -3, old streaming advanced, 43537 -github.tar, level -3 with dict, old streaming advanced, 41800 -github.tar, level -1, old streaming advanced, 42465 -github.tar, level -1 with dict, old streaming advanced, 41471 +github.tar, level -5, old streaming advanced, 64132 +github.tar, level -5 with dict, old streaming advanced, 48982 +github.tar, level -3, old streaming advanced, 50964 +github.tar, level -3 with dict, old streaming advanced, 43357 +github.tar, level -1, old streaming advanced, 42536 +github.tar, level -1 with dict, old streaming advanced, 41494 github.tar, level 0, old streaming advanced, 38441 github.tar, level 0 with dict, old streaming advanced, 38013 -github.tar, level 1, old streaming advanced, 39342 -github.tar, level 1 with dict, old streaming advanced, 38940 +github.tar, level 1, old streaming advanced, 39270 +github.tar, level 1 with dict, old streaming advanced, 38934 github.tar, level 3, old streaming advanced, 38441 github.tar, level 3 with dict, old streaming advanced, 38013 github.tar, level 4, old streaming advanced, 38467 github.tar, level 4 with dict, old streaming advanced, 38063 -github.tar, level 5, old streaming advanced, 38394 -github.tar, level 5 with dict, old streaming advanced, 37763 -github.tar, level 6, old streaming advanced, 38669 -github.tar, level 6 with dict, old streaming advanced, 37851 -github.tar, level 7, old streaming advanced, 38153 -github.tar, level 7 with dict, old streaming advanced, 37406 -github.tar, level 9, old streaming advanced, 36768 -github.tar, level 9 with dict, old streaming advanced, 36304 -github.tar, level 13, old streaming advanced, 35621 -github.tar, level 13 with dict, old streaming advanced, 36035 -github.tar, level 16, old streaming advanced, 40255 -github.tar, level 16 with dict, old streaming advanced, 38736 -github.tar, level 19, old streaming advanced, 32837 -github.tar, level 19 with dict, old streaming advanced, 32876 +github.tar, level 5, old streaming advanced, 38366 +github.tar, level 5 with dict, old streaming advanced, 37728 +github.tar, level 6, old streaming advanced, 38648 +github.tar, level 6 with dict, old streaming advanced, 37820 +github.tar, level 7, old streaming advanced, 38110 +github.tar, level 7 with dict, old streaming advanced, 37387 +github.tar, level 9, old streaming advanced, 36760 +github.tar, level 9 with dict, old streaming advanced, 36312 +github.tar, level 13, old streaming advanced, 35501 +github.tar, level 13 with dict, old streaming advanced, 35807 +github.tar, level 16, old streaming advanced, 40471 +github.tar, level 16 with dict, old streaming advanced, 38578 +github.tar, level 19, old streaming advanced, 32134 +github.tar, level 19 with dict, old streaming advanced, 32702 github.tar, no source size, old streaming advanced, 38438 github.tar, no source size with dict, old streaming advanced, 38015 github.tar, long distance mode, old streaming advanced, 38441 @@ -1413,10 +1413,10 @@ github.tar, multithreaded long distance mode, old stre github.tar, small window log, old streaming advanced, 199561 github.tar, small hash log, old streaming advanced, 129870 github.tar, small chain log, old streaming advanced, 41669 -github.tar, explicit params, old streaming advanced, 41351 +github.tar, explicit params, old streaming advanced, 41385 github.tar, uncompressed literals, old streaming advanced, 38441 -github.tar, uncompressed literals optimal, old streaming advanced, 32837 -github.tar, huffman literals, old streaming advanced, 42465 +github.tar, uncompressed literals optimal, old streaming advanced, 32134 +github.tar, huffman literals, old streaming advanced, 42536 github.tar, multithreaded with advanced params, old streaming advanced, 38441 github, level -5 with dict, old streaming cdict, 46718 github, level -3 with dict, old streaming cdict, 45395 @@ -1433,20 +1433,20 @@ github, level 13 with dict, old stre github, level 16 with dict, old streaming cdict, 37577 github, level 19 with dict, old streaming cdict, 37576 github, no source size with dict, old streaming cdict, 40654 -github.tar, level -5 with dict, old streaming cdict, 45018 -github.tar, level -3 with dict, old streaming cdict, 41886 -github.tar, level -1 with dict, old streaming cdict, 41636 +github.tar, level -5 with dict, old streaming cdict, 49146 +github.tar, level -3 with dict, old streaming cdict, 43468 +github.tar, level -1 with dict, old streaming cdict, 41662 github.tar, level 0 with dict, old streaming cdict, 37956 -github.tar, level 1 with dict, old streaming cdict, 38766 +github.tar, level 1 with dict, old streaming cdict, 38761 github.tar, level 3 with dict, old streaming cdict, 37956 github.tar, level 4 with dict, old streaming cdict, 37927 -github.tar, level 5 with dict, old streaming cdict, 37665 -github.tar, level 6 with dict, old streaming cdict, 37889 -github.tar, level 7 with dict, old streaming cdict, 37457 -github.tar, level 9 with dict, old streaming cdict, 36383 -github.tar, level 13 with dict, old streaming cdict, 36372 -github.tar, level 16 with dict, old streaming cdict, 39353 -github.tar, level 19 with dict, old streaming cdict, 32676 +github.tar, level 5 with dict, old streaming cdict, 37656 +github.tar, level 6 with dict, old streaming cdict, 37865 +github.tar, level 7 with dict, old streaming cdict, 37436 +github.tar, level 9 with dict, old streaming cdict, 36401 +github.tar, level 13 with dict, old streaming cdict, 36010 +github.tar, level 16 with dict, old streaming cdict, 39081 +github.tar, level 19 with dict, old streaming cdict, 32474 github.tar, no source size with dict, old streaming cdict, 38000 github, level -5 with dict, old streaming advanced cdict, 49562 github, level -3 with dict, old streaming advanced cdict, 44956 @@ -1459,7 +1459,7 @@ github, level 5 with dict, old stre github, level 6 with dict, old streaming advanced cdict, 39363 github, level 7 with dict, old streaming advanced cdict, 38924 github, level 9 with dict, old streaming advanced cdict, 38981 -github, level 13 with dict, old streaming advanced cdict, 39731 +github, level 13 with dict, old streaming advanced cdict, 39721 github, level 16 with dict, old streaming advanced cdict, 40789 github, level 19 with dict, old streaming advanced cdict, 37576 github, no source size with dict, old streaming advanced cdict, 40608 @@ -1470,11 +1470,11 @@ github.tar, level 0 with dict, old stre github.tar, level 1 with dict, old streaming advanced cdict, 39002 github.tar, level 3 with dict, old streaming advanced cdict, 38013 github.tar, level 4 with dict, old streaming advanced cdict, 38063 -github.tar, level 5 with dict, old streaming advanced cdict, 37763 -github.tar, level 6 with dict, old streaming advanced cdict, 37851 -github.tar, level 7 with dict, old streaming advanced cdict, 37406 -github.tar, level 9 with dict, old streaming advanced cdict, 36304 -github.tar, level 13 with dict, old streaming advanced cdict, 36035 -github.tar, level 16 with dict, old streaming advanced cdict, 38736 -github.tar, level 19 with dict, old streaming advanced cdict, 32876 +github.tar, level 5 with dict, old streaming advanced cdict, 37728 +github.tar, level 6 with dict, old streaming advanced cdict, 37820 +github.tar, level 7 with dict, old streaming advanced cdict, 37387 +github.tar, level 9 with dict, old streaming advanced cdict, 36312 +github.tar, level 13 with dict, old streaming advanced cdict, 35807 +github.tar, level 16 with dict, old streaming advanced cdict, 38578 +github.tar, level 19 with dict, old streaming advanced cdict, 32702 github.tar, no source size with dict, old streaming advanced cdict, 38015 From 894f05e88d07dd1c791597540e91f1aa6149b67e Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Tue, 28 Sep 2021 09:14:19 +0800 Subject: [PATCH 201/274] Fix ZSTD_countTrailingZeros() bug `>> 3` is wrong. --- lib/common/zstd_internal.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 4db5b00a7..efd7360a0 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -385,10 +385,10 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus } /** - * Computes CTZ on a U64. - * This will be slow on 32-bit mode, and on unsupported compilers. - * If you need this function to be fast (because it is hot) expand - * support. + * Counts the number of trailing zeros of a `size_t`. + * Most compilers should support CTZ as a builtin. A backup + * implementation is provided if the builtin isn't supported, but + * it may not be terribly efficient. */ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) { @@ -400,7 +400,7 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) if (val != 0) { unsigned long r; _BitScanForward64(&r, (U64)val); - return (unsigned)(r >> 3); + return (unsigned)r; } else { /* Should not reach this code path */ __assume(0); @@ -424,13 +424,13 @@ MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val) if (val != 0) { unsigned long r; _BitScanForward(&r, (U32)val); - return (unsigned)(r >> 3); + return (unsigned)r; } else { /* Should not reach this code path */ __assume(0); } # elif defined(__GNUC__) && (__GNUC__ >= 3) - return (__builtin_ctz((U32)val) >> 3); + return __builtin_ctz((U32)val); # else static const int DeBruijnBytePos[32] = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, From abc1a91fe2ef62b2b29ad487d3ffb66db7e30105 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 29 Sep 2021 07:09:08 +0200 Subject: [PATCH 202/274] add missing BUNDLE DESTINATION fixes build on iOS --- build/cmake/lib/CMakeLists.txt | 1 + build/cmake/programs/CMakeLists.txt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index d91ebe1f0..a9bff58e5 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -168,6 +168,7 @@ install(TARGETS ${library_targets} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}" ) # uninstall target diff --git a/build/cmake/programs/CMakeLists.txt b/build/cmake/programs/CMakeLists.txt index f1d127746..490030783 100644 --- a/build/cmake/programs/CMakeLists.txt +++ b/build/cmake/programs/CMakeLists.txt @@ -37,7 +37,9 @@ target_link_libraries(zstd ${PROGRAMS_ZSTD_LINK_TARGET}) if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") target_link_libraries(zstd rt) endif () -install(TARGETS zstd RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS zstd + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + BUNDLE DESTINATION "${CMAKE_INSTALL_BINDIR}") if (UNIX) add_custom_target(zstdcat ALL ${CMAKE_COMMAND} -E create_symlink zstd zstdcat DEPENDS zstd COMMENT "Creating zstdcat symlink") From 52598d54e98d1de87a8e89c7fc0aa1bfc9b67e16 Mon Sep 17 00:00:00 2001 From: stanjo74 Date: Mon, 4 Oct 2021 17:47:52 -0700 Subject: [PATCH 203/274] Limit train samples (#2809) * Limit training samples size to 2GB * simplified DISPLAYLEVEL() macro to use global vqriable instead of local. * refactored training samples loading * fixed compiler warning * addressed comments from the pull request * addressed @terrelln comments * missed some fixes * fixed type mismatch * Fixed bug passing estimated number of samples rather insted of the loaded number of samples. Changed unit conversion not to use bit-shifts. * fixed a declaration after code * fixed type conversion compile errors * fixed more type castting * fixed more type mismatching * changed sizes type to size_t * move type casting * more type cast fixes --- lib/dictBuilder/cover.c | 7 ++ lib/dictBuilder/fastcover.c | 7 ++ programs/dibio.c | 225 ++++++++++++++++++++++++------------ programs/dibio.h | 4 +- programs/zstdcli.c | 6 +- 5 files changed, 167 insertions(+), 82 deletions(-) diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c index ec5a169c0..028802a1b 100644 --- a/lib/dictBuilder/cover.c +++ b/lib/dictBuilder/cover.c @@ -40,6 +40,13 @@ /*-************************************* * Constants ***************************************/ +/** +* There are 32bit indexes used to ref samples, so limit samples size to 4GB +* on 64bit builds. +* For 32bit builds we choose 1 GB. +* Most 32bit platforms have 2GB user-mode addressable space and we allocate a large +* contiguous buffer, so 1GB is already a high limit. +*/ #define COVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB)) #define COVER_DEFAULT_SPLITPOINT 1.0 diff --git a/lib/dictBuilder/fastcover.c b/lib/dictBuilder/fastcover.c index f4a2eed99..3352859ad 100644 --- a/lib/dictBuilder/fastcover.c +++ b/lib/dictBuilder/fastcover.c @@ -32,6 +32,13 @@ /*-************************************* * Constants ***************************************/ +/** +* There are 32bit indexes used to ref samples, so limit samples size to 4GB +* on 64bit builds. +* For 32bit builds we choose 1 GB. +* Most 32bit platforms have 2GB user-mode addressable space and we allocate a large +* contiguous buffer, so 1GB is already a high limit. +*/ #define FASTCOVER_MAX_SAMPLES_SIZE (sizeof(size_t) == 8 ? ((unsigned)-1) : ((unsigned)1 GB)) #define FASTCOVER_MAX_F 31 #define FASTCOVER_MAX_ACCEL 10 diff --git a/programs/dibio.c b/programs/dibio.c index d6c9f6d9e..49fa21185 100644 --- a/programs/dibio.c +++ b/programs/dibio.c @@ -49,6 +49,7 @@ static const size_t g_maxMemory = (sizeof(size_t) == 4) ? (2 GB - 64 MB) : ((size_t)(512 MB) << sizeof(size_t)); #define NOISELENGTH 32 +#define MAX_SAMPLES_SIZE (2 GB) /* training dataset limited to 2GB */ /*-************************************* @@ -88,6 +89,15 @@ static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER; #undef MIN #define MIN(a,b) ((a) < (b) ? (a) : (b)) +/** + Returns the size of a file. + If error returns -1. +*/ +static S64 DiB_getFileSize (const char * fileName) +{ + U64 const fileSize = UTIL_getFileSize(fileName); + return (fileSize == UTIL_FILESIZE_UNKNOWN) ? -1 : (S64)fileSize; +} /* ******************************************************** * File related operations @@ -101,47 +111,67 @@ static UTIL_time_t g_displayClock = UTIL_TIME_INITIALIZER; * *bufferSizePtr is modified, it provides the amount data loaded within buffer. * sampleSizes is filled with the size of each sample. */ -static unsigned DiB_loadFiles(void* buffer, size_t* bufferSizePtr, - size_t* sampleSizes, unsigned sstSize, - const char** fileNamesTable, unsigned nbFiles, size_t targetChunkSize, - unsigned displayLevel) +static int DiB_loadFiles( + void* buffer, size_t* bufferSizePtr, + size_t* sampleSizes, int sstSize, + const char** fileNamesTable, int nbFiles, + size_t targetChunkSize, int displayLevel ) { char* const buff = (char*)buffer; - size_t pos = 0; - unsigned nbLoadedChunks = 0, fileIndex; + size_t totalDataLoaded = 0; + int nbSamplesLoaded = 0; + int fileIndex = 0; + FILE * f = NULL; - for (fileIndex=0; fileIndex *bufferSizePtr-pos) break; - { size_t const readSize = fread(buff+pos, 1, toLoad, f); - if (readSize != toLoad) EXM_THROW(11, "Pb reading %s", fileName); - pos += readSize; - sampleSizes[nbLoadedChunks++] = toLoad; - remainingToLoad -= targetChunkSize; - if (nbLoadedChunks == sstSize) { /* no more space left in sampleSizes table */ - fileIndex = nbFiles; /* stop there */ + assert(targetChunkSize <= SAMPLESIZE_MAX); + + while ( nbSamplesLoaded < sstSize && fileIndex < nbFiles ) { + size_t fileDataLoaded; + S64 const fileSize = DiB_getFileSize(fileNamesTable[fileIndex]); + if (fileSize <= 0) /* skip if zero-size or file error */ + continue; + + f = fopen( fileNamesTable[fileIndex], "rb"); + if (f == NULL) + EXM_THROW(10, "zstd: dictBuilder: %s %s ", fileNamesTable[fileIndex], strerror(errno)); + DISPLAYUPDATE(2, "Loading %s... \r", fileNamesTable[fileIndex]); + + /* Load the first chunk of data from the file */ + fileDataLoaded = targetChunkSize > 0 ? + (size_t)MIN(fileSize, (S64)targetChunkSize) : + (size_t)MIN(fileSize, SAMPLESIZE_MAX ); + if (totalDataLoaded + fileDataLoaded > *bufferSizePtr) + break; + if (fread( buff+totalDataLoaded, 1, fileDataLoaded, f ) != fileDataLoaded) + EXM_THROW(11, "Pb reading %s", fileNamesTable[fileIndex]); + sampleSizes[nbSamplesLoaded++] = fileDataLoaded; + totalDataLoaded += fileDataLoaded; + + /* If file-chunking is enabled, load the rest of the file as more samples */ + if (targetChunkSize > 0) { + while( (S64)fileDataLoaded < fileSize && nbSamplesLoaded < sstSize ) { + size_t const chunkSize = MIN((size_t)(fileSize-fileDataLoaded), targetChunkSize); + if (totalDataLoaded + chunkSize > *bufferSizePtr) /* buffer is full */ break; - } - if (toLoad < targetChunkSize) { - fseek(f, (long)(targetChunkSize - toLoad), SEEK_CUR); - } } } - fclose(f); + + if (fread( buff+totalDataLoaded, 1, chunkSize, f ) != chunkSize) + EXM_THROW(11, "Pb reading %s", fileNamesTable[fileIndex]); + sampleSizes[nbSamplesLoaded++] = chunkSize; + totalDataLoaded += chunkSize; + fileDataLoaded += chunkSize; + } + } + fileIndex += 1; + fclose(f); f = NULL; } + if (f != NULL) + fclose(f); + DISPLAYLEVEL(2, "\r%79s\r", ""); - *bufferSizePtr = pos; - DISPLAYLEVEL(4, "loaded : %u KB \n", (unsigned)(pos >> 10)) - return nbLoadedChunks; + DISPLAYLEVEL(4, "Loaded %d KB total training data, %d nb samples \n", + (int)(totalDataLoaded / (1 KB)), nbSamplesLoaded ); + *bufferSizePtr = totalDataLoaded; + return nbSamplesLoaded; } #define DiB_rotl32(x,r) ((x << r) | (x >> (32 - r))) @@ -223,11 +253,10 @@ static void DiB_saveDict(const char* dictFileName, if (n!=0) EXM_THROW(5, "%s : flush error", dictFileName) } } - typedef struct { - U64 totalSizeToLoad; - unsigned oneSampleTooLarge; - unsigned nbSamples; + S64 totalSizeToLoad; + int nbSamples; + int oneSampleTooLarge; } fileStats; /*! DiB_fileStats() : @@ -235,46 +264,87 @@ typedef struct { * provides the amount of data to be loaded and the resulting nb of samples. * This is useful primarily for allocation purpose => sample buffer, and sample sizes table. */ -static fileStats DiB_fileStats(const char** fileNamesTable, unsigned nbFiles, size_t chunkSize, unsigned displayLevel) +static fileStats DiB_fileStats(const char** fileNamesTable, int nbFiles, size_t chunkSize, int displayLevel) { fileStats fs; - unsigned n; + int n; memset(&fs, 0, sizeof(fs)); + + // We assume that if chunking is requsted, the chunk size is < SAMPLESIZE_MAX + assert( chunkSize <= SAMPLESIZE_MAX ); + for (n=0; n 2*SAMPLESIZE_MAX); - fs.nbSamples += nbSamples; + S64 const fileSize = DiB_getFileSize(fileNamesTable[n]); + // TODO: is there a minimum sample size? What if the file is 1-byte? + if (fileSize == 0) { + DISPLAYLEVEL(3, "Sample file '%s' has zero size, skipping...\n", fileNamesTable[n]); + continue; + } + + /* the case where we are breaking up files in sample chunks */ + if (chunkSize > 0) + { + // TODO: is there a minimum sample size? Can we have a 1-byte sample? + fs.nbSamples += (int)((fileSize + chunkSize-1) / chunkSize); + fs.totalSizeToLoad += fileSize; + } + else { + /* the case where one file is one sample */ + if (fileSize > SAMPLESIZE_MAX) { + /* flag excessively large sample files */ + fs.oneSampleTooLarge |= (fileSize > 2*SAMPLESIZE_MAX); + + /* Limit to the first SAMPLESIZE_MAX (128kB) of the file */ + DISPLAYLEVEL(3, "Sample file '%s' is too large, limiting to %d KB", + fileNamesTable[n], SAMPLESIZE_MAX / (1 KB)); + } + fs.nbSamples += 1; + fs.totalSizeToLoad += MIN(fileSize, SAMPLESIZE_MAX); + } } - DISPLAYLEVEL(4, "Preparing to load : %u KB \n", (unsigned)(fs.totalSizeToLoad >> 10)); + DISPLAYLEVEL(4, "Found training data %d files, %d KB, %d samples\n", nbFiles, (int)(fs.totalSizeToLoad / (1 KB)), fs.nbSamples); return fs; } - -int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize, - const char** fileNamesTable, unsigned nbFiles, size_t chunkSize, +int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize, + const char** fileNamesTable, int nbFiles, size_t chunkSize, ZDICT_legacy_params_t* params, ZDICT_cover_params_t* coverParams, ZDICT_fastCover_params_t* fastCoverParams, int optimize) { - unsigned const displayLevel = params ? params->zParams.notificationLevel : - coverParams ? coverParams->zParams.notificationLevel : - fastCoverParams ? fastCoverParams->zParams.notificationLevel : - 0; /* should never happen */ + fileStats fs; + size_t* sampleSizes; /* vector of sample sizes. Each sample can be up to SAMPLESIZE_MAX */ + int nbSamplesLoaded; /* nb of samples effectively loaded in srcBuffer */ + size_t loadedSize; /* total data loaded in srcBuffer for all samples */ + void* srcBuffer /* contiguous buffer with training data/samples */; void* const dictBuffer = malloc(maxDictSize); - fileStats const fs = DiB_fileStats(fileNamesTable, nbFiles, chunkSize, displayLevel); - size_t* const sampleSizes = (size_t*)malloc(fs.nbSamples * sizeof(size_t)); - size_t const memMult = params ? MEMMULT : - coverParams ? COVER_MEMMULT: - FASTCOVER_MEMMULT; - size_t const maxMem = DiB_findMaxMem(fs.totalSizeToLoad * memMult) / memMult; - size_t loadedSize = (size_t) MIN ((unsigned long long)maxMem, fs.totalSizeToLoad); - void* const srcBuffer = malloc(loadedSize+NOISELENGTH); int result = 0; + int const displayLevel = params ? params->zParams.notificationLevel : + coverParams ? coverParams->zParams.notificationLevel : + fastCoverParams ? fastCoverParams->zParams.notificationLevel : 0; + + /* Shuffle input files before we start assessing how much sample datA to load. + The purpose of the shuffle is to pick random samples when the sample + set is larger than what we can load in memory. */ + DISPLAYLEVEL(3, "Shuffling input files\n"); + DiB_shuffle(fileNamesTable, nbFiles); + + /* Figure out how much sample data to load with how many samples */ + fs = DiB_fileStats(fileNamesTable, nbFiles, chunkSize, displayLevel); + + { + int const memMult = params ? MEMMULT : + coverParams ? COVER_MEMMULT: + FASTCOVER_MEMMULT; + size_t const maxMem = DiB_findMaxMem(fs.totalSizeToLoad * memMult) / memMult; + /* Limit the size of the training data to the free memory */ + /* Limit the size of the training data to 2GB */ + /* TODO: there is oportunity to stop DiB_fileStats() early when the data limit is reached */ + loadedSize = (size_t)MIN( MIN((S64)maxMem, fs.totalSizeToLoad), MAX_SAMPLES_SIZE ); + srcBuffer = malloc(loadedSize+NOISELENGTH); + sampleSizes = (size_t*)malloc(fs.nbSamples * sizeof(size_t)); + } + /* Checks */ if ((!sampleSizes) || (!srcBuffer) || (!dictBuffer)) EXM_THROW(12, "not enough memory for DiB_trainFiles"); /* should not happen */ @@ -289,31 +359,32 @@ int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize, DISPLAYLEVEL(2, "! Alternatively, split files into fixed-size blocks representative of samples, with -B# \n"); EXM_THROW(14, "nb of samples too low"); /* we now clearly forbid this case */ } - if (fs.totalSizeToLoad < (unsigned long long)maxDictSize * 8) { + if (fs.totalSizeToLoad < (S64)maxDictSize * 8) { DISPLAYLEVEL(2, "! Warning : data size of samples too small for target dictionary size \n"); DISPLAYLEVEL(2, "! Samples should be about 100x larger than target dictionary size \n"); } /* init */ - if (loadedSize < fs.totalSizeToLoad) - DISPLAYLEVEL(1, "Not enough memory; training on %u MB only...\n", (unsigned)(loadedSize >> 20)); + if ((S64)loadedSize < fs.totalSizeToLoad) + DISPLAYLEVEL(1, "Training samples set too large (%u MB); training on %u MB only...\n", + (unsigned)(fs.totalSizeToLoad / (1 MB)), + (unsigned)(loadedSize / (1 MB))); /* Load input buffer */ - DISPLAYLEVEL(3, "Shuffling input files\n"); - DiB_shuffle(fileNamesTable, nbFiles); - - DiB_loadFiles(srcBuffer, &loadedSize, sampleSizes, fs.nbSamples, fileNamesTable, nbFiles, chunkSize, displayLevel); + nbSamplesLoaded = DiB_loadFiles( + srcBuffer, &loadedSize, sampleSizes, fs.nbSamples, fileNamesTable, + nbFiles, chunkSize, displayLevel); { size_t dictSize; if (params) { DiB_fillNoise((char*)srcBuffer + loadedSize, NOISELENGTH); /* guard band, for end of buffer condition */ dictSize = ZDICT_trainFromBuffer_legacy(dictBuffer, maxDictSize, - srcBuffer, sampleSizes, fs.nbSamples, + srcBuffer, sampleSizes, nbSamplesLoaded, *params); } else if (coverParams) { if (optimize) { dictSize = ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, maxDictSize, - srcBuffer, sampleSizes, fs.nbSamples, + srcBuffer, sampleSizes, nbSamplesLoaded, coverParams); if (!ZDICT_isError(dictSize)) { unsigned splitPercentage = (unsigned)(coverParams->splitPoint * 100); @@ -322,13 +393,13 @@ int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize, } } else { dictSize = ZDICT_trainFromBuffer_cover(dictBuffer, maxDictSize, srcBuffer, - sampleSizes, fs.nbSamples, *coverParams); + sampleSizes, nbSamplesLoaded, *coverParams); } } else { assert(fastCoverParams != NULL); if (optimize) { dictSize = ZDICT_optimizeTrainFromBuffer_fastCover(dictBuffer, maxDictSize, - srcBuffer, sampleSizes, fs.nbSamples, + srcBuffer, sampleSizes, nbSamplesLoaded, fastCoverParams); if (!ZDICT_isError(dictSize)) { unsigned splitPercentage = (unsigned)(fastCoverParams->splitPoint * 100); @@ -338,7 +409,7 @@ int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize, } } else { dictSize = ZDICT_trainFromBuffer_fastCover(dictBuffer, maxDictSize, srcBuffer, - sampleSizes, fs.nbSamples, *fastCoverParams); + sampleSizes, nbSamplesLoaded, *fastCoverParams); } } if (ZDICT_isError(dictSize)) { diff --git a/programs/dibio.h b/programs/dibio.h index f65ed9b8e..03ec80e59 100644 --- a/programs/dibio.h +++ b/programs/dibio.h @@ -31,8 +31,8 @@ `parameters` is optional and can be provided with values set to 0, meaning "default". @return : 0 == ok. Any other : error. */ -int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize, - const char** fileNamesTable, unsigned nbFiles, size_t chunkSize, +int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize, + const char** fileNamesTable, int nbFiles, size_t chunkSize, ZDICT_legacy_params_t* params, ZDICT_cover_params_t* coverParams, ZDICT_fastCover_params_t* fastCoverParams, int optimize); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 7e4f530f8..8fb65111e 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1290,18 +1290,18 @@ int main(int argCount, const char* argv[]) int const optimize = !coverParams.k || !coverParams.d; coverParams.nbThreads = (unsigned)nbWorkers; coverParams.zParams = zParams; - operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (unsigned)filenames->tableSize, blockSize, NULL, &coverParams, NULL, optimize); + operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, &coverParams, NULL, optimize); } else if (dict == fastCover) { int const optimize = !fastCoverParams.k || !fastCoverParams.d; fastCoverParams.nbThreads = (unsigned)nbWorkers; fastCoverParams.zParams = zParams; - operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (unsigned)filenames->tableSize, blockSize, NULL, NULL, &fastCoverParams, optimize); + operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, NULL, &fastCoverParams, optimize); } else { ZDICT_legacy_params_t dictParams; memset(&dictParams, 0, sizeof(dictParams)); dictParams.selectivityLevel = dictSelect; dictParams.zParams = zParams; - operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (unsigned)filenames->tableSize, blockSize, &dictParams, NULL, NULL, 0); + operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, &dictParams, NULL, NULL, 0); } #else (void)dictCLevel; (void)dictSelect; (void)dictID; (void)maxDictSize; /* not used when ZSTD_NODICT set */ From 258c0623e1e4e49a8d6ac3471dda3dd4030a2191 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 1 Sep 2021 17:26:19 -0400 Subject: [PATCH 204/274] Extract Single-Segment Variant of ZSTD_dfast --- lib/compress/zstd_double_fast.c | 162 +++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index c17367859..ee902e19e 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -47,6 +47,160 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, } +FORCE_INLINE_TEMPLATE +size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved = 0; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_singleSegment_generic"); + + /* init */ + ip += ((ip - prefixLowest) == 0); + { + U32 const curr = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; + if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; + } + + /* Main Search Loop */ + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ + size_t mLength; + U32 offset; + size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); + size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); + U32 const curr = (U32)(ip-base); + U32 const matchIndexL = hashLong[h2]; + U32 matchIndexS = hashSmall[h]; + const BYTE* matchLong = base + matchIndexL; + const BYTE* match = base + matchIndexS; + hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ + + /* check noDict repcode */ + if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { + mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH); + goto _match_stored; + } + + if (matchIndexL > prefixLowestIndex) { + /* check prefix long match */ + if (MEM_read64(matchLong) == MEM_read64(ip)) { + mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; + offset = (U32)(ip-matchLong); + while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + goto _match_found; + } + } + + if (matchIndexS > prefixLowestIndex) { + /* check prefix short match */ + if (MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } + } + + ip += ((ip-anchor) >> kSearchStrength) + 1; +#if defined(__aarch64__) + PREFETCH_L1(ip+256); +#endif + continue; + +_search_next_long: + + { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + U32 const matchIndexL3 = hashLong[hl3]; + const BYTE* matchL3 = base + matchIndexL3; + hashLong[hl3] = curr + 1; + + /* check prefix long +1 match */ + if (matchIndexL3 > prefixLowestIndex) { + if (MEM_read64(matchL3) == MEM_read64(ip+1)) { + mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + ip++; + offset = (U32)(ip-matchL3); + while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ + goto _match_found; + } + } + } + + /* if no long +1 match, explore the short match we found */ + { + mLength = ZSTD_count(ip+4, match+4, iend) + 4; + offset = (U32)(ip - match); + while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + + /* fall-through */ + +_match_found: + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && ( (offset_2>0) + & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); + ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } } + } /* while (ip < ilimit) */ + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved; + rep[1] = offset_2 ? offset_2 : offsetSaved; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + + FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_doubleFast_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -323,13 +477,13 @@ size_t ZSTD_compressBlock_doubleFast( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_noDict); + return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 4); case 5 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_noDict); + return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 5); case 6 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_noDict); + return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 6); case 7 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_noDict); + return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 7); } } From 1bdf0410713b25a5c3419e12f32ab16eac62ba86 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 1 Sep 2021 17:50:53 -0400 Subject: [PATCH 205/274] Track Step Rather than Recalculating (+0.5% Speed) --- lib/compress/zstd_double_fast.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index ee902e19e..73a8e08eb 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -70,6 +70,9 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( const BYTE* const ilimit = iend - HASH_READ_SIZE; U32 offset_1=rep[0], offset_2=rep[1]; U32 offsetSaved = 0; + size_t step = 1; + const size_t kStepIncr = 1 << kSearchStrength; + const BYTE* nextStep = ip + kStepIncr; DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_singleSegment_generic"); @@ -121,7 +124,14 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( } } - ip += ((ip-anchor) >> kSearchStrength) + 1; + if (ip >= nextStep) { + PREFETCH_L1(ip + 64); + PREFETCH_L1(ip + 128); + step++; + nextStep += kStepIncr; + } + ip += step; + #if defined(__aarch64__) PREFETCH_L1(ip+256); #endif @@ -190,6 +200,9 @@ _match_stored: anchor = ip; continue; /* faster when present ... (?) */ } } + + step = 1; + nextStep = ip + kStepIncr; } /* while (ip < ilimit) */ /* save reps for next block */ From 072ffaad67b67ea4aef50b7370268fe28fa3b7e1 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Sep 2021 12:03:49 -0400 Subject: [PATCH 206/274] Extract Working Variables --- lib/compress/zstd_double_fast.c | 70 ++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 73a8e08eb..c3694426c 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -74,6 +74,21 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( const size_t kStepIncr = 1 << kSearchStrength; const BYTE* nextStep = ip + kStepIncr; + size_t hl0; + size_t hs0; + size_t hl1; + // size_t hs1; + + U32 idxl0; + U32 idxs0; + U32 idxl1; + // U32 idxs0; + + const BYTE* matchl0; + const BYTE* matchs0; + const BYTE* matchl1; + // const BYTE* matchs1; + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_singleSegment_generic"); /* init */ @@ -90,14 +105,15 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ size_t mLength; U32 offset; - size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); - size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); U32 const curr = (U32)(ip-base); - U32 const matchIndexL = hashLong[h2]; - U32 matchIndexS = hashSmall[h]; - const BYTE* matchLong = base + matchIndexL; - const BYTE* match = base + matchIndexS; - hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ + hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + hs0 = ZSTD_hashPtr(ip, hBitsS, mls); + idxl0 = hashLong[hl0]; + idxs0 = hashSmall[hs0]; + matchl0 = base + idxl0; + matchs0 = base + idxs0; + + hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ /* check noDict repcode */ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { @@ -107,19 +123,19 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( goto _match_stored; } - if (matchIndexL > prefixLowestIndex) { + if (idxl0 > prefixLowestIndex) { /* check prefix long match */ - if (MEM_read64(matchLong) == MEM_read64(ip)) { - mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; - offset = (U32)(ip-matchLong); - while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + if (MEM_read64(matchl0) == MEM_read64(ip)) { + mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8; + offset = (U32)(ip-matchl0); + while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */ goto _match_found; } } - if (matchIndexS > prefixLowestIndex) { + if (idxs0 > prefixLowestIndex) { /* check prefix short match */ - if (MEM_read32(match) == MEM_read32(ip)) { + if (MEM_read32(matchs0) == MEM_read32(ip)) { goto _search_next_long; } } @@ -139,18 +155,18 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( _search_next_long: - { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); - U32 const matchIndexL3 = hashLong[hl3]; - const BYTE* matchL3 = base + matchIndexL3; - hashLong[hl3] = curr + 1; + { hl1 = ZSTD_hashPtr(ip+1, hBitsL, 8); + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + hashLong[hl1] = curr + 1; /* check prefix long +1 match */ - if (matchIndexL3 > prefixLowestIndex) { - if (MEM_read64(matchL3) == MEM_read64(ip+1)) { - mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + if (idxl1 > prefixLowestIndex) { + if (MEM_read64(matchl1) == MEM_read64(ip+1)) { + mLength = ZSTD_count(ip+9, matchl1+8, iend) + 8; ip++; - offset = (U32)(ip-matchL3); - while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ + offset = (U32)(ip-matchl1); + while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ goto _match_found; } } @@ -158,14 +174,14 @@ _search_next_long: /* if no long +1 match, explore the short match we found */ { - mLength = ZSTD_count(ip+4, match+4, iend) + 4; - offset = (U32)(ip - match); - while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ } /* fall-through */ -_match_found: +_match_found: /* requires ip, offset, mLength */ offset_2 = offset_1; offset_1 = offset; From a1ac7205d031a7f27ad1d5eae9deced4bba938f1 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Sep 2021 12:15:58 -0400 Subject: [PATCH 207/274] Pull Match Found Stuff Out of the Loop --- lib/compress/zstd_double_fast.c | 171 +++++++++++++++++--------------- 1 file changed, 92 insertions(+), 79 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index c3694426c..0cf2d2159 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -60,7 +60,6 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( const U32 hBitsS = cParams->chainLog; const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; - const BYTE* ip = istart; const BYTE* anchor = istart; const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); /* presumes that, if there is a dictionary, it must be using Attach mode */ @@ -70,9 +69,14 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( const BYTE* const ilimit = iend - HASH_READ_SIZE; U32 offset_1=rep[0], offset_2=rep[1]; U32 offsetSaved = 0; - size_t step = 1; + + size_t mLength; + U32 offset; + U32 curr; + const size_t kStepIncr = 1 << kSearchStrength; - const BYTE* nextStep = ip + kStepIncr; + const BYTE* nextStep; + size_t step; size_t hl0; size_t hs0; @@ -89,23 +93,34 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( const BYTE* matchl1; // const BYTE* matchs1; + const BYTE* ip = istart; + const BYTE* ip1; + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_singleSegment_generic"); /* init */ ip += ((ip - prefixLowest) == 0); { - U32 const curr = (U32)(ip - base); - U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); - U32 const maxRep = curr - windowLow; + U32 const current = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog); + U32 const maxRep = current - windowLow; if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0; if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; } +_start: + + step = 1; + nextStep = ip + kStepIncr; + ip1 = ip + step; + + if (ip1 >= ilimit) { + goto _cleanup; + } + /* Main Search Loop */ - while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ - size_t mLength; - U32 offset; - U32 const curr = (U32)(ip-base); + do { + curr = (U32)(ip-base); hl0 = ZSTD_hashPtr(ip, hBitsL, 8); hs0 = ZSTD_hashPtr(ip, hBitsS, mls); idxl0 = hashLong[hl0]; @@ -151,82 +166,80 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( #if defined(__aarch64__) PREFETCH_L1(ip+256); #endif - continue; - -_search_next_long: - - { hl1 = ZSTD_hashPtr(ip+1, hBitsL, 8); - idxl1 = hashLong[hl1]; - matchl1 = base + idxl1; - hashLong[hl1] = curr + 1; - - /* check prefix long +1 match */ - if (idxl1 > prefixLowestIndex) { - if (MEM_read64(matchl1) == MEM_read64(ip+1)) { - mLength = ZSTD_count(ip+9, matchl1+8, iend) + 8; - ip++; - offset = (U32)(ip-matchl1); - while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ - goto _match_found; - } - } - } - - /* if no long +1 match, explore the short match we found */ - { - mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; - offset = (U32)(ip - matchs0); - while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ - } - - /* fall-through */ - -_match_found: /* requires ip, offset, mLength */ - offset_2 = offset_1; - offset_1 = offset; - - ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH); - -_match_stored: - /* match found */ - ip += mLength; - anchor = ip; - - if (ip <= ilimit) { - /* Complementary insertion */ - /* done after iLimit test, as candidates could be > iend-8 */ - { U32 const indexToInsert = curr+2; - hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; - hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); - hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; - hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); - } - - /* check immediate repcode */ - while ( (ip <= ilimit) - && ( (offset_2>0) - & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { - /* store sequence */ - size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; - U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ - hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); - hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); - ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH); - ip += rLength; - anchor = ip; - continue; /* faster when present ... (?) */ - } } - - step = 1; - nextStep = ip + kStepIncr; - } /* while (ip < ilimit) */ + } while (ip < ilimit); +_cleanup: /* save reps for next block */ rep[0] = offset_1 ? offset_1 : offsetSaved; rep[1] = offset_2 ? offset_2 : offsetSaved; /* Return the last literals size */ return (size_t)(iend - anchor); + +_search_next_long: + { hl1 = ZSTD_hashPtr(ip+1, hBitsL, 8); + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + hashLong[hl1] = curr + 1; + + /* check prefix long +1 match */ + if (idxl1 > prefixLowestIndex) { + if (MEM_read64(matchl1) == MEM_read64(ip+1)) { + mLength = ZSTD_count(ip+9, matchl1+8, iend) + 8; + ip++; + offset = (U32)(ip-matchl1); + while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ + goto _match_found; + } + } + } + + /* if no long +1 match, explore the short match we found */ + { + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ + } + + /* fall-through */ + +_match_found: /* requires ip, offset, mLength */ + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && ( (offset_2>0) + & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); + ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } } + + goto _start; } From db4e1b5479c1df569732aa8f486633ed4098bd8c Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Sep 2021 12:25:08 -0400 Subject: [PATCH 208/274] Hash Long One Position Ahead (+2.5% Speed) Aside from maybe a latency win in the loop, this means that when we find a short match, we've already done the hash we need to check the next long match. --- lib/compress/zstd_double_fast.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 0cf2d2159..4e38e4662 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -118,10 +118,11 @@ _start: goto _cleanup; } + hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + /* Main Search Loop */ do { curr = (U32)(ip-base); - hl0 = ZSTD_hashPtr(ip, hBitsL, 8); hs0 = ZSTD_hashPtr(ip, hBitsS, mls); idxl0 = hashLong[hl0]; idxs0 = hashSmall[hs0]; @@ -148,6 +149,8 @@ _start: } } + hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + if (idxs0 > prefixLowestIndex) { /* check prefix short match */ if (MEM_read32(matchs0) == MEM_read32(ip)) { @@ -155,18 +158,20 @@ _start: } } - if (ip >= nextStep) { - PREFETCH_L1(ip + 64); - PREFETCH_L1(ip + 128); + if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); step++; nextStep += kStepIncr; } - ip += step; + ip = ip1; + ip1 += step; + hl0 = hl1; #if defined(__aarch64__) PREFETCH_L1(ip+256); #endif - } while (ip < ilimit); + } while (ip1 < ilimit); _cleanup: /* save reps for next block */ @@ -177,8 +182,7 @@ _cleanup: return (size_t)(iend - anchor); _search_next_long: - { hl1 = ZSTD_hashPtr(ip+1, hBitsL, 8); - idxl1 = hashLong[hl1]; + { idxl1 = hashLong[hl1]; matchl1 = base + idxl1; hashLong[hl1] = curr + 1; From 39f2491bfc70db883d45265af0f764d1e80cfa69 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 8 Sep 2021 12:41:15 -0400 Subject: [PATCH 209/274] Use Look-Ahead Hash for Next Long Check after Short Match (+0.5% Speed) This costs a little ratio, unfortunately. --- lib/compress/zstd_double_fast.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 4e38e4662..45770b886 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -139,6 +139,8 @@ _start: goto _match_stored; } + hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + if (idxl0 > prefixLowestIndex) { /* check prefix long match */ if (MEM_read64(matchl0) == MEM_read64(ip)) { @@ -149,8 +151,6 @@ _start: } } - hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); - if (idxs0 > prefixLowestIndex) { /* check prefix short match */ if (MEM_read32(matchs0) == MEM_read32(ip)) { @@ -184,13 +184,12 @@ _cleanup: _search_next_long: { idxl1 = hashLong[hl1]; matchl1 = base + idxl1; - hashLong[hl1] = curr + 1; /* check prefix long +1 match */ if (idxl1 > prefixLowestIndex) { - if (MEM_read64(matchl1) == MEM_read64(ip+1)) { - mLength = ZSTD_count(ip+9, matchl1+8, iend) + 8; - ip++; + if (MEM_read64(matchl1) == MEM_read64(ip1)) { + ip = ip1; + mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8; offset = (U32)(ip-matchl1); while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ goto _match_found; @@ -205,6 +204,17 @@ _search_next_long: while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ } + if (step < 4) { + /* It is unsafe to write this value back to the hashtable when ip1 is + * greater than or equal to the new ip we will have after we're done + * processing this match. Rather than perform that test directly + * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler + * more predictable test. The minmatch even if we take a short match is + * 4 bytes, so as long as step, the distance between ip and ip1 + * (initially) is less than 4, we know ip1 < new ip. */ + hashLong[hl1] = (U32)(ip1 - base); + } + /* fall-through */ _match_found: /* requires ip, offset, mLength */ From 2ddef7c872c123383aa8b998a3b428bf359a8ce0 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 8 Sep 2021 12:45:42 -0400 Subject: [PATCH 210/274] Write Back Advanced Hash in Long Matches as Well (+Ratio) Since we're now hashing the position ahead even if we find a long match and don't search that next position, we can write it back into the hashtable even in long matches. This seems to cost us no speed, and improves compression ratio slightly! --- lib/compress/zstd_double_fast.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 45770b886..2e310e322 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -204,6 +204,12 @@ _search_next_long: while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ } + /* fall-through */ + +_match_found: /* requires ip, offset, mLength */ + offset_2 = offset_1; + offset_1 = offset; + if (step < 4) { /* It is unsafe to write this value back to the hashtable when ip1 is * greater than or equal to the new ip we will have after we're done @@ -215,12 +221,6 @@ _search_next_long: hashLong[hl1] = (U32)(ip1 - base); } - /* fall-through */ - -_match_found: /* requires ip, offset, mLength */ - offset_2 = offset_1; - offset_1 = offset; - ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH); _match_stored: From 6ae44c0db8d9832dd6d1ac8cdd3435dd686c0d0a Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 8 Sep 2021 16:15:01 -0400 Subject: [PATCH 211/274] Advance Long Index Lookup (+0.5% Speed) This lookup can be advanced to before the short match check because either way we will use it (in the next loop iter or in `_search_next_long`). --- lib/compress/zstd_double_fast.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 2e310e322..4ac44894b 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -81,17 +81,14 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( size_t hl0; size_t hs0; size_t hl1; - // size_t hs1; U32 idxl0; U32 idxs0; U32 idxl1; - // U32 idxs0; const BYTE* matchl0; const BYTE* matchs0; const BYTE* matchl1; - // const BYTE* matchs1; const BYTE* ip = istart; const BYTE* ip1; @@ -119,14 +116,14 @@ _start: } hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + idxl0 = hashLong[hl0]; + matchl0 = base + idxl0; /* Main Search Loop */ do { curr = (U32)(ip-base); hs0 = ZSTD_hashPtr(ip, hBitsS, mls); - idxl0 = hashLong[hl0]; idxs0 = hashSmall[hs0]; - matchl0 = base + idxl0; matchs0 = base + idxs0; hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ @@ -151,6 +148,9 @@ _start: } } + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + if (idxs0 > prefixLowestIndex) { /* check prefix short match */ if (MEM_read32(matchs0) == MEM_read32(ip)) { @@ -168,6 +168,8 @@ _start: ip1 += step; hl0 = hl1; + idxl0 = idxl1; + matchl0 = matchl1; #if defined(__aarch64__) PREFETCH_L1(ip+256); #endif @@ -182,8 +184,7 @@ _cleanup: return (size_t)(iend - anchor); _search_next_long: - { idxl1 = hashLong[hl1]; - matchl1 = base + idxl1; + { /* check prefix long +1 match */ if (idxl1 > prefixLowestIndex) { From 2cdfad538c24e8fd108e1c46101f4e7ec645663c Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 8 Sep 2021 16:41:43 -0400 Subject: [PATCH 212/274] Search One Last Position --- lib/compress/zstd_double_fast.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 4ac44894b..a85d68f01 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -111,7 +111,7 @@ _start: nextStep = ip + kStepIncr; ip1 = ip + step; - if (ip1 >= ilimit) { + if (ip1 > ilimit) { goto _cleanup; } @@ -173,7 +173,7 @@ _start: #if defined(__aarch64__) PREFETCH_L1(ip+256); #endif - } while (ip1 < ilimit); + } while (ip1 <= ilimit); _cleanup: /* save reps for next block */ From 47fd762eccb3d8273a8e9c20239fd069271c3d0d Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 8 Sep 2021 16:47:26 -0400 Subject: [PATCH 213/274] Nit: Unnest Blocks that Don't Declare Anything --- lib/compress/zstd_double_fast.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index a85d68f01..3a579e76d 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -184,26 +184,22 @@ _cleanup: return (size_t)(iend - anchor); _search_next_long: - { - /* check prefix long +1 match */ - if (idxl1 > prefixLowestIndex) { - if (MEM_read64(matchl1) == MEM_read64(ip1)) { - ip = ip1; - mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8; - offset = (U32)(ip-matchl1); - while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ - goto _match_found; - } + /* check prefix long +1 match */ + if (idxl1 > prefixLowestIndex) { + if (MEM_read64(matchl1) == MEM_read64(ip1)) { + ip = ip1; + mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8; + offset = (U32)(ip-matchl1); + while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ + goto _match_found; } } /* if no long +1 match, explore the short match we found */ - { - mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; - offset = (U32)(ip - matchs0); - while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ - } + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ /* fall-through */ From fcab4841aa0df69de0dfe867f9a74510ad7a459c Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Sep 2021 16:39:29 -0400 Subject: [PATCH 214/274] Nit: Rename Function --- lib/compress/zstd_double_fast.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 3a579e76d..8a8e8263d 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -48,10 +48,9 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, FORCE_INLINE_TEMPLATE -size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( +size_t ZSTD_compressBlock_doubleFast_noDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize, - U32 const mls /* template */) + void const* src, size_t srcSize, U32 const mls /* template */) { ZSTD_compressionParameters const* cParams = &ms->cParams; U32* const hashLong = ms->hashTable; @@ -93,7 +92,7 @@ size_t ZSTD_compressBlock_doubleFast_singleSegment_generic( const BYTE* ip = istart; const BYTE* ip1; - DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_singleSegment_generic"); + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic"); /* init */ ip += ((ip - prefixLowest) == 0); @@ -530,13 +529,13 @@ size_t ZSTD_compressBlock_doubleFast( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 4); case 5 : - return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 5); case 6 : - return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 6); case 7 : - return ZSTD_compressBlock_doubleFast_singleSegment_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 7); } } From 051b473e7ebce26f0e2ea7d2ced994f2ec2bfb59 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Sep 2021 16:42:13 -0400 Subject: [PATCH 215/274] Fall Back in _extDict to New _noDict Rather than Old Merged Impl --- lib/compress/zstd_double_fast.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 8a8e8263d..380214c57 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -591,7 +591,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( /* if extDict is invalidated due to maxDistance, switch to "regular" variant */ if (prefixStartIndex == dictStartIndex) - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, mls, ZSTD_noDict); + return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, mls); /* Search Loop */ while (ip < ilimit) { /* < instead of <=, because (ip+1) */ From 62536ef7da6023a1a0d533351b402b5418c4199a Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Sep 2021 17:01:31 -0400 Subject: [PATCH 216/274] Simplify DMS Implementation by Removing noDict Support --- lib/compress/zstd_double_fast.c | 151 +++++++++++--------------------- 1 file changed, 50 insertions(+), 101 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 380214c57..c58e5cd3f 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -254,10 +254,10 @@ _match_stored: FORCE_INLINE_TEMPLATE -size_t ZSTD_compressBlock_doubleFast_generic( +size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, - U32 const mls /* template */, ZSTD_dictMode_e const dictMode) + U32 const mls /* template */) { ZSTD_compressionParameters const* cParams = &ms->cParams; U32* const hashLong = ms->hashTable; @@ -278,54 +278,30 @@ size_t ZSTD_compressBlock_doubleFast_generic( U32 offsetSaved = 0; const ZSTD_matchState_t* const dms = ms->dictMatchState; - const ZSTD_compressionParameters* const dictCParams = - dictMode == ZSTD_dictMatchState ? - &dms->cParams : NULL; - const U32* const dictHashLong = dictMode == ZSTD_dictMatchState ? - dms->hashTable : NULL; - const U32* const dictHashSmall = dictMode == ZSTD_dictMatchState ? - dms->chainTable : NULL; - const U32 dictStartIndex = dictMode == ZSTD_dictMatchState ? - dms->window.dictLimit : 0; - const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ? - dms->window.base : NULL; - const BYTE* const dictStart = dictMode == ZSTD_dictMatchState ? - dictBase + dictStartIndex : NULL; - const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ? - dms->window.nextSrc : NULL; - const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ? - prefixLowestIndex - (U32)(dictEnd - dictBase) : - 0; - const U32 dictHBitsL = dictMode == ZSTD_dictMatchState ? - dictCParams->hashLog : hBitsL; - const U32 dictHBitsS = dictMode == ZSTD_dictMatchState ? - dictCParams->chainLog : hBitsS; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams; + const U32* const dictHashLong = dms->hashTable; + const U32* const dictHashSmall = dms->chainTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase); + const U32 dictHBitsL = dictCParams->hashLog; + const U32 dictHBitsS = dictCParams->chainLog; const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart)); - DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_generic"); - - assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState); + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic"); /* if a dictionary is attached, it must be within window range */ - if (dictMode == ZSTD_dictMatchState) { - assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex); - } + assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex); /* init */ ip += (dictAndPrefixLength == 0); - if (dictMode == ZSTD_noDict) { - U32 const curr = (U32)(ip - base); - U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); - U32 const maxRep = curr - windowLow; - if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0; - if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; - } - if (dictMode == ZSTD_dictMatchState) { - /* dictMatchState repCode checks don't currently handle repCode == 0 - * disabling. */ - assert(offset_1 <= dictAndPrefixLength); - assert(offset_2 <= dictAndPrefixLength); - } + + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); /* Main Search Loop */ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ @@ -341,15 +317,13 @@ size_t ZSTD_compressBlock_doubleFast_generic( const BYTE* matchLong = base + matchIndexL; const BYTE* match = base + matchIndexS; const U32 repIndex = curr + 1 - offset_1; - const BYTE* repMatch = (dictMode == ZSTD_dictMatchState - && repIndex < prefixLowestIndex) ? + const BYTE* repMatch = (repIndex < prefixLowestIndex) ? dictBase + (repIndex - dictIndexDelta) : base + repIndex; hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ - /* check dictMatchState repcode */ - if (dictMode == ZSTD_dictMatchState - && ((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */) + /* check repcode */ + if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */) && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; @@ -358,15 +332,6 @@ size_t ZSTD_compressBlock_doubleFast_generic( goto _match_stored; } - /* check noDict repcode */ - if ( dictMode == ZSTD_noDict - && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) { - mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; - ip++; - ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH); - goto _match_stored; - } - if (matchIndexL > prefixLowestIndex) { /* check prefix long match */ if (MEM_read64(matchLong) == MEM_read64(ip)) { @@ -375,7 +340,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ goto _match_found; } - } else if (dictMode == ZSTD_dictMatchState) { + } else { /* check dictMatchState long match */ U32 const dictMatchIndexL = dictHashLong[dictHL]; const BYTE* dictMatchL = dictBase + dictMatchIndexL; @@ -393,7 +358,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( if (MEM_read32(match) == MEM_read32(ip)) { goto _search_next_long; } - } else if (dictMode == ZSTD_dictMatchState) { + } else { /* check dictMatchState short match */ U32 const dictMatchIndexS = dictHashSmall[dictHS]; match = dictBase + dictMatchIndexS; @@ -426,7 +391,7 @@ _search_next_long: while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ goto _match_found; } - } else if (dictMode == ZSTD_dictMatchState) { + } else { /* check dict long +1 match */ U32 const dictMatchIndexL3 = dictHashLong[dictHLNext]; const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3; @@ -440,7 +405,7 @@ _search_next_long: } } } /* if no long +1 match, explore the short match we found */ - if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) { + if (matchIndexS < prefixLowestIndex) { mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4; offset = (U32)(curr - matchIndexS); while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ @@ -472,43 +437,27 @@ _match_stored: } /* check immediate repcode */ - if (dictMode == ZSTD_dictMatchState) { - while (ip <= ilimit) { - U32 const current2 = (U32)(ip-base); - U32 const repIndex2 = current2 - offset_2; - const BYTE* repMatch2 = dictMode == ZSTD_dictMatchState - && repIndex2 < prefixLowestIndex ? - dictBase + repIndex2 - dictIndexDelta : - base + repIndex2; - if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */) - && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { - const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend; - size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4; - U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ - ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH); - hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; - hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; - ip += repLength2; - anchor = ip; - continue; - } - break; - } } - - if (dictMode == ZSTD_noDict) { - while ( (ip <= ilimit) - && ( (offset_2>0) - & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { - /* store sequence */ - size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; - U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ - hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); - hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); - ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH); - ip += rLength; + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ? + dictBase + repIndex2 - dictIndexDelta : + base + repIndex2; + if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; anchor = ip; - continue; /* faster when present ... (?) */ - } } } + continue; + } + break; + } + } } /* while (ip < ilimit) */ /* save reps for next block */ @@ -549,13 +498,13 @@ size_t ZSTD_compressBlock_doubleFast_dictMatchState( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_dictMatchState); + return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 4); case 5 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_dictMatchState); + return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 5); case 6 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_dictMatchState); + return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 6); case 7 : - return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_dictMatchState); + return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 7); } } From c2c32839dc8cc16ea8a75c2f552018623def8464 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 9 Sep 2021 17:17:46 -0400 Subject: [PATCH 217/274] Update results.csv --- tests/regression/results.csv | 448 +++++++++++++++++------------------ 1 file changed, 224 insertions(+), 224 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 2538728c8..72ac1f27b 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -2,10 +2,10 @@ Data, Config, Method, silesia.tar, level -5, compress simple, 7359401 silesia.tar, level -3, compress simple, 6901672 silesia.tar, level -1, compress simple, 6182241 -silesia.tar, level 0, compress simple, 4861424 +silesia.tar, level 0, compress simple, 4854086 silesia.tar, level 1, compress simple, 5331946 -silesia.tar, level 3, compress simple, 4861424 -silesia.tar, level 4, compress simple, 4799632 +silesia.tar, level 3, compress simple, 4854086 +silesia.tar, level 4, compress simple, 4791503 silesia.tar, level 5, compress simple, 4649987 silesia.tar, level 6, compress simple, 4616797 silesia.tar, level 7, compress simple, 4576661 @@ -13,16 +13,16 @@ silesia.tar, level 9, compress silesia.tar, level 13, compress simple, 4502956 silesia.tar, level 16, compress simple, 4360527 silesia.tar, level 19, compress simple, 4267266 -silesia.tar, uncompressed literals, compress simple, 4861424 +silesia.tar, uncompressed literals, compress simple, 4854086 silesia.tar, uncompressed literals optimal, compress simple, 4267266 silesia.tar, huffman literals, compress simple, 6182241 github.tar, level -5, compress simple, 66914 github.tar, level -3, compress simple, 52127 github.tar, level -1, compress simple, 42560 -github.tar, level 0, compress simple, 38441 +github.tar, level 0, compress simple, 38831 github.tar, level 1, compress simple, 39200 -github.tar, level 3, compress simple, 38441 -github.tar, level 4, compress simple, 38467 +github.tar, level 3, compress simple, 38831 +github.tar, level 4, compress simple, 38893 github.tar, level 5, compress simple, 38366 github.tar, level 6, compress simple, 38648 github.tar, level 7, compress simple, 38110 @@ -30,16 +30,16 @@ github.tar, level 9, compress github.tar, level 13, compress simple, 35501 github.tar, level 16, compress simple, 40471 github.tar, level 19, compress simple, 32134 -github.tar, uncompressed literals, compress simple, 38441 +github.tar, uncompressed literals, compress simple, 38831 github.tar, uncompressed literals optimal, compress simple, 32134 github.tar, huffman literals, compress simple, 42560 silesia, level -5, compress cctx, 7354675 silesia, level -3, compress cctx, 6902374 silesia, level -1, compress cctx, 6177565 -silesia, level 0, compress cctx, 4849553 +silesia, level 0, compress cctx, 4842075 silesia, level 1, compress cctx, 5309098 -silesia, level 3, compress cctx, 4849553 -silesia, level 4, compress cctx, 4786968 +silesia, level 3, compress cctx, 4842075 +silesia, level 4, compress cctx, 4779186 silesia, level 5, compress cctx, 4638691 silesia, level 6, compress cctx, 4605296 silesia, level 7, compress cctx, 4566984 @@ -47,28 +47,28 @@ silesia, level 9, compress silesia, level 13, compress cctx, 4493990 silesia, level 16, compress cctx, 4359864 silesia, level 19, compress cctx, 4296880 -silesia, long distance mode, compress cctx, 4849553 -silesia, multithreaded, compress cctx, 4849553 -silesia, multithreaded long distance mode, compress cctx, 4849553 -silesia, small window log, compress cctx, 7084179 +silesia, long distance mode, compress cctx, 4842075 +silesia, multithreaded, compress cctx, 4842075 +silesia, multithreaded long distance mode, compress cctx, 4842075 +silesia, small window log, compress cctx, 7082951 silesia, small hash log, compress cctx, 6526141 silesia, small chain log, compress cctx, 4912197 silesia, explicit params, compress cctx, 4794052 -silesia, uncompressed literals, compress cctx, 4849553 +silesia, uncompressed literals, compress cctx, 4842075 silesia, uncompressed literals optimal, compress cctx, 4296880 silesia, huffman literals, compress cctx, 6177565 -silesia, multithreaded with advanced params, compress cctx, 4849553 +silesia, multithreaded with advanced params, compress cctx, 4842075 github, level -5, compress cctx, 232315 github, level -5 with dict, compress cctx, 47294 github, level -3, compress cctx, 220760 github, level -3 with dict, compress cctx, 48047 github, level -1, compress cctx, 175468 github, level -1 with dict, compress cctx, 43527 -github, level 0, compress cctx, 136335 +github, level 0, compress cctx, 136332 github, level 0 with dict, compress cctx, 41534 github, level 1, compress cctx, 142365 github, level 1 with dict, compress cctx, 42157 -github, level 3, compress cctx, 136335 +github, level 3, compress cctx, 136332 github, level 3 with dict, compress cctx, 41534 github, level 4, compress cctx, 136199 github, level 4 with dict, compress cctx, 41725 @@ -86,24 +86,24 @@ github, level 16, compress github, level 16 with dict, compress cctx, 37568 github, level 19, compress cctx, 134064 github, level 19 with dict, compress cctx, 37567 -github, long distance mode, compress cctx, 141102 -github, multithreaded, compress cctx, 141102 -github, multithreaded long distance mode, compress cctx, 141102 -github, small window log, compress cctx, 141102 +github, long distance mode, compress cctx, 141069 +github, multithreaded, compress cctx, 141069 +github, multithreaded long distance mode, compress cctx, 141069 +github, small window log, compress cctx, 141069 github, small hash log, compress cctx, 138949 github, small chain log, compress cctx, 139242 github, explicit params, compress cctx, 140932 -github, uncompressed literals, compress cctx, 136335 +github, uncompressed literals, compress cctx, 136332 github, uncompressed literals optimal, compress cctx, 134064 github, huffman literals, compress cctx, 175468 -github, multithreaded with advanced params, compress cctx, 141102 +github, multithreaded with advanced params, compress cctx, 141069 silesia, level -5, zstdcli, 7354723 silesia, level -3, zstdcli, 6902422 silesia, level -1, zstdcli, 6177613 -silesia, level 0, zstdcli, 4849601 +silesia, level 0, zstdcli, 4842123 silesia, level 1, zstdcli, 5309146 -silesia, level 3, zstdcli, 4849601 -silesia, level 4, zstdcli, 4787016 +silesia, level 3, zstdcli, 4842123 +silesia, level 4, zstdcli, 4779234 silesia, level 5, zstdcli, 4638739 silesia, level 6, zstdcli, 4605344 silesia, level 7, zstdcli, 4567032 @@ -111,24 +111,24 @@ silesia, level 9, zstdcli, silesia, level 13, zstdcli, 4494038 silesia, level 16, zstdcli, 4359912 silesia, level 19, zstdcli, 4296928 -silesia, long distance mode, zstdcli, 4840807 -silesia, multithreaded, zstdcli, 4849601 -silesia, multithreaded long distance mode, zstdcli, 4840807 -silesia, small window log, zstdcli, 7095967 +silesia, long distance mode, zstdcli, 4833785 +silesia, multithreaded, zstdcli, 4842123 +silesia, multithreaded long distance mode, zstdcli, 4833785 +silesia, small window log, zstdcli, 7095048 silesia, small hash log, zstdcli, 6526189 silesia, small chain log, zstdcli, 4912245 silesia, explicit params, zstdcli, 4795432 -silesia, uncompressed literals, zstdcli, 5128030 +silesia, uncompressed literals, zstdcli, 5120614 silesia, uncompressed literals optimal, zstdcli, 4319566 silesia, huffman literals, zstdcli, 5326394 -silesia, multithreaded with advanced params, zstdcli, 5128030 +silesia, multithreaded with advanced params, zstdcli, 5120614 silesia.tar, level -5, zstdcli, 7363866 silesia.tar, level -3, zstdcli, 6902158 silesia.tar, level -1, zstdcli, 6182939 -silesia.tar, level 0, zstdcli, 4861512 +silesia.tar, level 0, zstdcli, 4854164 silesia.tar, level 1, zstdcli, 5333183 -silesia.tar, level 3, zstdcli, 4861512 -silesia.tar, level 4, zstdcli, 4800528 +silesia.tar, level 3, zstdcli, 4854164 +silesia.tar, level 4, zstdcli, 4792352 silesia.tar, level 5, zstdcli, 4650946 silesia.tar, level 6, zstdcli, 4618390 silesia.tar, level 7, zstdcli, 4578719 @@ -136,29 +136,29 @@ silesia.tar, level 9, zstdcli, silesia.tar, level 13, zstdcli, 4502960 silesia.tar, level 16, zstdcli, 4360531 silesia.tar, level 19, zstdcli, 4267270 -silesia.tar, no source size, zstdcli, 4861508 -silesia.tar, long distance mode, zstdcli, 4853225 -silesia.tar, multithreaded, zstdcli, 4861512 -silesia.tar, multithreaded long distance mode, zstdcli, 4853225 -silesia.tar, small window log, zstdcli, 7101576 +silesia.tar, no source size, zstdcli, 4854160 +silesia.tar, long distance mode, zstdcli, 4845745 +silesia.tar, multithreaded, zstdcli, 4854164 +silesia.tar, multithreaded long distance mode, zstdcli, 4845745 +silesia.tar, small window log, zstdcli, 7100701 silesia.tar, small hash log, zstdcli, 6529289 silesia.tar, small chain log, zstdcli, 4917022 silesia.tar, explicit params, zstdcli, 4820713 -silesia.tar, uncompressed literals, zstdcli, 5129559 +silesia.tar, uncompressed literals, zstdcli, 5122571 silesia.tar, uncompressed literals optimal, zstdcli, 4310145 silesia.tar, huffman literals, zstdcli, 5344915 -silesia.tar, multithreaded with advanced params, zstdcli, 5129559 +silesia.tar, multithreaded with advanced params, zstdcli, 5122571 github, level -5, zstdcli, 234315 github, level -5 with dict, zstdcli, 48718 github, level -3, zstdcli, 222760 github, level -3 with dict, zstdcli, 47395 github, level -1, zstdcli, 177468 github, level -1 with dict, zstdcli, 45170 -github, level 0, zstdcli, 138335 +github, level 0, zstdcli, 138332 github, level 0 with dict, zstdcli, 43148 github, level 1, zstdcli, 144365 github, level 1 with dict, zstdcli, 43682 -github, level 3, zstdcli, 138335 +github, level 3, zstdcli, 138332 github, level 3 with dict, zstdcli, 43148 github, level 4, zstdcli, 138199 github, level 4 with dict, zstdcli, 43251 @@ -176,30 +176,30 @@ github, level 16, zstdcli, github, level 16 with dict, zstdcli, 39577 github, level 19, zstdcli, 136064 github, level 19 with dict, zstdcli, 39576 -github, long distance mode, zstdcli, 138335 -github, multithreaded, zstdcli, 138335 -github, multithreaded long distance mode, zstdcli, 138335 -github, small window log, zstdcli, 138335 +github, long distance mode, zstdcli, 138332 +github, multithreaded, zstdcli, 138332 +github, multithreaded long distance mode, zstdcli, 138332 +github, small window log, zstdcli, 138332 github, small hash log, zstdcli, 137590 github, small chain log, zstdcli, 138341 github, explicit params, zstdcli, 136197 -github, uncompressed literals, zstdcli, 167915 +github, uncompressed literals, zstdcli, 167911 github, uncompressed literals optimal, zstdcli, 159227 github, huffman literals, zstdcli, 144365 -github, multithreaded with advanced params, zstdcli, 167915 +github, multithreaded with advanced params, zstdcli, 167911 github.tar, level -5, zstdcli, 66918 github.tar, level -5 with dict, zstdcli, 51529 github.tar, level -3, zstdcli, 52131 github.tar, level -3 with dict, zstdcli, 44246 github.tar, level -1, zstdcli, 42564 github.tar, level -1 with dict, zstdcli, 41140 -github.tar, level 0, zstdcli, 38445 +github.tar, level 0, zstdcli, 38835 github.tar, level 0 with dict, zstdcli, 37999 github.tar, level 1, zstdcli, 39204 github.tar, level 1 with dict, zstdcli, 38288 -github.tar, level 3, zstdcli, 38445 +github.tar, level 3, zstdcli, 38835 github.tar, level 3 with dict, zstdcli, 37999 -github.tar, level 4, zstdcli, 38471 +github.tar, level 4, zstdcli, 38897 github.tar, level 4 with dict, zstdcli, 37952 github.tar, level 5, zstdcli, 38370 github.tar, level 5 with dict, zstdcli, 39071 @@ -215,26 +215,26 @@ github.tar, level 16, zstdcli, github.tar, level 16 with dict, zstdcli, 33382 github.tar, level 19, zstdcli, 32138 github.tar, level 19 with dict, zstdcli, 32713 -github.tar, no source size, zstdcli, 38442 +github.tar, no source size, zstdcli, 38832 github.tar, no source size with dict, zstdcli, 38004 -github.tar, long distance mode, zstdcli, 39730 -github.tar, multithreaded, zstdcli, 38445 -github.tar, multithreaded long distance mode, zstdcli, 39730 +github.tar, long distance mode, zstdcli, 40236 +github.tar, multithreaded, zstdcli, 38835 +github.tar, multithreaded long distance mode, zstdcli, 40236 github.tar, small window log, zstdcli, 198544 github.tar, small hash log, zstdcli, 129874 github.tar, small chain log, zstdcli, 41673 github.tar, explicit params, zstdcli, 41385 -github.tar, uncompressed literals, zstdcli, 41126 +github.tar, uncompressed literals, zstdcli, 41529 github.tar, uncompressed literals optimal, zstdcli, 35401 github.tar, huffman literals, zstdcli, 38857 -github.tar, multithreaded with advanced params, zstdcli, 41126 +github.tar, multithreaded with advanced params, zstdcli, 41529 silesia, level -5, advanced one pass, 7354675 silesia, level -3, advanced one pass, 6902374 silesia, level -1, advanced one pass, 6177565 -silesia, level 0, advanced one pass, 4849553 +silesia, level 0, advanced one pass, 4842075 silesia, level 1, advanced one pass, 5309098 -silesia, level 3, advanced one pass, 4849553 -silesia, level 4, advanced one pass, 4786968 +silesia, level 3, advanced one pass, 4842075 +silesia, level 4, advanced one pass, 4779186 silesia, level 5 row 1, advanced one pass, 4638691 silesia, level 5 row 2, advanced one pass, 4640752 silesia, level 5, advanced one pass, 4638691 @@ -250,25 +250,25 @@ silesia, level 12 row 2, advanced silesia, level 13, advanced one pass, 4493990 silesia, level 16, advanced one pass, 4359864 silesia, level 19, advanced one pass, 4296880 -silesia, no source size, advanced one pass, 4849553 -silesia, long distance mode, advanced one pass, 4840737 -silesia, multithreaded, advanced one pass, 4849553 -silesia, multithreaded long distance mode, advanced one pass, 4840759 -silesia, small window log, advanced one pass, 7095919 +silesia, no source size, advanced one pass, 4842075 +silesia, long distance mode, advanced one pass, 4833710 +silesia, multithreaded, advanced one pass, 4842075 +silesia, multithreaded long distance mode, advanced one pass, 4833737 +silesia, small window log, advanced one pass, 7095000 silesia, small hash log, advanced one pass, 6526141 silesia, small chain log, advanced one pass, 4912197 silesia, explicit params, advanced one pass, 4795432 -silesia, uncompressed literals, advanced one pass, 5127982 +silesia, uncompressed literals, advanced one pass, 5120566 silesia, uncompressed literals optimal, advanced one pass, 4319518 silesia, huffman literals, advanced one pass, 5326346 -silesia, multithreaded with advanced params, advanced one pass, 5127982 +silesia, multithreaded with advanced params, advanced one pass, 5120566 silesia.tar, level -5, advanced one pass, 7359401 silesia.tar, level -3, advanced one pass, 6901672 silesia.tar, level -1, advanced one pass, 6182241 -silesia.tar, level 0, advanced one pass, 4861424 +silesia.tar, level 0, advanced one pass, 4854086 silesia.tar, level 1, advanced one pass, 5331946 -silesia.tar, level 3, advanced one pass, 4861424 -silesia.tar, level 4, advanced one pass, 4799632 +silesia.tar, level 3, advanced one pass, 4854086 +silesia.tar, level 4, advanced one pass, 4791503 silesia.tar, level 5 row 1, advanced one pass, 4649987 silesia.tar, level 5 row 2, advanced one pass, 4652862 silesia.tar, level 5, advanced one pass, 4649987 @@ -284,25 +284,25 @@ silesia.tar, level 12 row 2, advanced silesia.tar, level 13, advanced one pass, 4502956 silesia.tar, level 16, advanced one pass, 4360527 silesia.tar, level 19, advanced one pass, 4267266 -silesia.tar, no source size, advanced one pass, 4861424 -silesia.tar, long distance mode, advanced one pass, 4847752 -silesia.tar, multithreaded, advanced one pass, 4861508 -silesia.tar, multithreaded long distance mode, advanced one pass, 4853221 -silesia.tar, small window log, advanced one pass, 7101530 +silesia.tar, no source size, advanced one pass, 4854086 +silesia.tar, long distance mode, advanced one pass, 4840452 +silesia.tar, multithreaded, advanced one pass, 4854160 +silesia.tar, multithreaded long distance mode, advanced one pass, 4845741 +silesia.tar, small window log, advanced one pass, 7100655 silesia.tar, small hash log, advanced one pass, 6529231 silesia.tar, small chain log, advanced one pass, 4917041 silesia.tar, explicit params, advanced one pass, 4806855 -silesia.tar, uncompressed literals, advanced one pass, 5129458 +silesia.tar, uncompressed literals, advanced one pass, 5122473 silesia.tar, uncompressed literals optimal, advanced one pass, 4310141 silesia.tar, huffman literals, advanced one pass, 5344545 -silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 +silesia.tar, multithreaded with advanced params, advanced one pass, 5122567 github, level -5, advanced one pass, 232315 github, level -5 with dict, advanced one pass, 46718 github, level -3, advanced one pass, 220760 github, level -3 with dict, advanced one pass, 45395 github, level -1, advanced one pass, 175468 github, level -1 with dict, advanced one pass, 43170 -github, level 0, advanced one pass, 136335 +github, level 0, advanced one pass, 136332 github, level 0 with dict, advanced one pass, 41148 github, level 0 with dict dms, advanced one pass, 41148 github, level 0 with dict dds, advanced one pass, 41148 @@ -314,7 +314,7 @@ github, level 1 with dict dms, advanced github, level 1 with dict dds, advanced one pass, 41682 github, level 1 with dict copy, advanced one pass, 41674 github, level 1 with dict load, advanced one pass, 43755 -github, level 3, advanced one pass, 136335 +github, level 3, advanced one pass, 136332 github, level 3 with dict, advanced one pass, 41148 github, level 3 with dict dms, advanced one pass, 41148 github, level 3 with dict dds, advanced one pass, 41148 @@ -408,26 +408,26 @@ github, level 19 with dict dms, advanced github, level 19 with dict dds, advanced one pass, 37576 github, level 19 with dict copy, advanced one pass, 37567 github, level 19 with dict load, advanced one pass, 39613 -github, no source size, advanced one pass, 136335 +github, no source size, advanced one pass, 136332 github, no source size with dict, advanced one pass, 41148 -github, long distance mode, advanced one pass, 136335 -github, multithreaded, advanced one pass, 136335 -github, multithreaded long distance mode, advanced one pass, 136335 -github, small window log, advanced one pass, 136335 +github, long distance mode, advanced one pass, 136332 +github, multithreaded, advanced one pass, 136332 +github, multithreaded long distance mode, advanced one pass, 136332 +github, small window log, advanced one pass, 136332 github, small hash log, advanced one pass, 135590 github, small chain log, advanced one pass, 136341 github, explicit params, advanced one pass, 137727 -github, uncompressed literals, advanced one pass, 165915 +github, uncompressed literals, advanced one pass, 165911 github, uncompressed literals optimal, advanced one pass, 157227 github, huffman literals, advanced one pass, 142365 -github, multithreaded with advanced params, advanced one pass, 165915 +github, multithreaded with advanced params, advanced one pass, 165911 github.tar, level -5, advanced one pass, 66914 github.tar, level -5 with dict, advanced one pass, 51525 github.tar, level -3, advanced one pass, 52127 github.tar, level -3 with dict, advanced one pass, 44242 github.tar, level -1, advanced one pass, 42560 github.tar, level -1 with dict, advanced one pass, 41136 -github.tar, level 0, advanced one pass, 38441 +github.tar, level 0, advanced one pass, 38831 github.tar, level 0 with dict, advanced one pass, 37995 github.tar, level 0 with dict dms, advanced one pass, 38003 github.tar, level 0 with dict dds, advanced one pass, 38003 @@ -439,13 +439,13 @@ github.tar, level 1 with dict dms, advanced github.tar, level 1 with dict dds, advanced one pass, 38294 github.tar, level 1 with dict copy, advanced one pass, 38284 github.tar, level 1 with dict load, advanced one pass, 38724 -github.tar, level 3, advanced one pass, 38441 +github.tar, level 3, advanced one pass, 38831 github.tar, level 3 with dict, advanced one pass, 37995 github.tar, level 3 with dict dms, advanced one pass, 38003 github.tar, level 3 with dict dds, advanced one pass, 38003 github.tar, level 3 with dict copy, advanced one pass, 37995 github.tar, level 3 with dict load, advanced one pass, 37956 -github.tar, level 4, advanced one pass, 38467 +github.tar, level 4, advanced one pass, 38893 github.tar, level 4 with dict, advanced one pass, 37948 github.tar, level 4 with dict dms, advanced one pass, 37954 github.tar, level 4 with dict dds, advanced one pass, 37954 @@ -533,26 +533,26 @@ github.tar, level 19 with dict dms, advanced github.tar, level 19 with dict dds, advanced one pass, 32553 github.tar, level 19 with dict copy, advanced one pass, 32709 github.tar, level 19 with dict load, advanced one pass, 32474 -github.tar, no source size, advanced one pass, 38441 +github.tar, no source size, advanced one pass, 38831 github.tar, no source size with dict, advanced one pass, 37995 -github.tar, long distance mode, advanced one pass, 39757 -github.tar, multithreaded, advanced one pass, 38441 -github.tar, multithreaded long distance mode, advanced one pass, 39726 +github.tar, long distance mode, advanced one pass, 40252 +github.tar, multithreaded, advanced one pass, 38831 +github.tar, multithreaded long distance mode, advanced one pass, 40232 github.tar, small window log, advanced one pass, 198540 github.tar, small hash log, advanced one pass, 129870 github.tar, small chain log, advanced one pass, 41669 github.tar, explicit params, advanced one pass, 41385 -github.tar, uncompressed literals, advanced one pass, 41122 +github.tar, uncompressed literals, advanced one pass, 41525 github.tar, uncompressed literals optimal, advanced one pass, 35397 github.tar, huffman literals, advanced one pass, 38853 -github.tar, multithreaded with advanced params, advanced one pass, 41122 +github.tar, multithreaded with advanced params, advanced one pass, 41525 silesia, level -5, advanced one pass small out, 7354675 silesia, level -3, advanced one pass small out, 6902374 silesia, level -1, advanced one pass small out, 6177565 -silesia, level 0, advanced one pass small out, 4849553 +silesia, level 0, advanced one pass small out, 4842075 silesia, level 1, advanced one pass small out, 5309098 -silesia, level 3, advanced one pass small out, 4849553 -silesia, level 4, advanced one pass small out, 4786968 +silesia, level 3, advanced one pass small out, 4842075 +silesia, level 4, advanced one pass small out, 4779186 silesia, level 5 row 1, advanced one pass small out, 4638691 silesia, level 5 row 2, advanced one pass small out, 4640752 silesia, level 5, advanced one pass small out, 4638691 @@ -568,25 +568,25 @@ silesia, level 12 row 2, advanced silesia, level 13, advanced one pass small out, 4493990 silesia, level 16, advanced one pass small out, 4359864 silesia, level 19, advanced one pass small out, 4296880 -silesia, no source size, advanced one pass small out, 4849553 -silesia, long distance mode, advanced one pass small out, 4840737 -silesia, multithreaded, advanced one pass small out, 4849553 -silesia, multithreaded long distance mode, advanced one pass small out, 4840759 -silesia, small window log, advanced one pass small out, 7095919 +silesia, no source size, advanced one pass small out, 4842075 +silesia, long distance mode, advanced one pass small out, 4833710 +silesia, multithreaded, advanced one pass small out, 4842075 +silesia, multithreaded long distance mode, advanced one pass small out, 4833737 +silesia, small window log, advanced one pass small out, 7095000 silesia, small hash log, advanced one pass small out, 6526141 silesia, small chain log, advanced one pass small out, 4912197 silesia, explicit params, advanced one pass small out, 4795432 -silesia, uncompressed literals, advanced one pass small out, 5127982 +silesia, uncompressed literals, advanced one pass small out, 5120566 silesia, uncompressed literals optimal, advanced one pass small out, 4319518 silesia, huffman literals, advanced one pass small out, 5326346 -silesia, multithreaded with advanced params, advanced one pass small out, 5127982 +silesia, multithreaded with advanced params, advanced one pass small out, 5120566 silesia.tar, level -5, advanced one pass small out, 7359401 silesia.tar, level -3, advanced one pass small out, 6901672 silesia.tar, level -1, advanced one pass small out, 6182241 -silesia.tar, level 0, advanced one pass small out, 4861424 +silesia.tar, level 0, advanced one pass small out, 4854086 silesia.tar, level 1, advanced one pass small out, 5331946 -silesia.tar, level 3, advanced one pass small out, 4861424 -silesia.tar, level 4, advanced one pass small out, 4799632 +silesia.tar, level 3, advanced one pass small out, 4854086 +silesia.tar, level 4, advanced one pass small out, 4791503 silesia.tar, level 5 row 1, advanced one pass small out, 4649987 silesia.tar, level 5 row 2, advanced one pass small out, 4652862 silesia.tar, level 5, advanced one pass small out, 4649987 @@ -602,25 +602,25 @@ silesia.tar, level 12 row 2, advanced silesia.tar, level 13, advanced one pass small out, 4502956 silesia.tar, level 16, advanced one pass small out, 4360527 silesia.tar, level 19, advanced one pass small out, 4267266 -silesia.tar, no source size, advanced one pass small out, 4861424 -silesia.tar, long distance mode, advanced one pass small out, 4847752 -silesia.tar, multithreaded, advanced one pass small out, 4861508 -silesia.tar, multithreaded long distance mode, advanced one pass small out, 4853221 -silesia.tar, small window log, advanced one pass small out, 7101530 +silesia.tar, no source size, advanced one pass small out, 4854086 +silesia.tar, long distance mode, advanced one pass small out, 4840452 +silesia.tar, multithreaded, advanced one pass small out, 4854160 +silesia.tar, multithreaded long distance mode, advanced one pass small out, 4845741 +silesia.tar, small window log, advanced one pass small out, 7100655 silesia.tar, small hash log, advanced one pass small out, 6529231 silesia.tar, small chain log, advanced one pass small out, 4917041 silesia.tar, explicit params, advanced one pass small out, 4806855 -silesia.tar, uncompressed literals, advanced one pass small out, 5129458 +silesia.tar, uncompressed literals, advanced one pass small out, 5122473 silesia.tar, uncompressed literals optimal, advanced one pass small out, 4310141 silesia.tar, huffman literals, advanced one pass small out, 5344545 -silesia.tar, multithreaded with advanced params, advanced one pass small out, 5129555 +silesia.tar, multithreaded with advanced params, advanced one pass small out, 5122567 github, level -5, advanced one pass small out, 232315 github, level -5 with dict, advanced one pass small out, 46718 github, level -3, advanced one pass small out, 220760 github, level -3 with dict, advanced one pass small out, 45395 github, level -1, advanced one pass small out, 175468 github, level -1 with dict, advanced one pass small out, 43170 -github, level 0, advanced one pass small out, 136335 +github, level 0, advanced one pass small out, 136332 github, level 0 with dict, advanced one pass small out, 41148 github, level 0 with dict dms, advanced one pass small out, 41148 github, level 0 with dict dds, advanced one pass small out, 41148 @@ -632,7 +632,7 @@ github, level 1 with dict dms, advanced github, level 1 with dict dds, advanced one pass small out, 41682 github, level 1 with dict copy, advanced one pass small out, 41674 github, level 1 with dict load, advanced one pass small out, 43755 -github, level 3, advanced one pass small out, 136335 +github, level 3, advanced one pass small out, 136332 github, level 3 with dict, advanced one pass small out, 41148 github, level 3 with dict dms, advanced one pass small out, 41148 github, level 3 with dict dds, advanced one pass small out, 41148 @@ -726,26 +726,26 @@ github, level 19 with dict dms, advanced github, level 19 with dict dds, advanced one pass small out, 37576 github, level 19 with dict copy, advanced one pass small out, 37567 github, level 19 with dict load, advanced one pass small out, 39613 -github, no source size, advanced one pass small out, 136335 +github, no source size, advanced one pass small out, 136332 github, no source size with dict, advanced one pass small out, 41148 -github, long distance mode, advanced one pass small out, 136335 -github, multithreaded, advanced one pass small out, 136335 -github, multithreaded long distance mode, advanced one pass small out, 136335 -github, small window log, advanced one pass small out, 136335 +github, long distance mode, advanced one pass small out, 136332 +github, multithreaded, advanced one pass small out, 136332 +github, multithreaded long distance mode, advanced one pass small out, 136332 +github, small window log, advanced one pass small out, 136332 github, small hash log, advanced one pass small out, 135590 github, small chain log, advanced one pass small out, 136341 github, explicit params, advanced one pass small out, 137727 -github, uncompressed literals, advanced one pass small out, 165915 +github, uncompressed literals, advanced one pass small out, 165911 github, uncompressed literals optimal, advanced one pass small out, 157227 github, huffman literals, advanced one pass small out, 142365 -github, multithreaded with advanced params, advanced one pass small out, 165915 +github, multithreaded with advanced params, advanced one pass small out, 165911 github.tar, level -5, advanced one pass small out, 66914 github.tar, level -5 with dict, advanced one pass small out, 51525 github.tar, level -3, advanced one pass small out, 52127 github.tar, level -3 with dict, advanced one pass small out, 44242 github.tar, level -1, advanced one pass small out, 42560 github.tar, level -1 with dict, advanced one pass small out, 41136 -github.tar, level 0, advanced one pass small out, 38441 +github.tar, level 0, advanced one pass small out, 38831 github.tar, level 0 with dict, advanced one pass small out, 37995 github.tar, level 0 with dict dms, advanced one pass small out, 38003 github.tar, level 0 with dict dds, advanced one pass small out, 38003 @@ -757,13 +757,13 @@ github.tar, level 1 with dict dms, advanced github.tar, level 1 with dict dds, advanced one pass small out, 38294 github.tar, level 1 with dict copy, advanced one pass small out, 38284 github.tar, level 1 with dict load, advanced one pass small out, 38724 -github.tar, level 3, advanced one pass small out, 38441 +github.tar, level 3, advanced one pass small out, 38831 github.tar, level 3 with dict, advanced one pass small out, 37995 github.tar, level 3 with dict dms, advanced one pass small out, 38003 github.tar, level 3 with dict dds, advanced one pass small out, 38003 github.tar, level 3 with dict copy, advanced one pass small out, 37995 github.tar, level 3 with dict load, advanced one pass small out, 37956 -github.tar, level 4, advanced one pass small out, 38467 +github.tar, level 4, advanced one pass small out, 38893 github.tar, level 4 with dict, advanced one pass small out, 37948 github.tar, level 4 with dict dms, advanced one pass small out, 37954 github.tar, level 4 with dict dds, advanced one pass small out, 37954 @@ -851,26 +851,26 @@ github.tar, level 19 with dict dms, advanced github.tar, level 19 with dict dds, advanced one pass small out, 32553 github.tar, level 19 with dict copy, advanced one pass small out, 32709 github.tar, level 19 with dict load, advanced one pass small out, 32474 -github.tar, no source size, advanced one pass small out, 38441 +github.tar, no source size, advanced one pass small out, 38831 github.tar, no source size with dict, advanced one pass small out, 37995 -github.tar, long distance mode, advanced one pass small out, 39757 -github.tar, multithreaded, advanced one pass small out, 38441 -github.tar, multithreaded long distance mode, advanced one pass small out, 39726 +github.tar, long distance mode, advanced one pass small out, 40252 +github.tar, multithreaded, advanced one pass small out, 38831 +github.tar, multithreaded long distance mode, advanced one pass small out, 40232 github.tar, small window log, advanced one pass small out, 198540 github.tar, small hash log, advanced one pass small out, 129870 github.tar, small chain log, advanced one pass small out, 41669 github.tar, explicit params, advanced one pass small out, 41385 -github.tar, uncompressed literals, advanced one pass small out, 41122 +github.tar, uncompressed literals, advanced one pass small out, 41525 github.tar, uncompressed literals optimal, advanced one pass small out, 35397 github.tar, huffman literals, advanced one pass small out, 38853 -github.tar, multithreaded with advanced params, advanced one pass small out, 41122 +github.tar, multithreaded with advanced params, advanced one pass small out, 41525 silesia, level -5, advanced streaming, 7292053 silesia, level -3, advanced streaming, 6867875 silesia, level -1, advanced streaming, 6183923 -silesia, level 0, advanced streaming, 4849553 +silesia, level 0, advanced streaming, 4842075 silesia, level 1, advanced streaming, 5312694 -silesia, level 3, advanced streaming, 4849553 -silesia, level 4, advanced streaming, 4786968 +silesia, level 3, advanced streaming, 4842075 +silesia, level 4, advanced streaming, 4779186 silesia, level 5 row 1, advanced streaming, 4638691 silesia, level 5 row 2, advanced streaming, 4640752 silesia, level 5, advanced streaming, 4638691 @@ -886,25 +886,25 @@ silesia, level 12 row 2, advanced silesia, level 13, advanced streaming, 4493990 silesia, level 16, advanced streaming, 4359864 silesia, level 19, advanced streaming, 4296880 -silesia, no source size, advanced streaming, 4849517 -silesia, long distance mode, advanced streaming, 4840737 -silesia, multithreaded, advanced streaming, 4849553 -silesia, multithreaded long distance mode, advanced streaming, 4840759 -silesia, small window log, advanced streaming, 7112062 +silesia, no source size, advanced streaming, 4842039 +silesia, long distance mode, advanced streaming, 4833710 +silesia, multithreaded, advanced streaming, 4842075 +silesia, multithreaded long distance mode, advanced streaming, 4833737 +silesia, small window log, advanced streaming, 7111103 silesia, small hash log, advanced streaming, 6526141 silesia, small chain log, advanced streaming, 4912197 silesia, explicit params, advanced streaming, 4795452 -silesia, uncompressed literals, advanced streaming, 5127982 +silesia, uncompressed literals, advanced streaming, 5120566 silesia, uncompressed literals optimal, advanced streaming, 4319518 silesia, huffman literals, advanced streaming, 5332234 -silesia, multithreaded with advanced params, advanced streaming, 5127982 +silesia, multithreaded with advanced params, advanced streaming, 5120566 silesia.tar, level -5, advanced streaming, 7260007 silesia.tar, level -3, advanced streaming, 6845151 silesia.tar, level -1, advanced streaming, 6187938 -silesia.tar, level 0, advanced streaming, 4861426 +silesia.tar, level 0, advanced streaming, 4859271 silesia.tar, level 1, advanced streaming, 5334890 -silesia.tar, level 3, advanced streaming, 4861426 -silesia.tar, level 4, advanced streaming, 4799632 +silesia.tar, level 3, advanced streaming, 4859271 +silesia.tar, level 4, advanced streaming, 4797470 silesia.tar, level 5 row 1, advanced streaming, 4649992 silesia.tar, level 5 row 2, advanced streaming, 4652866 silesia.tar, level 5, advanced streaming, 4649992 @@ -920,25 +920,25 @@ silesia.tar, level 12 row 2, advanced silesia.tar, level 13, advanced streaming, 4502956 silesia.tar, level 16, advanced streaming, 4360527 silesia.tar, level 19, advanced streaming, 4267266 -silesia.tar, no source size, advanced streaming, 4861422 -silesia.tar, long distance mode, advanced streaming, 4847752 -silesia.tar, multithreaded, advanced streaming, 4861508 -silesia.tar, multithreaded long distance mode, advanced streaming, 4853221 -silesia.tar, small window log, advanced streaming, 7118769 +silesia.tar, no source size, advanced streaming, 4859267 +silesia.tar, long distance mode, advanced streaming, 4840452 +silesia.tar, multithreaded, advanced streaming, 4854160 +silesia.tar, multithreaded long distance mode, advanced streaming, 4845741 +silesia.tar, small window log, advanced streaming, 7117559 silesia.tar, small hash log, advanced streaming, 6529234 silesia.tar, small chain log, advanced streaming, 4917021 silesia.tar, explicit params, advanced streaming, 4806873 -silesia.tar, uncompressed literals, advanced streaming, 5129461 +silesia.tar, uncompressed literals, advanced streaming, 5127423 silesia.tar, uncompressed literals optimal, advanced streaming, 4310141 silesia.tar, huffman literals, advanced streaming, 5350519 -silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 +silesia.tar, multithreaded with advanced params, advanced streaming, 5122567 github, level -5, advanced streaming, 232315 github, level -5 with dict, advanced streaming, 46718 github, level -3, advanced streaming, 220760 github, level -3 with dict, advanced streaming, 45395 github, level -1, advanced streaming, 175468 github, level -1 with dict, advanced streaming, 43170 -github, level 0, advanced streaming, 136335 +github, level 0, advanced streaming, 136332 github, level 0 with dict, advanced streaming, 41148 github, level 0 with dict dms, advanced streaming, 41148 github, level 0 with dict dds, advanced streaming, 41148 @@ -950,7 +950,7 @@ github, level 1 with dict dms, advanced github, level 1 with dict dds, advanced streaming, 41682 github, level 1 with dict copy, advanced streaming, 41674 github, level 1 with dict load, advanced streaming, 43755 -github, level 3, advanced streaming, 136335 +github, level 3, advanced streaming, 136332 github, level 3 with dict, advanced streaming, 41148 github, level 3 with dict dms, advanced streaming, 41148 github, level 3 with dict dds, advanced streaming, 41148 @@ -1044,26 +1044,26 @@ github, level 19 with dict dms, advanced github, level 19 with dict dds, advanced streaming, 37576 github, level 19 with dict copy, advanced streaming, 37567 github, level 19 with dict load, advanced streaming, 39613 -github, no source size, advanced streaming, 136335 +github, no source size, advanced streaming, 136332 github, no source size with dict, advanced streaming, 41148 -github, long distance mode, advanced streaming, 136335 -github, multithreaded, advanced streaming, 136335 -github, multithreaded long distance mode, advanced streaming, 136335 -github, small window log, advanced streaming, 136335 +github, long distance mode, advanced streaming, 136332 +github, multithreaded, advanced streaming, 136332 +github, multithreaded long distance mode, advanced streaming, 136332 +github, small window log, advanced streaming, 136332 github, small hash log, advanced streaming, 135590 github, small chain log, advanced streaming, 136341 github, explicit params, advanced streaming, 137727 -github, uncompressed literals, advanced streaming, 165915 +github, uncompressed literals, advanced streaming, 165911 github, uncompressed literals optimal, advanced streaming, 157227 github, huffman literals, advanced streaming, 142365 -github, multithreaded with advanced params, advanced streaming, 165915 +github, multithreaded with advanced params, advanced streaming, 165911 github.tar, level -5, advanced streaming, 64132 github.tar, level -5 with dict, advanced streaming, 48642 github.tar, level -3, advanced streaming, 50964 github.tar, level -3 with dict, advanced streaming, 42750 github.tar, level -1, advanced streaming, 42536 github.tar, level -1 with dict, advanced streaming, 41198 -github.tar, level 0, advanced streaming, 38441 +github.tar, level 0, advanced streaming, 38831 github.tar, level 0 with dict, advanced streaming, 37995 github.tar, level 0 with dict dms, advanced streaming, 38003 github.tar, level 0 with dict dds, advanced streaming, 38003 @@ -1075,13 +1075,13 @@ github.tar, level 1 with dict dms, advanced github.tar, level 1 with dict dds, advanced streaming, 38326 github.tar, level 1 with dict copy, advanced streaming, 38316 github.tar, level 1 with dict load, advanced streaming, 38761 -github.tar, level 3, advanced streaming, 38441 +github.tar, level 3, advanced streaming, 38831 github.tar, level 3 with dict, advanced streaming, 37995 github.tar, level 3 with dict dms, advanced streaming, 38003 github.tar, level 3 with dict dds, advanced streaming, 38003 github.tar, level 3 with dict copy, advanced streaming, 37995 github.tar, level 3 with dict load, advanced streaming, 37956 -github.tar, level 4, advanced streaming, 38467 +github.tar, level 4, advanced streaming, 38893 github.tar, level 4 with dict, advanced streaming, 37948 github.tar, level 4 with dict dms, advanced streaming, 37954 github.tar, level 4 with dict dds, advanced streaming, 37954 @@ -1169,26 +1169,26 @@ github.tar, level 19 with dict dms, advanced github.tar, level 19 with dict dds, advanced streaming, 32553 github.tar, level 19 with dict copy, advanced streaming, 32709 github.tar, level 19 with dict load, advanced streaming, 32474 -github.tar, no source size, advanced streaming, 38438 +github.tar, no source size, advanced streaming, 38828 github.tar, no source size with dict, advanced streaming, 38000 -github.tar, long distance mode, advanced streaming, 39757 -github.tar, multithreaded, advanced streaming, 38441 -github.tar, multithreaded long distance mode, advanced streaming, 39726 +github.tar, long distance mode, advanced streaming, 40252 +github.tar, multithreaded, advanced streaming, 38831 +github.tar, multithreaded long distance mode, advanced streaming, 40232 github.tar, small window log, advanced streaming, 199558 github.tar, small hash log, advanced streaming, 129870 github.tar, small chain log, advanced streaming, 41669 github.tar, explicit params, advanced streaming, 41385 -github.tar, uncompressed literals, advanced streaming, 41122 +github.tar, uncompressed literals, advanced streaming, 41525 github.tar, uncompressed literals optimal, advanced streaming, 35397 github.tar, huffman literals, advanced streaming, 38874 -github.tar, multithreaded with advanced params, advanced streaming, 41122 +github.tar, multithreaded with advanced params, advanced streaming, 41525 silesia, level -5, old streaming, 7292053 silesia, level -3, old streaming, 6867875 silesia, level -1, old streaming, 6183923 -silesia, level 0, old streaming, 4849553 +silesia, level 0, old streaming, 4842075 silesia, level 1, old streaming, 5312694 -silesia, level 3, old streaming, 4849553 -silesia, level 4, old streaming, 4786968 +silesia, level 3, old streaming, 4842075 +silesia, level 4, old streaming, 4779186 silesia, level 5, old streaming, 4638691 silesia, level 6, old streaming, 4605296 silesia, level 7, old streaming, 4566984 @@ -1196,17 +1196,17 @@ silesia, level 9, old stre silesia, level 13, old streaming, 4493990 silesia, level 16, old streaming, 4359864 silesia, level 19, old streaming, 4296880 -silesia, no source size, old streaming, 4849517 -silesia, uncompressed literals, old streaming, 4849553 +silesia, no source size, old streaming, 4842039 +silesia, uncompressed literals, old streaming, 4842075 silesia, uncompressed literals optimal, old streaming, 4296880 silesia, huffman literals, old streaming, 6183923 silesia.tar, level -5, old streaming, 7260007 silesia.tar, level -3, old streaming, 6845151 silesia.tar, level -1, old streaming, 6187938 -silesia.tar, level 0, old streaming, 4861426 +silesia.tar, level 0, old streaming, 4859271 silesia.tar, level 1, old streaming, 5334890 -silesia.tar, level 3, old streaming, 4861426 -silesia.tar, level 4, old streaming, 4799632 +silesia.tar, level 3, old streaming, 4859271 +silesia.tar, level 4, old streaming, 4797470 silesia.tar, level 5, old streaming, 4649992 silesia.tar, level 6, old streaming, 4616803 silesia.tar, level 7, old streaming, 4576664 @@ -1214,8 +1214,8 @@ silesia.tar, level 9, old stre silesia.tar, level 13, old streaming, 4502956 silesia.tar, level 16, old streaming, 4360527 silesia.tar, level 19, old streaming, 4267266 -silesia.tar, no source size, old streaming, 4861422 -silesia.tar, uncompressed literals, old streaming, 4861426 +silesia.tar, no source size, old streaming, 4859267 +silesia.tar, uncompressed literals, old streaming, 4859271 silesia.tar, uncompressed literals optimal, old streaming, 4267266 silesia.tar, huffman literals, old streaming, 6187938 github, level -5, old streaming, 232315 @@ -1224,11 +1224,11 @@ github, level -3, old stre github, level -3 with dict, old streaming, 45395 github, level -1, old streaming, 175468 github, level -1 with dict, old streaming, 43170 -github, level 0, old streaming, 136335 +github, level 0, old streaming, 136332 github, level 0 with dict, old streaming, 41148 github, level 1, old streaming, 142365 github, level 1 with dict, old streaming, 41682 -github, level 3, old streaming, 136335 +github, level 3, old streaming, 136332 github, level 3 with dict, old streaming, 41148 github, level 4, old streaming, 136199 github, level 4 with dict, old streaming, 41251 @@ -1246,9 +1246,9 @@ github, level 16, old stre github, level 16 with dict, old streaming, 37577 github, level 19, old streaming, 134064 github, level 19 with dict, old streaming, 37576 -github, no source size, old streaming, 140632 +github, no source size, old streaming, 140599 github, no source size with dict, old streaming, 40654 -github, uncompressed literals, old streaming, 136335 +github, uncompressed literals, old streaming, 136332 github, uncompressed literals optimal, old streaming, 134064 github, huffman literals, old streaming, 175468 github.tar, level -5, old streaming, 64132 @@ -1257,13 +1257,13 @@ github.tar, level -3, old stre github.tar, level -3 with dict, old streaming, 42750 github.tar, level -1, old streaming, 42536 github.tar, level -1 with dict, old streaming, 41198 -github.tar, level 0, old streaming, 38441 +github.tar, level 0, old streaming, 38831 github.tar, level 0 with dict, old streaming, 37995 github.tar, level 1, old streaming, 39270 github.tar, level 1 with dict, old streaming, 38316 -github.tar, level 3, old streaming, 38441 +github.tar, level 3, old streaming, 38831 github.tar, level 3 with dict, old streaming, 37995 -github.tar, level 4, old streaming, 38467 +github.tar, level 4, old streaming, 38893 github.tar, level 4 with dict, old streaming, 37948 github.tar, level 5, old streaming, 38366 github.tar, level 5 with dict, old streaming, 39082 @@ -1279,18 +1279,18 @@ github.tar, level 16, old stre github.tar, level 16 with dict, old streaming, 33378 github.tar, level 19, old streaming, 32134 github.tar, level 19 with dict, old streaming, 32709 -github.tar, no source size, old streaming, 38438 +github.tar, no source size, old streaming, 38828 github.tar, no source size with dict, old streaming, 38000 -github.tar, uncompressed literals, old streaming, 38441 +github.tar, uncompressed literals, old streaming, 38831 github.tar, uncompressed literals optimal, old streaming, 32134 github.tar, huffman literals, old streaming, 42536 silesia, level -5, old streaming advanced, 7292053 silesia, level -3, old streaming advanced, 6867875 silesia, level -1, old streaming advanced, 6183923 -silesia, level 0, old streaming advanced, 4849553 +silesia, level 0, old streaming advanced, 4842075 silesia, level 1, old streaming advanced, 5312694 -silesia, level 3, old streaming advanced, 4849553 -silesia, level 4, old streaming advanced, 4786968 +silesia, level 3, old streaming advanced, 4842075 +silesia, level 4, old streaming advanced, 4779186 silesia, level 5, old streaming advanced, 4638691 silesia, level 6, old streaming advanced, 4605296 silesia, level 7, old streaming advanced, 4566984 @@ -1298,25 +1298,25 @@ silesia, level 9, old stre silesia, level 13, old streaming advanced, 4493990 silesia, level 16, old streaming advanced, 4359864 silesia, level 19, old streaming advanced, 4296880 -silesia, no source size, old streaming advanced, 4849517 -silesia, long distance mode, old streaming advanced, 4849553 -silesia, multithreaded, old streaming advanced, 4849553 -silesia, multithreaded long distance mode, old streaming advanced, 4849553 -silesia, small window log, old streaming advanced, 7112062 +silesia, no source size, old streaming advanced, 4842039 +silesia, long distance mode, old streaming advanced, 4842075 +silesia, multithreaded, old streaming advanced, 4842075 +silesia, multithreaded long distance mode, old streaming advanced, 4842075 +silesia, small window log, old streaming advanced, 7111103 silesia, small hash log, old streaming advanced, 6526141 silesia, small chain log, old streaming advanced, 4912197 silesia, explicit params, old streaming advanced, 4795452 -silesia, uncompressed literals, old streaming advanced, 4849553 +silesia, uncompressed literals, old streaming advanced, 4842075 silesia, uncompressed literals optimal, old streaming advanced, 4296880 silesia, huffman literals, old streaming advanced, 6183923 -silesia, multithreaded with advanced params, old streaming advanced, 4849553 +silesia, multithreaded with advanced params, old streaming advanced, 4842075 silesia.tar, level -5, old streaming advanced, 7260007 silesia.tar, level -3, old streaming advanced, 6845151 silesia.tar, level -1, old streaming advanced, 6187938 -silesia.tar, level 0, old streaming advanced, 4861426 +silesia.tar, level 0, old streaming advanced, 4859271 silesia.tar, level 1, old streaming advanced, 5334890 -silesia.tar, level 3, old streaming advanced, 4861426 -silesia.tar, level 4, old streaming advanced, 4799632 +silesia.tar, level 3, old streaming advanced, 4859271 +silesia.tar, level 4, old streaming advanced, 4797470 silesia.tar, level 5, old streaming advanced, 4649992 silesia.tar, level 6, old streaming advanced, 4616803 silesia.tar, level 7, old streaming advanced, 4576664 @@ -1324,18 +1324,18 @@ silesia.tar, level 9, old stre silesia.tar, level 13, old streaming advanced, 4502956 silesia.tar, level 16, old streaming advanced, 4360527 silesia.tar, level 19, old streaming advanced, 4267266 -silesia.tar, no source size, old streaming advanced, 4861422 -silesia.tar, long distance mode, old streaming advanced, 4861426 -silesia.tar, multithreaded, old streaming advanced, 4861426 -silesia.tar, multithreaded long distance mode, old streaming advanced, 4861426 -silesia.tar, small window log, old streaming advanced, 7118772 +silesia.tar, no source size, old streaming advanced, 4859267 +silesia.tar, long distance mode, old streaming advanced, 4859271 +silesia.tar, multithreaded, old streaming advanced, 4859271 +silesia.tar, multithreaded long distance mode, old streaming advanced, 4859271 +silesia.tar, small window log, old streaming advanced, 7117562 silesia.tar, small hash log, old streaming advanced, 6529234 silesia.tar, small chain log, old streaming advanced, 4917021 silesia.tar, explicit params, old streaming advanced, 4806873 -silesia.tar, uncompressed literals, old streaming advanced, 4861426 +silesia.tar, uncompressed literals, old streaming advanced, 4859271 silesia.tar, uncompressed literals optimal, old streaming advanced, 4267266 silesia.tar, huffman literals, old streaming advanced, 6187938 -silesia.tar, multithreaded with advanced params, old streaming advanced, 4861426 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 github, level -5, old streaming advanced, 241214 github, level -5 with dict, old streaming advanced, 49562 github, level -3, old streaming advanced, 222937 @@ -1364,7 +1364,7 @@ github, level 16, old stre github, level 16 with dict, old streaming advanced, 40789 github, level 19, old streaming advanced, 134064 github, level 19 with dict, old streaming advanced, 37576 -github, no source size, old streaming advanced, 140632 +github, no source size, old streaming advanced, 140599 github, no source size with dict, old streaming advanced, 40608 github, long distance mode, old streaming advanced, 141104 github, multithreaded, old streaming advanced, 141104 @@ -1383,13 +1383,13 @@ github.tar, level -3, old stre github.tar, level -3 with dict, old streaming advanced, 43357 github.tar, level -1, old streaming advanced, 42536 github.tar, level -1 with dict, old streaming advanced, 41494 -github.tar, level 0, old streaming advanced, 38441 +github.tar, level 0, old streaming advanced, 38831 github.tar, level 0 with dict, old streaming advanced, 38013 github.tar, level 1, old streaming advanced, 39270 github.tar, level 1 with dict, old streaming advanced, 38934 -github.tar, level 3, old streaming advanced, 38441 +github.tar, level 3, old streaming advanced, 38831 github.tar, level 3 with dict, old streaming advanced, 38013 -github.tar, level 4, old streaming advanced, 38467 +github.tar, level 4, old streaming advanced, 38893 github.tar, level 4 with dict, old streaming advanced, 38063 github.tar, level 5, old streaming advanced, 38366 github.tar, level 5 with dict, old streaming advanced, 37728 @@ -1405,19 +1405,19 @@ github.tar, level 16, old stre github.tar, level 16 with dict, old streaming advanced, 38578 github.tar, level 19, old streaming advanced, 32134 github.tar, level 19 with dict, old streaming advanced, 32702 -github.tar, no source size, old streaming advanced, 38438 +github.tar, no source size, old streaming advanced, 38828 github.tar, no source size with dict, old streaming advanced, 38015 -github.tar, long distance mode, old streaming advanced, 38441 -github.tar, multithreaded, old streaming advanced, 38441 -github.tar, multithreaded long distance mode, old streaming advanced, 38441 +github.tar, long distance mode, old streaming advanced, 38831 +github.tar, multithreaded, old streaming advanced, 38831 +github.tar, multithreaded long distance mode, old streaming advanced, 38831 github.tar, small window log, old streaming advanced, 199561 github.tar, small hash log, old streaming advanced, 129870 github.tar, small chain log, old streaming advanced, 41669 github.tar, explicit params, old streaming advanced, 41385 -github.tar, uncompressed literals, old streaming advanced, 38441 +github.tar, uncompressed literals, old streaming advanced, 38831 github.tar, uncompressed literals optimal, old streaming advanced, 32134 github.tar, huffman literals, old streaming advanced, 42536 -github.tar, multithreaded with advanced params, old streaming advanced, 38441 +github.tar, multithreaded with advanced params, old streaming advanced, 38831 github, level -5 with dict, old streaming cdict, 46718 github, level -3 with dict, old streaming cdict, 45395 github, level -1 with dict, old streaming cdict, 43170 From 168d0a3c89dd7d74fc682859520e895b6f1b521a Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 13 Sep 2021 16:35:58 -0400 Subject: [PATCH 218/274] Fix Flaky Test This test depended on `_extDict` and `_noDict` compressing identically, which is not a guarantee we make, AFAIK. --- tests/zstreamtest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index bbef903f8..093850e10 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -906,7 +906,7 @@ static int basicUnitTests(U32 seed, double compressibility) in.pos = 0; in.size = CNBufferSize - in.size; CHECK(!(ZSTD_compressStream2(cctx, &out, &in, ZSTD_e_end) == 0), "Not finished"); - CHECK_Z(ZSTD_decompress(decodedBuffer, CNBufferSize, compressedBuffer, cSize)); + CHECK_Z(ZSTD_decompress(decodedBuffer, CNBufferSize, compressedBuffer, out.pos)); DISPLAYLEVEL(3, "OK \n"); DISPLAYLEVEL(3, "test%3i : ZSTD_compressStream2() ZSTD_c_stableOutBuffer modify buffer : ", testNb++); From 79ca83076620d69a419e167b2a49ca01557285f8 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Tue, 5 Oct 2021 14:53:45 -0400 Subject: [PATCH 219/274] Style: Add Comments to Variables and Move a Couple into the Loop --- lib/compress/zstd_double_fast.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index c58e5cd3f..db95fe634 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -73,24 +73,24 @@ size_t ZSTD_compressBlock_doubleFast_noDict_generic( U32 offset; U32 curr; + /* how many positions to search before increasing step size */ const size_t kStepIncr = 1 << kSearchStrength; + /* the position at which to increment the step size if no match is found */ const BYTE* nextStep; - size_t step; + size_t step; /* the current step size */ - size_t hl0; - size_t hs0; - size_t hl1; + size_t hl0; /* the long hash at ip */ + size_t hl1; /* the long hash at ip1 */ - U32 idxl0; - U32 idxs0; - U32 idxl1; + U32 idxl0; /* the long match index for ip */ + U32 idxl1; /* the long match index for ip1 */ - const BYTE* matchl0; - const BYTE* matchs0; - const BYTE* matchl1; + const BYTE* matchl0; /* the long match for ip */ + const BYTE* matchs0; /* the short match for ip */ + const BYTE* matchl1; /* the long match for ip1 */ - const BYTE* ip = istart; - const BYTE* ip1; + const BYTE* ip = istart; /* the current position */ + const BYTE* ip1; /* the next position */ DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic"); @@ -120,9 +120,9 @@ _start: /* Main Search Loop */ do { + const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 idxs0 = hashSmall[hs0]; curr = (U32)(ip-base); - hs0 = ZSTD_hashPtr(ip, hBitsS, mls); - idxs0 = hashSmall[hs0]; matchs0 = base + idxs0; hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ From 399644b1f12cbdb61511fe3ad3139956fa658096 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 8 Oct 2021 11:13:11 -0700 Subject: [PATCH 220/274] [nit] Fix buggy indentation The bug was reported by Dan Carpenter and found by Smatch static checker. https://lore.kernel.org/all/20211008063704.GA5370@kili/ --- lib/compress/zstd_lazy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index c76fa840f..3f3a24264 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1056,7 +1056,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const const U32 kMaxMatchEndPositionsToUpdate = 32; if (useCache) { - /* Only skip positions when using hash cache, i.e. + /* Only skip positions when using hash cache, i.e. * if we are loading a dict, don't skip anything. * If we decide to skip, then we only update a set number * of positions at the beginning and end of the match. @@ -1985,7 +1985,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( matchLength = ml2, start = ip, offset=offsetFound; } - if (matchLength < 4) { + if (matchLength < 4) { ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */ continue; } From 1bbb372e3e2453a8f16813fc9d65c90f32eb9080 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 8 Oct 2021 11:17:40 -0700 Subject: [PATCH 221/274] [ldm] Fix ZSTD_c_ldmHashRateLog bounds check There is no minimum value check, so the parameter could be negative. Switch to the standard pattern of using `BOUNDCHECK()`. The bug was reported by Dan Carpenter and found by Smatch static checker. https://lore.kernel.org/all/20211008063704.GA5370@kili/ --- lib/compress/zstd_compress.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 9e2fb3193..edfd7eb07 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -866,8 +866,8 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, return CCtxParams->ldmParams.bucketSizeLog; case ZSTD_c_ldmHashRateLog : - RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN, - parameter_outOfBound, "Param out of bounds!"); + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmHashRateLog, value); CCtxParams->ldmParams.hashRateLog = value; return CCtxParams->ldmParams.hashRateLog; From 31316cf1584ceb3542cd07b5208fa53e86d2bd9f Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 8 Oct 2021 11:05:58 -0700 Subject: [PATCH 222/274] [multiple-ddicts] Fix NULL checks The bug was reported by Dan Carpenter and found by Smatch static checker. https://lore.kernel.org/all/20211008063704.GA5370@kili/ --- lib/decompress/zstd_decompress.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 4a4b3f72a..3307975a1 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -177,12 +177,15 @@ static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) { ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem); DEBUGLOG(4, "Allocating new hash set"); + if (!ret) + return NULL; ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem); - ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE; - ret->ddictPtrCount = 0; - if (!ret || !ret->ddictPtrTable) { + if (!ret->ddictPtrTable) { + ZSTD_customFree(ret, customMem); return NULL; } + ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE; + ret->ddictPtrCount = 0; return ret; } From c6c482fe07fb4f0e5007641ed9f6b758900c93c1 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 8 Oct 2021 11:45:30 -0700 Subject: [PATCH 223/274] [binary-tree] Fix underflow of nbCompares Fix underflow of `nbCompares` by switching to an `int` and comparing `nbCompares > 0`. This is a minimal fix, because I don't want to change the logic. These loops seem to be doing `nbCompares + 1` comparisons. The bug was reported by Dan Carpenter and found by Smatch static checker. https://lore.kernel.org/all/20211008063704.GA5370@kili/ --- lib/compress/zstd_lazy.c | 11 ++++++---- lib/compress/zstd_opt.c | 7 ++++--- tests/regression/results.csv | 40 ++++++++++++++++++------------------ 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index c76fa840f..7e44b8282 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -93,7 +93,7 @@ ZSTD_insertDUBT1(const ZSTD_matchState_t* ms, assert(curr >= btLow); assert(ip < iend); /* condition for ZSTD_count */ - while (nbCompares-- && (matchIndex > windowLow)) { + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ assert(matchIndex < curr); @@ -185,7 +185,7 @@ ZSTD_DUBT_findBetterDictMatch ( (void)dictMode; assert(dictMode == ZSTD_dictMatchState); - while (nbCompares-- && (dictMatchIndex > dictLowLimit)) { + for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) { U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ const BYTE* match = dictBase + dictMatchIndex; @@ -309,7 +309,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, matchIndex = hashTable[h]; hashTable[h] = curr; /* Update Hash Table */ - while (nbCompares-- && (matchIndex > windowLow)) { + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ const BYTE* match; @@ -357,6 +357,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, *smallerPtr = *largerPtr = 0; + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ if (dictMode == ZSTD_dictMatchState && nbCompares) { bestLength = ZSTD_DUBT_findBetterDictMatch( ms, ip, iend, @@ -758,6 +759,7 @@ size_t ZSTD_HcFindBestMatch_generic ( matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); } + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ if (dictMode == ZSTD_dedicatedDictSearch) { ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms, ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); @@ -1056,7 +1058,7 @@ FORCE_INLINE_TEMPLATE void ZSTD_row_update_internal(ZSTD_matchState_t* ms, const const U32 kMaxMatchEndPositionsToUpdate = 32; if (useCache) { - /* Only skip positions when using hash cache, i.e. + /* Only skip positions when using hash cache, i.e. * if we are loading a dict, don't skip anything. * If we decide to skip, then we only update a set number * of positions at the beginning and end of the match. @@ -1356,6 +1358,7 @@ size_t ZSTD_RowFindBestMatch_generic ( } } + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ if (dictMode == ZSTD_dedicatedDictSearch) { ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms, ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 4c765128a..909e06d05 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -442,7 +442,7 @@ static U32 ZSTD_insertBt1( hashTable[h] = curr; /* Update Hash Table */ assert(windowLow > 0); - while (nbCompares-- && (matchIndex >= windowLow)) { + for (; nbCompares && (matchIndex >= windowLow); --nbCompares) { U32* const nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ assert(matchIndex < curr); @@ -673,7 +673,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( hashTable[h] = curr; /* Update Hash Table */ - while (nbCompares-- && (matchIndex >= matchLow)) { + for (; nbCompares && (matchIndex >= matchLow); --nbCompares) { U32* const nextPtr = bt + 2*(matchIndex & btMask); const BYTE* match; size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ @@ -725,12 +725,13 @@ U32 ZSTD_insertBtAndGetAllMatches ( *smallerPtr = *largerPtr = 0; + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ if (dictMode == ZSTD_dictMatchState && nbCompares) { size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls); U32 dictMatchIndex = dms->hashTable[dmsH]; const U32* const dmsBt = dms->chainTable; commonLengthSmaller = commonLengthLarger = 0; - while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) { + for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) { const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ const BYTE* match = dmsBase + dictMatchIndex; diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 2538728c8..ec4a28025 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -171,7 +171,7 @@ github, level 7 with dict, zstdcli, github, level 9, zstdcli, 137122 github, level 9 with dict, zstdcli, 41393 github, level 13, zstdcli, 136064 -github, level 13 with dict, zstdcli, 41743 +github, level 13 with dict, zstdcli, 41900 github, level 16, zstdcli, 136064 github, level 16 with dict, zstdcli, 39577 github, level 19, zstdcli, 136064 @@ -391,9 +391,9 @@ github, level 12 row 2 with dict dds, advanced github, level 12 row 2 with dict copy, advanced one pass, 39677 github, level 12 row 2 with dict load, advanced one pass, 41166 github, level 13, advanced one pass, 134064 -github, level 13 with dict, advanced one pass, 39743 -github, level 13 with dict dms, advanced one pass, 39743 -github, level 13 with dict dds, advanced one pass, 39743 +github, level 13 with dict, advanced one pass, 39900 +github, level 13 with dict dms, advanced one pass, 39900 +github, level 13 with dict dds, advanced one pass, 39900 github, level 13 with dict copy, advanced one pass, 39948 github, level 13 with dict load, advanced one pass, 42626 github, level 16, advanced one pass, 134064 @@ -517,8 +517,8 @@ github.tar, level 12 row 2 with dict copy, advanced github.tar, level 12 row 2 with dict load, advanced one pass, 36459 github.tar, level 13, advanced one pass, 35501 github.tar, level 13 with dict, advanced one pass, 37130 -github.tar, level 13 with dict dms, advanced one pass, 37267 -github.tar, level 13 with dict dds, advanced one pass, 37267 +github.tar, level 13 with dict dms, advanced one pass, 37220 +github.tar, level 13 with dict dds, advanced one pass, 37220 github.tar, level 13 with dict copy, advanced one pass, 37130 github.tar, level 13 with dict load, advanced one pass, 36010 github.tar, level 16, advanced one pass, 40471 @@ -709,9 +709,9 @@ github, level 12 row 2 with dict dds, advanced github, level 12 row 2 with dict copy, advanced one pass small out, 39677 github, level 12 row 2 with dict load, advanced one pass small out, 41166 github, level 13, advanced one pass small out, 134064 -github, level 13 with dict, advanced one pass small out, 39743 -github, level 13 with dict dms, advanced one pass small out, 39743 -github, level 13 with dict dds, advanced one pass small out, 39743 +github, level 13 with dict, advanced one pass small out, 39900 +github, level 13 with dict dms, advanced one pass small out, 39900 +github, level 13 with dict dds, advanced one pass small out, 39900 github, level 13 with dict copy, advanced one pass small out, 39948 github, level 13 with dict load, advanced one pass small out, 42626 github, level 16, advanced one pass small out, 134064 @@ -835,8 +835,8 @@ github.tar, level 12 row 2 with dict copy, advanced github.tar, level 12 row 2 with dict load, advanced one pass small out, 36459 github.tar, level 13, advanced one pass small out, 35501 github.tar, level 13 with dict, advanced one pass small out, 37130 -github.tar, level 13 with dict dms, advanced one pass small out, 37267 -github.tar, level 13 with dict dds, advanced one pass small out, 37267 +github.tar, level 13 with dict dms, advanced one pass small out, 37220 +github.tar, level 13 with dict dds, advanced one pass small out, 37220 github.tar, level 13 with dict copy, advanced one pass small out, 37130 github.tar, level 13 with dict load, advanced one pass small out, 36010 github.tar, level 16, advanced one pass small out, 40471 @@ -1027,9 +1027,9 @@ github, level 12 row 2 with dict dds, advanced github, level 12 row 2 with dict copy, advanced streaming, 39677 github, level 12 row 2 with dict load, advanced streaming, 41166 github, level 13, advanced streaming, 134064 -github, level 13 with dict, advanced streaming, 39743 -github, level 13 with dict dms, advanced streaming, 39743 -github, level 13 with dict dds, advanced streaming, 39743 +github, level 13 with dict, advanced streaming, 39900 +github, level 13 with dict dms, advanced streaming, 39900 +github, level 13 with dict dds, advanced streaming, 39900 github, level 13 with dict copy, advanced streaming, 39948 github, level 13 with dict load, advanced streaming, 42626 github, level 16, advanced streaming, 134064 @@ -1153,8 +1153,8 @@ github.tar, level 12 row 2 with dict copy, advanced github.tar, level 12 row 2 with dict load, advanced streaming, 36459 github.tar, level 13, advanced streaming, 35501 github.tar, level 13 with dict, advanced streaming, 37130 -github.tar, level 13 with dict dms, advanced streaming, 37267 -github.tar, level 13 with dict dds, advanced streaming, 37267 +github.tar, level 13 with dict dms, advanced streaming, 37220 +github.tar, level 13 with dict dds, advanced streaming, 37220 github.tar, level 13 with dict copy, advanced streaming, 37130 github.tar, level 13 with dict load, advanced streaming, 36010 github.tar, level 16, advanced streaming, 40471 @@ -1241,7 +1241,7 @@ github, level 7 with dict, old stre github, level 9, old streaming, 135122 github, level 9 with dict, old streaming, 39437 github, level 13, old streaming, 134064 -github, level 13 with dict, old streaming, 39743 +github, level 13 with dict, old streaming, 39900 github, level 16, old streaming, 134064 github, level 16 with dict, old streaming, 37577 github, level 19, old streaming, 134064 @@ -1359,7 +1359,7 @@ github, level 7 with dict, old stre github, level 9, old streaming advanced, 138676 github, level 9 with dict, old streaming advanced, 38981 github, level 13, old streaming advanced, 138676 -github, level 13 with dict, old streaming advanced, 39721 +github, level 13 with dict, old streaming advanced, 39725 github, level 16, old streaming advanced, 138676 github, level 16 with dict, old streaming advanced, 40789 github, level 19, old streaming advanced, 134064 @@ -1429,7 +1429,7 @@ github, level 5 with dict, old stre github, level 6 with dict, old streaming cdict, 38671 github, level 7 with dict, old streaming cdict, 38758 github, level 9 with dict, old streaming cdict, 39437 -github, level 13 with dict, old streaming cdict, 39743 +github, level 13 with dict, old streaming cdict, 39900 github, level 16 with dict, old streaming cdict, 37577 github, level 19 with dict, old streaming cdict, 37576 github, no source size with dict, old streaming cdict, 40654 @@ -1459,7 +1459,7 @@ github, level 5 with dict, old stre github, level 6 with dict, old streaming advanced cdict, 39363 github, level 7 with dict, old streaming advanced cdict, 38924 github, level 9 with dict, old streaming advanced cdict, 38981 -github, level 13 with dict, old streaming advanced cdict, 39721 +github, level 13 with dict, old streaming advanced cdict, 39725 github, level 16 with dict, old streaming advanced cdict, 40789 github, level 19 with dict, old streaming advanced cdict, 37576 github, no source size with dict, old streaming advanced cdict, 40608 From 926d47004dfd7359158a7618be23ecba76397b3e Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 4 Oct 2021 08:23:57 +0200 Subject: [PATCH 224/274] Enhance streaming_compression examples. Add level argument to the first test and be more verbose about used compression level and number of threads. --- examples/streaming_compression.c | 28 +++++++++++++++----- examples/streaming_compression_thread_pool.c | 6 +++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index e20bcde99..87cb887de 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -15,9 +15,12 @@ #include // presumes zstd library is installed #include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() - -static void compressFile_orDie(const char* fname, const char* outName, int cLevel) +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, + int nbThreads) { + fprintf (stderr, "Starting compression of %s with level %d, using %d threads\n", + fname, cLevel, nbThreads); + /* Open the input and output files. */ FILE* const fin = fopen_orDie(fname, "rb"); FILE* const fout = fopen_orDie(outName, "wb"); @@ -39,7 +42,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve */ CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, cLevel) ); CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1) ); - ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 4); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads); /* This loop read from the input file, compresses that entire chunk, * and writes all output produced to the output file. @@ -106,17 +109,30 @@ int main(int argc, const char** argv) { const char* const exeName = argv[0]; - if (argc!=2) { + if (argc < 2) { printf("wrong arguments\n"); printf("usage:\n"); - printf("%s FILE\n", exeName); + printf("%s FILE [LEVEL] [THREADS]\n", exeName); return 1; } + int cLevel = 1; + int nbThreads = 4; + + if (argc >= 3) { + cLevel = atoi (argv[2]); + CHECK(cLevel != 0, "can't parse LEVEL!"); + } + + if (argc >= 4) { + nbThreads = atoi (argv[3]); + CHECK(nbThreads != 0, "can't parse THREADS!"); + } + const char* const inFilename = argv[1]; char* const outFilename = createOutFilename_orDie(inFilename); - compressFile_orDie(inFilename, outFilename, 1); + compressFile_orDie(inFilename, outFilename, cLevel, nbThreads); free(outFilename); /* not strictly required, since program execution stops there, * but some static analyzer main complain otherwise */ diff --git a/examples/streaming_compression_thread_pool.c b/examples/streaming_compression_thread_pool.c index 5a6551baa..471ca8631 100644 --- a/examples/streaming_compression_thread_pool.c +++ b/examples/streaming_compression_thread_pool.c @@ -28,8 +28,10 @@ typedef struct compress_args static void *compressFile_orDie(void *data) { + const int nbThreads = 16; + compress_args_t *args = (compress_args_t *)data; - fprintf (stderr, "Starting compression of %s with level %d\n", args->fname, args->cLevel); + fprintf (stderr, "Starting compression of %s with level %d, using %d threads\n", args->fname, args->cLevel, nbThreads); /* Open the input and output files. */ FILE* const fin = fopen_orDie(args->fname, "rb"); FILE* const fout = fopen_orDie(args->outName, "wb"); @@ -56,7 +58,7 @@ static void *compressFile_orDie(void *data) */ CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, args->cLevel) ); CHECK_ZSTD( ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1) ); - ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, 16); + ZSTD_CCtx_setParameter(cctx, ZSTD_c_nbWorkers, nbThreads); /* This loop read from the input file, compresses that entire chunk, * and writes all output produced to the output file. From 0bfc935add6f47630c28b4e9215026e5860cb85e Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 11 Oct 2021 15:57:29 -0400 Subject: [PATCH 225/274] Convert Outer Control Structure to Loop --- lib/compress/zstd_double_fast.c | 262 ++++++++++++++++---------------- 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index db95fe634..9d19468cb 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -104,152 +104,152 @@ size_t ZSTD_compressBlock_doubleFast_noDict_generic( if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0; } -_start: + /* Outer Loop: one iteration per match found and stored */ + while (1) { + step = 1; + nextStep = ip + kStepIncr; + ip1 = ip + step; - step = 1; - nextStep = ip + kStepIncr; - ip1 = ip + step; - - if (ip1 > ilimit) { - goto _cleanup; - } - - hl0 = ZSTD_hashPtr(ip, hBitsL, 8); - idxl0 = hashLong[hl0]; - matchl0 = base + idxl0; - - /* Main Search Loop */ - do { - const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls); - const U32 idxs0 = hashSmall[hs0]; - curr = (U32)(ip-base); - matchs0 = base + idxs0; - - hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ - - /* check noDict repcode */ - if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { - mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; - ip++; - ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH); - goto _match_stored; + if (ip1 > ilimit) { + goto _cleanup; } - hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + idxl0 = hashLong[hl0]; + matchl0 = base + idxl0; - if (idxl0 > prefixLowestIndex) { - /* check prefix long match */ - if (MEM_read64(matchl0) == MEM_read64(ip)) { - mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8; - offset = (U32)(ip-matchl0); - while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */ + /* Inner Loop: one iteration per search / position */ + do { + const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 idxs0 = hashSmall[hs0]; + curr = (U32)(ip-base); + matchs0 = base + idxs0; + + hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ + + /* check noDict repcode */ + if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { + mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH); + goto _match_stored; + } + + hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + + if (idxl0 > prefixLowestIndex) { + /* check prefix long match */ + if (MEM_read64(matchl0) == MEM_read64(ip)) { + mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8; + offset = (U32)(ip-matchl0); + while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */ + goto _match_found; + } + } + + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + + if (idxs0 > prefixLowestIndex) { + /* check prefix short match */ + if (MEM_read32(matchs0) == MEM_read32(ip)) { + goto _search_next_long; + } + } + + if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + step++; + nextStep += kStepIncr; + } + ip = ip1; + ip1 += step; + + hl0 = hl1; + idxl0 = idxl1; + matchl0 = matchl1; + #if defined(__aarch64__) + PREFETCH_L1(ip+256); + #endif + } while (ip1 <= ilimit); + +_cleanup: + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved; + rep[1] = offset_2 ? offset_2 : offsetSaved; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_search_next_long: + + /* check prefix long +1 match */ + if (idxl1 > prefixLowestIndex) { + if (MEM_read64(matchl1) == MEM_read64(ip1)) { + ip = ip1; + mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8; + offset = (U32)(ip-matchl1); + while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ goto _match_found; } } - idxl1 = hashLong[hl1]; - matchl1 = base + idxl1; + /* if no long +1 match, explore the short match we found */ + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ - if (idxs0 > prefixLowestIndex) { - /* check prefix short match */ - if (MEM_read32(matchs0) == MEM_read32(ip)) { - goto _search_next_long; - } - } - - if (ip1 >= nextStep) { - PREFETCH_L1(ip1 + 64); - PREFETCH_L1(ip1 + 128); - step++; - nextStep += kStepIncr; - } - ip = ip1; - ip1 += step; - - hl0 = hl1; - idxl0 = idxl1; - matchl0 = matchl1; -#if defined(__aarch64__) - PREFETCH_L1(ip+256); -#endif - } while (ip1 <= ilimit); - -_cleanup: - /* save reps for next block */ - rep[0] = offset_1 ? offset_1 : offsetSaved; - rep[1] = offset_2 ? offset_2 : offsetSaved; - - /* Return the last literals size */ - return (size_t)(iend - anchor); - -_search_next_long: - - /* check prefix long +1 match */ - if (idxl1 > prefixLowestIndex) { - if (MEM_read64(matchl1) == MEM_read64(ip1)) { - ip = ip1; - mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8; - offset = (U32)(ip-matchl1); - while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */ - goto _match_found; - } - } - - /* if no long +1 match, explore the short match we found */ - mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; - offset = (U32)(ip - matchs0); - while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */ - - /* fall-through */ + /* fall-through */ _match_found: /* requires ip, offset, mLength */ - offset_2 = offset_1; - offset_1 = offset; + offset_2 = offset_1; + offset_1 = offset; - if (step < 4) { - /* It is unsafe to write this value back to the hashtable when ip1 is - * greater than or equal to the new ip we will have after we're done - * processing this match. Rather than perform that test directly - * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler - * more predictable test. The minmatch even if we take a short match is - * 4 bytes, so as long as step, the distance between ip and ip1 - * (initially) is less than 4, we know ip1 < new ip. */ - hashLong[hl1] = (U32)(ip1 - base); - } - - ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH); - -_match_stored: - /* match found */ - ip += mLength; - anchor = ip; - - if (ip <= ilimit) { - /* Complementary insertion */ - /* done after iLimit test, as candidates could be > iend-8 */ - { U32 const indexToInsert = curr+2; - hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; - hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); - hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; - hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + if (step < 4) { + /* It is unsafe to write this value back to the hashtable when ip1 is + * greater than or equal to the new ip we will have after we're done + * processing this match. Rather than perform that test directly + * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler + * more predictable test. The minmatch even if we take a short match is + * 4 bytes, so as long as step, the distance between ip and ip1 + * (initially) is less than 4, we know ip1 < new ip. */ + hashLong[hl1] = (U32)(ip1 - base); } - /* check immediate repcode */ - while ( (ip <= ilimit) - && ( (offset_2>0) - & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { - /* store sequence */ - size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; - U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ - hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); - hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); - ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH); - ip += rLength; - anchor = ip; - continue; /* faster when present ... (?) */ - } } + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH); - goto _start; +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && ( (offset_2>0) + & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); + ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + } } From 1c2b02eee9679b412dbbd62ae1ef93edc8d26cbe Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 15 Oct 2021 17:55:08 +0200 Subject: [PATCH 226/274] Support thread pool section in HTML documentation. --- doc/zstd_manual.html | 56 +++++++++++++++++++++++++++++++++++++------- lib/zstd.h | 18 +++++++------- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 010f10a01..3d62f5952 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -1,10 +1,10 @@ -zstd 1.5.0 Manual +zstd 1.5.1 Manual -

zstd 1.5.0 Manual

+

zstd 1.5.1 Manual


Contents

    @@ -357,7 +357,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ * ZSTD_c_stableOutBuffer * ZSTD_c_blockDelimiters * ZSTD_c_validateSequences - * ZSTD_c_splitBlocks + * ZSTD_c_useBlockSplitter * ZSTD_c_useRowMatchFinder * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. * note : never ever use experimentalParam? names directly; @@ -803,7 +803,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds); /* accept NULL pointer */

    Advanced dictionary and prefix API (Requires v1.4.0+)

      This API allows dictionaries to be used with ZSTD_compress2(),
    - ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and
    + ZSTD_compressStream2(), and ZSTD_decompressDCtx(). Dictionaries are sticky, and
      only reset with the context is reset with ZSTD_reset_parameters or
      ZSTD_reset_session_and_parameters. Prefixes are single-use.
     
    @@ -1072,10 +1072,14 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); } ZSTD_literalCompressionMode_e;

    typedef enum {
    -  ZSTD_urm_auto = 0,                   /* Automatically determine whether or not we use row matchfinder */
    -  ZSTD_urm_disableRowMatchFinder = 1,  /* Never use row matchfinder */
    -  ZSTD_urm_enableRowMatchFinder = 2    /* Always use row matchfinder when applicable */
    -} ZSTD_useRowMatchFinderMode_e;
    +  /* Note: This enum controls features which are conditionally beneficial. Zstd typically will make a final
    +   * decision on whether or not to enable the feature (ZSTD_ps_auto), but setting the switch to ZSTD_ps_enable
    +   * or ZSTD_ps_disable allow for a force enable/disable the feature.
    +   */
    +  ZSTD_ps_auto = 0,         /* Let the library automatically determine whether the feature shall be enabled */
    +  ZSTD_ps_enable = 1,       /* Force-enable the feature */
    +  ZSTD_ps_disable = 2       /* Do not use the feature */
    +} ZSTD_paramSwitch_e;
     

    Frame size functions

    
     
    @@ -1205,6 +1209,25 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
      
     


    +
    size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
    +                                const void* src, size_t srcSize);
    +

    Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer. + + The parameter magicVariant will receive the magicVariant that was supplied when the frame was written, + i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested + in the magicVariant. + + Returns an error if destination buffer is not large enough, or if the frame is not skippable. + + @return : number of bytes written or a ZSTD error. + +


    + +
    unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
    +

    Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + +


    +

    Memory management

    
     
     
    size_t ZSTD_estimateCCtxSize(int compressionLevel);
    @@ -1303,6 +1326,21 @@ ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL };  /**< this con
      
     


    +
    typedef struct POOL_ctx_s ZSTD_threadPool;
    +ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
    +void ZSTD_freeThreadPool (ZSTD_threadPool* pool);  /* accept NULL pointer */
    +size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
    +

    These prototypes make it possible to share a thread pool among multiple compression contexts. + This can limit resources for applications with multiple threads where each one uses + a threaded compression mode (via ZSTD_c_nbWorkers parameter). + ZSTD_createThreadPool creates a new thread pool with a given number of threads. + Note that the lifetime of such pool must exist while being used. + ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value + to use an internal thread pool). + ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer. + +


    +

    Advanced compression functions

    
     
     
    ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
    @@ -1594,7 +1632,7 @@ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
     

    This function is DEPRECATED, and equivalent to: ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only); ZSTD_CCtx_refCDict(zcs, cdict); - + note : cdict will just be referenced, and must outlive compression session This prototype will generate compilation warnings. diff --git a/lib/zstd.h b/lib/zstd.h index 17fec948a..6709c65d7 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -1589,15 +1589,15 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS ZSTD_compressionParameters cParams, ZSTD_customMem customMem); -/* ! Thread pool : - * These prototypes make it possible to share a thread pool among multiple compression contexts. - * This can limit resources for applications with multiple threads where each one uses - * a threaded compression mode (via ZSTD_c_nbWorkers parameter). - * ZSTD_createThreadPool creates a new thread pool with a given number of threads. - * Note that the lifetime of such pool must exist while being used. - * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value - * to use an internal thread pool). - * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer. +/*! Thread pool : + * These prototypes make it possible to share a thread pool among multiple compression contexts. + * This can limit resources for applications with multiple threads where each one uses + * a threaded compression mode (via ZSTD_c_nbWorkers parameter). + * ZSTD_createThreadPool creates a new thread pool with a given number of threads. + * Note that the lifetime of such pool must exist while being used. + * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value + * to use an internal thread pool). + * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer. */ typedef struct POOL_ctx_s ZSTD_threadPool; ZSTDLIB_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads); From abd717a5fa90af6e35a6023fc88c31f45dc66901 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 20 Oct 2021 11:37:05 -0700 Subject: [PATCH 227/274] [asm] Switch to C style comments Switch to C style comments for increased portability, and consistency. --- lib/decompress/huf_decompress_amd64.S | 902 +++++++++++++------------- 1 file changed, 456 insertions(+), 446 deletions(-) diff --git a/lib/decompress/huf_decompress_amd64.S b/lib/decompress/huf_decompress_amd64.S index 77a2d8560..83e3d7565 100644 --- a/lib/decompress/huf_decompress_amd64.S +++ b/lib/decompress/huf_decompress_amd64.S @@ -1,57 +1,61 @@ -# Calling convention: -# -# %rdi contains the first argument: HUF_DecompressAsmArgs*. -# %rbp is'nt maintained (no frame pointer). -# %rsp contains the stack pointer that grows down. -# No red-zone is assumed, only addresses >= %rsp are used. -# All register contents are preserved. -# -# TODO: Support Windows calling convention. - #if !defined(HUF_DISABLE_ASM) && defined(__x86_64__) + +/* Calling convention: + * + * %rdi contains the first argument: HUF_DecompressAsmArgs*. + * %rbp is'nt maintained (no frame pointer). + * %rsp contains the stack pointer that grows down. + * No red-zone is assumed, only addresses >= %rsp are used. + * All register contents are preserved. + * + * TODO: Support Windows calling convention. + */ + .global HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop .global HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop .global _HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop .global _HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop .text -# Sets up register mappings for clarity. -# op[], bits[], dtable & ip[0] each get their own register. -# ip[1,2,3] & olimit alias var[]. -# %rax is a scratch register. +/* Sets up register mappings for clarity. + * op[], bits[], dtable & ip[0] each get their own register. + * ip[1,2,3] & olimit alias var[]. + * %rax is a scratch register. + */ -#define op0 rsi -#define op1 rbx -#define op2 rcx -#define op3 rdi +#define op0 rsi +#define op1 rbx +#define op2 rcx +#define op3 rdi -#define ip0 r8 -#define ip1 r9 -#define ip2 r10 -#define ip3 r11 +#define ip0 r8 +#define ip1 r9 +#define ip2 r10 +#define ip3 r11 -#define bits0 rbp -#define bits1 rdx -#define bits2 r12 -#define bits3 r13 -#define dtable r14 -#define olimit r15 +#define bits0 rbp +#define bits1 rdx +#define bits2 r12 +#define bits3 r13 +#define dtable r14 +#define olimit r15 -# var[] aliases ip[1,2,3] & olimit -# ip[1,2,3] are saved every iteration. -# olimit is only used in compute_olimit. -#define var0 r15 -#define var1 r9 -#define var2 r10 -#define var3 r11 +/* var[] aliases ip[1,2,3] & olimit + * ip[1,2,3] are saved every iteration. + * olimit is only used in compute_olimit. + */ +#define var0 r15 +#define var1 r9 +#define var2 r10 +#define var3 r11 -# 32-bit var registers -#define vard0 r15d -#define vard1 r9d -#define vard2 r10d -#define vard3 r11d +/* 32-bit var registers */ +#define vard0 r15d +#define vard1 r9d +#define vard2 r10d +#define vard3 r11d -# Helper macro: args if idx != 4. +/* Helper macro: args if idx != 4. */ #define IF_NOT_4_0(...) __VA_ARGS__ #define IF_NOT_4_1(...) __VA_ARGS__ #define IF_NOT_4_2(...) __VA_ARGS__ @@ -60,502 +64,508 @@ #define IF_NOT_4_(idx, ...) IF_NOT_4_##idx(__VA_ARGS__) #define IF_NOT_4(idx, ...) IF_NOT_4_(idx, __VA_ARGS__) -# Calls X(N) for each stream 0, 1, 2, 3. +/* Calls X(N) for each stream 0, 1, 2, 3. */ #define FOR_EACH_STREAM(X) \ - X(0); \ - X(1); \ - X(2); \ - X(3) + X(0); \ + X(1); \ + X(2); \ + X(3) -# Calls X(N, idx) for each stream 0, 1, 2, 3. +/* Calls X(N, idx) for each stream 0, 1, 2, 3. */ #define FOR_EACH_STREAM_WITH_INDEX(X, idx) \ - X(0, idx); \ - X(1, idx); \ - X(2, idx); \ - X(3, idx) + X(0, idx); \ + X(1, idx); \ + X(2, idx); \ + X(3, idx) -# Define both _HUF_* & HUF_* symbols because MacOS -# C symbols are prefixed with '_' & Linux symbols aren't. +/* Define both _HUF_* & HUF_* symbols because MacOS + * C symbols are prefixed with '_' & Linux symbols aren't. + */ _HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: - # Save all registers - even if they are callee saved for simplicity. - push %rax - push %rbx - push %rcx - push %rdx - push %rbp - push %rsi - push %rdi - push %r8 - push %r9 - push %r10 - push %r11 - push %r12 - push %r13 - push %r14 - push %r15 + /* Save all registers - even if they are callee saved for simplicity. */ + push %rax + push %rbx + push %rcx + push %rdx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 - # Read HUF_DecompressAsmArgs* args from %rax - movq %rdi, %rax - movq 0(%rax), %ip0 - movq 8(%rax), %ip1 - movq 16(%rax), %ip2 - movq 24(%rax), %ip3 - movq 32(%rax), %op0 - movq 40(%rax), %op1 - movq 48(%rax), %op2 - movq 56(%rax), %op3 - movq 64(%rax), %bits0 - movq 72(%rax), %bits1 - movq 80(%rax), %bits2 - movq 88(%rax), %bits3 - movq 96(%rax), %dtable - push %rax # argument - push 104(%rax) # ilimit - push 112(%rax) # oend - push %olimit # olimit space + /* Read HUF_DecompressAsmArgs* args from %rax */ + movq %rdi, %rax + movq 0(%rax), %ip0 + movq 8(%rax), %ip1 + movq 16(%rax), %ip2 + movq 24(%rax), %ip3 + movq 32(%rax), %op0 + movq 40(%rax), %op1 + movq 48(%rax), %op2 + movq 56(%rax), %op3 + movq 64(%rax), %bits0 + movq 72(%rax), %bits1 + movq 80(%rax), %bits2 + movq 88(%rax), %bits3 + movq 96(%rax), %dtable + push %rax /* argument */ + push 104(%rax) /* ilimit */ + push 112(%rax) /* oend */ + push %olimit /* olimit space */ - subq $24, %rsp + subq $24, %rsp .L_4X1_compute_olimit: - # Computes how many iterations we can do savely - # %r15, %rax may be clobbered - # rbx, rdx must be saved - # op3 & ip0 mustn't be clobbered - movq %rbx, 0(%rsp) - movq %rdx, 8(%rsp) + /* Computes how many iterations we can do savely + * %r15, %rax may be clobbered + * rbx, rdx must be saved + * op3 & ip0 mustn't be clobbered + */ + movq %rbx, 0(%rsp) + movq %rdx, 8(%rsp) - movq 32(%rsp), %rax # rax = oend - subq %op3, %rax # rax = oend - op3 + movq 32(%rsp), %rax /* rax = oend */ + subq %op3, %rax /* rax = oend - op3 */ - # r15 = (oend - op3) / 5 - movabsq $-3689348814741910323, %rdx - mulq %rdx - movq %rdx, %r15 - shrq $2, %r15 + /* r15 = (oend - op3) / 5 */ + movabsq $-3689348814741910323, %rdx + mulq %rdx + movq %rdx, %r15 + shrq $2, %r15 - movq %ip0, %rax # rax = ip0 - movq 40(%rsp), %rdx # rdx = ilimit - subq %rdx, %rax # rax = ip0 - ilimit - movq %rax, %rbx # rbx = ip0 - ilimit + movq %ip0, %rax /* rax = ip0 */ + movq 40(%rsp), %rdx /* rdx = ilimit */ + subq %rdx, %rax /* rax = ip0 - ilimit */ + movq %rax, %rbx /* rbx = ip0 - ilimit */ - # rdx = (ip0 - ilimit) / 7 - movabsq $2635249153387078803, %rdx - mulq %rdx - subq %rdx, %rbx - shrq %rbx - addq %rbx, %rdx - shrq $2, %rdx + /* rdx = (ip0 - ilimit) / 7 */ + movabsq $2635249153387078803, %rdx + mulq %rdx + subq %rdx, %rbx + shrq %rbx + addq %rbx, %rdx + shrq $2, %rdx - # r15 = min(%rdx, %r15) - cmpq %rdx, %r15 - cmova %rdx, %r15 + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 - # r15 = r15 * 5 - leaq (%r15, %r15, 4), %r15 + /* r15 = r15 * 5 */ + leaq (%r15, %r15, 4), %r15 - # olimit = op3 + r15 - addq %op3, %olimit + /* olimit = op3 + r15 */ + addq %op3, %olimit - movq 8(%rsp), %rdx - movq 0(%rsp), %rbx + movq 8(%rsp), %rdx + movq 0(%rsp), %rbx - # If (op3 + 20 > olimit) - movq %op3, %rax # rax = op3 - addq $20, %rax # rax = op3 + 20 - cmpq %rax, %olimit # op3 + 20 > olimit - jb .L_4X1_exit + /* If (op3 + 20 > olimit) */ + movq %op3, %rax /* rax = op3 */ + addq $20, %rax /* rax = op3 + 20 */ + cmpq %rax, %olimit /* op3 + 20 > olimit */ + jb .L_4X1_exit - # If (ip1 < ip0) go to exit - cmpq %ip0, %ip1 - jb .L_4X1_exit + /* If (ip1 < ip0) go to exit */ + cmpq %ip0, %ip1 + jb .L_4X1_exit - # If (ip2 < ip1) go to exit - cmpq %ip1, %ip2 - jb .L_4X1_exit + /* If (ip2 < ip1) go to exit */ + cmpq %ip1, %ip2 + jb .L_4X1_exit - # If (ip3 < ip2) go to exit - cmpq %ip2, %ip3 - jb .L_4X1_exit + /* If (ip3 < ip2) go to exit */ + cmpq %ip2, %ip3 + jb .L_4X1_exit -# Reads top 11 bits from bits[n] -# Loads dt[bits[n]] into var[n] -#define GET_NEXT_DELT(n) \ - movq $53, %var##n; \ - shrxq %var##n, %bits##n, %var##n; \ - movzwl (%dtable,%var##n,2),%vard##n +/* Reads top 11 bits from bits[n] + * Loads dt[bits[n]] into var[n] + */ +#define GET_NEXT_DELT(n) \ + movq $53, %var##n; \ + shrxq %var##n, %bits##n, %var##n; \ + movzwl (%dtable,%var##n,2),%vard##n -# var[n] must contain the DTable entry computed with GET_NEXT_DELT -# Moves var[n] to %rax -# bits[n] <<= var[n] & 63 -# op[n][idx] = %rax >> 8 -# %ah is a way to access bits [8, 16) of %rax -#define DECODE_FROM_DELT(n, idx) \ - movq %var##n, %rax; \ - shlxq %var##n, %bits##n, %bits##n; \ - movb %ah, idx(%op##n) +/* var[n] must contain the DTable entry computed with GET_NEXT_DELT + * Moves var[n] to %rax + * bits[n] <<= var[n] & 63 + * op[n][idx] = %rax >> 8 + * %ah is a way to access bits [8, 16) of %rax + */ +#define DECODE_FROM_DELT(n, idx) \ + movq %var##n, %rax; \ + shlxq %var##n, %bits##n, %bits##n; \ + movb %ah, idx(%op##n) -# Assumes GET_NEXT_DELT has been called. -# Calls DECODE_FROM_DELT then GET_NEXT_DELT if n < 4 -#define DECODE(n, idx) \ - DECODE_FROM_DELT(n, idx); \ - IF_NOT_4(idx, GET_NEXT_DELT(n)) +/* Assumes GET_NEXT_DELT has been called. + * Calls DECODE_FROM_DELT then GET_NEXT_DELT if n < 4 + */ +#define DECODE(n, idx) \ + DECODE_FROM_DELT(n, idx); \ + IF_NOT_4(idx, GET_NEXT_DELT(n)) -# // ctz & nbBytes is stored in bits[n] -# // nbBits is stored in %rax -# ctz = CTZ[bits[n]] -# nbBits = ctz & 7 -# nbBytes = ctz >> 3 -# op[n] += 5 -# ip[n] -= nbBytes -# // Note: x86-64 is little-endian ==> no bswap -# bits[n] = MEM_readST(ip[n]) | 1 -# bits[n] <<= nbBits -#define RELOAD_BITS(n) \ - bsfq %bits##n, %bits##n; \ - movq %bits##n, %rax; \ - andq $7, %rax; \ - shrq $3, %bits##n; \ - leaq 5(%op##n), %op##n; \ - subq %bits##n, %ip##n; \ - movq (%ip##n), %bits##n; \ - orq $1, %bits##n; \ - shlx %rax, %bits##n, %bits##n; +/* // ctz & nbBytes is stored in bits[n] + * // nbBits is stored in %rax + * ctz = CTZ[bits[n]] + * nbBits = ctz & 7 + * nbBytes = ctz >> 3 + * op[n] += 5 + * ip[n] -= nbBytes + * // Note: x86-64 is little-endian ==> no bswap + * bits[n] = MEM_readST(ip[n]) | 1 + * bits[n] <<= nbBits + */ +#define RELOAD_BITS(n) \ + bsfq %bits##n, %bits##n; \ + movq %bits##n, %rax; \ + andq $7, %rax; \ + shrq $3, %bits##n; \ + leaq 5(%op##n), %op##n; \ + subq %bits##n, %ip##n; \ + movq (%ip##n), %bits##n; \ + orq $1, %bits##n; \ + shlx %rax, %bits##n, %bits##n - # Store clobbered variables on the stack - movq %olimit, 24(%rsp) - movq %ip1, 0(%rsp) - movq %ip2, 8(%rsp) - movq %ip3, 16(%rsp) + /* Store clobbered variables on the stack */ + movq %olimit, 24(%rsp) + movq %ip1, 0(%rsp) + movq %ip2, 8(%rsp) + movq %ip3, 16(%rsp) - # Call GET_NEXT_DELT for each stream - FOR_EACH_STREAM(GET_NEXT_DELT) + /* Call GET_NEXT_DELT for each stream */ + FOR_EACH_STREAM(GET_NEXT_DELT) - .p2align 6 + .p2align 6 .L_4X1_loop_body: -# LLVM-MCA-BEGIN decode-4X1 - # Decode 5 symbols in each of the 4 streams (20 total) - # Must have called GET_NEXT_DELT for each stream - FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) + /* Decode 5 symbols in each of the 4 streams (20 total) + * Must have called GET_NEXT_DELT for each stream + */ + FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) - # Load ip[1,2,3] from stack (var[] aliases them) - # ip[] is needed for RELOAD_BITS - # Each will be stored back to the stack after RELOAD - movq 0(%rsp), %ip1 - movq 8(%rsp), %ip2 - movq 16(%rsp), %ip3 + /* Load ip[1,2,3] from stack (var[] aliases them) + * ip[] is needed for RELOAD_BITS + * Each will be stored back to the stack after RELOAD + */ + movq 0(%rsp), %ip1 + movq 8(%rsp), %ip2 + movq 16(%rsp), %ip3 - # Reload each stream & fetch the next table entry - # to prepare for the next iteration - RELOAD_BITS(0) - GET_NEXT_DELT(0) + /* Reload each stream & fetch the next table entry + * to prepare for the next iteration + */ + RELOAD_BITS(0) + GET_NEXT_DELT(0) - RELOAD_BITS(1) - movq %ip1, 0(%rsp) - GET_NEXT_DELT(1) + RELOAD_BITS(1) + movq %ip1, 0(%rsp) + GET_NEXT_DELT(1) - RELOAD_BITS(2) - movq %ip2, 8(%rsp) - GET_NEXT_DELT(2) + RELOAD_BITS(2) + movq %ip2, 8(%rsp) + GET_NEXT_DELT(2) - RELOAD_BITS(3) - movq %ip3, 16(%rsp) - GET_NEXT_DELT(3) + RELOAD_BITS(3) + movq %ip3, 16(%rsp) + GET_NEXT_DELT(3) - # If op3 < olimit: continue the loop - cmp %op3, 24(%rsp) - ja .L_4X1_loop_body + /* If op3 < olimit: continue the loop */ + cmp %op3, 24(%rsp) + ja .L_4X1_loop_body - # Reload ip[1,2,3] from stack - movq 0(%rsp), %ip1 - movq 8(%rsp), %ip2 - movq 16(%rsp), %ip3 + /* Reload ip[1,2,3] from stack */ + movq 0(%rsp), %ip1 + movq 8(%rsp), %ip2 + movq 16(%rsp), %ip3 - # Re-compute olimit - jmp .L_4X1_compute_olimit + /* Re-compute olimit */ + jmp .L_4X1_compute_olimit #undef GET_NEXT_DELT #undef DECODE_FROM_DELT #undef DECODE #undef RELOAD_BITS -# LLVM-MCA-END .L_4X1_exit: - addq $24, %rsp + addq $24, %rsp - # Restore stack (oend & olimit) - pop %rax # olimit - pop %rax # oend - pop %rax # ilimit - pop %rax # arg + /* Restore stack (oend & olimit) */ + pop %rax /* olimit */ + pop %rax /* oend */ + pop %rax /* ilimit */ + pop %rax /* arg */ - # Save ip / op / bits - movq %ip0, 0(%rax) - movq %ip1, 8(%rax) - movq %ip2, 16(%rax) - movq %ip3, 24(%rax) - movq %op0, 32(%rax) - movq %op1, 40(%rax) - movq %op2, 48(%rax) - movq %op3, 56(%rax) - movq %bits0, 64(%rax) - movq %bits1, 72(%rax) - movq %bits2, 80(%rax) - movq %bits3, 88(%rax) + /* Save ip / op / bits */ + movq %ip0, 0(%rax) + movq %ip1, 8(%rax) + movq %ip2, 16(%rax) + movq %ip3, 24(%rax) + movq %op0, 32(%rax) + movq %op1, 40(%rax) + movq %op2, 48(%rax) + movq %op3, 56(%rax) + movq %bits0, 64(%rax) + movq %bits1, 72(%rax) + movq %bits2, 80(%rax) + movq %bits3, 88(%rax) - # Restore registers - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %r11 - pop %r10 - pop %r9 - pop %r8 - pop %rdi - pop %rsi - pop %rbp - pop %rdx - pop %rcx - pop %rbx - pop %rax - ret + /* Restore registers */ + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rdx + pop %rcx + pop %rbx + pop %rax + ret _HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop: HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop: - # Save all registers - even if they are callee saved for simplicity. - push %rax - push %rbx - push %rcx - push %rdx - push %rbp - push %rsi - push %rdi - push %r8 - push %r9 - push %r10 - push %r11 - push %r12 - push %r13 - push %r14 - push %r15 + /* Save all registers - even if they are callee saved for simplicity. */ + push %rax + push %rbx + push %rcx + push %rdx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 - movq %rdi, %rax - movq 0(%rax), %ip0 - movq 8(%rax), %ip1 - movq 16(%rax), %ip2 - movq 24(%rax), %ip3 - movq 32(%rax), %op0 - movq 40(%rax), %op1 - movq 48(%rax), %op2 - movq 56(%rax), %op3 - movq 64(%rax), %bits0 - movq 72(%rax), %bits1 - movq 80(%rax), %bits2 - movq 88(%rax), %bits3 - movq 96(%rax), %dtable - push %rax # argument - push %rax # olimit - push 104(%rax) # ilimit + movq %rdi, %rax + movq 0(%rax), %ip0 + movq 8(%rax), %ip1 + movq 16(%rax), %ip2 + movq 24(%rax), %ip3 + movq 32(%rax), %op0 + movq 40(%rax), %op1 + movq 48(%rax), %op2 + movq 56(%rax), %op3 + movq 64(%rax), %bits0 + movq 72(%rax), %bits1 + movq 80(%rax), %bits2 + movq 88(%rax), %bits3 + movq 96(%rax), %dtable + push %rax /* argument */ + push %rax /* olimit */ + push 104(%rax) /* ilimit */ - movq 112(%rax), %rax - push %rax # oend3 + movq 112(%rax), %rax + push %rax /* oend3 */ - movq %op3, %rax - push %rax # oend2 + movq %op3, %rax + push %rax /* oend2 */ - movq %op2, %rax - push %rax # oend1 + movq %op2, %rax + push %rax /* oend1 */ - movq %op1, %rax - push %rax # oend0 + movq %op1, %rax + push %rax /* oend0 */ - # Scratch space - subq $8, %rsp + /* Scratch space */ + subq $8, %rsp .L_4X2_compute_olimit: - # Computes how many iterations we can do savely - # %r15, %rax may be clobbered - # rdx must be saved - # op[1,2,3,4] & ip0 mustn't be clobbered - movq %rdx, 0(%rsp) + /* Computes how many iterations we can do savely + * %r15, %rax may be clobbered + * rdx must be saved + * op[1,2,3,4] & ip0 mustn't be clobbered + */ + movq %rdx, 0(%rsp) - # We can consume up to 7 input bytes each iteration. - movq %ip0, %rax # rax = ip0 - movq 40(%rsp), %rdx # rdx = ilimit - subq %rdx, %rax # rax = ip0 - ilimit - movq %rax, %r15 # r15 = ip0 - ilimit + /* We can consume up to 7 input bytes each iteration. */ + movq %ip0, %rax /* rax = ip0 */ + movq 40(%rsp), %rdx /* rdx = ilimit */ + subq %rdx, %rax /* rax = ip0 - ilimit */ + movq %rax, %r15 /* r15 = ip0 - ilimit */ - # rdx = rax / 7 - movabsq $2635249153387078803, %rdx - mulq %rdx - subq %rdx, %r15 - shrq %r15 - addq %r15, %rdx - shrq $2, %rdx + /* rdx = rax / 7 */ + movabsq $2635249153387078803, %rdx + mulq %rdx + subq %rdx, %r15 + shrq %r15 + addq %r15, %rdx + shrq $2, %rdx - # r15 = (ip0 - ilimit) / 7 - movq %rdx, %r15 + /* r15 = (ip0 - ilimit) / 7 */ + movq %rdx, %r15 - movabsq $-3689348814741910323, %rdx - movq 8(%rsp), %rax # rax = oend0 - subq %op0, %rax # rax = oend0 - op0 - mulq %rdx - shrq $3, %rdx # rdx = rax / 10 + movabsq $-3689348814741910323, %rdx + movq 8(%rsp), %rax /* rax = oend0 */ + subq %op0, %rax /* rax = oend0 - op0 */ + mulq %rdx + shrq $3, %rdx /* rdx = rax / 10 */ - # r15 = min(%rdx, %r15) - cmpq %rdx, %r15 - cmova %rdx, %r15 + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 - movabsq $-3689348814741910323, %rdx - movq 16(%rsp), %rax # rax = oend1 - subq %op1, %rax # rax = oend1 - op1 - mulq %rdx - shrq $3, %rdx # rdx = rax / 10 + movabsq $-3689348814741910323, %rdx + movq 16(%rsp), %rax /* rax = oend1 */ + subq %op1, %rax /* rax = oend1 - op1 */ + mulq %rdx + shrq $3, %rdx /* rdx = rax / 10 */ - # r15 = min(%rdx, %r15) - cmpq %rdx, %r15 - cmova %rdx, %r15 + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 - movabsq $-3689348814741910323, %rdx - movq 24(%rsp), %rax # rax = oend2 - subq %op2, %rax # rax = oend2 - op2 - mulq %rdx - shrq $3, %rdx # rdx = rax / 10 + movabsq $-3689348814741910323, %rdx + movq 24(%rsp), %rax /* rax = oend2 */ + subq %op2, %rax /* rax = oend2 - op2 */ + mulq %rdx + shrq $3, %rdx /* rdx = rax / 10 */ - # r15 = min(%rdx, %r15) - cmpq %rdx, %r15 - cmova %rdx, %r15 + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 - movabsq $-3689348814741910323, %rdx - movq 32(%rsp), %rax # rax = oend3 - subq %op3, %rax # rax = oend3 - op3 - mulq %rdx - shrq $3, %rdx # rdx = rax / 10 + movabsq $-3689348814741910323, %rdx + movq 32(%rsp), %rax /* rax = oend3 */ + subq %op3, %rax /* rax = oend3 - op3 */ + mulq %rdx + shrq $3, %rdx /* rdx = rax / 10 */ - # r15 = min(%rdx, %r15) - cmpq %rdx, %r15 - cmova %rdx, %r15 + /* r15 = min(%rdx, %r15) */ + cmpq %rdx, %r15 + cmova %rdx, %r15 - # olimit = op3 + 5 * r15 - movq %r15, %rax - leaq (%op3, %rax, 4), %olimit - addq %rax, %olimit + /* olimit = op3 + 5 * r15 */ + movq %r15, %rax + leaq (%op3, %rax, 4), %olimit + addq %rax, %olimit - movq 0(%rsp), %rdx + movq 0(%rsp), %rdx - # If (op3 + 10 > olimit) - movq %op3, %rax # rax = op3 - addq $10, %rax # rax = op3 + 10 - cmpq %rax, %olimit # op3 + 10 > olimit - jb .L_4X2_exit + /* If (op3 + 10 > olimit) */ + movq %op3, %rax /* rax = op3 */ + addq $10, %rax /* rax = op3 + 10 */ + cmpq %rax, %olimit /* op3 + 10 > olimit */ + jb .L_4X2_exit - # If (ip1 < ip0) go to exit - cmpq %ip0, %ip1 - jb .L_4X2_exit + /* If (ip1 < ip0) go to exit */ + cmpq %ip0, %ip1 + jb .L_4X2_exit - # If (ip2 < ip1) go to exit - cmpq %ip1, %ip2 - jb .L_4X2_exit + /* If (ip2 < ip1) go to exit */ + cmpq %ip1, %ip2 + jb .L_4X2_exit - # If (ip3 < ip2) go to exit - cmpq %ip2, %ip3 - jb .L_4X2_exit + /* If (ip3 < ip2) go to exit */ + cmpq %ip2, %ip3 + jb .L_4X2_exit -#define DECODE(n, idx) \ - movq %bits##n, %rax; \ - shrq $53, %rax; \ - movzwl 0(%dtable,%rax,4),%r8d; \ - movzbl 2(%dtable,%rax,4),%r15d; \ - movzbl 3(%dtable,%rax,4),%eax; \ - movw %r8w, (%op##n); \ - shlxq %r15, %bits##n, %bits##n; \ - addq %rax, %op##n +#define DECODE(n, idx) \ + movq %bits##n, %rax; \ + shrq $53, %rax; \ + movzwl 0(%dtable,%rax,4),%r8d; \ + movzbl 2(%dtable,%rax,4),%r15d; \ + movzbl 3(%dtable,%rax,4),%eax; \ + movw %r8w, (%op##n); \ + shlxq %r15, %bits##n, %bits##n; \ + addq %rax, %op##n -#define RELOAD_BITS(n) \ - bsfq %bits##n, %bits##n; \ - movq %bits##n, %rax; \ - shrq $3, %bits##n; \ - andq $7, %rax; \ - subq %bits##n, %ip##n; \ - movq (%ip##n), %bits##n; \ - orq $1, %bits##n; \ - shlxq %rax, %bits##n, %bits##n; +#define RELOAD_BITS(n) \ + bsfq %bits##n, %bits##n; \ + movq %bits##n, %rax; \ + shrq $3, %bits##n; \ + andq $7, %rax; \ + subq %bits##n, %ip##n; \ + movq (%ip##n), %bits##n; \ + orq $1, %bits##n; \ + shlxq %rax, %bits##n, %bits##n - movq %olimit, 48(%rsp) + movq %olimit, 48(%rsp) - .p2align 6 + .p2align 6 .L_4X2_loop_body: -# LLVM-MCA-BEGIN decode-4X2 + /* We clobber r8, so store it on the stack */ + movq %r8, 0(%rsp) - # We clobber r8, so store it on the stack - movq %r8, 0(%rsp) + /* Decode 5 symbols from each of the 4 streams (20 symbols total). */ + FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) - # Decode 5 symbols from each of the 4 streams (20 symbols total). - FOR_EACH_STREAM_WITH_INDEX(DECODE, 0) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 1) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 2) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 3) - FOR_EACH_STREAM_WITH_INDEX(DECODE, 4) + /* Reload r8 */ + movq 0(%rsp), %r8 - # Reload r8 - movq 0(%rsp), %r8 + FOR_EACH_STREAM(RELOAD_BITS) - FOR_EACH_STREAM(RELOAD_BITS) - - cmp %op3, 48(%rsp) - ja .L_4X2_loop_body - jmp .L_4X2_compute_olimit + cmp %op3, 48(%rsp) + ja .L_4X2_loop_body + jmp .L_4X2_compute_olimit #undef DECODE #undef RELOAD_BITS -# LLVM-MCA-END .L_4X2_exit: - addq $8, %rsp - # Restore stack (oend & olimit) - pop %rax # oend0 - pop %rax # oend1 - pop %rax # oend2 - pop %rax # oend3 - pop %rax # ilimit - pop %rax # olimit - pop %rax # arg + addq $8, %rsp + /* Restore stack (oend & olimit) */ + pop %rax /* oend0 */ + pop %rax /* oend1 */ + pop %rax /* oend2 */ + pop %rax /* oend3 */ + pop %rax /* ilimit */ + pop %rax /* olimit */ + pop %rax /* arg */ - # Save ip / op / bits - movq %ip0, 0(%rax) - movq %ip1, 8(%rax) - movq %ip2, 16(%rax) - movq %ip3, 24(%rax) - movq %op0, 32(%rax) - movq %op1, 40(%rax) - movq %op2, 48(%rax) - movq %op3, 56(%rax) - movq %bits0, 64(%rax) - movq %bits1, 72(%rax) - movq %bits2, 80(%rax) - movq %bits3, 88(%rax) + /* Save ip / op / bits */ + movq %ip0, 0(%rax) + movq %ip1, 8(%rax) + movq %ip2, 16(%rax) + movq %ip3, 24(%rax) + movq %op0, 32(%rax) + movq %op1, 40(%rax) + movq %op2, 48(%rax) + movq %op3, 56(%rax) + movq %bits0, 64(%rax) + movq %bits1, 72(%rax) + movq %bits2, 80(%rax) + movq %bits3, 88(%rax) + + /* Restore registers */ + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rdx + pop %rcx + pop %rbx + pop %rax + ret - # Restore registers - pop %r15 - pop %r14 - pop %r13 - pop %r12 - pop %r11 - pop %r10 - pop %r9 - pop %r8 - pop %rdi - pop %rsi - pop %rbp - pop %rdx - pop %rcx - pop %rbx - pop %rax - ret #endif From 13cad3abb1bea4419fef9c4e5d4f79a327e89071 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 21 Oct 2021 12:52:26 -0700 Subject: [PATCH 228/274] [lazy] Speed up compilation times Speed up compilation times by moving each specialized search function into its own function. This is faster because compilers can handle many smaller functions much faster than one gigantic function. The previous approach generated one giant function with `switch` statements and inlining to select the implementation. | Compiler | Flags | Dev Time (s) | PR Time (s) | Delta | |----------|-------------------------------------|--------------|-------------|-------| | gcc | -O3 | 16.5 | 5.6 | -66% | | gcc | -O3 -g -fsanitize=address,undefined | 158.9 | 38.2 | -75% | | clang | -O3 | 36.5 | 5.5 | -85% | | clang | -O3 -g -fsanitize=address,undefined | 27.8 | 17.5 | -37% | This also reduces the binary size because the search functions are no longer inlined into the main body. | Compiler | Dev libzstd.a Size (B) | PR libzstd.a Size (B) | Delta | |----------|------------------------|-----------------------|-------| | gcc | 1563868 | 1308844 | -16% | | clang | 1924372 | 1376020 | -28% | Finally, the performance is not impacted significantly by this change, in fact we generally see a small speed boost. | Compiler | Level | Dev Speed (MB/s) | PR Speed (MB/s) | Delta | |----------|-------|------------------|-----------------|-------| | gcc | 5 | 110.6 | 110.0 | -0.5% | | gcc | 7 | 70.4 | 72.2 | +2.5% | | gcc | 9 | 53.2 | 53.5 | +0.5% | | gcc | 13 | 12.7 | 12.9 | +1.5% | | clang | 5 | 113.9 | 110.4 | -3.0% | | clang | 7 | 67.7 | 70.6 | +4.2% | | clang | 9 | 51.9 | 52.2 | +0.5% | | clang | 13 | 12.4 | 13.3 | +7.2% | The compression strategy is unmodified in this PR, so the compressed size should be exactly the same. I may have a follow up PR to slightly improve the compression ratio, if it doesn't cost too much speed. --- lib/compress/zstd_lazy.c | 375 ++++++++++++++++----------------------- 1 file changed, 155 insertions(+), 220 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 78cc5b09b..65d7990c3 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -391,54 +391,6 @@ ZSTD_BtFindBestMatch( ZSTD_matchState_t* ms, return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offsetPtr, mls, dictMode); } - -static size_t -ZSTD_BtFindBestMatch_selectMLS ( ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict); - case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict); - case 7 : - case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict); - } -} - - -static size_t ZSTD_BtFindBestMatch_dictMatchState_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState); - case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState); - case 7 : - case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState); - } -} - - -static size_t ZSTD_BtFindBestMatch_extDict_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict); - case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict); - case 7 : - case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict); - } -} - /*********************************** * Dedicated dict search ***********************************/ @@ -693,7 +645,7 @@ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) { /* inlining is important to hardwire a hot branch (template emulation) */ FORCE_INLINE_TEMPLATE -size_t ZSTD_HcFindBestMatch_generic ( +size_t ZSTD_HcFindBestMatch( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iLimit, size_t* offsetPtr, @@ -799,70 +751,6 @@ size_t ZSTD_HcFindBestMatch_generic ( return ml; } - -FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict); - case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict); - case 7 : - case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict); - } -} - - -static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState); - case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState); - case 7 : - case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState); - } -} - - -static size_t ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dedicatedDictSearch); - case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dedicatedDictSearch); - case 7 : - case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dedicatedDictSearch); - } -} - - -FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict); - case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict); - case 7 : - case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict); - } -} - /* ********************************* * (SIMD) Row-based matchfinder ***********************************/ @@ -1239,7 +1127,7 @@ ZSTD_VecMask ZSTD_row_getMatchMask(const BYTE* const tagRow, const BYTE tag, con * - Pick the longest match. */ FORCE_INLINE_TEMPLATE -size_t ZSTD_RowFindBestMatch_generic ( +size_t ZSTD_RowFindBestMatch( ZSTD_matchState_t* ms, const BYTE* const ip, const BYTE* const iLimit, size_t* offsetPtr, @@ -1415,88 +1303,168 @@ size_t ZSTD_RowFindBestMatch_generic ( return ml; } -/* Inlining is important to hardwire a hot branch (template emulation) */ -FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectMLS ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - const ZSTD_dictMode_e dictMode, size_t* offsetPtr, const U32 rowLog) -{ - switch(ms->cParams.minMatch) - { - default : /* includes case 3 */ - case 4 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, dictMode, rowLog); - case 5 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, dictMode, rowLog); - case 7 : - case 6 : return ZSTD_RowFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, dictMode, rowLog); - } -} -FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_selectRowLog ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); - switch(cappedSearchLog) - { - default : - case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 4); - case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 5); - case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_noDict, offsetPtr, 6); - } -} +typedef size_t (*searchMax_f)( + ZSTD_matchState_t* ms, + const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); -FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dictMatchState_selectRowLog( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); - switch(cappedSearchLog) - { - default : - case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 4); - case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 5); - case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dictMatchState, offsetPtr, 6); - } -} +/** + * This struct contains the functions necessary for lazy to search. + * Currently, that is only searchMax. However, it is still valuable to have the + * VTable because this makes it easier to add more functions to the VTable later. + * + * TODO: The start of the search function involves loading and calculating a + * bunch of constants from the ZSTD_matchState_t. These computations could be + * done in an initialization function, and saved somewhere in the match state. + * Then we could pass a pointer to the saved state instead of the match state, + * and avoid duplicate computations. + * + * TODO: Move the match re-winding into searchMax. This improves compression + * ratio, and unlocks further simplifications with the next TODO. + * + * TODO: Try moving the repcode search into searchMax. After the re-winding + * and repcode search are in searchMax, there is no more logic in the match + * finder loop that requires knowledge about the dictMode. So we should be + * able to avoid force inlining it, and we can join the extDict loop with + * the single segment loop. It should go in searchMax instead of its own + * function to avoid having multiple virtual function calls per search. + */ +typedef struct { + searchMax_f searchMax; +} ZSTD_LazyVTable; -FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRowLog( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); - switch(cappedSearchLog) - { - default : - case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 4); - case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 5); - case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_dedicatedDictSearch, offsetPtr, 6); - } -} +#define GEN_ZSTD_BT_VTABLE(dictMode, mls, ...) \ + static size_t ZSTD_BtFindBestMatch_##dictMode##_##mls( \ + ZSTD_matchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \ + } \ + static const ZSTD_LazyVTable ZSTD_BtVTable_##dictMode##_##mls = { \ + ZSTD_BtFindBestMatch_##dictMode##_##mls \ + }; -FORCE_INLINE_TEMPLATE size_t ZSTD_RowFindBestMatch_extDict_selectRowLog ( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* const iLimit, - size_t* offsetPtr) -{ - const U32 cappedSearchLog = MIN(ms->cParams.searchLog, 6); - switch(cappedSearchLog) - { - default : - case 4 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 4); - case 5 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 5); - case 6 : return ZSTD_RowFindBestMatch_selectMLS(ms, ip, iLimit, ZSTD_extDict, offsetPtr, 6); - } -} +#define GEN_ZSTD_HC_VTABLE(dictMode, mls, ...) \ + static size_t ZSTD_HcFindBestMatch_##dictMode##_##mls( \ + ZSTD_matchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \ + } \ + static const ZSTD_LazyVTable ZSTD_HcVTable_##dictMode##_##mls = { \ + ZSTD_HcFindBestMatch_##dictMode##_##mls \ + }; +#define GEN_ZSTD_ROW_VTABLE(dictMode, mls, rowLog) \ + static size_t ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog( \ + ZSTD_matchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \ + return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \ + } \ + static const ZSTD_LazyVTable ZSTD_RowVTable_##dictMode##_##mls##_##rowLog = { \ + ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog \ + }; + +#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \ + X(dictMode, mls, 4) \ + X(dictMode, mls, 5) \ + X(dictMode, mls, 6) + +#define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 4) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 5) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 6) + +#define ZSTD_FOR_EACH_MLS(X, dictMode) \ + X(dictMode, 4) \ + X(dictMode, 5) \ + X(dictMode, 6) + +#define ZSTD_FOR_EACH_DICT_MODE(X, ...) \ + X(__VA_ARGS__, noDict) \ + X(__VA_ARGS__, extDict) \ + X(__VA_ARGS__, dictMatchState) \ + X(__VA_ARGS__, dedicatedDictSearch) + +/* Generate Row VTables for each combination of (dictMode, mls, rowLog) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_VTABLE) +/* Generate Binary Tree VTables for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_VTABLE) +/* Generate Hash Chain VTables for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_VTABLE) + +#define GEN_ZSTD_BT_VTABLE_ARRAY(dictMode) \ + { \ + &ZSTD_BtVTable_##dictMode##_4, \ + &ZSTD_BtVTable_##dictMode##_5, \ + &ZSTD_BtVTable_##dictMode##_6 \ + } + +#define GEN_ZSTD_HC_VTABLE_ARRAY(dictMode) \ + { \ + &ZSTD_HcVTable_##dictMode##_4, \ + &ZSTD_HcVTable_##dictMode##_5, \ + &ZSTD_HcVTable_##dictMode##_6 \ + } + +#define GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, mls) \ + { \ + &ZSTD_RowVTable_##dictMode##_##mls##_4, \ + &ZSTD_RowVTable_##dictMode##_##mls##_5, \ + &ZSTD_RowVTable_##dictMode##_##mls##_6 \ + } + +#define GEN_ZSTD_ROW_VTABLE_ARRAY(dictMode) \ + { \ + GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 4), \ + GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 5), \ + GEN_ZSTD_ROW_VTABLE_ARRAY_(dictMode, 6) \ + } + +#define GEN_ZSTD_VTABLE_ARRAY(X) \ + { \ + X(noDict), \ + X(extDict), \ + X(dictMatchState), \ + X(dedicatedDictSearch) \ + } /* ******************************* * Common parser - lazy strategy *********************************/ typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e; + +static ZSTD_LazyVTable const* ZSTD_selectLazyVTable(ZSTD_matchState_t const* ms, searchMethod_e searchMethod, ZSTD_dictMode_e dictMode) +{ + /* Fill the Hc/Bt VTable arrays with the right functions for the (dictMode, mls) combination. */ + ZSTD_LazyVTable const* const hcVTables[4][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_HC_VTABLE_ARRAY); + ZSTD_LazyVTable const* const btVTables[4][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_BT_VTABLE_ARRAY); + /* Fill the Row VTable array with the right functions for the (dictMode, mls, rowLog) combination. */ + ZSTD_LazyVTable const* const rowVTables[4][3][3] = GEN_ZSTD_VTABLE_ARRAY(GEN_ZSTD_ROW_VTABLE_ARRAY); + + U32 const mls = MAX(4, MIN(6, ms->cParams.minMatch)); + U32 const rowLog = MAX(4, MIN(6, ms->cParams.searchLog)); + switch (searchMethod) { + case search_hashChain: + return hcVTables[dictMode][mls - 4]; + case search_binaryTree: + return btVTables[dictMode][mls - 4]; + case search_rowHash: + return rowVTables[dictMode][mls - 4][rowLog - 4]; + default: + return NULL; + } +} + FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_lazy_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, @@ -1515,9 +1483,6 @@ ZSTD_compressBlock_lazy_generic( const BYTE* const prefixLowest = base + prefixLowestIndex; const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5; - typedef size_t (*searchMax_f)( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); /** * This table is indexed first by the four ZSTD_dictMode_e values, and then @@ -1525,30 +1490,8 @@ ZSTD_compressBlock_lazy_generic( * that should never occur (extDict modes go to the other implementation * below and there is no DDSS for binary tree search yet). */ - const searchMax_f searchFuncs[4][3] = { - { - ZSTD_HcFindBestMatch_selectMLS, - ZSTD_BtFindBestMatch_selectMLS, - ZSTD_RowFindBestMatch_selectRowLog - }, - { - NULL, - NULL, - NULL - }, - { - ZSTD_HcFindBestMatch_dictMatchState_selectMLS, - ZSTD_BtFindBestMatch_dictMatchState_selectMLS, - ZSTD_RowFindBestMatch_dictMatchState_selectRowLog - }, - { - ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS, - NULL, - ZSTD_RowFindBestMatch_dedicatedDictSearch_selectRowLog - } - }; - searchMax_f const searchMax = searchFuncs[dictMode][(int)searchMethod]; + searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, dictMode)->searchMax; U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0; const int isDMS = dictMode == ZSTD_dictMatchState; @@ -1939,15 +1882,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( const U32 windowLog = ms->cParams.windowLog; const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5; - typedef size_t (*searchMax_f)( - ZSTD_matchState_t* ms, - const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); - const searchMax_f searchFuncs[3] = { - ZSTD_HcFindBestMatch_extDict_selectMLS, - ZSTD_BtFindBestMatch_extDict_selectMLS, - ZSTD_RowFindBestMatch_extDict_selectRowLog - }; - searchMax_f searchMax = searchFuncs[(int)searchMethod]; + searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, ZSTD_extDict)->searchMax; U32 offset_1 = rep[0], offset_2 = rep[1]; DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod); From 6a7ede3dfccbf3e0a5928b4224a039c260dcff72 Mon Sep 17 00:00:00 2001 From: binhdvo Date: Mon, 25 Oct 2021 10:38:01 -0400 Subject: [PATCH 229/274] Reduce size of dctx by reutilizing dst buffer (#2751) * Reduce size of dctx by reutilizing dst buffer Co-authored-by: Binh Vo --- lib/README.md | 6 + lib/common/zstd_internal.h | 4 +- lib/decompress/zstd_decompress.c | 7 +- lib/decompress/zstd_decompress_block.c | 726 +++++++++++++++++++--- lib/decompress/zstd_decompress_block.h | 8 +- lib/decompress/zstd_decompress_internal.h | 15 +- tests/fullbench.c | 6 +- 7 files changed, 666 insertions(+), 106 deletions(-) diff --git a/lib/README.md b/lib/README.md index f781ac57e..9cbeb8d4f 100644 --- a/lib/README.md +++ b/lib/README.md @@ -155,6 +155,12 @@ 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. + #### Windows : using MinGW+MSYS to create DLL diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index efd7360a0..eaa0afc90 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -181,7 +181,7 @@ static void ZSTD_copy16(void* dst, const void* src) { #if defined(ZSTD_ARCH_ARM_NEON) vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src)); #else - ZSTD_memcpy(dst, src, 16); + ZSTD_memmove(dst, src, 16); #endif } #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; } @@ -210,8 +210,6 @@ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e BYTE* op = (BYTE*)dst; BYTE* const oend = op + length; - assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN)); - if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) { /* Handle short offset copies. */ do { diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 3307975a1..b5ccac53c 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -916,7 +916,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, switch(blockProperties.blockType) { case bt_compressed: - decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1); + decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1, not_streaming); break; case bt_raw : decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize); @@ -1229,7 +1229,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c { case bt_compressed: DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed"); - rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1); + rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming); dctx->expected = 0; /* Streaming not supported */ break; case bt_raw : @@ -1824,7 +1824,8 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) { size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); - unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2); + /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/ + unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2); unsigned long long const neededSize = MIN(frameContentSize, neededRBSize); size_t const minRBSize = (size_t) neededSize; RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize, diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 054e62526..c2902eeec 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -69,15 +69,56 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, } } +/* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */ +static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize, + const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately) +{ + if (streaming == not_streaming && dstCapacity > ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) + { + /* room for litbuffer to fit without read faulting */ + dctx->litBuffer = (BYTE*)dst + ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_in_dst; + } + else if (litSize > ZSTD_LITBUFFEREXTRASIZE) + { + /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ + if (splitImmediately) { + /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE; + } + else { + /* initially this will be stored entirely in dst during huffman decoding, it will partially shifted to litExtraBuffer after */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize; + dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize; + } + dctx->litBufferLocation = ZSTD_split; + } + else + { + /* fits entirely within litExtraBuffer, so no split is necessary */ + dctx->litBuffer = dctx->litExtraBuffer; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + } +} /* Hidden declaration for fullbench */ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, - const void* src, size_t srcSize); + const void* src, size_t srcSize, + void* dst, size_t dstCapacity, const streaming_operation streaming); /*! ZSTD_decodeLiteralsBlock() : + * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored + * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current + * block will be output. Otherwise it will be stored at the end of the current dst blockspace, with a small portion being + * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write. + * * @return : nb of bytes read from src (< srcSize ) * note : symbol not declared but exposed for fullbench */ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, - const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */ + const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */ + void* dst, size_t dstCapacity, const streaming_operation streaming) { DEBUGLOG(5, "ZSTD_decodeLiteralsBlock"); RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, ""); @@ -99,6 +140,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, U32 const lhlCode = (istart[0] >> 2) & 3; U32 const lhc = MEM_readLE32(istart); size_t hufSuccess; + size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity); switch(lhlCode) { case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ @@ -121,8 +163,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, litCSize = (lhc >> 22) + ((size_t)istart[4] << 10); break; } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0); /* prefetch huffman table if cold */ if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) { @@ -159,6 +204,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx)); } } + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE); + dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd -= WILDCOPY_OVERLENGTH; + } RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, ""); @@ -166,13 +218,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, dctx->litSize = litSize; dctx->litEntropy = 1; if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; - ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return litCSize + lhSize; } case set_basic: { size_t litSize, lhSize; U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity); switch(lhlCode) { case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ @@ -189,23 +241,36 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, break; } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, ""); - ZSTD_memcpy(dctx->litBuffer, istart+lhSize, litSize); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize); + } dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; - ZSTD_memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); return lhSize+litSize; } /* direct reference into compressed stream */ dctx->litPtr = istart+lhSize; dctx->litSize = litSize; + dctx->litBufferEnd = dctx->litPtr + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; return lhSize+litSize; } case set_rle: { U32 const lhlCode = ((istart[0]) >> 2) & 3; size_t litSize, lhSize; + size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity); switch(lhlCode) { case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ @@ -222,8 +287,19 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4"); break; } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, ""); - ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize); + } dctx->litPtr = dctx->litBuffer; dctx->litSize = litSize; return lhSize+1; @@ -713,7 +789,7 @@ HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) { * - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart. * The src buffer must be before the dst buffer. */ -static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) { +static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) { ptrdiff_t const diff = op - ip; BYTE* const oend = op + length; @@ -729,6 +805,7 @@ static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_ /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */ assert(length >= 8); ZSTD_overlapCopy8(&op, &ip, diff); + length -= 8; assert(op - ip >= 8); assert(op <= oend); } @@ -743,12 +820,35 @@ static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_ assert(oend > oend_w); ZSTD_wildcopy(op, ip, oend_w - op, ovtype); ip += oend_w - op; - op = oend_w; + op += oend_w - op; } /* Handle the leftovers. */ while (op < oend) *op++ = *ip++; } +/* ZSTD_safecopyDstBeforeSrc(): + * This version allows overlap with dst before src, or handles the non-overlap case with dst after src + * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */ +static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + if (length < 8 || diff > -8) { + /* Handle short lengths, close overlaps, and dst not before src. */ + while (op < oend) *op++ = *ip++; + return; + } + + if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) { + ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap); + ip += oend - WILDCOPY_OVERLENGTH - op; + op += oend - WILDCOPY_OVERLENGTH - op; + } + + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + /* ZSTD_execSequenceEnd(): * This version handles cases that are near the end of the output buffer. It requires * more careful checks to make sure there is no overflow. By separating out these hard @@ -759,9 +859,9 @@ static void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_ */ FORCE_NOINLINE size_t ZSTD_execSequenceEnd(BYTE* op, - BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, - const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) { BYTE* const oLitEnd = op + sequence.litLength; size_t const sequenceLength = sequence.litLength + sequence.matchLength; @@ -784,27 +884,76 @@ size_t ZSTD_execSequenceEnd(BYTE* op, if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { /* offset beyond prefix */ RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); - match = dictEnd - (prefixStart-match); + match = dictEnd - (prefixStart - match); if (match + sequence.matchLength <= dictEnd) { ZSTD_memmove(oLitEnd, match, sequence.matchLength); return sequenceLength; } /* span extDict & currentPrefixSegment */ { size_t const length1 = dictEnd - match; - ZSTD_memmove(oLitEnd, match, length1); - op = oLitEnd + length1; - sequence.matchLength -= length1; - match = prefixStart; - } } + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +/* ZSTD_execSequenceEndSplitLitBuffer(): + * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case. + */ +FORCE_NOINLINE +size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer"); + ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); return sequenceLength; } HINT_INLINE size_t ZSTD_execSequence(BYTE* op, - BYTE* const oend, seq_t sequence, - const BYTE** litPtr, const BYTE* const litLimit, - const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) { BYTE* const oLitEnd = op + sequence.litLength; size_t const sequenceLength = sequence.litLength + sequence.matchLength; @@ -813,6 +962,98 @@ size_t ZSTD_execSequence(BYTE* op, const BYTE* const iLitEnd = *litPtr + sequence.litLength; const BYTE* match = oLitEnd - sequence.offset; + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + +HINT_INLINE +size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + assert(op != NULL /* Precondition */); assert(oend_w < oend /* No underflow */); /* Handle edge cases in a slow path: @@ -824,7 +1065,7 @@ size_t ZSTD_execSequence(BYTE* op, iLitEnd > litLimit || oMatchEnd > oend_w || (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) - return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ assert(op <= oLitEnd /* No overflow */); @@ -892,6 +1133,7 @@ size_t ZSTD_execSequence(BYTE* op, return sequenceLength; } + static void ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) { @@ -1073,9 +1315,11 @@ MEM_STATIC void ZSTD_assertValidSequence( #endif #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + + FORCE_INLINE_TEMPLATE size_t DONT_VECTORIZE -ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, +ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, const ZSTD_longOffset_e isLongOffset, @@ -1087,11 +1331,11 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, BYTE* const oend = ostart + maxDstSize; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* litBufferEnd = dctx->litBufferEnd; const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); - DEBUGLOG(5, "ZSTD_decompressSequences_body"); + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer"); (void)frame; /* Regen sequences */ @@ -1112,55 +1356,237 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, BIT_DStream_endOfBuffer < BIT_DStream_completed && BIT_DStream_completed < BIT_DStream_overflow); + /* decompress without overrunning litPtr begins */ + { + seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + /* Align the decompression loop to 32 + 16 bytes. + * + * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression + * speed swings based on the alignment of the decompression loop. This + * performance swing is caused by parts of the decompression loop falling + * out of the DSB. The entire decompression loop should fit in the DSB, + * when it can't we get much worse performance. You can measure if you've + * hit the good case or the bad case with this perf command for some + * compressed file test.zst: + * + * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \ + * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst + * + * If you see most cycles served out of the MITE you've hit the bad case. + * If you see most cycles served out of the DSB you've hit the good case. + * If it is pretty even then you may be in an okay case. + * + * This issue has been reproduced on the following CPUs: + * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9 + * Use Instruments->Counters to get DSB/MITE cycles. + * I never got performance swings, but I was able to + * go from the good case of mostly DSB to half of the + * cycles served from MITE. + * - Coffeelake: Intel i9-9900k + * - Coffeelake: Intel i7-9700k + * + * I haven't been able to reproduce the instability or DSB misses on any + * of the following CPUS: + * - Haswell + * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH + * - Skylake + * + * Alignment is done for each of the three major decompression loops: + * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer + * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer + * - ZSTD_decompressSequences_body + * Alignment choices are made to minimize large swings on bad cases and influence on performance + * from changes external to this code, rather than to overoptimize on the current commit. + * + * If you are seeing performance stability this script can help test. + * It tests on 4 commits in zstd where I saw performance change. + * + * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4 + */ #if defined(__GNUC__) && defined(__x86_64__) - /* Align the decompression loop to 32 + 16 bytes. - * - * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression - * speed swings based on the alignment of the decompression loop. This - * performance swing is caused by parts of the decompression loop falling - * out of the DSB. The entire decompression loop should fit in the DSB, - * when it can't we get much worse performance. You can measure if you've - * hit the good case or the bad case with this perf command for some - * compressed file test.zst: - * - * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \ - * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst - * - * If you see most cycles served out of the MITE you've hit the bad case. - * If you see most cycles served out of the DSB you've hit the good case. - * If it is pretty even then you may be in an okay case. - * - * This issue has been reproduced on the following CPUs: - * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9 - * Use Instruments->Counters to get DSB/MITE cycles. - * I never got performance swings, but I was able to - * go from the good case of mostly DSB to half of the - * cycles served from MITE. - * - Coffeelake: Intel i9-9900k - * - Coffeelake: Intel i7-9700k - * - * I haven't been able to reproduce the instability or DSB misses on any - * of the following CPUS: - * - Haswell - * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH - * - Skylake - * - * If you are seeing performance stability this script can help test. - * It tests on 4 commits in zstd where I saw performance change. - * - * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4 - */ - __asm__(".p2align 6"); - __asm__("nop"); - __asm__(".p2align 5"); - __asm__("nop"); -# if __GNUC__ >= 9 && __GNUC__ < 11 - /* better for gcc-9 and gcc-10, worse for clang and gcc-8, gcc-11 */ - __asm__(".p2align 3"); -# else - __asm__(".p2align 4"); + __asm__(".p2align 6"); +# if __GNUC__ >= 7 + /* good for gcc-7, gcc-9, and gcc-11 */ + __asm__("nop"); + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 4"); +# if __GNUC__ == 8 || __GNUC__ == 10 + /* good for gcc-8 and gcc-10 */ + __asm__("nop"); + __asm__(".p2align 3"); +# endif # endif #endif + + /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */ + for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) { + size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + if (UNLIKELY(!--nbSeq)) + break; + BIT_reloadDStream(&(seqState.DStream)); + sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + } + + /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */ + if (nbSeq > 0) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) + { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence.litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + if (--nbSeq) + BIT_reloadDStream(&(seqState.DStream)); + } + } + } + + if (nbSeq > 0) /* there is remaining lit from extra buffer */ + { + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ != 7 + /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */ + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# elif __GNUC__ >= 11 + __asm__(".p2align 3"); +# else + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for (; ; ) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + if (UNLIKELY(!--nbSeq)) + break; + BIT_reloadDStream(&(seqState.DStream)); + } + } + + /* check if reached exact end */ + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq); + RETURN_ERROR_IF(nbSeq, corruption_detected, ""); + RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */ + { + size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + } + { size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } + } + + return op-ostart; +} + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset, + const int frame) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart + maxDstSize : dctx->litBuffer; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart); + const BYTE* const vBase = (const BYTE*)(dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_body"); + (void)frame; + + /* Regen sequences */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + + ZSTD_STATIC_ASSERT( + BIT_DStream_unfinished < BIT_DStream_completed && + BIT_DStream_endOfBuffer < BIT_DStream_completed && + BIT_DStream_completed < BIT_DStream_overflow); + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ >= 7 + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# else + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + for ( ; ; ) { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); @@ -1206,6 +1632,16 @@ ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, { return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } + +static size_t +ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset, + const int frame) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); +} #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT @@ -1241,7 +1677,7 @@ ZSTD_decompressSequencesLong_body( BYTE* const oend = ostart + maxDstSize; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; - const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* litBufferEnd = dctx->litBufferEnd; const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); @@ -1277,32 +1713,94 @@ ZSTD_decompressSequencesLong_body( } RETURN_ERROR_IF(seqNblitBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) + { + /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */ + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) + { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } + else + { + /* lit buffer is either wholly contained in first or second split, or not split at all*/ + oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } } RETURN_ERROR_IF(seqNblitBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) + { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) + { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence->litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { + size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) - assert(!ZSTD_isError(oneSeqSize)); - if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); #endif - if (ZSTD_isError(oneSeqSize)) return oneSeqSize; - op += oneSeqSize; + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + else + { + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } } /* save reps for next block */ @@ -1310,10 +1808,21 @@ ZSTD_decompressSequencesLong_body( } /* last literal segment */ - { size_t const lastLLSize = litEnd - litPtr; + if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */ + { + size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + } + { size_t const lastLLSize = litBufferEnd - litPtr; RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); if (op != NULL) { - ZSTD_memcpy(op, litPtr, lastLLSize); + ZSTD_memmove(op, litPtr, lastLLSize); op += lastLLSize; } } @@ -1347,6 +1856,16 @@ ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, { return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } +static TARGET_ATTRIBUTE("bmi2") size_t +DONT_VECTORIZE +ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset, + const int frame) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); +} #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT @@ -1383,7 +1902,21 @@ ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } #endif - return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); +} +static size_t +ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset, + const int frame) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); + } +#endif + return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ @@ -1444,7 +1977,7 @@ ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable) size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, - const void* src, size_t srcSize, const int frame) + const void* src, size_t srcSize, const int frame, const streaming_operation streaming) { /* blockType == blockCompressed */ const BYTE* ip = (const BYTE*)src; /* isLongOffset must be true if there are long offsets. @@ -1459,7 +1992,7 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong, ""); /* Decode literals section */ - { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); + { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming); DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize); if (ZSTD_isError(litCSize)) return litCSize; ip += litCSize; @@ -1507,7 +2040,10 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG /* else */ - return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame); + if (dctx->litBufferLocation == ZSTD_split) + return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame); + else + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame); #endif } } @@ -1530,7 +2066,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, { size_t dSize; ZSTD_checkContinuity(dctx, dst, dstCapacity); - dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0); + dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming); dctx->previousDstEnd = (char*)dst + dSize; return dSize; } diff --git a/lib/decompress/zstd_decompress_block.h b/lib/decompress/zstd_decompress_block.h index 049a0cd84..4828d6a9f 100644 --- a/lib/decompress/zstd_decompress_block.h +++ b/lib/decompress/zstd_decompress_block.h @@ -33,6 +33,12 @@ */ + /* Streaming state is used to inform allocation of the literal buffer */ +typedef enum { + not_streaming = 0, + is_streaming = 1 +} streaming_operation; + /* ZSTD_decompressBlock_internal() : * decompress block, starting at `src`, * into destination buffer `dst`. @@ -41,7 +47,7 @@ */ size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, - const void* src, size_t srcSize, const int frame); + const void* src, size_t srcSize, const int frame, const streaming_operation streaming); /* ZSTD_buildFSETable() : * generate FSE decoding table for one symbol (ll, ml or off) diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index 4853f7f1f..ac5586cc7 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -106,6 +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 */ +#endif + +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) */ + ZSTD_split = 2 /* Split between litExtraBuffer and dst */ +} ZSTD_litLocation_e; + struct ZSTD_DCtx_s { const ZSTD_seqSymbol* LLTptr; @@ -171,7 +181,10 @@ struct ZSTD_DCtx_s ZSTD_outBuffer expectedOutBuffer; /* workspace */ - BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; + BYTE* litBuffer; + const BYTE* litBufferEnd; + ZSTD_litLocation_e litBufferLocation; + BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; size_t oversizedDuration; diff --git a/tests/fullbench.c b/tests/fullbench.c index dc20b837b..d190a872d 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -123,11 +123,11 @@ static size_t local_ZSTD_decompress(const void* src, size_t srcSize, static ZSTD_DCtx* g_zdc = NULL; #ifndef ZSTD_DLL_IMPORT -extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize); +extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize, void* dst, size_t dstCapacity); static size_t local_ZSTD_decodeLiteralsBlock(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) { (void)src; (void)srcSize; (void)dst; (void)dstSize; - return ZSTD_decodeLiteralsBlock(g_zdc, buff2, g_cSize); + return ZSTD_decodeLiteralsBlock(g_zdc, buff2, g_cSize, dst, dstSize); } static size_t local_ZSTD_decodeSeqHeaders(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) @@ -577,7 +577,7 @@ static int benchMem(unsigned benchNb, ip += ZSTD_blockHeaderSize; /* skip block header */ ZSTD_decompressBegin(g_zdc); CONTROL(iend > ip); - ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, (size_t)(iend-ip)); /* skip literal segment */ + ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, (size_t)(iend-ip), dstBuff, dstBuffSize); /* skip literal segment */ g_cSize = (size_t)(iend-ip); memcpy(dstBuff2, ip, g_cSize); /* copy rest of block (it starts by SeqHeader) */ srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ From 02be2a830f20e5801386be87d7f816776a068516 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 25 Oct 2021 08:09:04 -0700 Subject: [PATCH 230/274] build macro ZSTD_DECODER_INTERNAL_BUFFER just to make the topic more accessible for potential users. --- lib/README.md | 10 +++++----- lib/decompress/zstd_decompress_internal.h | 9 +++++++-- 2 files changed, 12 insertions(+), 7 deletions(-) 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/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index ac5586cc7..7f555911d 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -106,10 +106,15 @@ 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_LBMAX (128 << 10) + +/* extra buffer, compensates amount of dst required to store litBuffer */ +#define ZSTD_LITBUFFEREXTRASIZE MIN(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) */ From 082d6c67751275a0e2c48b63a9e7db0225f4560b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 25 Oct 2021 08:49:54 -0700 Subject: [PATCH 231/274] separate compression level tables into their own files that's clearer than finding the tables somewhere in the middle of `compress.c`. Also, down the line, it may potentially allows zstd to feature adjusted tables depending on target cpu. --- lib/compress/clevels.h | 134 +++++++++++++++++++++++++++++++++++ lib/compress/zstd_compress.c | 109 +--------------------------- 2 files changed, 135 insertions(+), 108 deletions(-) create mode 100644 lib/compress/clevels.h diff --git a/lib/compress/clevels.h b/lib/compress/clevels.h new file mode 100644 index 000000000..9fa6adb5f --- /dev/null +++ b/lib/compress/clevels.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CLEVELS_H +#define ZSTD_CLEVELS_H + +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */ +#include "../zstd.h" + +/*-===== Pre-defined compression levels =====-*/ + +#define ZSTD_MAX_CLEVEL 22 + +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif + +static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { +{ /* "default" - for any srcSize > 256 KB */ + /* W, C, H, S, L, TL, strat */ + { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ + { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */ + { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ + { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ + { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ + { 21, 18, 19, 4, 5, 2, ZSTD_greedy }, /* level 5 */ + { 21, 19, 20, 5, 5, 4, ZSTD_greedy }, /* level 6 */ + { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ + { 21, 19, 20, 5, 5, 16, ZSTD_lazy }, /* level 8 */ + { 21, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 22, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ + { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 11 */ + { 22, 21, 22, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ + { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ + { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ + { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ + { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */ + { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */ + { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */ + { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */ + { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */ + { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */ + { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */ +}, +{ /* for srcSize <= 256 KB */ + /* W, C, H, S, L, T, strat */ + { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ + { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ + { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ + { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/ + { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ + { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ + { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ + { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ + { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 128 KB */ + /* W, C, H, S, L, T, strat */ + { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ + { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ + { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ + { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ + { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ + { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ + { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ + { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ + { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/ + { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/ + { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 16 KB */ + /* W, C, H, S, L, T, strat */ + { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */ + { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */ + { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */ + { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */ + { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/ + { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */ + { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/ + { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/ + { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/ + { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/ + { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/ + { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/ + { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/ + { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/ + { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/ + { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +}; + + + +#endif /* ZSTD_CLEVELS_H */ diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index edfd7eb07..a4b95f053 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -6174,119 +6174,12 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) /*-===== Pre-defined compression levels =====-*/ +#include "clevels.h" -#define ZSTD_MAX_CLEVEL 22 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; } -static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { -{ /* "default" - for any srcSize > 256 KB */ - /* W, C, H, S, L, TL, strat */ - { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ - { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */ - { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ - { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ - { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ - { 21, 18, 19, 4, 5, 2, ZSTD_greedy }, /* level 5 */ - { 21, 19, 20, 5, 5, 4, ZSTD_greedy }, /* level 6 */ - { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ - { 21, 19, 20, 5, 5, 16, ZSTD_lazy }, /* level 8 */ - { 21, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ - { 22, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */ - { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 11 */ - { 22, 21, 22, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ - { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ - { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ - { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ - { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */ - { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */ - { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */ - { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */ - { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */ - { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */ - { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */ -}, -{ /* for srcSize <= 256 KB */ - /* W, C, H, S, L, T, strat */ - { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ - { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ - { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ - { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ - { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ - { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/ - { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ - { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ - { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ - { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ - { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ - { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ - { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ - { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ - { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ - { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/ - { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/ - { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/ - { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/ - { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ - { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/ - { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/ - { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/ -}, -{ /* for srcSize <= 128 KB */ - /* W, C, H, S, L, T, strat */ - { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ - { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */ - { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ - { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ - { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ - { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ - { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ - { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ - { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ - { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ - { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ - { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ - { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ - { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ - { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ - { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/ - { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/ - { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/ - { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/ - { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/ - { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/ - { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ - { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/ -}, -{ /* for srcSize <= 16 KB */ - /* W, C, H, S, L, T, strat */ - { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ - { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */ - { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */ - { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */ - { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */ - { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/ - { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */ - { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */ - { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/ - { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/ - { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/ - { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/ - { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/ - { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/ - { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/ - { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/ - { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/ - { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/ - { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/ - { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ - { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/ - { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ - { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/ -}, -}; - static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize) { ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict); From 518f06b2818cc77425ac502eb1c8575359f16431 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 26 Oct 2021 08:21:31 -0700 Subject: [PATCH 232/274] added minimum for decoder buffer also : introduced macro BOUNDED() --- lib/common/zstd_internal.h | 1 + lib/compress/zstd_compress.c | 4 ++-- lib/compress/zstd_lazy.c | 2 +- lib/decompress/zstd_decompress.c | 2 +- lib/decompress/zstd_decompress_internal.h | 5 +++-- 5 files changed, 8 insertions(+), 6 deletions(-) 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 edfd7eb07..656d3fdfa 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 = BOUNDED(1, 1 << 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 78cc5b09b..566da2d45 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1086,7 +1086,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 7f555911d..51dc34729 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -110,10 +110,11 @@ typedef struct { # define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16) #endif +#define ZSTD_LBMIN 64 #define ZSTD_LBMAX (128 << 10) -/* extra buffer, compensates amount of dst required to store litBuffer */ -#define ZSTD_LITBUFFEREXTRASIZE MIN(ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) +/* 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 */ From 2b2a5c449a7b522c6ea2626d82b8412826e2cfb2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 26 Oct 2021 08:38:17 -0700 Subject: [PATCH 233/274] fix minor cast warning --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 656d3fdfa..4bd3abde6 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 = BOUNDED(1, 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; From 23dd28df67bfd26d7e8f20a4420426158a2ebedd Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 26 Oct 2021 23:23:30 -0700 Subject: [PATCH 234/274] minor improvements to benchmark display --- programs/benchzstd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/benchzstd.c b/programs/benchzstd.c index 09035ea45..1e4d717d1 100644 --- a/programs/benchzstd.c +++ b/programs/benchzstd.c @@ -452,11 +452,11 @@ BMK_benchMemAdvancedNoAlloc( { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; assert(cSize < UINT_MAX); - OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s\r", + OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (x%5.*f), %6.*f MB/s \r", marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratioAccuracy, ratio, - benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); + benchResult.cSpeed < (10 * MB_UNIT) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT); } compressionCompleted = BMK_isCompleted_TimedFn(timeStateCompress); } @@ -475,11 +475,11 @@ BMK_benchMemAdvancedNoAlloc( } { int const ratioAccuracy = (ratio < 10.) ? 3 : 2; - OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (%5.*f), %6.*f MB/s, %6.1f MB/s \r", + OUTPUTLEVEL(2, "%2s-%-17.17s :%10u ->%10u (x%5.*f), %6.*f MB/s, %6.1f MB/s\r", marks[markNb], displayName, (unsigned)srcSize, (unsigned)cSize, ratioAccuracy, ratio, - benchResult.cSpeed < (10 MB) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, + benchResult.cSpeed < (10 * MB_UNIT) ? 2 : 1, (double)benchResult.cSpeed / MB_UNIT, (double)benchResult.dSpeed / MB_UNIT); } decompressionCompleted = BMK_isCompleted_TimedFn(timeStateDecompress); From 04734ee84a10466b4ada0edaa086f7a0a948c5fe Mon Sep 17 00:00:00 2001 From: binhdvo Date: Fri, 29 Oct 2021 10:29:50 -0400 Subject: [PATCH 235/274] Fix oss fuzz test error (#2837) --- lib/decompress/zstd_decompress_block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index c2902eeec..79a44d9cb 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -1674,7 +1674,7 @@ ZSTD_decompressSequencesLong_body( const BYTE* ip = (const BYTE*)seqStart; const BYTE* const iend = ip + seqSize; BYTE* const ostart = (BYTE*)dst; - BYTE* const oend = ostart + maxDstSize; + BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart + maxDstSize; BYTE* op = ostart; const BYTE* litPtr = dctx->litPtr; const BYTE* litBufferEnd = dctx->litBufferEnd; From b399b4746796f3f363ff19df89fcb1d478829b61 Mon Sep 17 00:00:00 2001 From: binhdvo Date: Tue, 2 Nov 2021 13:17:55 -0400 Subject: [PATCH 236/274] Move mingw tests from appveyor to github actions (#2838) --- .github/workflows/dev-long-tests.yml | 53 +++++++++++++++++++++++++ .github/workflows/dev-short-tests.yml | 36 +++++++++++++++++ appveyor.yml | 42 +------------------- lib/compress/zstd_compress_superblock.c | 1 + 4 files changed, 91 insertions(+), 41 deletions(-) diff --git a/.github/workflows/dev-long-tests.yml b/.github/workflows/dev-long-tests.yml index 0f0c36e33..3967d186f 100644 --- a/.github/workflows/dev-long-tests.yml +++ b/.github/workflows/dev-long-tests.yml @@ -150,6 +150,59 @@ jobs: make clean make -C tests test-fuzzer-stackmode + mingw-long-test: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + include: [ + { compiler: clang, platform: x64, action: build, script: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion -Wno-unused-command-line-argument -Wno-implicit-int-float-conversion' make -j allzstd V=1"}, + { compiler: gcc, platform: x64, action: test, script: ""}, + ] + steps: + - uses: actions/checkout@v2 + - name: Mingw long test + run: | + $env:PATH_ORIGINAL = $env:PATH + $env:PATH_MINGW32 = "C:\msys64\mingw32\bin" + $env:PATH_MINGW64 = "C:\msys64\mingw64\bin" + COPY C:\msys64\usr\bin\make.exe C:\msys64\mingw32\bin\make.exe + COPY C:\msys64\usr\bin\make.exe C:\msys64\mingw64\bin\make.exe + IF ("${{matrix.platform}}" -eq "x64") + { + $env:PATH = $env:PATH_MINGW64 + ";" + $env:PATH_ORIGINAL + } + ELSEIF ("${{matrix.platform}}" -eq "x86") + { + $env:PATH = $env:PATH_MINGW32 + ";" + $env:PATH_ORIGINAL + } + IF ("${{matrix.action}}" -eq "build") + { + make -v + sh -c "${{matrix.compiler}} -v" + ECHO "Building zlib to static link" + $env:CC = "${{matrix.compiler}}" + sh -c "cd .. && git clone --depth 1 --branch v1.2.11 https://github.com/madler/zlib" + sh -c "cd ../zlib && make -f win32/Makefile.gcc libz.a" + ECHO "Building zstd" + $env:CPPFLAGS = "-I../../zlib" + $env:LDFLAGS = "../../zlib/libz.a" + sh -c "${{matrix.script}}" + } + ELSEIF ("${{matrix.action}}" -eq "test") + { + ECHO "Testing ${{matrix.compiler}} ${{matrix.platform}}" + $env:CC = "gcc" + $env:CXX = "g++" + MKDIR build\cmake\build + CD build\cmake\build + $env:FUZZERTEST = "-T2mn" + $env:ZSTREAM_TESTTIME = "-T2mn" + cmake -G "Visual Studio 14 2015 Win64" .. + cd ..\..\.. + make clean + } + # lasts ~20mn oss-fuzz: runs-on: ubuntu-latest diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index df6b7ed46..8c1e29129 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -296,6 +296,42 @@ jobs: run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check + mingw-short-test: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + include: [ + { compiler: gcc, platform: x64, script: "CFLAGS=-Werror make -j allzstd DEBUGLEVEL=2"}, + { compiler: gcc, platform: x86, script: "CFLAGS=-Werror make -j allzstd"}, + { compiler: clang, platform: x64, script: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1"}, + ] + steps: + - uses: actions/checkout@v2 + - name: Mingw short test + run: | + ECHO "Building ${{matrix.compiler}} ${{matrix.platform}}" + $env:PATH_ORIGINAL = $env:PATH + $env:PATH_MINGW32 = "C:\msys64\mingw32\bin" + $env:PATH_MINGW64 = "C:\msys64\mingw64\bin" + COPY C:\msys64\usr\bin\make.exe C:\msys64\mingw32\bin\make.exe + COPY C:\msys64\usr\bin\make.exe C:\msys64\mingw64\bin\make.exe + IF ("${{matrix.platform}}" -eq "x64") + { + $env:PATH = $env:PATH_MINGW64 + ";" + $env:PATH_ORIGINAL + } + ELSEIF ("${{matrix.platform}}" -eq "x86") + { + $env:PATH = $env:PATH_MINGW32 + ";" + $env:PATH_ORIGINAL + } + make -v + sh -c "${{matrix.compiler}} -v" + $env:CC = "${{matrix.compiler}}" + sh -c "${{matrix.script}}" + ECHO "Testing ${{matrix.compiler}} ${{matrix.platform}}" + make clean + make check + # This test currently fails on Github Actions specifically. # Possible reason : TTY emulation. # Note that the same test works fine locally and on travisCI. diff --git a/appveyor.yml b/appveyor.yml index a7eeb3f1f..2656ca709 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,17 +23,6 @@ SCRIPT: "make allzstd MOREFLAGS=-static" ARTIFACT: "true" BUILD: "true" - - COMPILER: "clang" - HOST: "mingw" - PLATFORM: "x64" - SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1" - BUILD: "true" - - - COMPILER: "gcc" - HOST: "mingw" - PLATFORM: "x64" - SCRIPT: "" - TEST: "cmake" - COMPILER: "visual" HOST: "visual" @@ -201,18 +190,6 @@ - COMPILER: "gcc" HOST: "cygwin" PLATFORM: "x64" - - COMPILER: "gcc" - HOST: "mingw" - PLATFORM: "x64" - SCRIPT: "CFLAGS=-Werror make -j allzstd DEBUGLEVEL=2" - - COMPILER: "gcc" - HOST: "mingw" - PLATFORM: "x86" - SCRIPT: "CFLAGS=-Werror make -j allzstd" - - COMPILER: "clang" - HOST: "mingw" - PLATFORM: "x64" - SCRIPT: "CFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make -j allzstd V=1" - COMPILER: "clang-cl" HOST: "cmake-visual" @@ -233,12 +210,6 @@ cmake,^ make ) - - if [%HOST%]==[mingw] ( - SET "PATH_MINGW32=C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin" && - SET "PATH_MINGW64=C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin" && - COPY C:\msys64\usr\bin\make.exe C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin\make.exe && - COPY C:\msys64\usr\bin\make.exe C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin\make.exe - ) build_script: - ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION% @@ -253,17 +224,6 @@ ctest -V -L Medium; " ) - - if [%HOST%]==[mingw] ( - ( if [%PLATFORM%]==[x64] ( - SET "PATH=%PATH_MINGW64%;%PATH_ORIGINAL%" - ) else if [%PLATFORM%]==[x86] ( - SET "PATH=%PATH_MINGW32%;%PATH_ORIGINAL%" - ) ) && - make -v && - sh -c "%COMPILER% -v" && - set "CC=%COMPILER%" && - sh -c "%SCRIPT%" - ) - if [%HOST%]==[cmake-visual] ( ECHO *** && ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% && @@ -281,4 +241,4 @@ set "CC=%COMPILER%" && make clean && make check - ) + ) \ No newline at end of file diff --git a/lib/compress/zstd_compress_superblock.c b/lib/compress/zstd_compress_superblock.c index e4e45069b..82b3ee235 100644 --- a/lib/compress/zstd_compress_superblock.c +++ b/lib/compress/zstd_compress_superblock.c @@ -132,6 +132,7 @@ static size_t ZSTD_seqDecompressedSize(seqStore_t const* seqStore, const seqDef* const seqDef* sp = sstart; size_t matchLengthSum = 0; size_t litLengthSum = 0; + (void)(litLengthSum); /* suppress unused variable warning on some environments */ while (send-sp > 0) { ZSTD_sequenceLength const seqLen = ZSTD_getSequenceLength(seqStore, sp); litLengthSum += seqLen.litLength; From b10357ce65fa7fc908a06713c4f23f69dfc7ba8a Mon Sep 17 00:00:00 2001 From: Ma Lin Date: Thu, 28 Oct 2021 18:53:12 +0800 Subject: [PATCH 237/274] ZSTD_copy16() uses SSE2 instructions This accelerates the decompression speed of MSVC build. --- lib/common/zstd_internal.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index aeafac2fa..1dfa120e5 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -176,11 +176,17 @@ static void ZSTD_copy8(void* dst, const void* src) { ZSTD_memcpy(dst, src, 8); #endif } - #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } + +/* Need to use memmove here since the literal buffer can now be located within + the dst buffer. In circumstances where the op "catches up" to where the + literal buffer is, there can be partial overlaps in this call on the final + copy if the literal is being shifted by less than 16 bytes. */ static void ZSTD_copy16(void* dst, const void* src) { #if defined(ZSTD_ARCH_ARM_NEON) vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src)); +#elif defined(ZSTD_ARCH_X86_SSE2) + _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src)); #else ZSTD_memmove(dst, src, 16); #endif From 384744888e3e1682d6664e8ac98db6737b36e2af Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 3 Nov 2021 17:06:21 +0300 Subject: [PATCH 238/274] Void out unused functions --- lib/compress/huf_compress.c | 3 +-- lib/compress/zstd_compress.c | 17 ----------------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 0d2fb6eb8..07d57f55c 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -471,8 +471,7 @@ static void HUF_swapNodes(nodeElt* a, nodeElt* b) { } /* Returns 0 if the huffNode array is not sorted by descending count */ -UNUSED_ATTR -static int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) { +MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) { U32 i; for (i = 1; i < maxSymbolValue1; ++i) { if (huffNode[i].count > huffNode[i-1].count) { diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index ad57cce8c..f870bad63 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3737,16 +3737,6 @@ static size_t ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, return cSize; } -/* ZSTD_convertBlockSequencesToSeqStore() - * Converts an array of ZSTD_Sequence* with the corresponding original src buffer into - * the seqStore of a cctx. - * - * Returns 0 on success, ZSTD_error on failure. - */ -static UNUSED_ATTR size_t ZSTD_convertBlockSequencesToSeqStore(ZSTD_CCtx* cctx, - const ZSTD_Sequence* inSeqs, size_t inSeqsSize, - const void* src, size_t srcSize); - static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 frame) @@ -5836,13 +5826,6 @@ static size_t ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, ZS return 0; } -static size_t ZSTD_convertBlockSequencesToSeqStore(ZSTD_CCtx* cctx, - const ZSTD_Sequence* inSeqs, size_t inSeqsSize, - const void* src, size_t srcSize) { - ZSTD_sequencePosition dummySeqPos = {0, 0, 0}; - return ZSTD_copySequencesToSeqStoreExplicitBlockDelim(cctx, &dummySeqPos, inSeqs, inSeqsSize, src, srcSize); -} - /* Returns the number of bytes to move the current read position back by. Only non-zero * if we ended up splitting a sequence. Otherwise, it may return a ZSTD error if something * went wrong. From b3888193d92af6a871d4db7298b55f27de5428ee Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Mon, 1 Nov 2021 13:31:03 -0700 Subject: [PATCH 239/274] Report memory required to decompress while compressing in verbose mode --- programs/fileio.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/programs/fileio.c b/programs/fileio.c index db64ecb64..8e5301dee 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1332,6 +1332,7 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, FILE* const dstFile = ress.dstFile; U64 compressedfilesize = 0; ZSTD_EndDirective directive = ZSTD_e_continue; + U64 pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* stats */ ZSTD_frameProgression previous_zfp_update = { 0, 0, 0, 0, 0, 0 }; @@ -1348,12 +1349,25 @@ FIO_compressZstdFrame(FIO_ctx_t* const fCtx, /* init */ if (fileSize != UTIL_FILESIZE_UNKNOWN) { + pledgedSrcSize = fileSize; CHECK(ZSTD_CCtx_setPledgedSrcSize(ress.cctx, fileSize)); } else if (prefs->streamSrcSize > 0) { /* unknown source size; use the declared stream size */ + pledgedSrcSize = prefs->streamSrcSize; CHECK( ZSTD_CCtx_setPledgedSrcSize(ress.cctx, prefs->streamSrcSize) ); } + { + int windowLog; + UTIL_HumanReadableSize_t windowSize; + CHECK(ZSTD_CCtx_getParameter(ress.cctx, ZSTD_c_windowLog, &windowLog)); + if (windowLog == 0) { + const ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, fileSize, 0); + windowLog = cParams.windowLog; + } + windowSize = UTIL_makeHumanReadableSize(MAX(1ULL, MIN(1ULL << windowLog, pledgedSrcSize))); + DISPLAYLEVEL(4, "Decompression will require %.*f%s of memory\n", windowSize.precision, windowSize.value, windowSize.suffix); + } (void)srcFileName; /* Main compression loop */ From 0665d4c1c2357fb7f90478994f8dedfb31dce164 Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Fri, 5 Nov 2021 12:01:20 -0700 Subject: [PATCH 240/274] Display command line parameters with concrete values in verbose mode --- programs/fileio.c | 42 ++++++++++++++++++++++++++++++++++++++++++ programs/fileio.h | 1 + programs/zstdcli.c | 2 ++ 3 files changed, 45 insertions(+) diff --git a/programs/fileio.c b/programs/fileio.c index 8e5301dee..8a6b98d27 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1782,6 +1782,48 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx, return result; } +static const char* checked_index(const char* options[], size_t length, size_t index) { + assert(index < length); + return options[index]; +} + +#define INDEX(options, index) checked_index((options), sizeof(options) / sizeof(char*), (index)) + +void FIO_displayCompressionParameters(FIO_prefs_t* const prefs) { + static const char* formatOptions[5] = {ZSTD_EXTENSION, GZ_EXTENSION, XZ_EXTENSION, + LZMA_EXTENSION, LZ4_EXTENSION}; + static const char* sparseOptions[3] = {" --no-sparse", "", " --sparse"}; + static const char* checkSumOptions[3] = {" --no-check", "", " --check"}; + static const char* rowMatchFinderOptions[3] = {"", " --no-row-match-finder", " --row-match-finder"}; + static const char* compressLiteralsOptions[3] = {"", " --compress-literals", " --no-compress-literals"}; + + assert(g_display_prefs.displayLevel >= 4); + + DISPLAY("--format=%s", formatOptions[prefs->compressionType]); + DISPLAY("%s", INDEX(sparseOptions, prefs->sparseFileSupport)); + DISPLAY("%s", prefs->dictIDFlag ? "" : " --no-dictID"); + DISPLAY("%s", INDEX(checkSumOptions, prefs->checksumFlag)); + DISPLAY(" --block-size=%d", prefs->blockSize); + if (prefs->adaptiveMode) + DISPLAY(" --adapt=min=%d,max=%d", prefs->minAdaptLevel, prefs->maxAdaptLevel); + DISPLAY("%s", INDEX(rowMatchFinderOptions, prefs->useRowMatchFinder)); + DISPLAY("%s", prefs->rsyncable ? " --rsyncable" : ""); + if (prefs->streamSrcSize) + DISPLAY(" --stream-size=%lu", prefs->streamSrcSize); + if (prefs->srcSizeHint) + DISPLAY(" --size-hint=%d", prefs->srcSizeHint); + if (prefs->targetCBlockSize) + DISPLAY(" --target-compressed-block-size=%lu", prefs->targetCBlockSize); + DISPLAY("%s", INDEX(compressLiteralsOptions, prefs->literalCompressionMode)); + DISPLAY(" --memory=%u", prefs->memLimit ? prefs->memLimit : 128 MB); + DISPLAY(" --threads=%d", prefs->nbWorkers); + DISPLAY("%s", prefs->excludeCompressedFiles ? " --exclude-compressed" : ""); + DISPLAY(" --%scontent-size", prefs->contentSize ? "" : "no-"); + DISPLAY("\n"); +} + +#undef INDEX + int FIO_compressFilename(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs, const char* dstFileName, const char* srcFileName, const char* dictFileName, int compressionLevel, ZSTD_compressionParameters comprParams) diff --git a/programs/fileio.h b/programs/fileio.h index 82d5bc849..03527d042 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -108,6 +108,7 @@ void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompresse void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices); void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value); void FIO_setContentSize(FIO_prefs_t* const prefs, int value); +void FIO_displayCompressionParameters(FIO_prefs_t* const prefs); /* FIO_ctx_t functions */ void FIO_setNbFilesTotal(FIO_ctx_t* const fCtx, int value); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 8fb65111e..f895c4b23 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1430,6 +1430,8 @@ int main(int argCount, const char* argv[]) } } + if (g_displayLevel >= 4) + FIO_displayCompressionParameters(prefs); if ((filenames->tableSize==1) && outFileName) operationResult = FIO_compressFilename(fCtx, prefs, outFileName, filenames->fileNames[0], dictFileName, cLevel, compressionParams); else From d46995efeb60bd73eb87388d95b2790ce98cb1e1 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 5 Nov 2021 14:09:49 -0700 Subject: [PATCH 241/274] Backport zstd patch from LKML Credit to Nathan Chancellor for the bug fix and Nick Desaulniers for the bug report. Link: https://github.com/ClangBuiltLinux/linux/issues/1486 Link: https://lore.kernel.org/all/20211021202353.2356400-1-nathan@kernel.org/ --- lib/decompress/huf_decompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 227f804a8..bfa72c345 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -1355,7 +1355,7 @@ HUF_decompress4X2_usingDTable_internal_body( HUF_DECODE_SYMBOLX2_0(op2, &bitD2); HUF_DECODE_SYMBOLX2_0(op3, &bitD3); HUF_DECODE_SYMBOLX2_0(op4, &bitD4); - endSignal = (U32)LIKELY( + endSignal = (U32)LIKELY((U32) (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) From 61765cacd08103d47ce7c6709135f340d1074568 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 8 Nov 2021 20:03:52 -0500 Subject: [PATCH 242/274] Avoid Reducing Indices to Reserved Values Previously, if an index was equal to `reducerValue + 1`, it would get remapped during index reduction to 1 i.e. `ZSTD_DUBT_UNSORTED_MARK`. This can affect the parsing of the input slightly, by causing tree nodes to be nullified when they otherwise wouldn't be. This hardly matters from a correctness or efficiency perspective, but it does impact determinism. So this commit changes index reduction to avoid mapping indices to collide with `ZSTD_DUBT_UNSORTED_MARK`. --- lib/compress/zstd_compress.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f870bad63..59a216918 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2311,6 +2311,8 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa int const nbRows = (int)size / ZSTD_ROWSIZE; int cellNb = 0; int rowNb; + /* Protect special index values < ZSTD_WINDOW_START_INDEX. */ + U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX; assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */ assert(size < (1U<<31)); /* can be casted to int */ @@ -2330,12 +2332,12 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa for (rowNb=0 ; rowNb < nbRows ; rowNb++) { int column; for (column=0; column Date: Tue, 9 Nov 2021 12:15:18 -0500 Subject: [PATCH 243/274] Rewrite Fix to Still Auto-Vectorize --- lib/compress/zstd_compress.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 59a216918..09f18d6d9 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2332,12 +2332,17 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa for (rowNb=0 ; rowNb < nbRows ; rowNb++) { int column; for (column=0; column Date: Tue, 9 Nov 2021 15:15:35 -0500 Subject: [PATCH 244/274] Fix fullbench CI failure (#2851) --- tests/fullbench.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/fullbench.c b/tests/fullbench.c index d190a872d..f610fef4c 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -123,11 +123,15 @@ static size_t local_ZSTD_decompress(const void* src, size_t srcSize, static ZSTD_DCtx* g_zdc = NULL; #ifndef ZSTD_DLL_IMPORT -extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize, void* dst, size_t dstCapacity); +typedef enum { + not_streaming = 0, + is_streaming = 1 +} streaming_operation; +extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize, void* dst, size_t dstCapacity, const streaming_operation streaming); static size_t local_ZSTD_decodeLiteralsBlock(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) { (void)src; (void)srcSize; (void)dst; (void)dstSize; - return ZSTD_decodeLiteralsBlock(g_zdc, buff2, g_cSize, dst, dstSize); + return ZSTD_decodeLiteralsBlock(g_zdc, buff2, g_cSize, dst, dstSize, not_streaming); } static size_t local_ZSTD_decodeSeqHeaders(const void* src, size_t srcSize, void* dst, size_t dstSize, void* buff2) @@ -577,7 +581,7 @@ static int benchMem(unsigned benchNb, ip += ZSTD_blockHeaderSize; /* skip block header */ ZSTD_decompressBegin(g_zdc); CONTROL(iend > ip); - ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, (size_t)(iend-ip), dstBuff, dstBuffSize); /* skip literal segment */ + ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, (size_t)(iend-ip), dstBuff, dstBuffSize, not_streaming); /* skip literal segment */ g_cSize = (size_t)(iend-ip); memcpy(dstBuff2, ip, g_cSize); /* copy rest of block (it starts by SeqHeader) */ srcSize = srcSize > 128 KB ? 128 KB : srcSize; /* speed relative to block */ From 63fe6198ed9af6bf30de086238aa7e97009ac52a Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Fri, 5 Nov 2021 12:48:13 -0700 Subject: [PATCH 245/274] Display --zstd= subparameters in command-line ready form in verbose mode --- programs/zstdcli.c | 62 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index f895c4b23..8163ab37c 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -647,6 +647,44 @@ static void printVersion(void) } } } +#define ZSTD_NB_STRATEGIES 9 +static const char* ZSTD_strategyMap[ZSTD_NB_STRATEGIES + 1] = { "", "ZSTD_fast", + "ZSTD_dfast", "ZSTD_greedy", "ZSTD_lazy", "ZSTD_lazy2", "ZSTD_btlazy2", + "ZSTD_btopt", "ZSTD_btultra", "ZSTD_btultra2"}; + +static void printDefaultCParams(const char* filename, const char* dictFileName, int cLevel) { + unsigned long long fileSize = UTIL_getFileSize(filename); + const size_t dictSize = dictFileName != NULL ? (size_t)UTIL_getFileSize(dictFileName) : 0; + const ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, fileSize, dictSize); + if (fileSize != UTIL_FILESIZE_UNKNOWN) DISPLAY("%s (%u bytes)\n", filename, (unsigned)fileSize); + else DISPLAY("%s (src size unknown)\n", filename); + DISPLAY(" - windowLog : %u\n", cParams.windowLog); + DISPLAY(" - chainLog : %u\n", cParams.chainLog); + DISPLAY(" - hashLog : %u\n", cParams.hashLog); + DISPLAY(" - searchLog : %u\n", cParams.searchLog); + DISPLAY(" - minMatch : %u\n", cParams.minMatch); + DISPLAY(" - targetLength : %u\n", cParams.targetLength); + assert(cParams.strategy < ZSTD_NB_STRATEGIES + 1); + DISPLAY(" - strategy : %s (%u)\n", ZSTD_strategyMap[(int)cParams.strategy], (unsigned)cParams.strategy); +} + +static void printActualCParams(const char* filename, const char* dictFileName, int cLevel, const ZSTD_compressionParameters* cParams) { + unsigned long long fileSize = UTIL_getFileSize(filename); + const size_t dictSize = dictFileName != NULL ? (size_t)UTIL_getFileSize(dictFileName) : 0; + ZSTD_compressionParameters actualCParams = ZSTD_getCParams(cLevel, fileSize, dictSize); + assert(g_displayLevel >= 4); + actualCParams.windowLog = cParams->windowLog == 0 ? actualCParams.windowLog : cParams->windowLog; + actualCParams.chainLog = cParams->chainLog == 0 ? actualCParams.chainLog : cParams->chainLog; + actualCParams.hashLog = cParams->hashLog == 0 ? actualCParams.hashLog : cParams->hashLog; + actualCParams.searchLog = cParams->searchLog == 0 ? actualCParams.searchLog : cParams->searchLog; + actualCParams.minMatch = cParams->minMatch == 0 ? actualCParams.minMatch : cParams->minMatch; + actualCParams.targetLength = cParams->targetLength == 0 ? actualCParams.targetLength : cParams->targetLength; + actualCParams.strategy = cParams->strategy == 0 ? actualCParams.strategy : cParams->strategy; + DISPLAY("--zstd=wlog=%d,clog=%d,hlog=%d,slog=%d,mml=%d,tlen=%d,strat=%d\n", + actualCParams.windowLog, actualCParams.chainLog, actualCParams.hashLog, actualCParams.searchLog, + actualCParams.minMatch, actualCParams.targetLength, actualCParams.strategy); +} + /* Environment variables for parameter setting */ #define ENV_CLEVEL "ZSTD_CLEVEL" #define ENV_NBTHREADS "ZSTD_NBTHREADS" /* takes lower precedence than directly specifying -T# in the CLI */ @@ -723,11 +761,6 @@ static unsigned init_nbThreads(void) { val32 = readU32FromChar(&__nb); \ } -#define ZSTD_NB_STRATEGIES 9 -static const char* ZSTD_strategyMap[ZSTD_NB_STRATEGIES + 1] = { "", "ZSTD_fast", - "ZSTD_dfast", "ZSTD_greedy", "ZSTD_lazy", "ZSTD_lazy2", "ZSTD_btlazy2", - "ZSTD_btopt", "ZSTD_btultra", "ZSTD_btultra2"}; - typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom_list } zstd_operation_mode; #define CLEAN_RETURN(i) { operationResult = (i); goto _end; } @@ -1411,22 +1444,13 @@ int main(int argCount, const char* argv[]) assert(ZSTD_NB_STRATEGIES == strategyBounds.upperBound); (void)strategyBounds; } - if (showDefaultCParams) { + if (showDefaultCParams || g_displayLevel >= 4) { size_t fileNb; for (fileNb = 0; fileNb < (size_t)filenames->tableSize; fileNb++) { - unsigned long long fileSize = UTIL_getFileSize(filenames->fileNames[fileNb]); - const size_t dictSize = dictFileName != NULL ? (size_t)UTIL_getFileSize(dictFileName) : 0; - const ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, fileSize, dictSize); - if (fileSize != UTIL_FILESIZE_UNKNOWN) DISPLAY("%s (%u bytes)\n", filenames->fileNames[fileNb], (unsigned)fileSize); - else DISPLAY("%s (src size unknown)\n", filenames->fileNames[fileNb]); - DISPLAY(" - windowLog : %u\n", cParams.windowLog); - DISPLAY(" - chainLog : %u\n", cParams.chainLog); - DISPLAY(" - hashLog : %u\n", cParams.hashLog); - DISPLAY(" - searchLog : %u\n", cParams.searchLog); - DISPLAY(" - minMatch : %u\n", cParams.minMatch); - DISPLAY(" - targetLength : %u\n", cParams.targetLength); - assert(cParams.strategy < ZSTD_NB_STRATEGIES + 1); - DISPLAY(" - strategy : %s (%u)\n", ZSTD_strategyMap[(int)cParams.strategy], (unsigned)cParams.strategy); + if (showDefaultCParams) + printDefaultCParams(filenames->fileNames[fileNb], dictFileName, cLevel); + if (g_displayLevel >= 4) + printActualCParams(filenames->fileNames[fileNb], dictFileName, cLevel, &compressionParams); } } From df9b7755cb38799e47c073fc5c03e146d23565fa Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Wed, 10 Nov 2021 17:25:27 -0800 Subject: [PATCH 246/274] Fix const-ness of FIO_displayCompressionParameters --- programs/fileio.c | 2 +- programs/fileio.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 8a6b98d27..2f5850903 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1789,7 +1789,7 @@ static const char* checked_index(const char* options[], size_t length, size_t in #define INDEX(options, index) checked_index((options), sizeof(options) / sizeof(char*), (index)) -void FIO_displayCompressionParameters(FIO_prefs_t* const prefs) { +void FIO_displayCompressionParameters(const FIO_prefs_t* prefs) { static const char* formatOptions[5] = {ZSTD_EXTENSION, GZ_EXTENSION, XZ_EXTENSION, LZMA_EXTENSION, LZ4_EXTENSION}; static const char* sparseOptions[3] = {" --no-sparse", "", " --sparse"}; diff --git a/programs/fileio.h b/programs/fileio.h index 03527d042..61094db83 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -108,7 +108,7 @@ void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompresse void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices); void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value); void FIO_setContentSize(FIO_prefs_t* const prefs, int value); -void FIO_displayCompressionParameters(FIO_prefs_t* const prefs); +void FIO_displayCompressionParameters(const FIO_prefs_t* prefs); /* FIO_ctx_t functions */ void FIO_setNbFilesTotal(FIO_ctx_t* const fCtx, int value); From f6ffd392302df82e348a1ab42db3c1374bb29605 Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Thu, 11 Nov 2021 11:57:55 -0800 Subject: [PATCH 247/274] Add test case for detailed compression parameter verbose output --- tests/test_verbose_output.sh | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100755 tests/test_verbose_output.sh diff --git a/tests/test_verbose_output.sh b/tests/test_verbose_output.sh new file mode 100755 index 000000000..9fc8a29e9 --- /dev/null +++ b/tests/test_verbose_output.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e -u -o pipefail + +make -j -C .. CFLAGS=-O1 zstd +empty_file=$(mktemp) +trap 'rm -f $empty_file' EXIT +../zstd -vv "$empty_file" 2>&1 | \ +grep -q -E -- "--zstd=wlog=[[:digit:]]+,clog=[[:digit:]]+,hlog=[[:digit:]]+,\ +slog=[[:digit:]]+,mml=[[:digit:]]+,tlen=[[:digit:]]+,strat=[[:digit:]]+" From 365c91194ce308650197fa08ecee9d802f7225a1 Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Thu, 11 Nov 2021 12:14:56 -0800 Subject: [PATCH 248/274] Ensure print*CParams functions are only defined when used --- programs/zstdcli.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 8163ab37c..05c537b5e 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -652,6 +652,8 @@ static const char* ZSTD_strategyMap[ZSTD_NB_STRATEGIES + 1] = { "", "ZSTD_fast", "ZSTD_dfast", "ZSTD_greedy", "ZSTD_lazy", "ZSTD_lazy2", "ZSTD_btlazy2", "ZSTD_btopt", "ZSTD_btultra", "ZSTD_btultra2"}; +#ifndef ZSTD_NOCOMPRESS + static void printDefaultCParams(const char* filename, const char* dictFileName, int cLevel) { unsigned long long fileSize = UTIL_getFileSize(filename); const size_t dictSize = dictFileName != NULL ? (size_t)UTIL_getFileSize(dictFileName) : 0; @@ -685,6 +687,8 @@ static void printActualCParams(const char* filename, const char* dictFileName, i actualCParams.minMatch, actualCParams.targetLength, actualCParams.strategy); } +#endif + /* Environment variables for parameter setting */ #define ENV_CLEVEL "ZSTD_CLEVEL" #define ENV_NBTHREADS "ZSTD_NBTHREADS" /* takes lower precedence than directly specifying -T# in the CLI */ From 375e3aad6c35be2605acbec873d8ad6c54f49434 Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Thu, 11 Nov 2021 13:17:30 -0800 Subject: [PATCH 249/274] Ensure formatting directives for displaying size_t are portable --- programs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 2f5850903..cf3e7414c 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1809,11 +1809,11 @@ void FIO_displayCompressionParameters(const FIO_prefs_t* prefs) { DISPLAY("%s", INDEX(rowMatchFinderOptions, prefs->useRowMatchFinder)); DISPLAY("%s", prefs->rsyncable ? " --rsyncable" : ""); if (prefs->streamSrcSize) - DISPLAY(" --stream-size=%lu", prefs->streamSrcSize); + DISPLAY(" --stream-size=%u", (unsigned) prefs->streamSrcSize); if (prefs->srcSizeHint) DISPLAY(" --size-hint=%d", prefs->srcSizeHint); if (prefs->targetCBlockSize) - DISPLAY(" --target-compressed-block-size=%lu", prefs->targetCBlockSize); + DISPLAY(" --target-compressed-block-size=%u", (unsigned) prefs->targetCBlockSize); DISPLAY("%s", INDEX(compressLiteralsOptions, prefs->literalCompressionMode)); DISPLAY(" --memory=%u", prefs->memLimit ? prefs->memLimit : 128 MB); DISPLAY(" --threads=%d", prefs->nbWorkers); From 7fbd126e089a1359ce7c9729be91ee546312af1a Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Thu, 11 Nov 2021 14:37:02 -0800 Subject: [PATCH 250/274] Suppress spurious unused parameter warning --- programs/fileio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/fileio.c b/programs/fileio.c index cf3e7414c..c1881a4f0 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1784,6 +1784,8 @@ FIO_compressFilename_srcFile(FIO_ctx_t* const fCtx, static const char* checked_index(const char* options[], size_t length, size_t index) { assert(index < length); + // Necessary to avoid warnings since -O3 will omit the above `assert` + (void) length; return options[index]; } From 9b28c26cbff0d43eb72d90ba5ef2fea27659638e Mon Sep 17 00:00:00 2001 From: Kevin Svetlitski Date: Fri, 12 Nov 2021 14:10:21 -0800 Subject: [PATCH 251/274] Integrate verbose mode tests into playTests.sh --- tests/playTests.sh | 7 +++++++ tests/test_verbose_output.sh | 9 --------- 2 files changed, 7 insertions(+), 9 deletions(-) delete mode 100755 tests/test_verbose_output.sh diff --git a/tests/playTests.sh b/tests/playTests.sh index 69653276a..5d26fb8f5 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -753,6 +753,13 @@ datagen -g257000 > tmp_files/tmp3 zstd --show-default-cparams -f -r tmp_files rm -rf tmp* +println "test : show compression parameters in verbose mode" +datagen > tmp +zstd -vv tmp 2>&1 | \ +grep -q -E -- "--zstd=wlog=[[:digit:]]+,clog=[[:digit:]]+,hlog=[[:digit:]]+,\ +slog=[[:digit:]]+,mml=[[:digit:]]+,tlen=[[:digit:]]+,strat=[[:digit:]]+" +rm -rf tmp* + println "\n===> Advanced compression parameters " println "Hello world!" | zstd --zstd=windowLog=21, - -o tmp.zst && die "wrong parameters not detected!" println "Hello world!" | zstd --zstd=windowLo=21 - -o tmp.zst && die "wrong parameters not detected!" diff --git a/tests/test_verbose_output.sh b/tests/test_verbose_output.sh deleted file mode 100755 index 9fc8a29e9..000000000 --- a/tests/test_verbose_output.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -set -e -u -o pipefail - -make -j -C .. CFLAGS=-O1 zstd -empty_file=$(mktemp) -trap 'rm -f $empty_file' EXIT -../zstd -vv "$empty_file" 2>&1 | \ -grep -q -E -- "--zstd=wlog=[[:digit:]]+,clog=[[:digit:]]+,hlog=[[:digit:]]+,\ -slog=[[:digit:]]+,mml=[[:digit:]]+,tlen=[[:digit:]]+,strat=[[:digit:]]+" From ebbd67599897b8a2510f92e6392cee100df62ee6 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Sat, 13 Nov 2021 10:04:04 +0200 Subject: [PATCH 252/274] Fix typos --- .github/workflows/dev-short-tests.yml | 2 +- CONTRIBUTING.md | 24 +++++++++++------------ build/single_file_libs/zstd-in.c | 2 +- build/single_file_libs/zstddeclib-in.c | 2 +- doc/educational_decoder/zstd_decompress.c | 2 +- doc/zstd_compression_format.md | 2 +- lib/README.md | 2 +- lib/common/compiler.h | 2 +- lib/compress/huf_compress.c | 4 ++-- lib/compress/zstd_compress.c | 2 +- lib/compress/zstd_compress_internal.h | 2 +- lib/compress/zstd_compress_superblock.c | 2 +- lib/compress/zstd_cwksp.h | 2 +- lib/compress/zstd_ldm.c | 2 +- lib/decompress/huf_decompress.c | 2 +- lib/decompress/huf_decompress_amd64.S | 6 +++--- lib/zdict.h | 4 ++-- lib/zstd.h | 4 ++-- programs/dibio.c | 4 ++-- programs/util.c | 4 ++-- programs/util.h | 2 +- programs/zstd.1 | 2 +- programs/zstd.1.md | 2 +- tests/README.md | 2 +- tests/automated_benchmarking.py | 2 +- tests/fuzzer.c | 4 ++-- tests/paramgrill.c | 8 ++++---- tests/playTests.sh | 2 +- tests/zstreamtest.c | 10 +++++----- zlibWrapper/examples/fitblk.c | 2 +- zlibWrapper/examples/fitblk_original.c | 2 +- 31 files changed, 57 insertions(+), 57 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 8c1e29129..c68fe5edf 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -335,7 +335,7 @@ jobs: # This test currently fails on Github Actions specifically. # Possible reason : TTY emulation. # Note that the same test works fine locally and on travisCI. -# This will have to be fixed before transfering the test to GA. +# This will have to be fixed before transferring the test to GA. # versions-compatibility: # runs-on: ubuntu-latest # steps: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5effa26eb..a936d747e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,7 +47,7 @@ Our contribution process works in three main stages: * Topic and development: * Make a new branch on your fork about the topic you're developing for ``` - # branch names should be consise but sufficiently informative + # branch names should be concise but sufficiently informative git checkout -b git push origin ``` @@ -104,7 +104,7 @@ Our contribution process works in three main stages: issue at hand, then please indicate this by requesting that an issue be closed by commenting. * Just because your changes have been merged does not mean the topic or larger issue is complete. Remember that the change must make it to an official zstd release for it to be meaningful. We recommend - that contributers track the activity on their pull request and corresponding issue(s) page(s) until + that contributors track the activity on their pull request and corresponding issue(s) page(s) until their change makes it to the next release of zstd. Users will often discover bugs in your code or suggest ways to refine and improve your initial changes even after the pull request is merged. @@ -270,15 +270,15 @@ for level 1 compression on Zstd. Typically this means, you have identified a sec code that you think can be made to run faster. The first thing you will want to do is make sure that the piece of code is actually taking up -a notable amount of time to run. It is usually not worth optimzing something which accounts for less than +a notable amount of time to run. It is usually not worth optimizing something which accounts for less than 0.0001% of the total running time. Luckily, there are tools to help with this. Profilers will let you see how much time your code spends inside a particular function. -If your target code snippit is only part of a function, it might be worth trying to -isolate that snippit by moving it to its own function (this is usually not necessary but +If your target code snippet is only part of a function, it might be worth trying to +isolate that snippet by moving it to its own function (this is usually not necessary but might be). -Most profilers (including the profilers dicusssed below) will generate a call graph of -functions for you. Your goal will be to find your function of interest in this call grapch +Most profilers (including the profilers discussed below) will generate a call graph of +functions for you. Your goal will be to find your function of interest in this call graph and then inspect the time spent inside of it. You might also want to to look at the annotated assembly which most profilers will provide you with. @@ -301,16 +301,16 @@ $ zstd -b1 -i5 # this will run for 5 seconds 5. Once you run your benchmarking script, switch back over to instruments and attach your process to the time profiler. You can do this by: * Clicking on the `All Processes` drop down in the top left of the toolbar. - * Selecting your process from the dropdown. In my case, it is just going to be labled + * Selecting your process from the dropdown. In my case, it is just going to be labeled `zstd` * Hitting the bright red record circle button on the top left of the toolbar -6. You profiler will now start collecting metrics from your bencharking script. Once +6. You profiler will now start collecting metrics from your benchmarking script. Once you think you have collected enough samples (usually this is the case after 3 seconds of recording), stop your profiler. 7. Make sure that in toolbar of the bottom window, `profile` is selected. 8. You should be able to see your call graph. * If you don't see the call graph or an incomplete call graph, make sure you have compiled - zstd and your benchmarking scripg using debug flags. On mac and linux, this just means + zstd and your benchmarking script using debug flags. On mac and linux, this just means you will have to supply the `-g` flag alone with your build script. You might also have to provide the `-fno-omit-frame-pointer` flag 9. Dig down the graph to find your function call and then inspect it by double clicking @@ -329,7 +329,7 @@ Some general notes on perf: counter statistics. Perf uses a high resolution timer and this is likely one of the first things your team will run when assessing your PR. * Perf has a long list of hardware counters that can be viewed with `perf --list`. -When measuring optimizations, something worth trying is to make sure the handware +When measuring optimizations, something worth trying is to make sure the hardware counters you expect to be impacted by your change are in fact being so. For example, if you expect the L1 cache misses to decrease with your change, you can look at the counter `L1-dcache-load-misses` @@ -368,7 +368,7 @@ Follow these steps to link travis-ci with your github fork of zstd TODO ### appveyor -Follow these steps to link circle-ci with your girhub fork of zstd +Follow these steps to link circle-ci with your github fork of zstd 1. Make sure you are logged into your github account 2. Go to https://www.appveyor.com/ diff --git a/build/single_file_libs/zstd-in.c b/build/single_file_libs/zstd-in.c index f73a2e72c..733dcb757 100644 --- a/build/single_file_libs/zstd-in.c +++ b/build/single_file_libs/zstd-in.c @@ -25,7 +25,7 @@ * Note: MEM_MODULE stops xxhash redefining BYTE, U16, etc., which are also * defined in mem.h (breaking C99 compatibility). * - * Note: the undefs for xxHash allow Zstd's implementation to coinside with with + * Note: the undefs for xxHash allow Zstd's implementation to coincide with with * standalone xxHash usage (with global defines). * * Note: multithreading is enabled for all platforms apart from Emscripten. diff --git a/build/single_file_libs/zstddeclib-in.c b/build/single_file_libs/zstddeclib-in.c index a5fd958e4..cbf70c619 100644 --- a/build/single_file_libs/zstddeclib-in.c +++ b/build/single_file_libs/zstddeclib-in.c @@ -25,7 +25,7 @@ * Note: MEM_MODULE stops xxhash redefining BYTE, U16, etc., which are also * defined in mem.h (breaking C99 compatibility). * - * Note: the undefs for xxHash allow Zstd's implementation to coinside with with + * Note: the undefs for xxHash allow Zstd's implementation to coincide with with * standalone xxHash usage (with global defines). */ #define DEBUGLEVEL 0 diff --git a/doc/educational_decoder/zstd_decompress.c b/doc/educational_decoder/zstd_decompress.c index 62e6f0dd4..936407086 100644 --- a/doc/educational_decoder/zstd_decompress.c +++ b/doc/educational_decoder/zstd_decompress.c @@ -2145,7 +2145,7 @@ static void FSE_init_dtable(FSE_dtable *const dtable, // "All remaining symbols are sorted in their natural order. Starting from // symbol 0 and table position 0, each symbol gets attributed as many cells - // as its probability. Cell allocation is spreaded, not linear." + // as its probability. Cell allocation is spread, not linear." // Place the rest in the table const u16 step = (size >> 1) + (size >> 3) + 3; const u16 mask = size - 1; diff --git a/doc/zstd_compression_format.md b/doc/zstd_compression_format.md index bb244d437..fc09bd553 100644 --- a/doc/zstd_compression_format.md +++ b/doc/zstd_compression_format.md @@ -1124,7 +1124,7 @@ These symbols define a full state reset, reading `Accuracy_Log` bits. Then, all remaining symbols, sorted in natural order, are allocated cells. Starting from symbol `0` (if it exists), and table position `0`, each symbol gets allocated as many cells as its probability. -Cell allocation is spreaded, not linear : +Cell allocation is spread, not linear : each successor position follows this rule : ``` diff --git a/lib/README.md b/lib/README.md index aab0869af..4c9d8f059 100644 --- a/lib/README.md +++ b/lib/README.md @@ -125,7 +125,7 @@ The file structure is designed to make this selection manually achievable for an `ZSTD_getErrorName` (implied by `ZSTD_LIB_MINIFY`). Finally, when integrating into your application, make sure you're doing link- - time optimation and unused symbol garbage collection (via some combination of, + time optimization and unused symbol garbage collection (via some combination of, e.g., `-flto`, `-ffat-lto-objects`, `-fuse-linker-plugin`, `-ffunction-sections`, `-fdata-sections`, `-fmerge-all-constants`, `-Wl,--gc-sections`, `-Wl,-z,norelro`, and an archiver that understands diff --git a/lib/common/compiler.h b/lib/common/compiler.h index ddbba5503..a9062d0f3 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -40,7 +40,7 @@ /** On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC). - This explictly marks such functions as __cdecl so that the code will still compile + This explicitly marks such functions as __cdecl so that the code will still compile if a CC other than __cdecl has been made the default. */ #if defined(_MSC_VER) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 07d57f55c..facec3300 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -760,7 +760,7 @@ typedef struct { } HUF_CStream_t; /**! HUF_initCStream(): - * Initializes the bistream. + * Initializes the bitstream. * @returns 0 or an error code. */ static size_t HUF_initCStream(HUF_CStream_t* bitC, @@ -779,7 +779,7 @@ static size_t HUF_initCStream(HUF_CStream_t* bitC, * * @param elt The element we're adding. This is a (nbBits, value) pair. * See the HUF_CStream_t docs for the format. - * @param idx Insert into the bistream at this idx. + * @param idx Insert into the bitstream at this idx. * @param kFast This is a template parameter. If the bitstream is guaranteed * to have at least 4 unused bits after this call it may be 1, * otherwise it must be 0. HUF_addBits() is faster when fast is set. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 09f18d6d9..32e486cd8 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1333,7 +1333,7 @@ ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, break; case ZSTD_cpm_createCDict: /* Assume a small source size when creating a dictionary - * with an unkown source size. + * with an unknown source size. */ if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN) srcSize = minSrcSize; diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 9e4c1ac17..a9f3486db 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -392,7 +392,7 @@ struct ZSTD_CCtx_s { ZSTD_blockState_t blockState; U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */ - /* Wether we are streaming or not */ + /* Whether we are streaming or not */ ZSTD_buffered_policy_e bufferedPolicy; /* streaming */ diff --git a/lib/compress/zstd_compress_superblock.c b/lib/compress/zstd_compress_superblock.c index 82b3ee235..bcbe158b7 100644 --- a/lib/compress/zstd_compress_superblock.c +++ b/lib/compress/zstd_compress_superblock.c @@ -475,7 +475,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr, /* I think there is an optimization opportunity here. * Calling ZSTD_estimateSubBlockSize for every sequence can be wasteful * since it recalculates estimate from scratch. - * For example, it would recount literal distribution and symbol codes everytime. + * For example, it would recount literal distribution and symbol codes every time. */ cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount, &nextCBlock->entropy, entropyMetadata, diff --git a/lib/compress/zstd_cwksp.h b/lib/compress/zstd_cwksp.h index 2656d26ca..7ba90262d 100644 --- a/lib/compress/zstd_cwksp.h +++ b/lib/compress/zstd_cwksp.h @@ -219,7 +219,7 @@ MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size) { MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) { /* For alignment, the wksp will always allocate an additional n_1=[1, 64] bytes * to align the beginning of tables section, as well as another n_2=[0, 63] bytes - * to align the beginning of the aligned secion. + * to align the beginning of the aligned section. * * n_1 + n_2 == 64 bytes if the cwksp is freshly allocated, due to tables and * aligneds being sized in multiples of 64 bytes. diff --git a/lib/compress/zstd_ldm.c b/lib/compress/zstd_ldm.c index 45eebccec..19b99f278 100644 --- a/lib/compress/zstd_ldm.c +++ b/lib/compress/zstd_ldm.c @@ -478,7 +478,7 @@ static size_t ZSTD_ldm_generateSequences_internal( */ if (anchor > ip + hashed) { ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength); - /* Continue the outter loop at anchor (ip + hashed == anchor). */ + /* Continue the outer loop at anchor (ip + hashed == anchor). */ ip = anchor - hashed; break; } diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index bfa72c345..9322c99a6 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -429,7 +429,7 @@ size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t sr /* fill DTable * We fill all entries of each weight in order. - * That way length is a constant for each iteration of the outter loop. + * That way length is a constant for each iteration of the outer loop. * We can switch based on the length to a different inner loop which is * optimized for that particular case. */ diff --git a/lib/decompress/huf_decompress_amd64.S b/lib/decompress/huf_decompress_amd64.S index 83e3d7565..769e5b3d0 100644 --- a/lib/decompress/huf_decompress_amd64.S +++ b/lib/decompress/huf_decompress_amd64.S @@ -3,7 +3,7 @@ /* Calling convention: * * %rdi contains the first argument: HUF_DecompressAsmArgs*. - * %rbp is'nt maintained (no frame pointer). + * %rbp isn't maintained (no frame pointer). * %rsp contains the stack pointer that grows down. * No red-zone is assumed, only addresses >= %rsp are used. * All register contents are preserved. @@ -123,7 +123,7 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: subq $24, %rsp .L_4X1_compute_olimit: - /* Computes how many iterations we can do savely + /* Computes how many iterations we can do safely * %r15, %rax may be clobbered * rbx, rdx must be saved * op3 & ip0 mustn't be clobbered @@ -389,7 +389,7 @@ HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop: subq $8, %rsp .L_4X2_compute_olimit: - /* Computes how many iterations we can do savely + /* Computes how many iterations we can do safely * %r15, %rax may be clobbered * rdx must be saved * op[1,2,3,4] & ip0 mustn't be clobbered diff --git a/lib/zdict.h b/lib/zdict.h index 75b05dbf4..ac98a169b 100644 --- a/lib/zdict.h +++ b/lib/zdict.h @@ -46,7 +46,7 @@ extern "C" { * * Zstd can use dictionaries to improve compression ratio of small data. * Traditionally small files don't compress well because there is very little - * repetion in a single sample, since it is small. But, if you are compressing + * repetition in a single sample, since it is small. But, if you are compressing * many similar files, like a bunch of JSON records that share the same * structure, you can train a dictionary on ahead of time on some samples of * these files. Then, zstd can use the dictionary to find repetitions that are @@ -132,7 +132,7 @@ extern "C" { * * # Benchmark levels 1-3 without a dictionary * zstd -b1e3 -r /path/to/my/files - * # Benchmark levels 1-3 with a dictioanry + * # Benchmark levels 1-3 with a dictionary * zstd -b1e3 -r /path/to/my/files -D /path/to/my/dictionary * * When should I retrain a dictionary? diff --git a/lib/zstd.h b/lib/zstd.h index 6709c65d7..571d5fe90 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -247,7 +247,7 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, * * It's possible to reset all parameters to "default" using ZSTD_CCtx_reset(). * - * This API supercedes all other "advanced" API entry points in the experimental section. + * This API supersedes all other "advanced" API entry points in the experimental section. * In the future, we expect to remove from experimental API entry points which are redundant with this API. */ @@ -1804,7 +1804,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre * * Note that this means that the CDict tables can no longer be copied into the * CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be - * useable. The dictionary can only be attached or reloaded. + * usable. The dictionary can only be attached or reloaded. * * In general, you should expect compression to be faster--sometimes very much * so--and CDict creation to be slightly slower. Eventually, we will probably diff --git a/programs/dibio.c b/programs/dibio.c index 49fa21185..e7fb905ec 100644 --- a/programs/dibio.c +++ b/programs/dibio.c @@ -270,7 +270,7 @@ static fileStats DiB_fileStats(const char** fileNamesTable, int nbFiles, size_t int n; memset(&fs, 0, sizeof(fs)); - // We assume that if chunking is requsted, the chunk size is < SAMPLESIZE_MAX + // We assume that if chunking is requested, the chunk size is < SAMPLESIZE_MAX assert( chunkSize <= SAMPLESIZE_MAX ); for (n=0; n 0 && (FUZ_rand(&lseed) & 7) == 0) { DISPLAYLEVEL(6, "t%u: Modify nbWorkers: %d -> %d \n", testNb, nbWorkers, nbWorkers + iter); diff --git a/zlibWrapper/examples/fitblk.c b/zlibWrapper/examples/fitblk.c index 669b176eb..8dc7071ee 100644 --- a/zlibWrapper/examples/fitblk.c +++ b/zlibWrapper/examples/fitblk.c @@ -119,7 +119,7 @@ local int recompress(z_streamp inf, z_streamp def) if (ret == Z_MEM_ERROR) return ret; - /* compress what was decompresed until done or no room */ + /* compress what was decompressed until done or no room */ def->avail_in = RAWLEN - inf->avail_out; def->next_in = raw; if (inf->avail_out != 0) diff --git a/zlibWrapper/examples/fitblk_original.c b/zlibWrapper/examples/fitblk_original.c index 20f351bfa..723dc0028 100644 --- a/zlibWrapper/examples/fitblk_original.c +++ b/zlibWrapper/examples/fitblk_original.c @@ -109,7 +109,7 @@ local int recompress(z_streamp inf, z_streamp def) if (ret == Z_MEM_ERROR) return ret; - /* compress what was decompresed until done or no room */ + /* compress what was decompressed until done or no room */ def->avail_in = RAWLEN - inf->avail_out; def->next_in = raw; if (inf->avail_out != 0) From c67e07f34e89346ed4ee8b7f42972b679583ba96 Mon Sep 17 00:00:00 2001 From: ko-zu Date: Sat, 13 Nov 2021 22:48:33 +0900 Subject: [PATCH 253/274] Remove executable flag from GNU_STACK section Putting stack marking into every assembly files is required to indicate that the stack does not need to be executable. Executable flag on stack conflicts with some security measures, Systemd MemoryDenyWriteExecute=yes for example. --- lib/decompress/huf_decompress_amd64.S | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/decompress/huf_decompress_amd64.S b/lib/decompress/huf_decompress_amd64.S index 83e3d7565..97646a2e1 100644 --- a/lib/decompress/huf_decompress_amd64.S +++ b/lib/decompress/huf_decompress_amd64.S @@ -1,5 +1,12 @@ #if !defined(HUF_DISABLE_ASM) && defined(__x86_64__) +/* Stack marking + * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart + */ +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + /* Calling convention: * * %rdi contains the first argument: HUF_DecompressAsmArgs*. From 27455638aa308ae943f51ad380e7144ba559ec93 Mon Sep 17 00:00:00 2001 From: "Lvv.me" Date: Sun, 14 Nov 2021 17:29:33 +0800 Subject: [PATCH 254/274] Support Swift Package Manager --- Package.swift | 36 ++++++++++++++++++++++++++++++++++++ lib/include/zstd.h | 1 + 2 files changed, 37 insertions(+) create mode 100644 Package.swift create mode 120000 lib/include/zstd.h diff --git a/Package.swift b/Package.swift new file mode 100644 index 000000000..33587029a --- /dev/null +++ b/Package.swift @@ -0,0 +1,36 @@ +// swift-tools-version:5.0 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "zstd", + platforms: [ + .macOS(.v10_10), .iOS(.v9), .tvOS(.v9) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "zstd", + targets: [ "zstd" ]) + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "zstd", + path: "lib", + sources: [ "common", "compress", "decompress", "dictBuilder" ], + publicHeadersPath: "include", + cSettings: [ + .headerSearchPath(".") + ]) + ], + swiftLanguageVersions: [.v5], + cLanguageStandard: .gnu11, + cxxLanguageStandard: .gnucxx14 +) diff --git a/lib/include/zstd.h b/lib/include/zstd.h new file mode 120000 index 000000000..61fb36420 --- /dev/null +++ b/lib/include/zstd.h @@ -0,0 +1 @@ +../zstd.h \ No newline at end of file From 81b96205afb5b70dcbf292d48e07c0c66945285b Mon Sep 17 00:00:00 2001 From: "Lvv.me" Date: Mon, 15 Nov 2021 13:23:50 +0800 Subject: [PATCH 255/274] Using `module.modulemap` replace symbol link for public header --- Package.swift | 8 ++++---- lib/include/zstd.h | 1 - lib/modulemap/module.modulemap | 4 ++++ 3 files changed, 8 insertions(+), 5 deletions(-) delete mode 120000 lib/include/zstd.h create mode 100644 lib/modulemap/module.modulemap diff --git a/Package.swift b/Package.swift index 33587029a..75a5a0b33 100644 --- a/Package.swift +++ b/Package.swift @@ -11,8 +11,8 @@ let package = Package( products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( - name: "zstd", - targets: [ "zstd" ]) + name: "libzstd", + targets: [ "libzstd" ]) ], dependencies: [ // Dependencies declare other packages that this package depends on. @@ -22,10 +22,10 @@ let package = Package( // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( - name: "zstd", + name: "libzstd", path: "lib", sources: [ "common", "compress", "decompress", "dictBuilder" ], - publicHeadersPath: "include", + publicHeadersPath: "modulemap", cSettings: [ .headerSearchPath(".") ]) diff --git a/lib/include/zstd.h b/lib/include/zstd.h deleted file mode 120000 index 61fb36420..000000000 --- a/lib/include/zstd.h +++ /dev/null @@ -1 +0,0 @@ -../zstd.h \ No newline at end of file diff --git a/lib/modulemap/module.modulemap b/lib/modulemap/module.modulemap new file mode 100644 index 000000000..5e09fca9e --- /dev/null +++ b/lib/modulemap/module.modulemap @@ -0,0 +1,4 @@ +module libzstd { + umbrella header "../zstd.h" + export * +} From 802ea885efd73572fdd7afcdfd897a4460218cac Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 15 Nov 2021 17:25:24 -0800 Subject: [PATCH 256/274] Reduce function size in fast & dfast Take the same approach as in PR #2828 [0] to remove functions that force inline many function bodies and `switch`. Instead, create one function per "template" combination, and then switch between these functions. This allows the compiler to break the large function into many small functions, which generally helps codegen. Also, in the `extDict` modes when there is no ext-dict, call the top level function instead of the force inlined one, to save on code size. I'm specifically doing this because gcc on the parisc architecture doesn't handle the large function body well, and ends up using a lot of excess stack space. Outlining these functions fixes it. --- lib/compress/zstd_double_fast.c | 48 ++++++++++++++++++++++--------- lib/compress/zstd_fast.c | 50 ++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 27 deletions(-) diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 9d19468cb..b9393b6a4 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -468,6 +468,24 @@ _match_stored: return (size_t)(iend - anchor); } +#define ZSTD_GEN_DFAST_FN(dictMode, mls) \ + static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \ + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \ + } + +ZSTD_GEN_DFAST_FN(noDict, 4) +ZSTD_GEN_DFAST_FN(noDict, 5) +ZSTD_GEN_DFAST_FN(noDict, 6) +ZSTD_GEN_DFAST_FN(noDict, 7) + +ZSTD_GEN_DFAST_FN(dictMatchState, 4) +ZSTD_GEN_DFAST_FN(dictMatchState, 5) +ZSTD_GEN_DFAST_FN(dictMatchState, 6) +ZSTD_GEN_DFAST_FN(dictMatchState, 7) + size_t ZSTD_compressBlock_doubleFast( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -478,13 +496,13 @@ size_t ZSTD_compressBlock_doubleFast( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize); } } @@ -498,13 +516,13 @@ size_t ZSTD_compressBlock_doubleFast_dictMatchState( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_doubleFast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize); } } @@ -540,7 +558,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( /* if extDict is invalidated due to maxDistance, switch to "regular" variant */ if (prefixStartIndex == dictStartIndex) - return ZSTD_compressBlock_doubleFast_noDict_generic(ms, seqStore, rep, src, srcSize, mls); + return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize); /* Search Loop */ while (ip < ilimit) { /* < instead of <=, because (ip+1) */ @@ -653,6 +671,10 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( return (size_t)(iend - anchor); } +ZSTD_GEN_DFAST_FN(extDict, 4) +ZSTD_GEN_DFAST_FN(extDict, 5) +ZSTD_GEN_DFAST_FN(extDict, 6) +ZSTD_GEN_DFAST_FN(extDict, 7) size_t ZSTD_compressBlock_doubleFast_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -663,12 +685,12 @@ size_t ZSTD_compressBlock_doubleFast_extDict( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize); } } diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 2555e0720..87de17f81 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -90,7 +90,7 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms, * This is also the work we do at the beginning to enter the loop initially. */ FORCE_INLINE_TEMPLATE size_t -ZSTD_compressBlock_fast_generic( +ZSTD_compressBlock_fast_noDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize, U32 const mls) @@ -310,6 +310,18 @@ _match: /* Requires: ip0, match0, offcode */ goto _start; } +#define ZSTD_GEN_FAST_FN(dictMode, mls) \ + static size_t ZSTD_compressBlock_fast_##dictMode##_##mls( \ + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \ + } + +ZSTD_GEN_FAST_FN(noDict, 4) +ZSTD_GEN_FAST_FN(noDict, 5) +ZSTD_GEN_FAST_FN(noDict, 6) +ZSTD_GEN_FAST_FN(noDict, 7) size_t ZSTD_compressBlock_fast( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -321,13 +333,13 @@ size_t ZSTD_compressBlock_fast( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_fast_noDict_4(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_fast_noDict_5(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_fast_noDict_6(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_fast_noDict_7(ms, seqStore, rep, src, srcSize); } } @@ -479,6 +491,12 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( return (size_t)(iend - anchor); } + +ZSTD_GEN_FAST_FN(dictMatchState, 4) +ZSTD_GEN_FAST_FN(dictMatchState, 5) +ZSTD_GEN_FAST_FN(dictMatchState, 6) +ZSTD_GEN_FAST_FN(dictMatchState, 7) + size_t ZSTD_compressBlock_fast_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], void const* src, size_t srcSize) @@ -489,13 +507,13 @@ size_t ZSTD_compressBlock_fast_dictMatchState( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_fast_dictMatchState_4(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_fast_dictMatchState_5(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_fast_dictMatchState_6(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_fast_dictMatchState_7(ms, seqStore, rep, src, srcSize); } } @@ -530,7 +548,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( /* switch to "regular" variant if extDict is invalidated due to maxDistance */ if (prefixStartIndex == dictStartIndex) - return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls); + return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize); /* Search Loop */ while (ip < ilimit) { /* < instead of <=, because (ip+1) */ @@ -603,6 +621,10 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( return (size_t)(iend - anchor); } +ZSTD_GEN_FAST_FN(extDict, 4) +ZSTD_GEN_FAST_FN(extDict, 5) +ZSTD_GEN_FAST_FN(extDict, 6) +ZSTD_GEN_FAST_FN(extDict, 7) size_t ZSTD_compressBlock_fast_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -613,12 +635,12 @@ size_t ZSTD_compressBlock_fast_extDict( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 4); + return ZSTD_compressBlock_fast_extDict_4(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 5); + return ZSTD_compressBlock_fast_extDict_5(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 6); + return ZSTD_compressBlock_fast_extDict_6(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 7); + return ZSTD_compressBlock_fast_extDict_7(ms, seqStore, rep, src, srcSize); } } From 19eb459da38318eb238560ca6087a46fe5c5bbd0 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 15 Nov 2021 16:57:00 -0800 Subject: [PATCH 257/274] [linux-kernel] Don't inline function in zstd_opt.c The optimal parser is unlikely to be used in the linux kernel in practice. There is no reason these functions should be force inlined, since we aren't gaining anything, and are losing build size. | Compiler | Before (Bytes) | After (Bytes) | Delta (Bytes) | |----------|----------------|---------------|---------------| | gcc-11 | 1142090 | 952754 | -189336 | | clang-12 | 1228402 | 976290 | -252112 | This is a temporary solution pending the resolution of PR #2862 in the `dev` branch. --- contrib/linux-kernel/Makefile | 4 ++-- contrib/linux-kernel/test/macro-test.sh | 1 - lib/compress/zstd_opt.c | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/contrib/linux-kernel/Makefile b/contrib/linux-kernel/Makefile index f79de6792..47a431740 100644 --- a/contrib/linux-kernel/Makefile +++ b/contrib/linux-kernel/Makefile @@ -41,7 +41,6 @@ libzstd: -DZSTD_MEMORY_SANITIZER=0 \ -DZSTD_DATAFLOW_SANITIZER=0 \ -DZSTD_COMPRESS_HEAPMODE=1 \ - -UZSTD_NO_INLINE \ -UNO_PREFETCH \ -U__cplusplus \ -UZSTD_DLL_EXPORT \ @@ -55,7 +54,8 @@ libzstd: -RZSTD_FALLTHROUGH=fallthrough \ -DZSTD_HAVE_WEAK_SYMBOLS=0 \ -DZSTD_TRACE=0 \ - -DZSTD_NO_TRACE + -DZSTD_NO_TRACE \ + -DZSTD_LINUX_KERNEL mv linux/lib/zstd/zstd.h linux/include/linux/zstd_lib.h mv linux/lib/zstd/zstd_errors.h linux/include/linux/ cp linux_zstd.h linux/include/linux/zstd.h diff --git a/contrib/linux-kernel/test/macro-test.sh b/contrib/linux-kernel/test/macro-test.sh index bde6cbb56..9ea84aa66 100755 --- a/contrib/linux-kernel/test/macro-test.sh +++ b/contrib/linux-kernel/test/macro-test.sh @@ -36,7 +36,6 @@ test_not_present "ZSTD_NO_INTRINSICS" test_not_present "ZSTD_NO_UNUSED_FUNCTIONS" test_not_present "ZSTD_LEGACY_SUPPORT" test_not_present "STATIC_BMI2" -test_not_present "ZSTD_NO_INLINE" test_not_present "ZSTD_DLL_EXPORT" test_not_present "ZSTD_DLL_IMPORT" test_not_present "__ICCARM__" diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 909e06d05..0488589ff 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -8,6 +8,20 @@ * You may select, at your option, one of the above-listed licenses. */ +/** + * Disable inlining for the optimal parser for the kernel build. + * It is unlikely to be used in the kernel, and where it is used + * latency shouldn't matter because it is very slow to begin with. + * We prefer a ~180KB binary size win over faster optimal parsing. + * + * TODO(https://github.com/facebook/zstd/issues/2862): + * Improve the code size of the optimal parser in general, so we + * don't need this hack for the kernel build. + */ +#ifdef ZSTD_LINUX_KERNEL +#define ZSTD_NO_INLINE 1 +#endif + #include "zstd_compress_internal.h" #include "hist.h" #include "zstd_opt.h" From e2d01863bce98a4642c98cf7727ed8bfb0f33c81 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 16 Nov 2021 14:25:18 -0800 Subject: [PATCH 258/274] [linux-kernel] Don't add -O3 to CFLAGS It is no longer necessary to get good performance, there is only a small speed difference between -O2 and -O3, so just stick to the default of -O2. I've measured neutral compression speed and a ~3% decompression speed loss in userspace with clang & gcc. I've also measured neutral compression speed and a ~1% decompression speed loss in the kernel benchmarks. This also fixes the stack space usage on parisc. The compiler was buggy for -O3 and used ~3KB of stack space for several functions. With -O2 the problem is completely resolved, and stack space is back to a few hundred bytes. Additionally, we get a large code size win on gcc: | Compiler | Before (Bytes) | After (Bytes) | Delta (Bytes) | |----------|----------------|---------------|---------------| | gcc-11 | 952754 | 738954 | -213800 | | clang-12 | 976290 | 938826 | -37464 | --- contrib/linux-kernel/linux.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/linux-kernel/linux.mk b/contrib/linux-kernel/linux.mk index 9df9c9c6d..f6f3a8983 100644 --- a/contrib/linux-kernel/linux.mk +++ b/contrib/linux-kernel/linux.mk @@ -11,7 +11,6 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o -ccflags-y += -O3 ccflags-y += -Wno-error=deprecated-declarations zstd_compress-y := \ From 66079085f06c526e55e3f97cbe17d04d11960698 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 17 Nov 2021 18:09:18 -0500 Subject: [PATCH 259/274] Determinism: Avoid Mapping Window into Reserved Indices during Reduction PR #2850 attempted to fix a determinism bug that was uncovered by OSS-Fuzz. It succeeded in addressing that source of non-determinism, but introduced a new one: it was possible, when index reduction occurred, to map indices in the window to the reserved value, which would cause them to be zeroed, potentially altering parsing of the input. This PR addresses this issue. It makes sure that the bottom of the window is always `>= ZSTD_WINDOW_START_INDEX`. I'm not sure if this makes #2850 redundant. I think it's probably still valuable to have that protection as well. Credit to OSS-Fuzz for discovering this issue. --- lib/compress/zstd_compress_internal.h | 32 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 9e4c1ac17..d9473c104 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -982,7 +982,9 @@ MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window, { U32 const cycleSize = 1u << cycleLog; U32 const curr = (U32)((BYTE const*)src - window.base); - U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize); + U32 const minIndexToOverflowCorrect = cycleSize + + MAX(maxDist, cycleSize) + + ZSTD_WINDOW_START_INDEX; /* Adjust the min index to backoff the overflow correction frequency, * so we don't waste too much CPU in overflow correction. If this @@ -1057,10 +1059,14 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, U32 const cycleSize = 1u << cycleLog; U32 const cycleMask = cycleSize - 1; U32 const curr = (U32)((BYTE const*)src - window->base); - U32 const currentCycle0 = curr & cycleMask; - /* Exclude zero so that newCurrent - maxDist >= 1. */ - U32 const currentCycle1 = currentCycle0 == 0 ? cycleSize : currentCycle0; - U32 const newCurrent = currentCycle1 + MAX(maxDist, cycleSize); + U32 const currentCycle = curr & cycleMask; + /* Ensure newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX. */ + U32 const currentCycleCorrection = currentCycle < ZSTD_WINDOW_START_INDEX + ? MAX(cycleSize, ZSTD_WINDOW_START_INDEX) + : 0; + U32 const newCurrent = currentCycle + + currentCycleCorrection + + MAX(maxDist, cycleSize); U32 const correction = curr - newCurrent; /* maxDist must be a power of two so that: * (newCurrent & cycleMask) == (curr & cycleMask) @@ -1076,14 +1082,20 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, window->base += correction; window->dictBase += correction; - if (window->lowLimit <= correction) window->lowLimit = 1; - else window->lowLimit -= correction; - if (window->dictLimit <= correction) window->dictLimit = 1; - else window->dictLimit -= correction; + if (window->lowLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->lowLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->lowLimit -= correction; + } + if (window->dictLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->dictLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->dictLimit -= correction; + } /* Ensure we can still reference the full window. */ assert(newCurrent >= maxDist); - assert(newCurrent - maxDist >= 1); + assert(newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX); /* Ensure that lowLimit and dictLimit didn't underflow. */ assert(window->lowLimit <= newCurrent); assert(window->dictLimit <= newCurrent); From 7ce6f71c6f954dee08ee4217ace4fb1b5de90806 Mon Sep 17 00:00:00 2001 From: 15596858998 Date: Sun, 21 Nov 2021 12:35:58 +0800 Subject: [PATCH 260/274] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20playTests.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/playTests.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index 69653276a..4face06dd 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -713,6 +713,10 @@ test -f tmp2 test -f tmp3 test -f tmp4 +println "test : survive the list of files with too long filenames (--filelist=FILE)" +datagen -g51M > tmp_badList +zstd -f --filelist=tmp_badList && die "should have failed : file name length is too long" + println "test : survive a list of files which is text garbage (--filelist=FILE)" datagen > tmp_badList zstd -f --filelist=tmp_badList && die "should have failed : list is text garbage" From ebf664b7442197cfccbd5a6075c2c80af5946146 Mon Sep 17 00:00:00 2001 From: "Lvv.me" Date: Sun, 21 Nov 2021 21:57:55 +0800 Subject: [PATCH 261/274] Fix SPM warning: umbrella header for module 'libzstd' does not include header 'xxx.h' --- lib/modulemap/module.modulemap | 4 ++-- lib/modulemap/zstd-umbrella.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 lib/modulemap/zstd-umbrella.h diff --git a/lib/modulemap/module.modulemap b/lib/modulemap/module.modulemap index 5e09fca9e..2344fd947 100644 --- a/lib/modulemap/module.modulemap +++ b/lib/modulemap/module.modulemap @@ -1,4 +1,4 @@ -module libzstd { - umbrella header "../zstd.h" +module libzstd [extern_c] { + umbrella header "zstd-umbrella.h" export * } diff --git a/lib/modulemap/zstd-umbrella.h b/lib/modulemap/zstd-umbrella.h new file mode 100644 index 000000000..531e71254 --- /dev/null +++ b/lib/modulemap/zstd-umbrella.h @@ -0,0 +1 @@ +#include "../zstd.h" \ No newline at end of file From e315a047c7c6b804cfd5f27a3f1e2220b523e773 Mon Sep 17 00:00:00 2001 From: 15596858998 Date: Tue, 23 Nov 2021 22:08:23 +0800 Subject: [PATCH 262/274] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20fileio.c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Solve the logic problem of wrong output of newline characters. --- programs/fileio.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 8e5301dee..de0c318e4 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -889,26 +889,25 @@ static int FIO_removeMultiFilesWarning(FIO_ctx_t* const fCtx, const FIO_prefs_t* if (fCtx->nbFilesTotal > 1 && !prefs->overwrite) { if (g_display_prefs.displayLevel <= displayLevelCutoff) { if (prefs->removeSrcFile) { - DISPLAYLEVEL(1, "zstd: Aborting... not deleting files and processing into dst: %s", outFileName); + DISPLAYLEVEL(1, "zstd: Aborting... not deleting files and processing into dst: %s\n", outFileName); error = 1; } } else { if (!strcmp(outFileName, stdoutmark)) { - DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into stdout. "); + DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into stdout. \n"); } else { - DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); + DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into a single output file: %s \n", outFileName); } - DISPLAYLEVEL(2, "\nThe concatenated output CANNOT regenerate the original directory tree. ") + DISPLAYLEVEL(2, "The concatenated output CANNOT regenerate the original directory tree. \n") if (prefs->removeSrcFile) { if (fCtx->hasStdoutOutput) { - DISPLAYLEVEL(1, "\nAborting. Use -f if you really want to delete the files and output to stdout"); + DISPLAYLEVEL(1, "Aborting. Use -f if you really want to delete the files and output to stdout\n"); error = 1; } else { error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("This is a destructive operation. Proceed? (y/n): ", "Aborting...", "yY", fCtx->hasStdinInput); } } } - DISPLAY("\n"); } return error; } From 944c71c07d21d4286bb8efdb1dc66517696aeafd Mon Sep 17 00:00:00 2001 From: "Lvv.me" Date: Wed, 24 Nov 2021 07:48:40 +0800 Subject: [PATCH 263/274] Remove zstd-umbrella.h --- lib/modulemap/module.modulemap | 2 +- lib/modulemap/zstd-umbrella.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 lib/modulemap/zstd-umbrella.h diff --git a/lib/modulemap/module.modulemap b/lib/modulemap/module.modulemap index 2344fd947..eeda69885 100644 --- a/lib/modulemap/module.modulemap +++ b/lib/modulemap/module.modulemap @@ -1,4 +1,4 @@ module libzstd [extern_c] { - umbrella header "zstd-umbrella.h" + header "../zstd.h" export * } diff --git a/lib/modulemap/zstd-umbrella.h b/lib/modulemap/zstd-umbrella.h deleted file mode 100644 index 531e71254..000000000 --- a/lib/modulemap/zstd-umbrella.h +++ /dev/null @@ -1 +0,0 @@ -#include "../zstd.h" \ No newline at end of file From 0a36c104ca2f16200822b389f9a1bd0e35f64c1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jann=20K=C3=B6ker?= <39256107+jannkoeker@users.noreply.github.com> Date: Wed, 24 Nov 2021 11:35:36 +0100 Subject: [PATCH 264/274] Update CMakeLists.txt Prevents multiple rules error when building with ninja and clang under windows --- build/cmake/lib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt index a9bff58e5..7ba469330 100644 --- a/build/cmake/lib/CMakeLists.txt +++ b/build/cmake/lib/CMakeLists.txt @@ -106,7 +106,7 @@ if (MSVC) endif () # With MSVC static library needs to be renamed to avoid conflict with import library -if (MSVC) +if (MSVC OR (WIN32 AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) set(STATIC_LIBRARY_BASE_NAME zstd_static) else () set(STATIC_LIBRARY_BASE_NAME zstd) From 20660a02e281116c63538ec499ffde61454df7b2 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 3 Nov 2021 16:48:34 +0300 Subject: [PATCH 265/274] msvc tests to dev --- appveyor.yml | 112 ++++++++++++++++++++------------------------------- 1 file changed, 43 insertions(+), 69 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2656ca709..ce339077a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,23 +24,6 @@ ARTIFACT: "true" BUILD: "true" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "x64" - CONFIGURATION: "Debug" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "Win32" - CONFIGURATION: "Debug" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "x64" - CONFIGURATION: "Release" - - COMPILER: "visual" - HOST: "visual" - PLATFORM: "Win32" - CONFIGURATION: "Release" - - COMPILER: "clang-cl" HOST: "cmake-visual" PLATFORM: "x64" @@ -102,46 +85,6 @@ appveyor PushArtifact zstd-win-release-%PLATFORM%.zip ) ) - - if [%HOST%]==[visual] ( - ECHO *** && - ECHO *** Building Visual Studio 2008 %PLATFORM%\%CONFIGURATION% in %APPVEYOR_BUILD_FOLDER% && - ECHO *** && - msbuild "build\VS2008\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v90 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2008\bin\%PLATFORM%\%CONFIGURATION%\*.exe && - MD5sum build/VS2008/bin/%PLATFORM%/%CONFIGURATION%/*.exe && - COPY build\VS2008\bin\%PLATFORM%\%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2008_%PLATFORM%_%CONFIGURATION%.exe && - ECHO *** && - ECHO *** Building Visual Studio 2010 %PLATFORM%\%CONFIGURATION% && - ECHO *** && - msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - msbuild "build\VS2010\zstd.sln" %ADDITIONALPARAM% /m /verbosity:minimal /property:PlatformToolset=v100 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2010_%PLATFORM%_%CONFIGURATION%.exe && - ECHO *** && - ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% && - ECHO *** && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && - ECHO *** && - ECHO *** Building Visual Studio 2013 %PLATFORM%\%CONFIGURATION% && - ECHO *** && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v120 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2013_%PLATFORM%_%CONFIGURATION%.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ - ) - if [%HOST%]==[cmake-visual] ( ECHO *** && ECHO *** Building %CMAKE_GENERATOR% ^(%CMAKE_GENERATOR_TOOLSET%^) %PLATFORM%\%CONFIGURATION% && @@ -165,18 +108,6 @@ cd ..\..\.. && make clean ) - - SET "FUZZERTEST=-T30s" - - if [%HOST%]==[visual] if [%CONFIGURATION%]==[Release] ( - CD tests && - SET ZSTD_BIN=./zstd.exe&& - SET DATAGEN_BIN=./datagen.exe&& - sh -e playTests.sh --test-large-data && - fullbench.exe -i1 && - fullbench.exe -i1 -P0 && - fuzzer_VS2012_%PLATFORM%_Release.exe %FUZZERTEST% && - fuzzer_VS2013_%PLATFORM%_Release.exe %FUZZERTEST% && - fuzzer_VS2015_%PLATFORM%_Release.exe %FUZZERTEST% - ) # The following tests are for regular pushes @@ -187,6 +118,23 @@ version: 1.0.{build} environment: matrix: + - COMPILER: "visual" + HOST: "visual" + PLATFORM: "x64" + CONFIGURATION: "Debug" + - COMPILER: "visual" + HOST: "visual" + PLATFORM: "Win32" + CONFIGURATION: "Debug" + - COMPILER: "visual" + HOST: "visual" + PLATFORM: "x64" + CONFIGURATION: "Release" + - COMPILER: "visual" + HOST: "visual" + PLATFORM: "Win32" + CONFIGURATION: "Release" + - COMPILER: "gcc" HOST: "cygwin" PLATFORM: "x64" @@ -210,6 +158,9 @@ cmake,^ make ) + - IF [%HOST%]==[visual] IF [%PLATFORM%]==[x64] ( + SET ADDITIONALPARAM=/p:LibraryPath="C:\Program Files\Microsoft SDKs\Windows\v7.1\lib\x64;c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib\amd64;C:\Program Files (x86)\Microsoft Visual Studio 10.0\;C:\Program Files (x86)\Microsoft Visual Studio 10.0\lib\amd64;" + ) build_script: - ECHO Building %COMPILER% %PLATFORM% %CONFIGURATION% @@ -233,12 +184,35 @@ POPD && ECHO *** ) + - if [%HOST%]==[visual] ( + ECHO *** && + ECHO *** Building Visual Studio 2012 %PLATFORM%\%CONFIGURATION% && + ECHO *** && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && + MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && + COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ + ) test_script: - ECHO Testing %COMPILER% %PLATFORM% %CONFIGURATION% + - SET "FUZZERTEST=-T10s" - if [%HOST%]==[mingw] ( set "CC=%COMPILER%" && make clean && make check + ) + - if [%HOST%]==[visual] if [%CONFIGURATION%]==[Release] ( + CD tests && + SET ZSTD_BIN=./zstd.exe&& + SET DATAGEN_BIN=./datagen.exe&& + sh -e playTests.sh --test-large-data && + fullbench.exe -i1 && + fullbench.exe -i1 -P0 && + fuzzer_VS2012_%PLATFORM%_Release.exe %FUZZERTEST% ) \ No newline at end of file From 7abebc847b5e3d1f4cd632289b1e6cdfc85cee8d Mon Sep 17 00:00:00 2001 From: binhdvo Date: Mon, 29 Nov 2021 14:10:43 -0500 Subject: [PATCH 266/274] Clarify documentation for -c (#2883) --- contrib/pzstd/Options.cpp | 2 +- programs/README.md | 2 +- programs/zstd.1 | 2 +- programs/zstd.1.md | 2 +- programs/zstdcli.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp index 37292221b..90f9d571f 100644 --- a/contrib/pzstd/Options.cpp +++ b/contrib/pzstd/Options.cpp @@ -87,7 +87,7 @@ void usage() { std::fprintf(stderr, " -V, --version : display version number and exit\n"); std::fprintf(stderr, " -v, --verbose : verbose mode; specify multiple times to increase log level (default:2)\n"); std::fprintf(stderr, " -q, --quiet : suppress warnings; specify twice to suppress errors too\n"); - std::fprintf(stderr, " -c, --stdout : force write to standard output, even if it is the console\n"); + std::fprintf(stderr, " -c, --stdout : write to standard output (even if it is the console)\n"); #ifdef UTIL_HAS_CREATEFILELIST std::fprintf(stderr, " -r : operate recursively on directories\n"); #endif diff --git a/programs/README.md b/programs/README.md index 02a83ca3c..5570f90c3 100644 --- a/programs/README.md +++ b/programs/README.md @@ -156,7 +156,7 @@ Arguments : Advanced arguments : -V : display Version number and exit - -c : force write to standard output, even if it is the console + -c : write to standard output (even if it is the console) -v : verbose mode; specify multiple times to increase verbosity -q : suppress warnings; specify twice to suppress errors too --no-progress : do not display the progress counter diff --git a/programs/zstd.1 b/programs/zstd.1 index 63e8863c9..3dd8634df 100644 --- a/programs/zstd.1 +++ b/programs/zstd.1 @@ -111,7 +111,7 @@ This is also used during compression when using with \-\-patch\-from=\. In this .IP "\[ci]" 4 \fB\-f\fR, \fB\-\-force\fR: disable input and output checks\. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc\. .IP "\[ci]" 4 -\fB\-c\fR, \fB\-\-stdout\fR: force write to standard output, even if it is the console +\fB\-c\fR, \fB\-\-stdout\fR: write to standard output (even if it is the console) .IP "\[ci]" 4 \fB\-\-[no\-]sparse\fR: enable / disable sparse FS support, to make files with many zeroes smaller on disk\. Creating sparse files may save disk space and speed up decompression by reducing the amount of disk I/O\. default: enabled when output is into a file, and disabled when output is stdout\. This setting overrides default and can force sparse mode over stdout\. .IP "\[ci]" 4 diff --git a/programs/zstd.1.md b/programs/zstd.1.md index 94ef87869..ef37fef32 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -208,7 +208,7 @@ the last one takes effect. disable input and output checks. Allows overwriting existing files, input from console, output to stdout, operating on links, block devices, etc. * `-c`, `--stdout`: - force write to standard output, even if it is the console + write to standard output (even if it is the console) * `--[no-]sparse`: enable / disable sparse FS support, to make files with many zeroes smaller on disk. diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 05c537b5e..a3f8ebab7 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -163,7 +163,7 @@ static void usage_advanced(const char* programName) DISPLAYOUT( "Advanced arguments : \n"); DISPLAYOUT( " -V : display Version number and exit \n"); - DISPLAYOUT( " -c : force write to standard output, even if it is the console \n"); + DISPLAYOUT( " -c : write to standard output (even if it is the console) \n"); DISPLAYOUT( " -v : verbose mode; specify multiple times to increase verbosity \n"); DISPLAYOUT( " -q : suppress warnings; specify twice to suppress errors too \n"); From d7e17363751974dc1ad10785deb4170b23bee0ec Mon Sep 17 00:00:00 2001 From: binhdvo Date: Mon, 29 Nov 2021 14:11:39 -0500 Subject: [PATCH 267/274] Fix build for cygwin/bsd (#2882) --- programs/util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/util.c b/programs/util.c index 82363c39a..d69b72a37 100644 --- a/programs/util.c +++ b/programs/util.c @@ -1359,11 +1359,11 @@ int UTIL_countCores(int logical) * see: man 3 sysconf */ int UTIL_countCores(int logical) { - /* suppress unused parameter warning */ - (void) logical; - static int numCores = 0; + /* suppress unused parameter warning */ + (void)logical; + if (numCores != 0) return numCores; numCores = (int)sysconf(_SC_NPROCESSORS_ONLN); From 0907ab5f156853b2d6d30a1a495d86d82bddb967 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 29 Nov 2021 13:09:56 -0500 Subject: [PATCH 268/274] Add GH Actions windows runtime test --- .github/workflows/dev-short-tests.yml | 25 +++++++++++++++++++++++++ appveyor.yml | 15 +-------------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 8c1e29129..ae8409d72 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -332,6 +332,31 @@ jobs: make clean make check + + visual-runtime-tests: + runs-on: windows-latest + strategy: + matrix: + platform: [x64, Win32] + configuration: [Release] + steps: + - uses: actions/checkout@v2 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + - name: Build and run tests + working-directory: ${{env.GITHUB_WORKSPACE}} + env: + ZSTD_BIN: ./zstd.exe + DATAGEN_BIN: ./datagen.exe + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + run: | + msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v142 /t:Clean,Build /p:Platform=${{matrix.platform}} /p:Configuration=${{matrix.configuration}} + COPY build\VS2010\bin\${{matrix.platform}}_${{matrix.configuration}}\*.exe tests\ + CD tests + sh -e playTests.sh + DIR + .\fuzzer.exe -T2m + # This test currently fails on Github Actions specifically. # Possible reason : TTY emulation. # Note that the same test works fine locally and on travisCI. diff --git a/appveyor.yml b/appveyor.yml index ce339077a..c58ef91a1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -190,12 +190,8 @@ ECHO *** && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /p:ForceImportBeforeCppTargets=%APPVEYOR_BUILD_FOLDER%\build\VS2010\CompileAsCpp.props /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && msbuild "build\VS2010\zstd.sln" /m /verbosity:minimal /property:PlatformToolset=v110 /t:Clean,Build /p:Platform=%PLATFORM% /p:Configuration=%CONFIGURATION% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe && - MD5sum build/VS2010/bin/%PLATFORM%_%CONFIGURATION%/*.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\fuzzer.exe tests\fuzzer_VS2012_%PLATFORM%_%CONFIGURATION%.exe && - COPY build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe tests\ + DIR build\VS2010\bin\%PLATFORM%_%CONFIGURATION%\*.exe ) @@ -206,13 +202,4 @@ set "CC=%COMPILER%" && make clean && make check - ) - - if [%HOST%]==[visual] if [%CONFIGURATION%]==[Release] ( - CD tests && - SET ZSTD_BIN=./zstd.exe&& - SET DATAGEN_BIN=./datagen.exe&& - sh -e playTests.sh --test-large-data && - fullbench.exe -i1 && - fullbench.exe -i1 -P0 && - fuzzer_VS2012_%PLATFORM%_Release.exe %FUZZERTEST% ) \ No newline at end of file From ef2cba609d4cbb3dffe423dccf737165c72b4b2e Mon Sep 17 00:00:00 2001 From: Yonatan Komornik Date: Tue, 30 Nov 2021 10:31:52 -0800 Subject: [PATCH 269/274] `ZSTD_maxCLevel` now limited to 21 for 32-bit binaries. CI tests for constrained memory runs with max level on 32-bit binaries. --- .github/workflows/dev-short-tests.yml | 2 ++ doc/zstd_manual.html | 2 +- lib/compress/clevels.h | 3 ++- lib/compress/zstd_compress.c | 4 ++-- tests/fuzzer.c | 2 +- tests/playTests.sh | 5 +++++ 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index c68fe5edf..bc931e836 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -30,6 +30,8 @@ jobs: steps: - uses: actions/checkout@v2 - name: make check on 32-bit + env: + CHECK_CONSTRAINED_MEM: true run: | sudo apt update APT_PACKAGES="gcc-multilib" make apt-install diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 3d62f5952..7d2e1c6ca 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -40,7 +40,7 @@ functions. The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), - which is currently 22. Levels >= 20, labeled `--ultra`, should be used with + which is 22 in most cases. Levels >= 20, labeled `--ultra`, should be used with caution, as they require more memory. The library also offers negative compression levels, which extend the range of speed vs. ratio preferences. The lower the level, the faster the speed (at the cost of compression). diff --git a/lib/compress/clevels.h b/lib/compress/clevels.h index 9fa6adb5f..38622f1a1 100644 --- a/lib/compress/clevels.h +++ b/lib/compress/clevels.h @@ -16,7 +16,8 @@ /*-===== Pre-defined compression levels =====-*/ -#define ZSTD_MAX_CLEVEL 22 +#define ZSTD_MAX_CLEVEL 22 +#define ZSTD_MAX_32BIT_CLEVEL 21 #ifdef __GNUC__ __attribute__((__unused__)) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 32e486cd8..1edd1444a 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -6166,7 +6166,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) /*-===== Pre-defined compression levels =====-*/ #include "clevels.h" -int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } +int ZSTD_maxCLevel(void) { return MEM_32bits() ? ZSTD_MAX_32BIT_CLEVEL : ZSTD_MAX_CLEVEL; } int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; } @@ -6262,7 +6262,7 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, /* row */ if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */ - else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; + else if (compressionLevel > ZSTD_maxCLevel()) row = ZSTD_maxCLevel(); else row = compressionLevel; { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; diff --git a/tests/fuzzer.c b/tests/fuzzer.c index e3cdd321d..e2eedbcea 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1982,7 +1982,7 @@ static int basicUnitTests(U32 const seed, double compressibility) int const rowLevelEnd = 8; DISPLAYLEVEL(3, "test%3i : flat-dictionary efficiency test : \n", testNb++); - assert(maxLevel == 22); + assert(maxLevel == (MEM_32bits() ? 21 : 22)); RDG_genBuffer(CNBuffer, flatdictSize + contentSize, compressibility, 0., seed); DISPLAYLEVEL(4, "content hash : %016llx; dict hash : %016llx \n", XXH64(contentStart, contentSize, 0), XXH64(dict, flatdictSize, 0)); diff --git a/tests/playTests.sh b/tests/playTests.sh index 1edca7c3c..dc7c2e8ed 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1538,6 +1538,11 @@ elif [ "$longCSize19wlog23" -gt "$optCSize19wlog23" ]; then exit 1 fi +if [ -n "$CHECK_CONSTRAINED_MEM" ]; then + println "\n===> zsdt constrained memory tests " + # shellcheck disable=SC2039 + (ulimit -Sv 500000 ; datagen -g2M | zstd -22 --single-thread --ultra > /dev/null) +fi if [ "$1" != "--test-large-data" ]; then println "Skipping large data tests" From 5414dd7978273967f3d1d22156ff6c68bc543dc1 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 30 Nov 2021 17:43:28 -0800 Subject: [PATCH 270/274] [bmi2] Add lzcnt and bmi target attributes * When dynamic dispatching to bmi2 add lzcnt and bmi to the TARGET_ATTRIBUTE. * Centralize the bmi2 TARGET_ATTRIBUTE definition to BMI2_TARGET_ATTRIBUTE so we can change it in the future. * Only enable bmi2 when both bmi1 & bmi2 are supported. There shouldn't be any cases where bmi2 is supported but bmi1 isn't. But, since we are using the instruction we should check bmi1 as well. --- lib/common/compiler.h | 7 +++++++ lib/common/entropy_common.c | 4 ++-- lib/common/fse_decompress.c | 2 +- lib/common/zstd_internal.h | 9 +++++++++ lib/compress/huf_compress.c | 2 +- lib/compress/zstd_compress.c | 3 +-- lib/compress/zstd_compress_sequences.c | 2 +- lib/decompress/huf_decompress.c | 8 ++++---- lib/decompress/zstd_decompress.c | 3 +-- lib/decompress/zstd_decompress_block.c | 8 ++++---- 10 files changed, 31 insertions(+), 17 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index a9062d0f3..ea5fe2f47 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -101,6 +101,13 @@ # define TARGET_ATTRIBUTE(target) #endif +/* Target attribute for BMI2 dynamic dispatch. + * Enable lzcnt, bmi, and bmi2. + * We test for bmi1 & bmi2. lzcnt is included in bmi1. + */ +#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2") + + /* Enable runtime BMI2 dispatch based on the CPU. * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. */ diff --git a/lib/common/entropy_common.c b/lib/common/entropy_common.c index 3ac00255f..4229b40c5 100644 --- a/lib/common/entropy_common.c +++ b/lib/common/entropy_common.c @@ -223,7 +223,7 @@ static size_t FSE_readNCount_body_default( } #if DYNAMIC_BMI2 -TARGET_ATTRIBUTE("bmi2") static size_t FSE_readNCount_body_bmi2( +BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2( short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, const void* headerBuffer, size_t hbSize) { @@ -343,7 +343,7 @@ static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* r } #if DYNAMIC_BMI2 -static TARGET_ATTRIBUTE("bmi2") size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, +static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) diff --git a/lib/common/fse_decompress.c b/lib/common/fse_decompress.c index f4ff58fa0..a5a358015 100644 --- a/lib/common/fse_decompress.c +++ b/lib/common/fse_decompress.c @@ -365,7 +365,7 @@ static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, co } #if DYNAMIC_BMI2 -TARGET_ATTRIBUTE("bmi2") static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) { return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1); } diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 1dfa120e5..9073df422 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -20,6 +20,7 @@ * Dependencies ***************************************/ #include "compiler.h" +#include "cpu.h" #include "mem.h" #include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ #include "error_private.h" @@ -472,6 +473,14 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, const void* src, size_t srcSize); +/** + * @returns true iff the CPU supports dynamic BMI2 dispatch. + */ +MEM_STATIC int ZSTD_cpuSupportsBmi2(void) +{ + ZSTD_cpuid_t cpuid = ZSTD_cpuid(); + return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid); +} #if defined (__cplusplus) } diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index facec3300..41a414b5c 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -1029,7 +1029,7 @@ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, #if DYNAMIC_BMI2 -static TARGET_ATTRIBUTE("bmi2") size_t +static BMI2_TARGET_ATTRIBUTE size_t HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 32e486cd8..579c105b2 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -12,7 +12,6 @@ * Dependencies ***************************************/ #include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */ -#include "../common/cpu.h" #include "../common/mem.h" #include "hist.h" /* HIST_countFast_wksp */ #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */ @@ -100,7 +99,7 @@ static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) assert(cctx != NULL); ZSTD_memset(cctx, 0, sizeof(*cctx)); cctx->customMem = memManager; - cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + cctx->bmi2 = ZSTD_cpuSupportsBmi2(); { size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters); assert(!ZSTD_isError(err)); (void)err; diff --git a/lib/compress/zstd_compress_sequences.c b/lib/compress/zstd_compress_sequences.c index 44e1728ff..fa31e6e94 100644 --- a/lib/compress/zstd_compress_sequences.c +++ b/lib/compress/zstd_compress_sequences.c @@ -399,7 +399,7 @@ ZSTD_encodeSequences_default( #if DYNAMIC_BMI2 -static TARGET_ATTRIBUTE("bmi2") size_t +static BMI2_TARGET_ATTRIBUTE size_t ZSTD_encodeSequences_bmi2( void* dst, size_t dstCapacity, FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 9322c99a6..dd6c466c7 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -68,7 +68,7 @@ #endif #if HUF_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2 -# define HUF_ASM_X86_64_BMI2_ATTRS TARGET_ATTRIBUTE("bmi2") +# define HUF_ASM_X86_64_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE #else # define HUF_ASM_X86_64_BMI2_ATTRS #endif @@ -120,7 +120,7 @@ return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ } \ \ - static TARGET_ATTRIBUTE("bmi2") size_t fn##_bmi2( \ + static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \ void* dst, size_t dstSize, \ const void* cSrc, size_t cSrcSize, \ const HUF_DTable* DTable) \ @@ -670,7 +670,7 @@ HUF_decompress4X1_usingDTable_internal_body( } #if HUF_NEED_BMI2_FUNCTION -static TARGET_ATTRIBUTE("bmi2") +static BMI2_TARGET_ATTRIBUTE size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, size_t cSrcSize, HUF_DTable const* DTable) { return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); @@ -1386,7 +1386,7 @@ HUF_decompress4X2_usingDTable_internal_body( } #if HUF_NEED_BMI2_FUNCTION -static TARGET_ATTRIBUTE("bmi2") +static BMI2_TARGET_ATTRIBUTE size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, size_t cSrcSize, HUF_DTable const* DTable) { return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 47ca874bf..0031e98cf 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -56,7 +56,6 @@ * Dependencies *********************************************************/ #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ -#include "../common/cpu.h" /* bmi2 */ #include "../common/mem.h" /* low level memory routines */ #define FSE_STATIC_LINKING_ONLY #include "../common/fse.h" @@ -265,7 +264,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) dctx->noForwardProgress = 0; dctx->oversizedDuration = 0; #if DYNAMIC_BMI2 - dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + dctx->bmi2 = ZSTD_cpuSupportsBmi2(); #endif dctx->ddictSet = NULL; ZSTD_DCtx_resetParameters(dctx); diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index 79a44d9cb..e548844ce 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -571,7 +571,7 @@ static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt, } #if DYNAMIC_BMI2 -TARGET_ATTRIBUTE("bmi2") static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt, +BMI2_TARGET_ATTRIBUTE static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, const U32* baseValue, const U32* nbAdditionalBits, unsigned tableLog, void* wksp, size_t wkspSize) @@ -1846,7 +1846,7 @@ ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, #if DYNAMIC_BMI2 #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG -static TARGET_ATTRIBUTE("bmi2") size_t +static BMI2_TARGET_ATTRIBUTE size_t DONT_VECTORIZE ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, @@ -1856,7 +1856,7 @@ ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, { return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame); } -static TARGET_ATTRIBUTE("bmi2") size_t +static BMI2_TARGET_ATTRIBUTE size_t DONT_VECTORIZE ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, @@ -1869,7 +1869,7 @@ ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT -static TARGET_ATTRIBUTE("bmi2") size_t +static BMI2_TARGET_ATTRIBUTE size_t ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, const void* seqStart, size_t seqSize, int nbSeq, From 0356e05f0741181e6dc3354dc323e889065c4684 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 30 Nov 2021 16:51:16 -0800 Subject: [PATCH 271/274] [zdict] Remove ZDICT_CONTENTSIZE_MIN restriction for ZDICT_finalizeDictionary Allow the `dictContentSize` to be any size. The finalized dictionary content size must be at least as large as the maximum repcode (8). So we add zero bytes to the dictionary to ensure that we meet that requirement. I've removed this restriction because its been causing us headaches when people complain that dictionary training failed. It fails because there isn't enough useful content to put in the dictionary. Either because every sample is exactly the same and less than ZDICT_CONTENTSIZE_MIN bytes, or there isn't enough content. Instead, we should succeed in creating the dictionary, and it is up to the user to decide if it is worthwhile. It is possible that the tables alone provide enough value. NOTE: This allows us to produce dictionaries with finalized `dictContentSize < ZDICT_CONTENTSIZE_MIN`. But, they are still valid zstd dictionaries. We could remove the `ZDICT_CONTENTSIZE_MIN` macro, but I've decided to leave that for now, so we don't break users. --- lib/dictBuilder/zdict.c | 58 ++++++++++++++++++++++++++++++++++++----- lib/zdict.h | 4 +-- tests/playTests.sh | 4 --- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index d93b202e7..8b8b381ed 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -915,6 +915,17 @@ _cleanup: } +/** + * @returns the maximum repcode value + */ +static U32 ZDICT_maxRep(U32 const reps[ZSTD_REP_NUM]) +{ + U32 maxRep = reps[0]; + int r; + for (r = 1; r < ZSTD_REP_NUM; ++r) + maxRep = MAX(maxRep, reps[r]); + return maxRep; +} size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity, const void* customDictContent, size_t dictContentSize, @@ -926,11 +937,13 @@ size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity, BYTE header[HBUFFSIZE]; int const compressionLevel = (params.compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : params.compressionLevel; U32 const notificationLevel = params.notificationLevel; + /* The final dictionary content must be at least as large as the largest repcode */ + size_t const minContentSize = (size_t)ZDICT_maxRep(repStartValue); + size_t paddingSize; /* check conditions */ DEBUGLOG(4, "ZDICT_finalizeDictionary"); if (dictBufferCapacity < dictContentSize) return ERROR(dstSize_tooSmall); - if (dictContentSize < ZDICT_CONTENTSIZE_MIN) return ERROR(srcSize_wrong); if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) return ERROR(dstSize_tooSmall); /* dictionary header */ @@ -954,12 +967,43 @@ size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity, hSize += eSize; } - /* copy elements in final buffer ; note : src and dst buffer can overlap */ - if (hSize + dictContentSize > dictBufferCapacity) dictContentSize = dictBufferCapacity - hSize; - { size_t const dictSize = hSize + dictContentSize; - char* dictEnd = (char*)dictBuffer + dictSize; - memmove(dictEnd - dictContentSize, customDictContent, dictContentSize); - memcpy(dictBuffer, header, hSize); + /* Shrink the content size if it doesn't fit in the buffer */ + if (hSize + dictContentSize > dictBufferCapacity) { + dictContentSize = dictBufferCapacity - hSize; + } + + /* Pad the dictionary content with zeros if it is too small */ + if (dictContentSize < minContentSize) { + RETURN_ERROR_IF(hSize + minContentSize > dictBufferCapacity, dstSize_tooSmall, + "dictBufferCapacity too small to fit max repcode"); + paddingSize = minContentSize - dictContentSize; + } else { + paddingSize = 0; + } + + { + size_t const dictSize = hSize + paddingSize + dictContentSize; + + /* The dictionary consists of the header, optional padding, and the content. + * The padding comes before the content because the "best" position in the + * dictionary is the last byte. + */ + BYTE* const outDictHeader = (BYTE*)dictBuffer; + BYTE* const outDictPadding = outDictHeader + hSize; + BYTE* const outDictContent = outDictPadding + paddingSize; + + assert(dictSize <= dictBufferCapacity); + assert(outDictContent + dictContentSize == (BYTE*)dictBuffer + dictSize); + + /* First copy the customDictContent into its final location. + * `customDictContent` and `dictBuffer` may overlap, so we must + * do this before any other writes into the output buffer. + * Then copy the header & padding into the output buffer. + */ + memmove(outDictContent, customDictContent, dictContentSize); + memcpy(outDictHeader, header, hSize); + memset(outDictPadding, 0, paddingSize); + return dictSize; } } diff --git a/lib/zdict.h b/lib/zdict.h index ac98a169b..f1e139a40 100644 --- a/lib/zdict.h +++ b/lib/zdict.h @@ -237,7 +237,6 @@ typedef struct { * is presumed that the most profitable content is at the end of the dictionary, * since that is the cheapest to reference. * - * `dictContentSize` must be >= ZDICT_CONTENTSIZE_MIN bytes. * `maxDictSize` must be >= max(dictContentSize, ZSTD_DICTSIZE_MIN). * * @return: size of dictionary stored into `dstDictBuffer` (<= `maxDictSize`), @@ -272,8 +271,9 @@ ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode); * Use them only in association with static linking. * ==================================================================================== */ -#define ZDICT_CONTENTSIZE_MIN 128 #define ZDICT_DICTSIZE_MIN 256 +/* Deprecated: Remove in v1.6.0 */ +#define ZDICT_CONTENTSIZE_MIN 128 /*! ZDICT_cover_params_t: * k and d are the only required parameters. diff --git a/tests/playTests.sh b/tests/playTests.sh index 1edca7c3c..3c773ed5b 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1018,12 +1018,8 @@ zstd -o tmpDict --train "$TESTDIR"/*.c "$PRGDIR"/*.c test -f tmpDict zstd --train "$TESTDIR"/*.c "$PRGDIR"/*.c test -f dictionary -println "- Test dictionary training fails" -echo "000000000000000000000000000000000" > tmpz -zstd --train tmpz tmpz tmpz tmpz tmpz tmpz tmpz tmpz tmpz && die "Dictionary training should fail : source is all zeros" if [ -n "$hasMT" ] then - zstd --train -T0 tmpz tmpz tmpz tmpz tmpz tmpz tmpz tmpz tmpz && die "Dictionary training should fail : source is all zeros" println "- Create dictionary with multithreading enabled" zstd --train -T0 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict fi From 360c2630e4180e6e0510755cbce076e15736b2f0 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 30 Nov 2021 12:29:55 -0800 Subject: [PATCH 272/274] [test] Test that the exec-stack bit isn't set on libzstd.so Tests that libzstd.so doesn't have the exec-stack bit set using readelf. If the stack is marked executable systemd will refuse to link against zstd. We now test that it isn't set on every PR. Adds a test for PR #2857 Fixes Issue #2865 --- .github/workflows/dev-short-tests.yml | 6 +++--- tests/{libzstd_partial_builds.sh => libzstd_builds.sh} | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) rename tests/{libzstd_partial_builds.sh => libzstd_builds.sh} (92%) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 584baa858..0f6590ecc 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -117,11 +117,11 @@ jobs: make -C zlibWrapper test make -C zlibWrapper valgrindTest - lz4-threadpool-partial-libs: + lz4-threadpool-libs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: LZ4, thread pool, and partial libs testslib wrapper test + - name: LZ4, thread pool, and libs build testslib wrapper test run: | make lz4install make -C tests test-lz4 @@ -129,7 +129,7 @@ jobs: make clean make -C tests test-pool make clean - bash tests/libzstd_partial_builds.sh + bash tests/libzstd_builds.sh gcc-make-tests-32bit: runs-on: ubuntu-latest diff --git a/tests/libzstd_partial_builds.sh b/tests/libzstd_builds.sh similarity index 92% rename from tests/libzstd_partial_builds.sh rename to tests/libzstd_builds.sh index 05dad8f98..f9e1e76c6 100755 --- a/tests/libzstd_partial_builds.sh +++ b/tests/libzstd_builds.sh @@ -23,14 +23,19 @@ mustBeAbsent() { # default compilation : all features enabled - no zbuff $ECHO "testing default library compilation" -CFLAGS= make -C $DIR/../lib libzstd.a > $INTOVOID +CFLAGS= make -C $DIR/../lib libzstd libzstd.a > $INTOVOID nm $DIR/../lib/libzstd.a | $GREP "\.o" > tmplog isPresent "zstd_compress.o" isPresent "zstd_decompress.o" isPresent "zdict.o" isPresent "zstd_v07.o" mustBeAbsent "zbuff_compress.o" -$RM $DIR/../lib/libzstd.a tmplog +$RM tmplog + +# Check that the exec-stack bit isn't set +readelf -lW $DIR/../lib/libzstd.so | $GREP "GNU_STACK" > tmplog +mustBeAbsent "RWE" +$RM $DIR/../lib/libzstd.a $DIR/../lib/libzstd.so* tmplog # compression disabled => also disable zdict $ECHO "testing with compression disabled" From a7a469e09514fd71e0a1b1fb61f78dc158ca91d2 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Tue, 30 Nov 2021 18:26:11 -0800 Subject: [PATCH 273/274] [contrib][pzstd] Fix build issue with gcc-5 gcc-5 didn't like the l-value overload for defaulted operator=. There is no reason it needs to be l-value overloaded, so just remove it. I'm not sure why the build broke for @mckaygerhard in Issue #2811, since this code hasn't changed since it was added. But, there is no harm in fixing it. Fixes issue #2811. --- contrib/pzstd/utils/Buffer.h | 2 +- contrib/pzstd/utils/Range.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/pzstd/utils/Buffer.h b/contrib/pzstd/utils/Buffer.h index f69c3b4d9..d17ad2f2c 100644 --- a/contrib/pzstd/utils/Buffer.h +++ b/contrib/pzstd/utils/Buffer.h @@ -45,7 +45,7 @@ class Buffer { : buffer_(buffer), range_(data) {} Buffer(Buffer&&) = default; - Buffer& operator=(Buffer&&) & = default; + Buffer& operator=(Buffer&&) = default; /** * Splits the data into two pieces: [begin, begin + n), [begin + n, end). diff --git a/contrib/pzstd/utils/Range.h b/contrib/pzstd/utils/Range.h index fedb5d786..6a850ad4e 100644 --- a/contrib/pzstd/utils/Range.h +++ b/contrib/pzstd/utils/Range.h @@ -6,7 +6,7 @@ * LICENSE file in the root directory of this source tree) and the GPLv2 (found * in the COPYING file in the root directory of this source tree). */ - + /** * A subset of `folly/Range.h`. * All code copied verbatim modulo formatting @@ -83,8 +83,8 @@ class Range { Range(const Range&) = default; Range(Range&&) = default; - Range& operator=(const Range&) & = default; - Range& operator=(Range&&) & = default; + Range& operator=(const Range&) = default; + Range& operator=(Range&&) = default; constexpr size_type size() const { return e_ - b_; From 49d578763d957a3272cf7365bf8ec839660dd285 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Dec 2021 15:10:55 -0800 Subject: [PATCH 274/274] reduce storage requirement 51 MB seems excessive for CI storate and considering the nature of the test. (note : maybe we should consider using `/tmp` for files generated during tests, as tmpfs is typically using RAM, thus preserving storage.) --- tests/playTests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index b6028e7b5..83b0cd438 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -714,7 +714,7 @@ test -f tmp3 test -f tmp4 println "test : survive the list of files with too long filenames (--filelist=FILE)" -datagen -g51M > tmp_badList +datagen -g5M > tmp_badList zstd -f --filelist=tmp_badList && die "should have failed : file name length is too long" println "test : survive a list of files which is text garbage (--filelist=FILE)"