From 91c9a247b67374b74753a7d3dcc8999db710b139 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 13 May 2021 15:44:12 -0700 Subject: [PATCH 001/340] [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/340] [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/340] [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/340] [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/340] 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 e81d5675479016e43ef410082df53c2d589615cf Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Wed, 17 Feb 2021 20:24:21 +0100 Subject: [PATCH 006/340] Distinguish static symbols, allow hiding them Even with -fvisibility=hidden added to CFLAGS, any symbol which is given a default visibility attribute ends up exported in the dynamic library. This happens through zstd_internal.h which defines ..._STATIC_LINKING_ONLY before including various header files, and is included for example in lib/common/pool.c. To avoid this, this patch distinguishes static and non-static APIs, by using ZSTDLIB_API only for the latter, and introducing ZSTDLIB_STATIC_API for the former. For now, both are exported, but non-static APIs can be hidden by overriding the definition ZSTDLIB_STATIC_API. lib/Makefile is modified to allow this using make CPPFLAGS_DYNLIB=-DZSTDLIB_STATIC_API=ZSTDLIB_HIDDEN In addition, API declarations are dropped from zstd_compress.c (they aren't needed there). Signed-off-by: Stephen Kitt --- lib/Makefile | 6 +- lib/compress/zstd_compress.c | 8 +- lib/zstd.h | 211 +++++++++++++++++++---------------- 3 files changed, 119 insertions(+), 106 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 9109476bf..e258dea8a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -71,9 +71,9 @@ DEBUGFLAGS= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ 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 +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 ?= diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b7ee2980a..7edd94183 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1067,7 +1067,7 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams( return 0; } -ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) +size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) { DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %u bytes", (U32)pledgedSrcSize); RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, @@ -1147,14 +1147,14 @@ size_t ZSTD_CCtx_loadDictionary_advanced( return 0; } -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference( +size_t ZSTD_CCtx_loadDictionary_byReference( ZSTD_CCtx* cctx, const void* dict, size_t dictSize) { return ZSTD_CCtx_loadDictionary_advanced( cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); } -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize) { return ZSTD_CCtx_loadDictionary_advanced( cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); @@ -4842,7 +4842,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, &cctxParams, customMem); } -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2( +ZSTD_CDict* ZSTD_createCDict_advanced2( const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, diff --git a/lib/zstd.h b/lib/zstd.h index 4651e6c4d..c3f642d47 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -20,19 +20,21 @@ extern "C" { /* ===== ZSTDLIB_API : control library symbols visibility ===== */ -#ifndef ZSTDLIB_VISIBILITY -# if defined(__GNUC__) && (__GNUC__ >= 4) -# define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default"))) +#ifndef ZSTDLIB_VISIBLE +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default"))) +# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden"))) # else -# define ZSTDLIB_VISIBILITY +# define ZSTDLIB_VISIBLE +# define ZSTDLIB_HIDDEN # endif #endif #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) -# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY +# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE #elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) -# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ #else -# define ZSTDLIB_API ZSTDLIB_VISIBILITY +# define ZSTDLIB_API ZSTDLIB_VISIBLE #endif @@ -1073,25 +1075,36 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); #if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) #define ZSTD_H_ZSTD_STATIC_LINKING_ONLY +/* This can be overridden externally to hide static symbols. */ +#ifndef ZSTDLIB_STATIC_API +# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDLIB_STATIC_API __declspec(dllexport) ZSTDLIB_VISIBLE +# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_STATIC_API __declspec(dllimport) ZSTDLIB_VISIBLE +# else +# define ZSTDLIB_STATIC_API ZSTDLIB_VISIBLE +# endif +#endif + /* Deprecation warnings : * Should these warnings be a problem, it is generally possible to disable them, * typically with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual. * Otherwise, it's also possible to define ZSTD_DISABLE_DEPRECATE_WARNINGS. */ #ifdef ZSTD_DISABLE_DEPRECATE_WARNINGS -# define ZSTD_DEPRECATED(message) ZSTDLIB_API /* disable deprecation warnings */ +# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API /* disable deprecation warnings */ #else # if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ -# define ZSTD_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_API +# define ZSTD_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_STATIC_API # elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__) -# define ZSTD_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated(message))) +# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __attribute__((deprecated(message))) # elif defined(__GNUC__) && (__GNUC__ >= 3) -# define ZSTD_DEPRECATED(message) ZSTDLIB_API __attribute__((deprecated)) +# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __attribute__((deprecated)) # elif defined(_MSC_VER) -# define ZSTD_DEPRECATED(message) ZSTDLIB_API __declspec(deprecated(message)) +# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __declspec(deprecated(message)) # else # pragma message("WARNING: You need to implement ZSTD_DEPRECATED for this compiler") -# define ZSTD_DEPRECATED(message) ZSTDLIB_API +# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API # endif #endif /* ZSTD_DISABLE_DEPRECATE_WARNINGS */ @@ -1332,7 +1345,7 @@ typedef enum { * note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to * read each contained frame header. This is fast as most of the data is skipped, * however it does mean that all frame data must be present and valid. */ -ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); +ZSTDLIB_STATIC_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); /*! ZSTD_decompressBound() : * `src` should point to the start of a series of ZSTD encoded and/or skippable frames @@ -1347,13 +1360,13 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t * note 3 : when the decompressed size field isn't available, the upper-bound for that frame is calculated by: * upper-bound = # blocks * min(128 KB, Window_Size) */ -ZSTDLIB_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize); +ZSTDLIB_STATIC_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize); /*! ZSTD_frameHeaderSize() : * srcSize must be >= ZSTD_FRAMEHEADERSIZE_PREFIX. * @return : size of the Frame Header, * or an error code (if srcSize is too small) */ -ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); typedef enum { ZSTD_sf_noBlockDelimiters = 0, /* Representation of ZSTD_Sequence has no block delimiters, sequences only */ @@ -1376,7 +1389,7 @@ typedef enum { * @return : number of sequences generated */ -ZSTDLIB_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, +ZSTDLIB_STATIC_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, size_t outSeqsSize, const void* src, size_t srcSize); /*! ZSTD_mergeBlockDelimiters() : @@ -1390,7 +1403,7 @@ ZSTDLIB_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs, * setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters * @return : number of sequences left after merging */ -ZSTDLIB_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize); +ZSTDLIB_STATIC_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize); /*! ZSTD_compressSequences() : * Compress an array of ZSTD_Sequence, generated from the original source buffer, into dst. @@ -1420,7 +1433,7 @@ ZSTDLIB_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t se * and cannot emit an RLE block that disagrees with the repcode history * @return : final compressed size or a ZSTD error. */ -ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize, +ZSTDLIB_STATIC_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize, const ZSTD_Sequence* inSeqs, size_t inSeqsSize, const void* src, size_t srcSize); @@ -1438,7 +1451,7 @@ ZSTDLIB_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size * * @return : number of bytes written or a ZSTD error. */ -ZSTDLIB_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, +ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned magicVariant); @@ -1469,10 +1482,10 @@ ZSTDLIB_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, * Note 2 : only single-threaded compression is supported. * ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. */ -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel); -ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); -ZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); -ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void); /*! ZSTD_estimateCStreamSize() : * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. @@ -1487,20 +1500,20 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); * Note : if streaming is init with function ZSTD_init?Stream_usingDict(), * an internal ?Dict will be created, which additional size is not estimated here. * In this case, get total size by adding ZSTD_estimate?DictSize */ -ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel); -ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams); -ZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params); -ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize); -ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t windowSize); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); /*! ZSTD_estimate?DictSize() : * ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). * ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced(). * Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller. */ -ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel); -ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod); -ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod); /*! ZSTD_initStatic*() : * Initialize an object using a pre-allocated fixed-size buffer. @@ -1523,20 +1536,20 @@ ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e * Limitation 2 : static cctx currently not compatible with multi-threading. * Limitation 3 : static dctx is incompatible with legacy support. */ -ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); -ZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */ +ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); +ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */ -ZSTDLIB_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); -ZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */ +ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); +ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */ -ZSTDLIB_API const ZSTD_CDict* ZSTD_initStaticCDict( +ZSTDLIB_STATIC_API const ZSTD_CDict* ZSTD_initStaticCDict( void* workspace, size_t workspaceSize, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_compressionParameters cParams); -ZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict( +ZSTDLIB_STATIC_API const ZSTD_DDict* ZSTD_initStaticDDict( void* workspace, size_t workspaceSize, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, @@ -1557,12 +1570,12 @@ __attribute__((__unused__)) #endif ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ -ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem); +ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); +ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); +ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); +ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, ZSTD_compressionParameters cParams, @@ -1579,22 +1592,22 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS * 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); -ZSTDLIB_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */ -ZSTDLIB_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool); +ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads); +ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool); /* * This API is temporary and is expected to change or disappear in the future! */ -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced2( +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced2( const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, const ZSTD_CCtx_params* cctxParams, ZSTD_customMem customMem); -ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced( +ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_advanced( const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType, @@ -1611,22 +1624,22 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced( * As a consequence, `dictBuffer` **must** outlive CDict, * and its content must remain unmodified throughout the lifetime of CDict. * note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */ -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); /*! ZSTD_getCParams() : * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. * `estimatedSrcSize` value is optional, select 0 if not known */ -ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); +ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); /*! ZSTD_getParams() : * same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. * All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */ -ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); +ZSTDLIB_STATIC_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); /*! ZSTD_checkCParams() : * Ensure param values remain within authorized range. * @return 0 on success, or an error code (can be checked with ZSTD_isError()) */ -ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); +ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); /*! ZSTD_adjustCParams() : * optimize params for a given `srcSize` and `dictSize`. @@ -1634,7 +1647,7 @@ ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); * `dictSize` must be `0` when there is no dictionary. * cPar can be invalid : all parameters will be clamped within valid range in the @return struct. * This function never fails (wide contract) */ -ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); +ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); /*! ZSTD_compress_advanced() : * Note : this function is now DEPRECATED. @@ -1662,18 +1675,18 @@ size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, /*! ZSTD_CCtx_loadDictionary_byReference() : * Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx. * It saves some memory, but also requires that `dict` outlives its usage within `cctx` */ -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); /*! ZSTD_CCtx_loadDictionary_advanced() : * Same as ZSTD_CCtx_loadDictionary(), but gives finer control over * how to load the dictionary (by copy ? by reference ?) * and how to interpret it (automatic ? force raw mode ? full mode only ?) */ -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); /*! ZSTD_CCtx_refPrefix_advanced() : * Same as ZSTD_CCtx_refPrefix(), but gives finer control over * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */ -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); /* === experimental parameters === */ /* these parameters can be used with ZSTD_setParameter() @@ -1911,7 +1924,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre * and store it into int* value. * @return : 0, or an error code (which can be tested with ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value); +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value); /*! ZSTD_CCtx_params : @@ -1931,25 +1944,25 @@ ZSTDLIB_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter * This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() * for static allocation of CCtx for single-threaded compression. */ -ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void); -ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */ +ZSTDLIB_STATIC_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void); +ZSTDLIB_STATIC_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */ /*! ZSTD_CCtxParams_reset() : * Reset params to default values. */ -ZSTDLIB_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params); +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params); /*! ZSTD_CCtxParams_init() : * Initializes the compression parameters of cctxParams according to * compression level. All other parameters are reset to their default values. */ -ZSTDLIB_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel); /*! ZSTD_CCtxParams_init_advanced() : * Initializes the compression and frame parameters of cctxParams according to * params. All other parameters are reset to their default values. */ -ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); /*! ZSTD_CCtxParams_setParameter() : Requires v1.4.0+ * Similar to ZSTD_CCtx_setParameter. @@ -1959,14 +1972,14 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, Z * @result : a code representing success or failure (which can be tested with * ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value); +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value); /*! ZSTD_CCtxParams_getParameter() : * Similar to ZSTD_CCtx_getParameter. * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. * @result : 0, or an error code (which can be tested with ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value); +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value); /*! ZSTD_CCtx_setParametersUsingCCtxParams() : * Apply a set of ZSTD_CCtx_params to the compression context. @@ -1975,7 +1988,7 @@ ZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, * if nbWorkers>=1, new parameters will be picked up at next job, * with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated). */ -ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params); /*! ZSTD_compressStream2_simpleArgs() : @@ -1984,7 +1997,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( * This variant might be helpful for binders from dynamic languages * which have troubles handling structures containing memory pointers. */ -ZSTDLIB_API size_t ZSTD_compressStream2_simpleArgs ( +ZSTDLIB_STATIC_API size_t ZSTD_compressStream2_simpleArgs ( ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, size_t* dstPos, const void* src, size_t srcSize, size_t* srcPos, @@ -2000,33 +2013,33 @@ ZSTDLIB_API size_t ZSTD_compressStream2_simpleArgs ( * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. * Note 3 : Skippable Frame Identifiers are considered valid. */ -ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size); +ZSTDLIB_STATIC_API unsigned ZSTD_isFrame(const void* buffer, size_t size); /*! ZSTD_createDDict_byReference() : * Create a digested dictionary, ready to start decompression operation without startup delay. * Dictionary content is referenced, and therefore stays in dictBuffer. * It is important that dictBuffer outlives DDict, * it must remain read accessible throughout the lifetime of DDict */ -ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize); +ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize); /*! ZSTD_DCtx_loadDictionary_byReference() : * Same as ZSTD_DCtx_loadDictionary(), * but references `dict` content instead of copying it into `dctx`. * This saves memory if `dict` remains around., * However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. */ -ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); /*! ZSTD_DCtx_loadDictionary_advanced() : * Same as ZSTD_DCtx_loadDictionary(), * but gives direct control over * how to load the dictionary (by copy ? by reference ?) * and how to interpret it (automatic ? force raw mode ? full mode only ?). */ -ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); /*! ZSTD_DCtx_refPrefix_advanced() : * Same as ZSTD_DCtx_refPrefix(), but gives finer control over * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */ -ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); /*! ZSTD_DCtx_setMaxWindowSize() : * Refuses allocating internal buffers for frames requiring a window size larger than provided limit. @@ -2035,14 +2048,14 @@ ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* pre * By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) * @return : 0, or an error code (which can be tested using ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); /*! ZSTD_DCtx_getParameter() : * Get the requested decompression parameter value, selected by enum ZSTD_dParameter, * and store it into int* value. * @return : 0, or an error code (which can be tested with ZSTD_isError()). */ -ZSTDLIB_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value); +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value); /* ZSTD_d_format * experimental parameter, @@ -2131,7 +2144,7 @@ size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); * This can be helpful for binders from dynamic languages * which have troubles handling structures containing memory pointers. */ -ZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs ( +ZSTDLIB_STATIC_API size_t ZSTD_decompressStream_simpleArgs ( ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, size_t* dstPos, const void* src, size_t srcSize, size_t* srcPos); @@ -2270,7 +2283,7 @@ typedef struct { * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed. * Aggregates progression inside active worker threads. */ -ZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx); +ZSTDLIB_STATIC_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx); /*! ZSTD_toFlushNow() : * Tell how many bytes are ready to be flushed immediately. @@ -2285,7 +2298,7 @@ ZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx * therefore flush speed is limited by production speed of oldest job * irrespective of the speed of concurrent (and newer) jobs. */ -ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); +ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); /*===== Advanced Streaming decompression functions =====*/ @@ -2299,7 +2312,7 @@ ZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); * note: no dictionary will be used if dict == NULL or dictSize < 8 * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x */ -ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /*! * This function is deprecated, and is equivalent to: @@ -2310,7 +2323,7 @@ ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dic * note : ddict is referenced, it must outlive decompression session * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x */ -ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); +ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); /*! * This function is deprecated, and is equivalent to: @@ -2320,7 +2333,7 @@ ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDi * re-use decompression parameters from previous init; saves dictionary loading * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x */ -ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); +ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); /********************************************************************* @@ -2362,13 +2375,13 @@ ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); */ /*===== Buffer-less streaming compression functions =====*/ -ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); -ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); -ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ -ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ +ZSTDLIB_STATIC_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ -ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); /* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */ ZSTD_DEPRECATED("use advanced API to access custom parameters") @@ -2465,24 +2478,24 @@ typedef struct { * @return : 0, `zfhPtr` is correctly filled, * >0, `srcSize` is too small, value is wanted `srcSize` amount, * or an error code, which can be tested using ZSTD_isError() */ -ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */ /*! ZSTD_getFrameHeader_advanced() : * same as ZSTD_getFrameHeader(), * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ -ZSTDLIB_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); -ZSTDLIB_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); +ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ -ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); -ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); -ZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); -ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx); -ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); /* misc */ -ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); +ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; -ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); @@ -2519,10 +2532,10 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); */ /*===== Raw zstd block functions =====*/ -ZSTDLIB_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); -ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ +ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); +ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ #endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ From 25bda9053add6218a58d88c5b8119afa63165231 Mon Sep 17 00:00:00 2001 From: TrianglesPCT Date: Fri, 14 May 2021 16:32:04 -0600 Subject: [PATCH 007/340] 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 008/340] 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 009/340] 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 010/340] 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 011/340] 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 012/340] 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 013/340] 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 014/340] 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 015/340] 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 016/340] 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 017/340] 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 018/340] 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 019/340] [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 020/340] 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 021/340] 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 022/340] 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 023/340] [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 024/340] [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 025/340] [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 026/340] [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 027/340] 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 028/340] 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 029/340] 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 030/340] 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 fa2a6d474653028a447f15cd1d7c7573e576b530 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Thu, 27 May 2021 10:31:49 +0300 Subject: [PATCH 031/340] Makefile: fix build for mingw Add ${EXT} to required places to make install succeed for mingw build. --- programs/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index 599fb02fa..c857b97d2 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -242,8 +242,8 @@ $(BUILD_DIR)/zstd : $(ZSTD_OBJ) $(CC) $(FLAGS) $^ $(LDLIBS) -o $@$(EXT) ifeq ($(HAVE_HASH),1) -SRCBIN_HASH = $(shell cat $(BUILD_DIR)/zstd 2> $(VOID) | $(HASH) | cut -f 1 -d " ") -DSTBIN_HASH = $(shell cat zstd 2> $(VOID) | $(HASH) | cut -f 1 -d " ") +SRCBIN_HASH = $(shell cat $(BUILD_DIR)/zstd$(EXT) 2> $(VOID) | $(HASH) | cut -f 1 -d " ") +DSTBIN_HASH = $(shell cat zstd$(EXT) 2> $(VOID) | $(HASH) | cut -f 1 -d " ") BIN_ISDIFFERENT = $(if $(filter $(SRCBIN_HASH),$(DSTBIN_HASH)),0,1) else BIN_ISDIFFERENT = 1 @@ -251,7 +251,7 @@ endif zstd : $(BUILD_DIR)/zstd if [ $(BIN_ISDIFFERENT) -eq 1 ]; then \ - cp -f $< $@; \ + cp -f $<$(EXT) $@$(EXT); \ echo zstd build completed; \ else \ echo zstd already built; \ From a80d268700d1a8496dd05de50833dfc6bdd750f0 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Sat, 29 May 2021 18:21:10 +0100 Subject: [PATCH 032/340] 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 033/340] 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 034/340] 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 035/340] 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 036/340] 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 037/340] 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 038/340] 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 039/340] 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 040/340] 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 041/340] 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 042/340] 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 043/340] 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 044/340] 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 045/340] 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 046/340] 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 047/340] 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 048/340] 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 049/340] 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 050/340] 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 051/340] 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 052/340] 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 053/340] 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 054/340] 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 055/340] 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 056/340] 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 057/340] 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 058/340] 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 059/340] 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 060/340] 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 061/340] 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 062/340] 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 063/340] 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 064/340] 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 065/340] 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 066/340] 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 067/340] 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 068/340] 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 069/340] 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 070/340] 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 071/340] 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 072/340] 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 073/340] [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 074/340] 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 075/340] 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 076/340] 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 4d0995270114e4c1f093e29bb1f734dac08b4c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Nogueira?= Date: Sat, 15 May 2021 22:56:08 -0300 Subject: [PATCH 077/340] [lib] Fix libzstd.pc for lib-mt builds Add the libzstd.pc target to the lib target in lib/Makefile, which makes it inherit LDFLAGS_DYNLIB from the lib-mt target. This allows us to add a Libs.private field to libzstd.pc which gets conditionally populated with '-pthread'. The 1.5.0 release notes mention that the static library isn't multi-threaded by default, due to concern for people building static binaries with libzstd: Now the dynamic library supports multi-threaded compression by default. Note that this property is not extended to the static library because doing so would have impacted the build script of existing client applications (requiring them to add -pthread to their recipe), thus potentially breaking their build. To get closer to being able to enable multi-threading for all library builds by default, this commit makes it so that any libzstd consumer using pkg-config gets the correct flags. We also fix the indentation of the rule for libzstd.pc and move it outside the if/endif block for install rules (which uses a list of OSs where the rules were validated), so the rule is available for all users of the 'lib*' targets. --- lib/Makefile | 25 +++++++++++++------------ lib/libzstd.pc.in | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 376a6690c..fd79898ef 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -308,7 +308,7 @@ endif # if windows libzstd : $(LIBZSTD) .PHONY: lib -lib : libzstd.a libzstd +lib : libzstd.a libzstd libzstd.pc # note : do not define lib-mt or lib-release as .PHONY @@ -371,6 +371,18 @@ clean: $(RM) -r obj/* @echo Cleaning library completed +libzstd.pc: +libzstd.pc: libzstd.pc.in + @echo creating pkgconfig + @sed $(SED_ERE_OPT) \ + -e 's|@PREFIX@|$(PREFIX)|' \ + -e 's|@EXEC_PREFIX@|$(PCEXEC_PREFIX)|' \ + -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ + -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ + -e 's|@VERSION@|$(VERSION)|' \ + -e 's|@LIBS_PRIVATE@|$(LDFLAGS_DYNLIB)|' \ + $< >$@ + #----------------------------------------------------------------------------- # make install is validated only for below listed environments #----------------------------------------------------------------------------- @@ -421,17 +433,6 @@ INSTALL_PROGRAM ?= $(INSTALL) INSTALL_DATA ?= $(INSTALL) -m 644 -libzstd.pc: -libzstd.pc: libzstd.pc.in - @echo creating pkgconfig - @sed $(SED_ERE_OPT) \ - -e 's|@PREFIX@|$(PREFIX)|' \ - -e 's|@EXEC_PREFIX@|$(PCEXEC_PREFIX)|' \ - -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ - -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ - -e 's|@VERSION@|$(VERSION)|' \ - $< >$@ - .PHONY: install install: install-pc install-static install-shared install-includes @echo zstd static and shared library installed diff --git a/lib/libzstd.pc.in b/lib/libzstd.pc.in index 8465c9770..43ebaec35 100644 --- a/lib/libzstd.pc.in +++ b/lib/libzstd.pc.in @@ -12,4 +12,5 @@ Description: fast lossless compression algorithm library URL: http://www.zstd.net/ Version: @VERSION@ Libs: -L${libdir} -lzstd +Libs.private: @LIBS_PRIVATE@ Cflags: -I${includedir} From 76466dfadf871babdaebcecb448cc00c08fbfd78 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 23 Jun 2021 11:21:14 -0400 Subject: [PATCH 078/340] 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 079/340] 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 080/340] 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 081/340] 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 082/340] 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 083/340] 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 084/340] 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 085/340] 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 086/340] 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 087/340] 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 088/340] [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 089/340] 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 090/340] [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 091/340] 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 092/340] 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 093/340] [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 094/340] 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 095/340] 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 096/340] 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 097/340] 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 098/340] 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 099/340] 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 100/340] 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 101/340] 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 102/340] 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 103/340] 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 104/340] 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 105/340] 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 106/340] 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 107/340] 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 108/340] 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 109/340] 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 110/340] 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 111/340] 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 112/340] 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 113/340] 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 114/340] 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 115/340] 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 116/340] 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 117/340] 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 118/340] 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 119/340] 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 120/340] 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 121/340] 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 122/340] 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 123/340] 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 124/340] 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 125/340] 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 126/340] 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 127/340] 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 128/340] 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 129/340] 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 130/340] 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 131/340] 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 132/340] 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 133/340] 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 134/340] 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 135/340] 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 136/340] 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 137/340] 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 138/340] 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 139/340] 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 140/340] 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 141/340] 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 142/340] 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 143/340] 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 144/340] 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 145/340] 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 146/340] 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 147/340] 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 148/340] 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 149/340] 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 150/340] 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 151/340] 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 152/340] 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 153/340] 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 154/340] 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 155/340] 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 156/340] 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 157/340] 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 158/340] 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 159/340] 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 160/340] [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 161/340] [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 162/340] 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 163/340] 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 164/340] [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 165/340] [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 166/340] 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 167/340] 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 168/340] 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 169/340] 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 170/340] [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 171/340] 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 172/340] 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 173/340] 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 174/340] 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 175/340] 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 176/340] 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 177/340] [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 178/340] [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 179/340] 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 180/340] [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 181/340] [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 182/340] [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 183/340] 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 184/340] [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 185/340] 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 186/340] [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 187/340] [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 188/340] 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 189/340] 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 190/340] 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 191/340] [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 192/340] 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 193/340] 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 194/340] 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 195/340] 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 196/340] 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 197/340] 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 198/340] 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 199/340] [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 200/340] 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 201/340] 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 202/340] 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 203/340] 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 204/340] 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 205/340] 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 206/340] 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 207/340] 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 208/340] 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 209/340] 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 210/340] 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 211/340] 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 212/340] 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 213/340] 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 214/340] 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 215/340] 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 216/340] 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 217/340] 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 218/340] 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 219/340] 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 220/340] 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 221/340] 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 222/340] 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 223/340] [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 224/340] [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 225/340] [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 226/340] [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 227/340] 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 228/340] 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 229/340] 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 230/340] [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 231/340] [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 232/340] 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 233/340] 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 234/340] 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 235/340] 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 236/340] 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 237/340] 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 238/340] 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 239/340] 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 240/340] 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 241/340] 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 242/340] 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 243/340] 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 244/340] 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 245/340] 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 246/340] 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 247/340] 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 248/340] 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 249/340] 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 250/340] 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 251/340] 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 252/340] 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 253/340] 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 254/340] 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 255/340] 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 256/340] 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 257/340] 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 258/340] 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 259/340] 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 260/340] [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 261/340] [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 262/340] 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 263/340] =?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 264/340] 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 265/340] =?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 266/340] 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 267/340] 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 268/340] 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 269/340] 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 270/340] 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 271/340] 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 272/340] `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 273/340] [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 274/340] [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 275/340] [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 276/340] [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 a8adfa7f67840dec0fd94f25eecfb4abda208f23 Mon Sep 17 00:00:00 2001 From: 15596858998 Date: Wed, 1 Dec 2021 21:47:35 +0800 Subject: [PATCH 277/340] fixbug CLI's -D fails when the argument is not a regular file --- programs/fileio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/fileio.c b/programs/fileio.c index 8e5301dee..d3995a434 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -742,6 +742,8 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName, FIO_p if (fileHandle==NULL) EXM_THROW(31, "%s: %s", fileName, strerror(errno)); fileSize = UTIL_getFileSize(fileName); + if (fileSize == UTIL_FILESIZE_UNKNOWN) + EXM_THROW(32, "This file format is not supported : Dictionary file %s\n", fileName); { size_t const dictSizeMax = prefs->patchFromMode ? prefs->memLimit : DICTSIZE_MAX; if (fileSize > dictSizeMax) { From d4713de5a352dd86293ad935c4c5dd138d2f01df Mon Sep 17 00:00:00 2001 From: supperPants <1350628449@qq.com> Date: Wed, 1 Dec 2021 22:36:21 +0800 Subject: [PATCH 278/340] Fix typos. --- 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 32e486cd8..d1f716dcb 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -1911,7 +1911,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock"); zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, ENTROPY_WORKSPACE_SIZE); - RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace"); + RETURN_ERROR_IF(zc->entropyWorkspace == NULL, memory_allocation, "couldn't allocate entropyWorkspace"); } } ZSTD_cwksp_clear(ws); From 49d578763d957a3272cf7365bf8ec839660dd285 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Dec 2021 15:10:55 -0800 Subject: [PATCH 279/340] 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)" From a71eed360b5d0fbef910b58986d24011f3afab44 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Dec 2021 16:54:59 -0800 Subject: [PATCH 280/340] removed lib/Makefile preamble now included from libzstd.mk --- lib/Makefile | 92 ++-------------------------------------------------- 1 file changed, 3 insertions(+), 89 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 934c2b681..66a94c22f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -8,92 +8,6 @@ # 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_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 @@ -143,9 +57,9 @@ VERSION := $(ZSTD_VERSION) .PHONY: default default: lib-release -CPPFLAGS_DYNLIB = -DZSTD_MULTITHREAD # dynamic library build defaults to multi-threaded -LDFLAGS_DYNLIB = -pthread -CPPFLAGS_STATLIB = # static library build defaults to single-threaded +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) From e89e84782058f6785bdb5e5d3a1c7111f55e152d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Dec 2021 17:16:36 -0800 Subject: [PATCH 281/340] added alignment test and fix an incorrect alignment check in cwksp which was failing on m68k --- lib/common/mem.h | 20 ++++++++++++++++++++ lib/compress/zstd_cwksp.h | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/common/mem.h b/lib/common/mem.h index 1c61b7e52..4803897cf 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -80,6 +80,26 @@ extern "C" { #endif +/*-************************************************************** +* Alignment check +*****************************************************************/ + +/* C11 support */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) + +#include +# define MEM_ALIGN_COND(T) alignof(T) + +#elif defined(__GNUC__) || defined(_MSC_VER) + +# define MEM_ALIGN_COND(T) __alignof(T) + +#else + +# define MEM_ALIGN_COND(T) 1 /* most likely incorrect, just to pass tests */ + +#endif + /*-************************************************************** * Memory I/O API *****************************************************************/ diff --git a/lib/compress/zstd_cwksp.h b/lib/compress/zstd_cwksp.h index 7ba90262d..305667606 100644 --- a/lib/compress/zstd_cwksp.h +++ b/lib/compress/zstd_cwksp.h @@ -422,8 +422,8 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) { DEBUGLOG(5, "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining", alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes); - assert(((size_t)alloc & (sizeof(void*)-1)) == 0); - assert((bytes & (sizeof(void*)-1)) == 0); + assert((size_t)alloc % MEM_ALIGN_COND(void*) == 0); + assert(bytes % MEM_ALIGN_COND(void*) == 0); ZSTD_cwksp_assert_internal_consistency(ws); /* we must be in the first phase, no advance is possible */ if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) { From 91f5891dd01aad6c5bd1f462438c2c3039811685 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 1 Dec 2021 11:49:58 -0800 Subject: [PATCH 282/340] [CircleCI] Fix short-tests-0 short-tests-0 were silently failing. I think because of the && make clean construction. Switch to ; instead. Also fix all the test failures that were exposed. `make all` is failing on CircleCI because it is missing Docker. Move that test to GitHub actions, and switch the pedantic CircleCI test to `make allmost`. --- .circleci/config.yml | 13 +++++++------ .github/workflows/dev-long-tests.yml | 7 +++++++ examples/common.h | 2 +- lib/common/compiler.h | 5 ++++- lib/compress/zstd_lazy.c | 4 ++-- lib/decompress/huf_decompress_amd64.S | 25 ++++++++----------------- tests/zstreamtest.c | 4 ++-- 7 files changed, 31 insertions(+), 29 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 65bb3c227..f2eab6807 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,12 +15,13 @@ jobs: name: Test command: | ./tests/test-license.py - cc -v; CFLAGS="-O0 -Werror -pedantic" make all && make clean - make c99build && make clean - make c11build && make clean - make -j regressiontest&& make clean - make shortest && make clean - make cxxtest && make clean + cc -v + CFLAGS="-O0 -Werror -pedantic" make allmost; 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-long-tests.yml b/.github/workflows/dev-long-tests.yml index 3967d186f..7a94fb666 100644 --- a/.github/workflows/dev-long-tests.yml +++ b/.github/workflows/dev-long-tests.yml @@ -10,6 +10,13 @@ on: branches: [ dev, release, actionsTest ] jobs: + make-all: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: make all + run: make all + # lasts ~24mn make-test: runs-on: ubuntu-latest diff --git a/examples/common.h b/examples/common.h index 181f6b398..5f45b3406 100644 --- a/examples/common.h +++ b/examples/common.h @@ -57,7 +57,7 @@ typedef enum { * Check the zstd error code and die if an error occurred after printing a * message. */ -#define CHECK_ZSTD(fn, ...) \ +#define CHECK_ZSTD(fn) \ do { \ size_t const err = (fn); \ CHECK(!ZSTD_isError(err), "%s", ZSTD_getErrorName(err)); \ diff --git a/lib/common/compiler.h b/lib/common/compiler.h index ea5fe2f47..27632ab06 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -258,7 +258,10 @@ # elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough) # define ZSTD_FALLTHROUGH [[fallthrough]] # elif __has_attribute(__fallthrough__) -# define ZSTD_FALLTHROUGH __attribute__((__fallthrough__)) +/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon + * gcc complains about: a label can only be part of a statement and a declaration is not a statement. + */ +# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__)) # else # define ZSTD_FALLTHROUGH # endif diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index d6354be7f..5326ec5f3 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1333,7 +1333,7 @@ typedef struct { searchMax_f searchMax; } ZSTD_LazyVTable; -#define GEN_ZSTD_BT_VTABLE(dictMode, mls, ...) \ +#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, \ @@ -1346,7 +1346,7 @@ typedef struct { ZSTD_BtFindBestMatch_##dictMode##_##mls \ }; -#define GEN_ZSTD_HC_VTABLE(dictMode, mls, ...) \ +#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, \ diff --git a/lib/decompress/huf_decompress_amd64.S b/lib/decompress/huf_decompress_amd64.S index cebe2f321..bb517d7aa 100644 --- a/lib/decompress/huf_decompress_amd64.S +++ b/lib/decompress/huf_decompress_amd64.S @@ -62,15 +62,6 @@ #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); \ @@ -211,11 +202,11 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: movb %ah, idx(%op##n) /* Assumes GET_NEXT_DELT has been called. - * Calls DECODE_FROM_DELT then GET_NEXT_DELT if n < 4 + * Calls DECODE_FROM_DELT then GET_NEXT_DELT */ -#define DECODE(n, idx) \ +#define DECODE_AND_GET_NEXT(n, idx) \ DECODE_FROM_DELT(n, idx); \ - IF_NOT_4(idx, GET_NEXT_DELT(n)) + GET_NEXT_DELT(n) \ /* // ctz & nbBytes is stored in bits[n] * // nbBits is stored in %rax @@ -254,11 +245,11 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop: /* 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) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 0) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 1) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 2) + FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 3) + FOR_EACH_STREAM_WITH_INDEX(DECODE_FROM_DELT, 4) /* Load ip[1,2,3] from stack (var[] aliases them) * ip[] is needed for RELOAD_BITS diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 6eb107f9d..72fd72ea3 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1855,7 +1855,7 @@ static int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double co && oldTestLog /* at least one test happened */ && resetAllowed) { maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2); maxTestSize = MIN(maxTestSize, srcBufferSize-16); - { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; + { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; CHECK_Z( ZSTD_CCtx_reset(zc, ZSTD_reset_session_only) ); CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) ); } @@ -2357,7 +2357,7 @@ static int fuzzerTests_newAPI(U32 seed, int nbTests, int startTest, /* multi - fragments decompression test */ if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) { - DISPLAYLEVEL(5, "resetting DCtx (dict:%p) \n", dict); + DISPLAYLEVEL(5, "resetting DCtx (dict:%p) \n", (void const*)dict); CHECK_Z( ZSTD_resetDStream(zd) ); } else { if (dictSize) From 39dced092e7ba82ea40f1e0ca0eb2037b8eb86c0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 1 Dec 2021 23:02:00 -0800 Subject: [PATCH 283/340] fix align conditions for huf_compress --- lib/compress/huf_compress.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index 41a414b5c..ceedce727 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -97,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*)HUF_alignUpWorkspace(workspace, &workspaceSize, sizeof(U32)); + HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, MEM_ALIGN_COND(U32)); if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC); @@ -176,7 +176,7 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, HUF_CElt const* const ct = CTable + 1; BYTE* op = (BYTE*)dst; U32 n; - HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, sizeof(U32)); + HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, MEM_ALIGN_COND(U32)); /* check conditions */ if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); @@ -679,7 +679,7 @@ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, i size_t HUF_buildCTable_wksp (HUF_CElt* CTable, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize) { - HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)HUF_alignUpWorkspace(workSpace, &wkspSize, sizeof(U32)); + HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)HUF_alignUpWorkspace(workSpace, &wkspSize, MEM_ALIGN_COND(U32)); nodeElt* const huffNode0 = wksp_tables->huffNodeTbl; nodeElt* const huffNode = huffNode0+1; int nonNullRank; @@ -1183,7 +1183,7 @@ HUF_compress_internal (void* dst, size_t dstSize, HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat, const int bmi2, unsigned suspectUncompressible) { - HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, sizeof(size_t)); + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, MEM_ALIGN_COND(size_t)); BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; BYTE* op = ostart; From 1e514feec63f29be10963f6d8bfa753d2386b07d Mon Sep 17 00:00:00 2001 From: Alexander Kanavin Date: Wed, 23 Dec 2020 19:14:32 +0100 Subject: [PATCH 284/340] Makefile: sort all wildcard file list expansions Otherwise the order is non-deterministic and breaks reproducible builds. --- programs/Makefile | 2 +- tests/Makefile | 4 ++-- tests/fuzz/Makefile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index fa557e6f9..669a84120 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -41,7 +41,7 @@ ZSTDLIB_LOCAL_SRC = $(notdir $(ZSTDLIB_FULL_SRC)) ZSTDLIB_LOCAL_OBJ0 := $(ZSTDLIB_LOCAL_SRC:.c=.o) ZSTDLIB_LOCAL_OBJ := $(ZSTDLIB_LOCAL_OBJ0:.S=.o) -ZSTD_CLI_SRC := $(wildcard *.c) +ZSTD_CLI_SRC := $(sort $(wildcard *.c)) ZSTD_CLI_OBJ := $(ZSTD_CLI_SRC:.c=.o) ZSTD_ALL_SRC = $(ZSTDLIB_LOCAL_SRC) $(ZSTD_CLI_SRC) diff --git a/tests/Makefile b/tests/Makefile index bd45451a5..efcbe9761 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -45,7 +45,7 @@ ZSTDDECOMP_FILES := $(sort $(ZSTD_DECOMPRESS_FILES)) ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) ZDICT_FILES := $(sort $(ZSTD_DICTBUILDER_FILES)) -ZSTD_F1 := $(wildcard $(ZSTD_FILES)) +ZSTD_F1 := $(sort $(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)) @@ -206,7 +206,7 @@ bigdict: $(ZSTDMT_OBJECTS) $(PRGDIR)/datagen.c bigdict.c invalidDictionaries : $(ZSTD_OBJECTS) invalidDictionaries.c legacy : CPPFLAGS += -I$(ZSTDDIR)/legacy -UZSTD_LEGACY_SUPPORT -DZSTD_LEGACY_SUPPORT=4 -legacy : $(ZSTD_FILES) $(wildcard $(ZSTDDIR)/legacy/*.c) legacy.c +legacy : $(ZSTD_FILES) $(sort $(wildcard $(ZSTDDIR)/legacy/*.c)) legacy.c decodecorpus : LDLIBS += -lm decodecorpus : $(filter-out zstdc_zstd_compress.o, $(ZSTD_OBJECTS)) $(ZDICT_FILES) $(PRGDIR)/util.c $(PRGDIR)/timefn.c decodecorpus.c diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile index d733f7cad..b707bd951 100644 --- a/tests/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -68,7 +68,7 @@ FUZZ_SRC := \ $(ZSTDCOMP_SRC) \ $(ZSTDDICT_SRC) \ $(ZSTDLEGACY_SRC) -FUZZ_SRC := $(wildcard $(FUZZ_SRC)) +FUZZ_SRC := $(sort $(wildcard $(FUZZ_SRC))) FUZZ_D_OBJ1 := $(subst $(ZSTDDIR)/common/,d_lib_common_,$(FUZZ_SRC)) FUZZ_D_OBJ2 := $(subst $(ZSTDDIR)/compress/,d_lib_compress_,$(FUZZ_D_OBJ1)) From ffbdc8ac575652d3609f317e93d1604f568d92f2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 2 Dec 2021 10:30:04 -0800 Subject: [PATCH 285/340] m68k CI tests on GA are now compulsory --- .github/workflows/dev-short-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index ae9d13c18..c8e85cd3b 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -294,7 +294,6 @@ jobs: LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check - name: M68K if: ${{ matrix.name == 'M68K' }} - continue-on-error: true # disable reporting errors (alignment issues) run: | LDFLAGS="-static" CC=$XCC QEMU_SYS=$XEMU make clean check From 80a13fd64555e2be571a0436a3fae0dd867ce626 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 2 Dec 2021 11:20:01 -0800 Subject: [PATCH 286/340] move the alignment macro to compiler.h because mem.h is dropped in the Linux kernel. Changed macro definition order (gcc/clang/msvc before c11) due to a limitation in the kernel source builder. Changed the backup to sizeof(), reverting to previous behavior when no support of alignof() is detected. --- lib/common/compiler.h | 33 +++++++++++++++++++++++++++++++++ lib/common/mem.h | 20 -------------------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index ea5fe2f47..907b6bfac 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -282,6 +282,39 @@ # endif #endif +/*-************************************************************** +* Alignment check +*****************************************************************/ + +/* this test was initially positioned in mem.h, + * but this file is removed (or replaced) for linux kernel + * so it's now hosted in compiler.h, + * which remains valid for both user & kernel spaces. + */ + +#ifndef MEM_ALIGN_COND +# if defined(__GNUC__) || defined(_MSC_VER) +/* covers gcc, clang & MSVC */ +/* note : this section must come first, before C11, + * due to a limitation in the kernel source generator */ +# define MEM_ALIGN_COND(T) __alignof(T) + +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +/* C11 support */ +# include +# define MEM_ALIGN_COND(T) alignof(T) + +# else +/* No known support for alignof() - imperfect backup */ +# define MEM_ALIGN_COND(T) sizeof(T) + +# endif +#endif /* MEM_ALIGN_COND */ + +/*-************************************************************** +* Sanitizer +*****************************************************************/ + #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/common/mem.h b/lib/common/mem.h index 4803897cf..1c61b7e52 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -80,26 +80,6 @@ extern "C" { #endif -/*-************************************************************** -* Alignment check -*****************************************************************/ - -/* C11 support */ -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) - -#include -# define MEM_ALIGN_COND(T) alignof(T) - -#elif defined(__GNUC__) || defined(_MSC_VER) - -# define MEM_ALIGN_COND(T) __alignof(T) - -#else - -# define MEM_ALIGN_COND(T) 1 /* most likely incorrect, just to pass tests */ - -#endif - /*-************************************************************** * Memory I/O API *****************************************************************/ From a3ee9815c784921c5fad48e3567ba0ad87ff62de Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Dec 2021 14:25:33 -0500 Subject: [PATCH 287/340] Avoid Using Deprecated Functions in Deprecated Code `lib/deprecated` is no longer built by zstd's bundled build files. However, users may try to build these files when they import the source tree into their own build systems. And if they have `-Wdeprecated-declarations` on, this can produce warnings. This PR migrates these files away from using deprecated declarations. This addresses #2767. --- lib/deprecated/zbuff_compress.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/deprecated/zbuff_compress.c b/lib/deprecated/zbuff_compress.c index 2e7226735..ec896264f 100644 --- a/lib/deprecated/zbuff_compress.c +++ b/lib/deprecated/zbuff_compress.c @@ -72,14 +72,36 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) { + size_t ret; if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* preserve "0 == unknown" behavior */ - return ZSTD_initCStream_advanced(zbc, dict, dictSize, params, pledgedSrcSize); + ret = ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setPledgedSrcSize(zbc, pledgedSrcSize); + + ret = ZSTD_isError(ret) ? ret : ZSTD_checkCParams(params.cParams); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_windowLog, params.cParams.windowLog); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_hashLog, params.cParams.hashLog); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_chainLog, params.cParams.chainLog); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_searchLog, params.cParams.searchLog); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_minMatch, params.cParams.minMatch); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_targetLength, params.cParams.targetLength); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_strategy, params.cParams.strategy); + + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_contentSizeFlag, params.fParams.contentSizeFlag); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_checksumFlag, params.fParams.checksumFlag); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_dictIDFlag, params.fParams.noDictIDFlag); + + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_loadDictionary(zbc, dict, dictSize); + return ZSTD_isError(ret) ? ret : 0; } size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel) { - return ZSTD_initCStream_usingDict(zbc, dict, dictSize, compressionLevel); + size_t ret; + ret = ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_compressionLevel, compressionLevel); + ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_loadDictionary(zbc, dict, dictSize); + return ZSTD_isError(ret) ? ret : 0; } size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel) From 1d025d871bf0891aceac437685f33cd6e638f4c7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 2 Dec 2021 11:30:03 -0800 Subject: [PATCH 288/340] bound alignment backup to sizeof(void*) --- lib/common/compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 907b6bfac..98590ce67 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -306,7 +306,7 @@ # else /* No known support for alignof() - imperfect backup */ -# define MEM_ALIGN_COND(T) sizeof(T) +# define MEM_ALIGN_COND(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T)) # endif #endif /* MEM_ALIGN_COND */ From 30b9db8ae45834fd4b654e6c4e0310cdaa5ab3ae Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 2 Dec 2021 12:57:42 -0800 Subject: [PATCH 289/340] changed macro name to ZSTD_ALIGNOF for better consistency --- lib/common/compiler.h | 10 +++++----- lib/compress/huf_compress.c | 8 ++++---- lib/compress/zstd_cwksp.h | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/common/compiler.h b/lib/common/compiler.h index 98590ce67..17c049bfd 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -292,24 +292,24 @@ * which remains valid for both user & kernel spaces. */ -#ifndef MEM_ALIGN_COND +#ifndef ZSTD_ALIGNOF # if defined(__GNUC__) || defined(_MSC_VER) /* covers gcc, clang & MSVC */ /* note : this section must come first, before C11, * due to a limitation in the kernel source generator */ -# define MEM_ALIGN_COND(T) __alignof(T) +# define ZSTD_ALIGNOF(T) __alignof(T) # elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 support */ # include -# define MEM_ALIGN_COND(T) alignof(T) +# define ZSTD_ALIGNOF(T) alignof(T) # else /* No known support for alignof() - imperfect backup */ -# define MEM_ALIGN_COND(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T)) +# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T)) # endif -#endif /* MEM_ALIGN_COND */ +#endif /* ZSTD_ALIGNOF */ /*-************************************************************** * Sanitizer diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c index ceedce727..2b3d6adc2 100644 --- a/lib/compress/huf_compress.c +++ b/lib/compress/huf_compress.c @@ -97,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*)HUF_alignUpWorkspace(workspace, &workspaceSize, MEM_ALIGN_COND(U32)); + HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC); @@ -176,7 +176,7 @@ size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, HUF_CElt const* const ct = CTable + 1; BYTE* op = (BYTE*)dst; U32 n; - HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, MEM_ALIGN_COND(U32)); + HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); /* check conditions */ if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); @@ -679,7 +679,7 @@ static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, i size_t HUF_buildCTable_wksp (HUF_CElt* CTable, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize) { - HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)HUF_alignUpWorkspace(workSpace, &wkspSize, MEM_ALIGN_COND(U32)); + HUF_buildCTable_wksp_tables* const wksp_tables = (HUF_buildCTable_wksp_tables*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(U32)); nodeElt* const huffNode0 = wksp_tables->huffNodeTbl; nodeElt* const huffNode = huffNode0+1; int nonNullRank; @@ -1183,7 +1183,7 @@ HUF_compress_internal (void* dst, size_t dstSize, HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat, const int bmi2, unsigned suspectUncompressible) { - HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, MEM_ALIGN_COND(size_t)); + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t)); BYTE* const ostart = (BYTE*)dst; BYTE* const oend = ostart + dstSize; BYTE* op = ostart; diff --git a/lib/compress/zstd_cwksp.h b/lib/compress/zstd_cwksp.h index 305667606..29d027e9c 100644 --- a/lib/compress/zstd_cwksp.h +++ b/lib/compress/zstd_cwksp.h @@ -422,8 +422,8 @@ MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) { DEBUGLOG(5, "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining", alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes); - assert((size_t)alloc % MEM_ALIGN_COND(void*) == 0); - assert(bytes % MEM_ALIGN_COND(void*) == 0); + assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0); + assert(bytes % ZSTD_ALIGNOF(void*) == 0); ZSTD_cwksp_assert_internal_consistency(ws); /* we must be in the first phase, no advance is possible */ if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) { From d82d67d07391ba3427a4342d91e783a295a1fff8 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Dec 2021 16:06:07 -0500 Subject: [PATCH 290/340] Migrate to `FORWARD_IF_ERROR` --- lib/deprecated/zbuff_compress.c | 42 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/lib/deprecated/zbuff_compress.c b/lib/deprecated/zbuff_compress.c index ec896264f..4ff29337e 100644 --- a/lib/deprecated/zbuff_compress.c +++ b/lib/deprecated/zbuff_compress.c @@ -15,6 +15,7 @@ ***************************************/ #define ZBUFF_STATIC_LINKING_ONLY #include "zbuff.h" +#include "error_private.h" /*-*********************************************************** @@ -72,36 +73,33 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) { - size_t ret; if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* preserve "0 == unknown" behavior */ - ret = ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setPledgedSrcSize(zbc, pledgedSrcSize); + FORWARD_IF_ERROR(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setPledgedSrcSize(zbc, pledgedSrcSize), ""); - ret = ZSTD_isError(ret) ? ret : ZSTD_checkCParams(params.cParams); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_windowLog, params.cParams.windowLog); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_hashLog, params.cParams.hashLog); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_chainLog, params.cParams.chainLog); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_searchLog, params.cParams.searchLog); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_minMatch, params.cParams.minMatch); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_targetLength, params.cParams.targetLength); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_strategy, params.cParams.strategy); + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_windowLog, params.cParams.windowLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_hashLog, params.cParams.hashLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_chainLog, params.cParams.chainLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_searchLog, params.cParams.searchLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_minMatch, params.cParams.minMatch), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_targetLength, params.cParams.targetLength), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_strategy, params.cParams.strategy), ""); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_contentSizeFlag, params.fParams.contentSizeFlag); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_checksumFlag, params.fParams.checksumFlag); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_dictIDFlag, params.fParams.noDictIDFlag); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_contentSizeFlag, params.fParams.contentSizeFlag), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_checksumFlag, params.fParams.checksumFlag), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_dictIDFlag, params.fParams.noDictIDFlag), ""); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_loadDictionary(zbc, dict, dictSize); - return ZSTD_isError(ret) ? ret : 0; + FORWARD_IF_ERROR(ZSTD_CCtx_loadDictionary(zbc, dict, dictSize), ""); + return 0; } - size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel) { - size_t ret; - ret = ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_setParameter(zbc, ZSTD_c_compressionLevel, compressionLevel); - ret = ZSTD_isError(ret) ? ret : ZSTD_CCtx_loadDictionary(zbc, dict, dictSize); - return ZSTD_isError(ret) ? ret : 0; + FORWARD_IF_ERROR(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_compressionLevel, compressionLevel), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_loadDictionary(zbc, dict, dictSize), ""); + return 0; } size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel) From e6883176527c474176446cd232f3c83c0f51a2e9 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Dec 2021 16:53:52 -0500 Subject: [PATCH 291/340] Fix Include Path --- lib/deprecated/zbuff_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/deprecated/zbuff_compress.c b/lib/deprecated/zbuff_compress.c index 4ff29337e..51cf158c4 100644 --- a/lib/deprecated/zbuff_compress.c +++ b/lib/deprecated/zbuff_compress.c @@ -15,7 +15,7 @@ ***************************************/ #define ZBUFF_STATIC_LINKING_ONLY #include "zbuff.h" -#include "error_private.h" +#include "../common/error_private.h" /*-*********************************************************** From e5bfaeede7aa1d42aee916e6910701d27d135c8c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 2 Dec 2021 13:32:53 -0800 Subject: [PATCH 292/340] Improve zstd_opt build speed and size Use the same trick as we did for zstd_lazy in PR #2828: * Create one search function specialization for each (dictMode, mls). * Select the search function pointer at the top of the match finder. Additionally, we no longer inline `ZSTD_compressBlock_opt_generic` into every function, since `dictMode` is no longer used as a template. Create two specializations, for opt levels 0 and 2, and call one of the two specializations. Lastly, remove the hack that disabled inlining for zstd_opt for the Linux Kernel, as we've gotten most of the benefit already. Compilation time sees a ~4x reduction: | Compiler | Flags | Dev Time (s) | PR Time (s) | Delta | |----------|----------------------------------|--------------|-------------|-------| | gcc | -O3 | 10.1 | 2.3 | -77% | | gcc | -O3 -fsanitize=address,undefined | 61.1 | 10.2 | -83% | | clang | -O3 | 9.0 | 2.1 | -76% | | clang | -O3 -fsanitize=address,undefined | 33.5 | 5.1 | -84% | Build size is reduced by 150KB - 200KB: | Compiler | Dev libzstd.a Size (B) | PR libzstd.a Size (B) | Delta | |----------|------------------------|-----------------------|-------| | gcc | 1327476 | 1177108 | -11% | | clang | 1378324 | 1167780 | -15% | There is a <2% speed loss in all cases: | Compiler | Level | Dev Speed (MB/s) | PR Speed (MB/s) | Delta | |----------|-------|------------------|-----------------|--------| | gcc | 16 | 4.78 | 4.72 | -1.25% | | gcc | 17 | 3.49 | 3.46 | -0.85% | | gcc | 18 | 2.92 | 2.86 | -2.04% | | gcc | 19 | 2.61 | 2.61 | 0.00% | | clang | 16 | 4.69 | 4.80 | 2.34% | | clang | 17 | 3.53 | 3.49 | -1.13% | | clang | 18 | 2.86 | 2.85 | -0.34% | | clang | 19 | 2.61 | 2.61 | 0.00% | Fixes Issue #2862. --- lib/compress/zstd_opt.c | 144 +++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 45 deletions(-) diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 0488589ff..7e5eb8b57 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -8,20 +8,6 @@ * 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" @@ -783,30 +769,83 @@ U32 ZSTD_insertBtAndGetAllMatches ( return mnum; } +typedef U32 (*ZSTD_getAllMatchesFn)( + ZSTD_match_t*, + ZSTD_matchState_t*, + U32*, + const BYTE*, + const BYTE*, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat); -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, - const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode, - const U32 rep[ZSTD_REP_NUM], - U32 const ll0, - U32 const lengthToBeat) +FORCE_INLINE_TEMPLATE U32 ZSTD_btGetAllMatches_internal( + ZSTD_match_t* matches, + ZSTD_matchState_t* ms, + U32* nextToUpdate3, + const BYTE* ip, + const BYTE* const iHighLimit, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat, + const ZSTD_dictMode_e dictMode, + const U32 mls) { - const ZSTD_compressionParameters* const cParams = &ms->cParams; - U32 const matchLengthSearch = cParams->minMatch; - DEBUGLOG(8, "ZSTD_BtGetAllMatches"); - if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ - ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode); - switch(matchLengthSearch) - { - case 3 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 3); - default : - case 4 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 4); - case 5 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 5); - case 7 : - case 6 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 6); + assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls); + DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls); + if (ip < ms->window.base + ms->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode); + return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls); +} + +#define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls + +#define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls) \ + static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)( \ + ZSTD_match_t* matches, \ + ZSTD_matchState_t* ms, \ + U32* nextToUpdate3, \ + const BYTE* ip, \ + const BYTE* const iHighLimit, \ + const U32 rep[ZSTD_REP_NUM], \ + U32 const ll0, \ + U32 const lengthToBeat) \ + { \ + return ZSTD_btGetAllMatches_internal( \ + matches, ms, nextToUpdate3, ip, iHighLimit, \ + rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \ } + +#define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6) + +GEN_ZSTD_BT_GET_ALL_MATCHES(noDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(extDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState) + +#define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode) \ + { \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6) \ + } + +static ZSTD_getAllMatchesFn ZSTD_selectBtGetAllMatches(ZSTD_matchState_t const* ms, ZSTD_dictMode_e const dictMode) +{ + ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = { + ZSTD_BT_GET_ALL_MATCHES_ARRAY(noDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(extDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState) + }; + U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6); + assert((U32)dictMode < 3); + assert(mls - 3 < 4); + return getAllMatchesFns[(int)dictMode][mls - 3]; } /************************* @@ -989,6 +1028,8 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, const BYTE* const prefixStart = base + ms->window.dictLimit; const ZSTD_compressionParameters* const cParams = &ms->cParams; + ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode); + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4; U32 nextToUpdate3 = ms->nextToUpdate; @@ -1016,7 +1057,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, /* find first match */ { U32 const litlen = (U32)(ip - anchor); U32 const ll0 = !litlen; - U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch); + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch); ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, (U32)(ip-istart), (U32)(iend - ip)); if (!nbMatches) { ip++; continue; } @@ -1133,7 +1174,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0; 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 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch); U32 matchNb; ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, @@ -1257,13 +1298,26 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ return (size_t)(iend - anchor); } +static size_t ZSTD_compressBlock_opt0( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode); +} + +static size_t ZSTD_compressBlock_opt2( + ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode); +} size_t ZSTD_compressBlock_btopt( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { DEBUGLOG(5, "ZSTD_compressBlock_btopt"); - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_noDict); + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict); } @@ -1289,7 +1343,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms, assert(ms->window.dictLimit == ms->window.lowLimit); /* no dictionary */ assert(ms->window.dictLimit - ms->nextToUpdate <= 1); /* no prefix (note: intentional overflow, defined as 2-complement) */ - ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict); /* generate stats into ms->opt*/ + ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/ /* invalidate first scan from history */ ZSTD_resetSeqStore(seqStore); @@ -1305,7 +1359,7 @@ size_t ZSTD_compressBlock_btultra( const void* src, size_t srcSize) { DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize); - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); } size_t ZSTD_compressBlock_btultra2( @@ -1333,35 +1387,35 @@ size_t ZSTD_compressBlock_btultra2( ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize); } - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); } size_t ZSTD_compressBlock_btopt_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_dictMatchState); + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); } size_t ZSTD_compressBlock_btultra_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_dictMatchState); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); } size_t ZSTD_compressBlock_btopt_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_extDict); + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict); } size_t ZSTD_compressBlock_btultra_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], const void* src, size_t srcSize) { - return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_extDict); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict); } /* note : no btultra2 variant for extDict nor dictMatchState, From 4a82bc9d00c8eccd7872e76d0e0feb12f6558308 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Thu, 2 Dec 2021 17:23:42 -0500 Subject: [PATCH 293/340] Disable Multithreading in CMake Builds for Android --- build/cmake/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt index a0505778a..93a167caf 100644 --- a/build/cmake/CMakeLists.txt +++ b/build/cmake/CMakeLists.txt @@ -92,8 +92,14 @@ else () add_definitions(-DZSTD_LEGACY_SUPPORT=0) endif () +if (ANDROID) + set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT OFF) +else() + set(ZSTD_MULTITHREAD_SUPPORT_DEFAULT ON) +endif() + # Multi-threading support -option(ZSTD_MULTITHREAD_SUPPORT "MULTITHREADING SUPPORT" ON) +option(ZSTD_MULTITHREAD_SUPPORT "MULTITHREADING SUPPORT" ${ZSTD_MULTITHREAD_SUPPORT_DEFAULT}) if (ZSTD_MULTITHREAD_SUPPORT) message(STATUS "ZSTD_MULTITHREAD_SUPPORT is enabled") From a74a36985a7c296eba0ca0bb84f9bbee0f0dca0e Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 2 Dec 2021 14:42:17 -0800 Subject: [PATCH 294/340] [CI] Add cmake windows build Build on windows with cmake to ensure everything compiles. --- .github/workflows/dev-short-tests.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index ae9d13c18..69d56b485 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -164,6 +164,28 @@ jobs: make clean CC=clang MOREFLAGS="-Werror -Wimplicit-fallthrough -O0" make -C lib -j libzstd.a ZSTD_LEGACY_SUPPORT=0 + cmake-visual-2019: + runs-on: windows-latest + strategy: + matrix: + include: + - generator: "Visual Studio 16 2019" + flags: "-A x64" + - generator: "Visual Studio 16 2019" + flags: "-A Win32" + - generator: "MinGW Makefiles" + steps: + - uses: actions/checkout@v2 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + run: | + cd build\cmake + mkdir build + cd build + cmake.exe -G "${{matrix.generator}}" ${{matrix.flags}} .. + cmake.exe --build . visual-2019: runs-on: windows-latest From c284569457febd659f6afecdc74c0e26ea700fd4 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 1 Dec 2021 12:52:23 -0800 Subject: [PATCH 295/340] [asm] Share portability macros and restrict ASM further Move portability macros to `lib/common/portability_macros.h`. This file only contains platform/feature detection (e.g. 0/1 macros). This file is shared between C and ASM code, so it cannot include any C code. Rename `HUF_` ASM macros to be `ZSTD_` prefixed, and move to the new header. Restrict `ZSTD_ASM_SUPPORTED` to `__GNUC__`, because we need the GAS assembler. Finally, only include the ASM code if we are actually going to use it. This disables it on all Windows platforms, which should resolve the problem brought up in Issue #2789. --- build/single_file_libs/zstd-in.c | 2 +- build/single_file_libs/zstddeclib-in.c | 2 +- contrib/linux-kernel/decompress_sources.h | 11 +- lib/common/compiler.h | 60 +--------- lib/common/portability_macros.h | 129 ++++++++++++++++++++++ lib/decompress/huf_decompress.c | 48 ++------ lib/decompress/huf_decompress_amd64.S | 4 +- lib/libzstd.mk | 2 +- 8 files changed, 155 insertions(+), 103 deletions(-) create mode 100644 lib/common/portability_macros.h diff --git a/build/single_file_libs/zstd-in.c b/build/single_file_libs/zstd-in.c index 733dcb757..b69468139 100644 --- a/build/single_file_libs/zstd-in.c +++ b/build/single_file_libs/zstd-in.c @@ -44,7 +44,7 @@ #endif #define ZSTD_TRACE 0 /* TODO: Can't amalgamate ASM function */ -#define HUF_DISABLE_ASM 1 +#define ZSTD_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 cbf70c619..72abe6134 100644 --- a/build/single_file_libs/zstddeclib-in.c +++ b/build/single_file_libs/zstddeclib-in.c @@ -40,7 +40,7 @@ #define ZSTD_STRIP_ERROR_STRINGS #define ZSTD_TRACE 0 /* TODO: Can't amalgamate ASM function */ -#define HUF_DISABLE_ASM 1 +#define ZSTD_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/decompress_sources.h b/contrib/linux-kernel/decompress_sources.h index a2aefe8f2..a06ca187a 100644 --- a/contrib/linux-kernel/decompress_sources.h +++ b/contrib/linux-kernel/decompress_sources.h @@ -16,16 +16,17 @@ * decompression. */ +/* + * Disable the ASM Huffman implementation because we need to + * include all the sources. + */ +#define ZSTD_DISABLE_ASM 1 + #include "common/debug.c" #include "common/entropy_common.c" #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/lib/common/compiler.h b/lib/common/compiler.h index 95ecb75e0..516930c01 100644 --- a/lib/common/compiler.h +++ b/lib/common/compiler.h @@ -11,6 +11,8 @@ #ifndef ZSTD_COMPILER_H #define ZSTD_COMPILER_H +#include "portability_macros.h" + /*-******************************************************* * Compiler specifics *********************************************************/ @@ -92,9 +94,6 @@ /* target attribute */ -#ifndef __has_attribute - #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif #if defined(__GNUC__) || defined(__ICCARM__) # define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) #else @@ -107,22 +106,6 @@ */ #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. - */ -#ifndef DYNAMIC_BMI2 - #if ((defined(__clang__) && __has_attribute(__target__)) \ - || (defined(__GNUC__) \ - && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ - && (defined(__x86_64__) || defined(_M_X64)) \ - && !defined(__BMI2__) - # define DYNAMIC_BMI2 1 - #else - # define DYNAMIC_BMI2 0 - #endif -#endif - /* prefetch * can be disabled, by declaring NO_PREFETCH build macro */ #if defined(NO_PREFETCH) @@ -221,16 +204,6 @@ # endif #endif -/* compat. with non-clang compilers */ -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -/* compat. with non-clang compilers */ -#ifndef __has_feature -# 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) @@ -267,24 +240,6 @@ # endif #endif -/* detects whether we are being compiled under msan */ -#ifndef ZSTD_MEMORY_SANITIZER -# if __has_feature(memory_sanitizer) -# define ZSTD_MEMORY_SANITIZER 1 -# else -# define ZSTD_MEMORY_SANITIZER 0 -# 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 - /*-************************************************************** * Alignment check *****************************************************************/ @@ -339,17 +294,6 @@ void __msan_poison(const volatile void *a, size_t size); intptr_t __msan_test_shadow(const volatile void *x, size_t size); #endif -/* detects whether we are being compiled under asan */ -#ifndef ZSTD_ADDRESS_SANITIZER -# if __has_feature(address_sanitizer) -# define ZSTD_ADDRESS_SANITIZER 1 -# elif defined(__SANITIZE_ADDRESS__) -# define ZSTD_ADDRESS_SANITIZER 1 -# else -# define ZSTD_ADDRESS_SANITIZER 0 -# endif -#endif - #if ZSTD_ADDRESS_SANITIZER /* Not all platforms that support asan provide sanitizers/asan_interface.h. * We therefore declare the functions we need ourselves, rather than trying to diff --git a/lib/common/portability_macros.h b/lib/common/portability_macros.h new file mode 100644 index 000000000..ef7987d41 --- /dev/null +++ b/lib/common/portability_macros.h @@ -0,0 +1,129 @@ +/* + * 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. + */ + +#ifndef ZSTD_PORTABILITY_MACROS_H +#define ZSTD_PORTABILITY_MACROS_H + +/** + * This header file contains macro defintions to support portability. + * This header is shared between C and ASM code, so it MUST only + * contain macro definitions. It MUST not contain any C code. + * + * This header ONLY defines macros to detect platforms/feature support. + * + */ + + +/* compat. with non-clang compilers */ +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +/* detects whether we are being compiled under msan */ +#ifndef ZSTD_MEMORY_SANITIZER +# if __has_feature(memory_sanitizer) +# define ZSTD_MEMORY_SANITIZER 1 +# else +# define ZSTD_MEMORY_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under asan */ +#ifndef ZSTD_ADDRESS_SANITIZER +# if __has_feature(address_sanitizer) +# define ZSTD_ADDRESS_SANITIZER 1 +# elif defined(__SANITIZE_ADDRESS__) +# define ZSTD_ADDRESS_SANITIZER 1 +# else +# define ZSTD_ADDRESS_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under dfsan */ +#ifndef ZSTD_DATAFLOW_SANITIZER +# if __has_feature(dataflow_sanitizer) +# define ZSTD_DATAFLOW_SANITIZER 1 +# else +# define ZSTD_DATAFLOW_SANITIZER 0 +# endif +#endif + + +/* Enable runtime BMI2 dispatch based on the CPU. + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. + */ +#ifndef DYNAMIC_BMI2 + #if ((defined(__clang__) && __has_attribute(__target__)) \ + || (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ + && (defined(__x86_64__) || defined(_M_X64)) \ + && !defined(__BMI2__) + # define DYNAMIC_BMI2 1 + #else + # define DYNAMIC_BMI2 0 + #endif +#endif + +/** + * Only enable assembly for GNUC comptabile compilers, + * because other platforms may not support GAS assembly syntax. + * + * Only enable assembly for Linux / MacOS, other platforms may + * work, but they haven't been tested. This could likely be + * extended to BSD systems. + * + * Disable assembly when MSAN is enabled, because MSAN requires + * 100% of code to be instrumented to work. + */ +#if defined(__GNUC__) +# if defined(__linux__) || defined(__linux) || defined(__APPLE__) +# if ZSTD_MEMORY_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# else +# define ZSTD_ASM_SUPPORTED 1 +# endif +# else +# define ZSTD_ASM_SUPPORTED 0 +# endif +#else +# define ZSTD_ASM_SUPPORTED 0 +#endif + +/** + * Determines whether we should enable assembly for x86-64 + * with BMI2. + * + * Enable if all of the following conditions hold: + * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM + * - Assembly is supported + * - We are compiling for x86-64 and either: + * - DYNAMIC_BMI2 is enabled + * - BMI2 is supported at compile time + */ +#if !defined(ZSTD_DISABLE_ASM) && \ + ZSTD_ASM_SUPPORTED && \ + defined(__x86_64__) && \ + (DYNAMIC_BMI2 || defined(__BMI2__)) +# define ZSTD_ENABLE_ASM_X86_64_BMI2 1 +#else +# define ZSTD_ENABLE_ASM_X86_64_BMI2 0 +#endif + +#endif /* ZSTD_PORTABILITY_MACROS_H */ diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index dd6c466c7..a00f938ce 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -43,31 +43,7 @@ #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 -# elif ZSTD_DATAFLOW_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 +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2 # define HUF_ASM_X86_64_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE #else # define HUF_ASM_X86_64_BMI2_ATTRS @@ -80,13 +56,13 @@ #endif #define HUF_ASM_DECL HUF_EXTERN_C -#if DYNAMIC_BMI2 || (HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)) +#if DYNAMIC_BMI2 || (ZSTD_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__)) +#if !(ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)) # define HUF_NEED_DEFAULT_FUNCTION 1 #else # define HUF_NEED_DEFAULT_FUNCTION 0 @@ -162,7 +138,7 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) return dtd; } -#if HUF_ENABLE_ASM_X86_64_BMI2 +#if ZSTD_ENABLE_ASM_X86_64_BMI2 static size_t HUF_initDStream(BYTE const* ip) { BYTE const lastByte = ip[7]; @@ -685,7 +661,7 @@ size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, } #endif -#if HUF_ENABLE_ASM_X86_64_BMI2 +#if ZSTD_ENABLE_ASM_X86_64_BMI2 HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args); @@ -741,7 +717,7 @@ HUF_decompress4X1_usingDTable_internal_bmi2_asm( /* decoded size */ return dstSize; } -#endif /* HUF_ENABLE_ASM_X86_64_BMI2 */ +#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */ typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize, const void *cSrc, @@ -755,7 +731,7 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, { #if DYNAMIC_BMI2 if (bmi2) { -# if HUF_ENABLE_ASM_X86_64_BMI2 +# if ZSTD_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); @@ -765,7 +741,7 @@ static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, (void)bmi2; #endif -#if HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) +#if ZSTD_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); @@ -1401,7 +1377,7 @@ size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, } #endif -#if HUF_ENABLE_ASM_X86_64_BMI2 +#if ZSTD_ENABLE_ASM_X86_64_BMI2 HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args); @@ -1453,14 +1429,14 @@ HUF_decompress4X2_usingDTable_internal_bmi2_asm( /* decoded size */ return dstSize; } -#endif /* HUF_ENABLE_ASM_X86_64_BMI2 */ +#endif /* ZSTD_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 +# if ZSTD_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); @@ -1470,7 +1446,7 @@ static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, (void)bmi2; #endif -#if HUF_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) +#if ZSTD_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); diff --git a/lib/decompress/huf_decompress_amd64.S b/lib/decompress/huf_decompress_amd64.S index bb517d7aa..98173cce8 100644 --- a/lib/decompress/huf_decompress_amd64.S +++ b/lib/decompress/huf_decompress_amd64.S @@ -1,4 +1,6 @@ -#if !defined(HUF_DISABLE_ASM) && defined(__x86_64__) +#include "../common/portability_macros.h" + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 /* Stack marking * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart diff --git a/lib/libzstd.mk b/lib/libzstd.mk index 45ee1ce62..af12daffe 100644 --- a/lib/libzstd.mk +++ b/lib/libzstd.mk @@ -114,7 +114,7 @@ ZSTD_LEGACY_FILES := ZSTD_DECOMPRESS_AMD64_ASM_FILES := $(sort $(wildcard $(LIBZSTD)/decompress/*_amd64.S)) ifneq ($(ZSTD_NO_ASM), 0) - CPPFLAGS += -DHUF_DISABLE_ASM + CPPFLAGS += -DZSTD_DISABLE_ASM else # Unconditionally add the ASM files they are disabled by # macros in the .S file. From ba7e8f1051913982d809f4904f829d512702225d Mon Sep 17 00:00:00 2001 From: 15596858998 Date: Sun, 5 Dec 2021 19:12:52 +0800 Subject: [PATCH 296/340] add test case --- tests/playTests.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 4face06dd..f3c45fa24 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -184,10 +184,16 @@ fi println "\n===> simple tests " - +datagen datagen > tmp +zstd -h +zstd -H +zstd -V println "test : basic compression " zstd -f tmp # trivial compression case, creates tmp.zst +zstd -f -z tmp +zstd -f -k tmp +zstd -f -C tmp println "test : basic decompression" zstd -df tmp.zst # trivial decompression case (overwrites tmp) println "test : too large compression level => auto-fix" @@ -747,6 +753,7 @@ rm -rf tmp* println "test : show-default-cparams regular" datagen > tmp zstd --show-default-cparams -f tmp +zstd --show-default-cparams -d tmp.zst && die "error: can't use --show-default-cparams in decompression mode" rm -rf tmp* println "test : show-default-cparams recursive" @@ -785,6 +792,7 @@ println "world!" > world.tmp cat hello.tmp world.tmp > helloworld.tmp zstd -c hello.tmp > hello.zst zstd -c world.tmp > world.zst +zstd -c hello.tmp world.tmp > helloworld.zst cat hello.zst world.zst > helloworld.zst zstd -dc helloworld.zst > result.tmp cat result.tmp @@ -937,6 +945,13 @@ cat tmp | zstd -14 -f --size-hint=11050 | zstd -t # slightly too high cat tmp | zstd -14 -f --size-hint=10950 | zstd -t # slightly too low cat tmp | zstd -14 -f --size-hint=22000 | zstd -t # considerably too high cat tmp | zstd -14 -f --size-hint=5500 | zstd -t # considerably too low +println "test : allows and interprets K,KB,KiB,M,MB and MiB suffix" +cat tmp | zstd -14 -f --size-hint=11K | zstd -t +cat tmp | zstd -14 -f --size-hint=11KB | zstd -t +cat tmp | zstd -14 -f --size-hint=11KiB | zstd -t +cat tmp | zstd -14 -f --size-hint=1M | zstd -t +cat tmp | zstd -14 -f --size-hint=1MB | zstd -t +cat tmp | zstd -14 -f --size-hint=1MiB | zstd -t println "\n===> dictionary tests " @@ -1047,6 +1062,7 @@ println "- Create dictionaries with shrink-dict flag enabled" zstd --train-fastcover=steps=1,shrink "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict zstd --train-fastcover=steps=1,shrink=1 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict1 zstd --train-fastcover=steps=1,shrink=5 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict2 +zstd --train-fastcover=shrink=5,steps=1 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpShrinkDict3 println "- Create dictionary with size limit" zstd --train-fastcover=steps=1 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict2 --maxdict=4K println "- Create dictionary using all samples for both training and testing" @@ -1549,6 +1565,7 @@ if [ -n "$hasMT" ] then println "\n===> adaptive mode " roundTripTest -g270000000 " --adapt" + roundTripTest -g270000000 " --adapt=" && die "invalid compression parameter" roundTripTest -g27000000 " --adapt=min=1,max=4" roundTripTest -g27000000 " --adapt=min=-2,max=-1" println "===> test: --adapt must fail on incoherent bounds " @@ -1671,6 +1688,7 @@ println "- Create first dictionary" zstd --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c -o tmpDict cp "$TESTFILE" tmp zstd -f tmp -D tmpDict +zstd -f tmp -D tmpDict --patch-from=tmpDict && die "error: can't use -D and --patch-from=#at the same time" zstd -d tmp.zst -D tmpDict -fo result $DIFF "$TESTFILE" result zstd --train-cover=k=56,d=8 && die "Create dictionary without input file (should error)" @@ -1681,6 +1699,7 @@ println "- Create dictionary using shrink-dict flag" zstd --train-cover=steps=256,shrink "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict zstd --train-cover=steps=256,shrink=1 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict1 zstd --train-cover=steps=256,shrink=5 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict2 +zstd --train-cover=shrink=5,steps=256 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpShrinkDict3 println "- Create dictionary with short dictID" zstd --train-cover=k=46,d=8,split=80 "$TESTDIR"/*.c "$PRGDIR"/*.c --dictID=1 -o tmpDict1 cmp tmpDict tmpDict1 && die "dictionaries should have different ID !" From 3d773d701391c72d79eac65e64a93049459841ca Mon Sep 17 00:00:00 2001 From: "Alex Xu (Hello71)" Date: Sun, 5 Dec 2021 22:51:44 -0500 Subject: [PATCH 297/340] Apply FORCE_MEMORY_ACCESS=1 to legacy See #2633, #2881. --- lib/legacy/zstd_v01.c | 5 +---- 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 +---- 7 files changed, 7 insertions(+), 28 deletions(-) diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 13115bec5..b177a078d 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -204,10 +204,7 @@ typedef signed long long S64; * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef FSE_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define FSE_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define FSE_FORCE_MEMORY_ACCESS 1 # endif #endif diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index 9abb6d033..40303db11 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -129,10 +129,7 @@ extern "C" { * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define MEM_FORCE_MEMORY_ACCESS 1 # endif #endif diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index a19cb205a..e70c04904 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -130,10 +130,7 @@ extern "C" { * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define MEM_FORCE_MEMORY_ACCESS 1 # endif #endif diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c index 77d52555b..60023fdcd 100644 --- a/lib/legacy/zstd_v04.c +++ b/lib/legacy/zstd_v04.c @@ -101,10 +101,7 @@ extern "C" { * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define MEM_FORCE_MEMORY_ACCESS 1 # endif #endif diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c index ca8d5c9bf..3dd87ba6f 100644 --- a/lib/legacy/zstd_v05.c +++ b/lib/legacy/zstd_v05.c @@ -120,10 +120,7 @@ extern "C" { * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define MEM_FORCE_MEMORY_ACCESS 1 # endif #endif diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c index c4ac7dba8..bd95dde8a 100644 --- a/lib/legacy/zstd_v06.c +++ b/lib/legacy/zstd_v06.c @@ -122,10 +122,7 @@ extern "C" { * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define MEM_FORCE_MEMORY_ACCESS 1 # endif #endif diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c index 049ba4749..fcd54ac95 100644 --- a/lib/legacy/zstd_v07.c +++ b/lib/legacy/zstd_v07.c @@ -282,10 +282,7 @@ extern "C" { * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define MEM_FORCE_MEMORY_ACCESS 2 -# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) +# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__) # define MEM_FORCE_MEMORY_ACCESS 1 # endif #endif From 38dfc4699e1108d839b3222b6093caaad5befd1c Mon Sep 17 00:00:00 2001 From: binhdvo Date: Tue, 7 Dec 2021 16:56:19 -0500 Subject: [PATCH 298/340] Imply -q when stderr is not a tty (#2884) * Imply -q when stderr is not a tty --- programs/zstdcli.c | 2 +- tests/playTests.sh | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index a3f8ebab7..4d1978c80 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1402,7 +1402,7 @@ int main(int argCount, const char* argv[]) /* No status message in pipe mode (stdin - stdout) */ hasStdout = outFileName && !strcmp(outFileName,stdoutmark); - if (hasStdout && (g_displayLevel==2)) g_displayLevel=1; + if ((hasStdout || !IS_CONSOLE(stderr)) && (g_displayLevel==2)) g_displayLevel=1; /* IO Stream/File */ FIO_setHasStdoutOutput(fCtx, hasStdout); diff --git a/tests/playTests.sh b/tests/playTests.sh index 6dbfffca2..f6b6ac8f2 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -351,8 +351,8 @@ zstd < tmpPrompt -o tmpPrompt.zst -f # should successfully overwrite with -f zstd -q -d -f tmpPrompt.zst -o tmpPromptRegenerated $DIFF tmpPromptRegenerated tmpPrompt # the first 'y' character should not be swallowed -echo 'yes' | zstd tmpPrompt -o tmpPrompt.zst # accept piped "y" input to force overwrite when using files -echo 'yes' | zstd < tmpPrompt -o tmpPrompt.zst && die "should have aborted immediately and failed to overwrite" +echo 'yes' | zstd tmpPrompt -v -o tmpPrompt.zst # accept piped "y" input to force overwrite when using files +echo 'yes' | zstd < tmpPrompt -v -o tmpPrompt.zst && die "should have aborted immediately and failed to overwrite" zstd tmpPrompt - < tmpPrompt -o tmpPromp.zst --rm && die "should have aborted immediately and failed to remove" println "Test completed" @@ -371,9 +371,9 @@ test ! -f tmp.zst # tmp.zst should no longer be present println "test : should quietly not remove non-regular file" println hello > tmp zstd tmp -f -o "$DEVDEVICE" 2>tmplog > "$INTOVOID" -grep -v "Refusing to remove non-regular file" tmplog +grep "Refusing to remove non-regular file" tmplog && die rm -f tmplog -zstd tmp -f -o "$INTOVOID" 2>&1 | grep -v "Refusing to remove non-regular file" +zstd tmp -f -o "$INTOVOID" 2>&1 | grep "Refusing to remove non-regular file" && die println "test : --rm on stdin" println a | zstd --rm > $INTOVOID # --rm should remain silent rm -f tmp @@ -420,11 +420,11 @@ zstd tmp1 tmp2 -q -o tmpexists && die "should have refused to overwrite" println gooder > tmp_rm1 println boi > tmp_rm2 println worldly > tmp_rm3 -echo 'y' | zstd tmp_rm1 tmp_rm2 -o tmp_rm3.zst --rm # tests the warning prompt for --rm with multiple inputs into once source +echo 'y' | zstd tmp_rm1 tmp_rm2 -v -o tmp_rm3.zst --rm # tests the warning prompt for --rm with multiple inputs into once source test ! -f tmp_rm1 test ! -f tmp_rm2 cp tmp_rm3.zst tmp_rm4.zst -echo 'Y' | zstd -d tmp_rm3.zst tmp_rm4.zst -o tmp_rm_out --rm +echo 'Y' | zstd -d tmp_rm3.zst tmp_rm4.zst -v -o tmp_rm_out --rm test ! -f tmp_rm3.zst test ! -f tmp_rm4.zst echo 'yes' | zstd tmp_rm_out tmp_rm3 -c --rm && die "compressing multiple files to stdout with --rm should fail unless -f is specified" From 1c7d2c4dd561e557964b78c3757ee4cc745be445 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 7 Dec 2021 21:14:52 -0800 Subject: [PATCH 299/340] updated xxHash to latest v0.8.1 with minor modifications directly embedded in source : - does not compile XXH3 - namespace emulation (ZSTD_ prefix) Incidentally fix #2824 --- lib/common/xxhash.c | 851 +------ lib/common/xxhash.h | 5800 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 5660 insertions(+), 991 deletions(-) diff --git a/lib/common/xxhash.c b/lib/common/xxhash.c index 926b33604..0fae88c5d 100644 --- a/lib/common/xxhash.c +++ b/lib/common/xxhash.c @@ -1,824 +1,43 @@ /* - * xxHash - Fast Hash algorithm - * Copyright (c) Yann Collet, Facebook, Inc. + * xxHash - Extremely Fast Hash algorithm + * Copyright (C) 2012-2020 Yann Collet * - * You can contact the author at : - * - xxHash homepage: http://www.xxhash.com - * - xxHash source repository : https://github.com/Cyan4973/xxHash - * - * 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. -*/ - - -/* ************************************* -* Tuning parameters -***************************************/ -/*!XXH_FORCE_MEMORY_ACCESS : - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. - * It can generate buggy code on targets which do not support unaligned memory accesses. - * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) - * See http://stackoverflow.com/a/32095106/646947 for details. - * Prefer these methods in priority order (0 > 1 > 2) + * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at: + * - xxHash homepage: https://www.xxhash.com + * - xxHash source repository: https://github.com/Cyan4973/xxHash */ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) || \ - defined(__ICCARM__) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif -/*!XXH_ACCEPT_NULL_INPUT_POINTER : - * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. - * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. - * By default, this option is disabled. To enable it, uncomment below define : + +/* + * xxhash.c instantiates functions defined in xxhash.h */ -/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ -/*!XXH_FORCE_NATIVE_FORMAT : - * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. - * Results are therefore identical for little-endian and big-endian CPU. - * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. - * Should endian-independence be of no importance for your application, you may set the #define below to 1, - * to improve speed for Big-endian CPU. - * This option has no impact on Little_Endian CPU. - */ -#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ -# define XXH_FORCE_NATIVE_FORMAT 0 -#endif +#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */ +#define XXH_IMPLEMENTATION /* access definitions */ -/*!XXH_FORCE_ALIGN_CHECK : - * This is a minor performance trick, only useful with lots of very small keys. - * It means : check for aligned/unaligned input. - * The check costs one initial branch per hash; set to 0 when the input data - * is guaranteed to be aligned. - */ -#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ -# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_FORCE_ALIGN_CHECK 0 -# else -# define XXH_FORCE_ALIGN_CHECK 1 -# endif -#endif - - -/* ************************************* -* Includes & Memory related functions -***************************************/ -/* Modify the local functions below should you wish to use some other memory routines */ -/* for ZSTD_malloc(), ZSTD_free() */ -#define ZSTD_DEPS_NEED_MALLOC -#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */ -static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); } -static void XXH_free (void* p) { ZSTD_free(p); } -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); } - -#ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY -#endif #include "xxhash.h" - - -/* ************************************* -* Compiler Specific Options -***************************************/ -#include "compiler.h" - - -/* ************************************* -* Basic Types -***************************************/ -#include "mem.h" /* BYTE, U32, U64, size_t */ - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } -static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign; - -static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } -static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - -static U32 XXH_read32(const void* memPtr) -{ - U32 val; - ZSTD_memcpy(&val, memPtr, sizeof(val)); - return val; -} - -static U64 XXH_read64(const void* memPtr) -{ - U64 val; - ZSTD_memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ - - -/* **************************************** -* Compiler-specific Functions and Macros -******************************************/ -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -#if defined(__ICCARM__) -# include -# define XXH_rotl32(x,r) __ROR(x,(32 - r)) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -#endif -# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -# define XXH_swap64 _byteswap_uint64 -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -# define XXH_swap64 __builtin_bswap64 -#else -static U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -static U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - - -/* ************************************* -* Architecture Macros -***************************************/ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; - -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ -#ifndef XXH_CPU_LITTLE_ENDIAN - static const int g_one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one)) -#endif - - -/* *************************** -* Memory reads -*****************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -FORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); - else - return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); -} - -FORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian) -{ - return XXH_readLE32_align(ptr, endian, XXH_unaligned); -} - -static U32 XXH_readBE32(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); -} - -FORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); - else - return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); -} - -FORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian) -{ - return XXH_readLE64_align(ptr, endian, XXH_unaligned); -} - -static U64 XXH_readBE64(const void* ptr) -{ - return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); -} - - -/* ************************************* -* Macros -***************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ - - -/* ************************************* -* Constants -***************************************/ -static const U32 PRIME32_1 = 2654435761U; -static const U32 PRIME32_2 = 2246822519U; -static const U32 PRIME32_3 = 3266489917U; -static const U32 PRIME32_4 = 668265263U; -static const U32 PRIME32_5 = 374761393U; - -static const U64 PRIME64_1 = 11400714785074694791ULL; -static const U64 PRIME64_2 = 14029467366897019727ULL; -static const U64 PRIME64_3 = 1609587929392839161ULL; -static const U64 PRIME64_4 = 9650029242287828579ULL; -static const U64 PRIME64_5 = 2870177450012600261ULL; - -XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } - - -/* ************************** -* Utils -****************************/ -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState) -{ - ZSTD_memcpy(dstState, srcState, sizeof(*dstState)); -} - -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState) -{ - ZSTD_memcpy(dstState, srcState, sizeof(*dstState)); -} - - -/* *************************** -* Simple Hash Functions -*****************************/ - -static U32 XXH32_round(U32 seed, U32 input) -{ - seed += input * PRIME32_2; - seed = XXH_rotl32(seed, 13); - seed *= PRIME32_1; - return seed; -} - -FORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do { - v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4; - v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4; - v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4; - v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4; - } while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } else { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p+4<=bEnd) { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH32_CREATESTATE_STATIC(state); - XXH32_reset(state, seed); - XXH32_update(state, input, len); - return XXH32_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } } - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - - -static U64 XXH64_round(U64 acc, U64 input) -{ - acc += input * PRIME64_2; - acc = XXH_rotl64(acc, 31); - acc *= PRIME64_1; - return acc; -} - -static U64 XXH64_mergeRound(U64 acc, U64 val) -{ - val = XXH64_round(0, val); - acc ^= val; - acc = acc * PRIME64_1 + PRIME64_4; - return acc; -} - -FORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - U64 h64; -#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do { - v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8; - v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8; - v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8; - v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8; - } while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - - } else { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - while (p+8<=bEnd) { - U64 const k1 = XXH64_round(0, XXH_get64bits(p)); - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) { - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH64_CREATESTATE_STATIC(state); - XXH64_reset(state, seed); - XXH64_update(state, input, len); - return XXH64_digest(state); -#else - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if (XXH_FORCE_ALIGN_CHECK) { - if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */ - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } } - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - - -/* ************************************************** -* Advanced Hash Functions -****************************************************/ - -XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) -{ - return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void) -{ - return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); -} -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - - -/*** Hash feed ***/ - -XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed) -{ - XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - ZSTD_memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */ - state.v1 = seed + PRIME32_1 + PRIME32_2; - state.v2 = seed + PRIME32_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME32_1; - ZSTD_memcpy(statePtr, &state, sizeof(state)); - return XXH_OK; -} - - -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed) -{ - XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ - ZSTD_memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */ - state.v1 = seed + PRIME64_1 + PRIME64_2; - state.v2 = seed + PRIME64_2; - state.v3 = seed + 0; - state.v4 = seed - PRIME64_1; - ZSTD_memcpy(statePtr, &state, sizeof(state)); - return XXH_OK; -} - - -FORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len_32 += (unsigned)len; - state->large_len |= (len>=16) | (state->total_len_32>=16); - - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); - state->memsize += (unsigned)len; - return XXH_OK; - } - - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const U32* p32 = state->mem32; - state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; - state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; - state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; - state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do { - v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4; - v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4; - v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4; - v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian) -{ - const BYTE * p = (const BYTE*)state->mem32; - const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize; - U32 h32; - - if (state->large_len) { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } else { - h32 = state->v3 /* == seed */ + PRIME32_5; - } - - h32 += state->total_len_32; - - while (p+4<=bEnd) { - h32 += XXH_readLE32(p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_digest_endian(state_in, XXH_littleEndian); - else - return XXH32_digest_endian(state_in, XXH_bigEndian); -} - - - -/* **** XXH64 **** */ - -FORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 32) { /* fill in tmp buffer */ - if (input != NULL) { - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); - } - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian)); - state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian)); - state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian)); - state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian)); - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do { - v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8; - v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8; - v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8; - v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8; - } while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); - } - - return XXH_OK; -} - -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH64_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian) -{ - const BYTE * p = (const BYTE*)state->mem64; - const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize; - U64 h64; - - if (state->total_len >= 32) { - U64 const v1 = state->v1; - U64 const v2 = state->v2; - U64 const v3 = state->v3; - U64 const v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - h64 = XXH64_mergeRound(h64, v1); - h64 = XXH64_mergeRound(h64, v2); - h64 = XXH64_mergeRound(h64, v3); - h64 = XXH64_mergeRound(h64, v4); - } else { - h64 = state->v3 + PRIME64_5; - } - - h64 += (U64) state->total_len; - - while (p+8<=bEnd) { - U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian)); - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) { - h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in) -{ - XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_digest_endian(state_in, XXH_littleEndian); - else - return XXH64_digest_endian(state_in, XXH_bigEndian); -} - - -/* ************************** -* Canonical representation -****************************/ - -/*! Default XXH result types are basic unsigned 32 and 64 bits. -* The canonical representation follows human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs. -*/ - -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); - ZSTD_memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); - if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); - ZSTD_memcpy(dst, &hash, sizeof(*dst)); -} - -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) -{ - return XXH_readBE32(src); -} - -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) -{ - return XXH_readBE64(src); -} diff --git a/lib/common/xxhash.h b/lib/common/xxhash.h index 16c1f1617..a813b1813 100644 --- a/lib/common/xxhash.h +++ b/lib/common/xxhash.h @@ -1,20 +1,68 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (c) Yann Collet, Facebook, Inc. + * Copyright (C) 2012-2020 Yann Collet * - * You can contact the author at : - * - xxHash source repository : https://github.com/Cyan4973/xxHash - * - * 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. -*/ + * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You can contact the author at: + * - xxHash homepage: https://www.xxhash.com + * - xxHash source repository: https://github.com/Cyan4973/xxHash + */ -/* Notice extracted from xxHash homepage : +/* Note : This is a slightly modified version of xxHash + * for zstd internal usage. + * Modifications are : + * - Removal of XXH3 / XXH128 algorithms, unused within zstd + * - prefix names of all symbols, to reduce risks of collisions + * This could be achieved at build stage, with CPPFLAGS typically, + * but doing it directly within source file + * make it possible for 3rd party to simply grab the directory + * and compile it locally, with whichever build system they wish, + * without a need for them to configure some build flag. + */ -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. +#ifndef XXH_NO_XXH3 +# define XXH_NO_XXH3 +#endif + +#ifndef XXH_NAMESPACE +# define XXH_NAMESPACE ZSTD_ +#endif + +/*! + * @mainpage xxHash + * + * @file xxhash.h + * xxHash prototypes and implementation + */ +/* TODO: update */ +/* Notice extracted from xxHash homepage: + +xxHash is an extremely fast hash algorithm, running at RAM speed limits. It also successfully passes all tests from the SMHasher suite. Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) @@ -22,7 +70,7 @@ Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo Name Speed Q.Score Author xxHash 5.4 GB/s 10 CrapWow 3.2 GB/s 2 Andrew -MumurHash 3a 2.7 GB/s 10 Austin Appleby +MurmurHash 3a 2.7 GB/s 10 Austin Appleby SpookyHash 2.0 GB/s 10 Bob Jenkins SBox 1.4 GB/s 9 Bret Mulvey Lookup3 1.2 GB/s 9 Bob Jenkins @@ -37,8 +85,13 @@ Q.Score is a measure of quality of the hash function. It depends on successfully passing SMHasher test set. 10 is a perfect score. -A 64-bits version, named XXH64, is available since r35. -It offers much better speed, but for 64-bits applications only. +Note: SMHasher's CRC32 implementation is not the fastest one. +Other speed-oriented implementations can be faster, +especially in combination with PCLMUL instruction: +https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735 + +A 64-bit version, named XXH64, is available since r35. +It offers much better speed, but for 64-bit applications only. Name Speed on 64 bits Speed on 32 bits XXH64 13.8 GB/s 1.9 GB/s XXH32 6.8 GB/s 6.0 GB/s @@ -48,33 +101,34 @@ XXH32 6.8 GB/s 6.0 GB/s extern "C" { #endif -#ifndef XXHASH_H_5627135585666179 -#define XXHASH_H_5627135585666179 1 - - /* **************************** -* Definitions -******************************/ -#include "zstd_deps.h" -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - - -/* **************************** -* API modifier -******************************/ -/** XXH_PRIVATE_API -* This is useful if you want to include xxhash functions in `static` mode -* in order to inline them, and remove their symbol from the public list. -* Methodology : -* #define XXH_PRIVATE_API -* #include "xxhash.h" -* `xxhash.c` is automatically included. -* It's not useful to compile and link it as a separate module anymore. -*/ -#ifdef XXH_PRIVATE_API -# ifndef XXH_STATIC_LINKING_ONLY -# define XXH_STATIC_LINKING_ONLY -# endif + * INLINE mode + ******************************/ +/*! + * XXH_INLINE_ALL (and XXH_PRIVATE_API) + * Use these build macros to inline xxhash into the target unit. + * Inlining improves performance on small inputs, especially when the length is + * expressed as a compile-time constant: + * + * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html + * + * It also keeps xxHash symbols private to the unit, so they are not exported. + * + * Usage: + * #define XXH_INLINE_ALL + * #include "xxhash.h" + * + * Do not compile and link xxhash.o as a separate object, as it is not useful. + */ +#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \ + && !defined(XXH_INLINE_ALL_31684351384) + /* this section should be traversed only once */ +# define XXH_INLINE_ALL_31684351384 + /* give access to the advanced API, required to compile implementations */ +# undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */ +# define XXH_STATIC_LINKING_ONLY + /* make all functions private */ +# undef XXH_PUBLIC_API # if defined(__GNUC__) # define XXH_PUBLIC_API static __inline __attribute__((unused)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) @@ -82,45 +136,205 @@ typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; # elif defined(_MSC_VER) # define XXH_PUBLIC_API static __inline # else -# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */ + /* note: this version may generate warnings for unused static functions */ +# define XXH_PUBLIC_API static # endif -#else -# define XXH_PUBLIC_API /* do nothing */ -#endif /* XXH_PRIVATE_API */ -/*!XXH_NAMESPACE, aka Namespace Emulation : + /* + * This part deals with the special case where a unit wants to inline xxHash, + * but "xxhash.h" has previously been included without XXH_INLINE_ALL, + * such as part of some previously included *.h header file. + * Without further action, the new include would just be ignored, + * and functions would effectively _not_ be inlined (silent failure). + * The following macros solve this situation by prefixing all inlined names, + * avoiding naming collision with previous inclusions. + */ + /* Before that, we unconditionally #undef all symbols, + * in case they were already defined with XXH_NAMESPACE. + * They will then be redefined for XXH_INLINE_ALL + */ +# undef XXH_versionNumber + /* XXH32 */ +# undef XXH32 +# undef XXH32_createState +# undef XXH32_freeState +# undef XXH32_reset +# undef XXH32_update +# undef XXH32_digest +# undef XXH32_copyState +# undef XXH32_canonicalFromHash +# undef XXH32_hashFromCanonical + /* XXH64 */ +# undef XXH64 +# undef XXH64_createState +# undef XXH64_freeState +# undef XXH64_reset +# undef XXH64_update +# undef XXH64_digest +# undef XXH64_copyState +# undef XXH64_canonicalFromHash +# undef XXH64_hashFromCanonical + /* XXH3_64bits */ +# undef XXH3_64bits +# undef XXH3_64bits_withSecret +# undef XXH3_64bits_withSeed +# undef XXH3_64bits_withSecretandSeed +# undef XXH3_createState +# undef XXH3_freeState +# undef XXH3_copyState +# undef XXH3_64bits_reset +# undef XXH3_64bits_reset_withSeed +# undef XXH3_64bits_reset_withSecret +# undef XXH3_64bits_update +# undef XXH3_64bits_digest +# undef XXH3_generateSecret + /* XXH3_128bits */ +# undef XXH128 +# undef XXH3_128bits +# undef XXH3_128bits_withSeed +# undef XXH3_128bits_withSecret +# undef XXH3_128bits_reset +# undef XXH3_128bits_reset_withSeed +# undef XXH3_128bits_reset_withSecret +# undef XXH3_128bits_reset_withSecretandSeed +# undef XXH3_128bits_update +# undef XXH3_128bits_digest +# undef XXH128_isEqual +# undef XXH128_cmp +# undef XXH128_canonicalFromHash +# undef XXH128_hashFromCanonical + /* Finally, free the namespace itself */ +# undef XXH_NAMESPACE -If you want to include _and expose_ xxHash functions from within your own library, -but also want to avoid symbol collisions with another library which also includes xxHash, + /* employ the namespace for XXH_INLINE_ALL */ +# define XXH_NAMESPACE XXH_INLINE_ + /* + * Some identifiers (enums, type names) are not symbols, + * but they must nonetheless be renamed to avoid redeclaration. + * Alternative solution: do not redeclare them. + * However, this requires some #ifdefs, and has a more dispersed impact. + * Meanwhile, renaming can be achieved in a single place. + */ +# define XXH_IPREF(Id) XXH_NAMESPACE ## Id +# define XXH_OK XXH_IPREF(XXH_OK) +# define XXH_ERROR XXH_IPREF(XXH_ERROR) +# define XXH_errorcode XXH_IPREF(XXH_errorcode) +# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t) +# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t) +# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t) +# define XXH32_state_s XXH_IPREF(XXH32_state_s) +# define XXH32_state_t XXH_IPREF(XXH32_state_t) +# define XXH64_state_s XXH_IPREF(XXH64_state_s) +# define XXH64_state_t XXH_IPREF(XXH64_state_t) +# define XXH3_state_s XXH_IPREF(XXH3_state_s) +# define XXH3_state_t XXH_IPREF(XXH3_state_t) +# define XXH128_hash_t XXH_IPREF(XXH128_hash_t) + /* Ensure the header is parsed again, even if it was previously included */ +# undef XXHASH_H_5627135585666179 +# undef XXHASH_H_STATIC_13879238742 +#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ -you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library -with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values). -Note that no change is required within the calling program as long as it includes `xxhash.h` : -regular symbol name will be automatically translated by this header. -*/ + +/* **************************************************************** + * Stable API + *****************************************************************/ +#ifndef XXHASH_H_5627135585666179 +#define XXHASH_H_5627135585666179 1 + + +/*! + * @defgroup public Public API + * Contains details on the public xxHash functions. + * @{ + */ +/* specific declaration modes for Windows */ +#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) +# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# ifdef XXH_EXPORT +# define XXH_PUBLIC_API __declspec(dllexport) +# elif XXH_IMPORT +# define XXH_PUBLIC_API __declspec(dllimport) +# endif +# else +# define XXH_PUBLIC_API /* do nothing */ +# endif +#endif + +#ifdef XXH_DOXYGEN +/*! + * @brief Emulate a namespace by transparently prefixing all symbols. + * + * If you want to include _and expose_ xxHash functions from within your own + * library, but also want to avoid symbol collisions with other libraries which + * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix + * any public symbol from xxhash library with the value of XXH_NAMESPACE + * (therefore, avoid empty or numeric values). + * + * Note that no change is required within the calling program as long as it + * includes `xxhash.h`: Regular symbol names will be automatically translated + * by this header. + */ +# define XXH_NAMESPACE /* YOUR NAME HERE */ +# undef XXH_NAMESPACE +#endif + #ifdef XXH_NAMESPACE # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) -# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) -# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) +/* XXH32 */ +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) -# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) -# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) -# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) -# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) -# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) -# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) -# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) +/* XXH64 */ +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) +# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) +/* XXH3_64bits */ +# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits) +# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret) +# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed) +# define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed) +# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState) +# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState) +# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState) +# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset) +# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed) +# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret) +# define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed) +# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update) +# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest) +# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret) +# define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed) +/* XXH3_128bits */ +# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128) +# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits) +# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed) +# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret) +# define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed) +# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset) +# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed) +# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret) +# define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed) +# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update) +# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest) +# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual) +# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp) +# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash) +# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical) #endif @@ -128,156 +342,5392 @@ regular symbol name will be automatically translated by this header. * Version ***************************************/ #define XXH_VERSION_MAJOR 0 -#define XXH_VERSION_MINOR 6 -#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_MINOR 8 +#define XXH_VERSION_RELEASE 1 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) + +/*! + * @brief Obtains the xxHash version. + * + * This is mostly useful when xxHash is compiled as a shared library, + * since the returned value comes from the library, as opposed to header file. + * + * @return `XXH_VERSION_NUMBER` of the invoked library. + */ XXH_PUBLIC_API unsigned XXH_versionNumber (void); /* **************************** -* Simple Hash Functions +* Common basic types ******************************/ -typedef unsigned int XXH32_hash_t; -typedef unsigned long long XXH64_hash_t; +#include /* size_t */ +typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed); -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed); + +/*-********************************************************************** +* 32-bit hash +************************************************************************/ +#if defined(XXH_DOXYGEN) /* Don't show include */ +/*! + * @brief An unsigned 32-bit integer. + * + * Not necessarily defined to `uint32_t` but functionally equivalent. + */ +typedef uint32_t XXH32_hash_t; + +#elif !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint32_t XXH32_hash_t; + +#else +# include +# if UINT_MAX == 0xFFFFFFFFUL + typedef unsigned int XXH32_hash_t; +# else +# if ULONG_MAX == 0xFFFFFFFFUL + typedef unsigned long XXH32_hash_t; +# else +# error "unsupported platform: need a 32-bit type" +# endif +# endif +#endif /*! -XXH32() : - Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s -XXH64() : - Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". - "seed" can be used to alter the result predictably. - This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark). -*/ + * @} + * + * @defgroup xxh32_family XXH32 family + * @ingroup public + * Contains functions used in the classic 32-bit xxHash algorithm. + * + * @note + * XXH32 is useful for older platforms, with no or poor 64-bit performance. + * Note that @ref xxh3_family provides competitive speed + * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results. + * + * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families + * @see @ref xxh32_impl for implementation details + * @{ + */ +/*! + * @brief Calculates the 32-bit hash of @p input using xxHash32. + * + * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 32-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 32-bit hash value. + * + * @see + * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): + * Direct equivalents for the other variants of xxHash. + * @see + * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. + */ +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); -/* **************************** -* Streaming Hash Functions -******************************/ -typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ -typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ +/*! + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * Example code for incrementally hashing a file: + * @code{.c} + * #include + * #include + * #define BUFFER_SIZE 256 + * + * // Note: XXH64 and XXH3 use the same interface. + * XXH32_hash_t + * hashFile(FILE* stream) + * { + * XXH32_state_t* state; + * unsigned char buf[BUFFER_SIZE]; + * size_t amt; + * XXH32_hash_t hash; + * + * state = XXH32_createState(); // Create a state + * assert(state != NULL); // Error check here + * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed + * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) { + * XXH32_update(state, buf, amt); // Hash the file in chunks + * } + * hash = XXH32_digest(state); // Finalize the hash + * XXH32_freeState(state); // Clean up + * return hash; + * } + * @endcode + */ -/*! State allocation, compatible with dynamic libraries */ +/*! + * @typedef struct XXH32_state_s XXH32_state_t + * @brief The opaque state struct for the XXH32 streaming API. + * + * @see XXH32_state_s for details. + */ +typedef struct XXH32_state_s XXH32_state_t; +/*! + * @brief Allocates an @ref XXH32_state_t. + * + * Must be freed with XXH32_freeState(). + * @return An allocated XXH32_state_t on success, `NULL` on failure. + */ XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void); +/*! + * @brief Frees an @ref XXH32_state_t. + * + * Must be allocated with XXH32_createState(). + * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). + * @return XXH_OK. + */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); +/*! + * @brief Copies one @ref XXH32_state_t to another. + * + * @param dst_state The state to copy to. + * @param src_state The state to copy from. + * @pre + * @p dst_state and @p src_state must not be `NULL` and must not overlap. + */ +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state); -XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); -XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); +/*! + * @brief Resets an @ref XXH32_state_t to begin a new hash. + * + * This function resets and seeds a state. Call it before @ref XXH32_update(). + * + * @param statePtr The state struct to reset. + * @param seed The 32-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + */ +XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); - -/* hash streaming */ - -XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed); +/*! + * @brief Consumes a block of @p input to an @ref XXH32_state_t. + * + * Call this to incrementally consume blocks of data. + * + * @param statePtr The state struct to update. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); + +/*! + * @brief Returns the calculated hash value from an @ref XXH32_state_t. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @param statePtr The state struct to calculate the hash from. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return The calculated xxHash32 value from that state. + */ XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); -XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); +/******* Canonical representation *******/ + +/* + * The default return values from XXH functions are unsigned 32 and 64 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + */ + +/*! + * @brief Canonical (big endian) representation of @ref XXH32_hash_t. + */ +typedef struct { + unsigned char digest[4]; /*!< Hash bytes, big endian */ +} XXH32_canonical_t; + +/*! + * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. + * + * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param hash The @ref XXH32_hash_t to be converted. + * + * @pre + * @p dst must not be `NULL`. + */ +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); + +/*! + * @brief Converts an @ref XXH32_canonical_t to a native @ref XXH32_hash_t. + * + * @param src The @ref XXH32_canonical_t to convert. + * + * @pre + * @p src must not be `NULL`. + * + * @return The converted hash. + */ +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); + + +#ifdef __has_attribute +# define XXH_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +# define XXH_HAS_ATTRIBUTE(x) 0 +#endif + +/* C-language Attributes are added in C23. */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +# define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define XXH_HAS_C_ATTRIBUTE(x) 0 +#endif + +#if defined(__cplusplus) && defined(__has_cpp_attribute) +# define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define XXH_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +/* +Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute +introduced in CPP17 and C23. +CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough +C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough +*/ +#if XXH_HAS_C_ATTRIBUTE(x) +# define XXH_FALLTHROUGH [[fallthrough]] +#elif XXH_HAS_CPP_ATTRIBUTE(x) +# define XXH_FALLTHROUGH [[fallthrough]] +#elif XXH_HAS_ATTRIBUTE(__fallthrough__) +# define XXH_FALLTHROUGH __attribute__ ((fallthrough)) +#else +# define XXH_FALLTHROUGH +#endif + +/*! + * @} + * @ingroup public + * @{ + */ + +#ifndef XXH_NO_LONG_LONG +/*-********************************************************************** +* 64-bit hash +************************************************************************/ +#if defined(XXH_DOXYGEN) /* don't include */ +/*! + * @brief An unsigned 64-bit integer. + * + * Not necessarily defined to `uint64_t` but functionally equivalent. + */ +typedef uint64_t XXH64_hash_t; +#elif !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint64_t XXH64_hash_t; +#else +# include +# if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL + /* LP64 ABI says uint64_t is unsigned long */ + typedef unsigned long XXH64_hash_t; +# else + /* the following type must have a width of 64-bit */ + typedef unsigned long long XXH64_hash_t; +# endif +#endif + +/*! + * @} + * + * @defgroup xxh64_family XXH64 family + * @ingroup public + * @{ + * Contains functions used in the classic 64-bit xxHash algorithm. + * + * @note + * XXH3 provides competitive speed for both 32-bit and 64-bit systems, + * and offers true 64/128 bit hash results. + * It provides better speed for systems with vector processing capabilities. + */ + + +/*! + * @brief Calculates the 64-bit hash of @p input using xxHash64. + * + * This function usually runs faster on 64-bit systems, but slower on 32-bit + * systems (see benchmark). + * + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit hash. + * + * @see + * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): + * Direct equivalents for the other variants of xxHash. + * @see + * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + */ +XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed); + +/******* Streaming *******/ +/*! + * @brief The opaque state struct for the XXH64 streaming API. + * + * @see XXH64_state_s for details. + */ +typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ +XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); +XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state); + +XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed); XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr); -/* -These functions generate the xxHash of an input provided in multiple segments. -Note that, for small input, they are slower than single-call functions, due to state management. -For small input, prefer `XXH32()` and `XXH64()` . - -XXH state must first be allocated, using XXH*_createState() . - -Start a new hash by initializing state with a seed, using XXH*_reset(). - -Then, feed the hash state by calling XXH*_update() as many times as necessary. -Obviously, input must be allocated and read accessible. -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. - -Finally, a hash value can be produced anytime, by using XXH*_digest(). -This function returns the nn-bits hash as an int or long long. - -It's still possible to continue inserting input into the hash state after a digest, -and generate some new hashes later on, by calling again XXH*_digest(). - -When done, free XXH state space if it was allocated dynamically. -*/ - - -/* ************************** -* Utils -****************************/ -#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */ -# define restrict /* disable restrict */ -#endif - -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state); -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state); - - -/* ************************** -* Canonical representation -****************************/ -/* Default result type for XXH functions are primitive unsigned 32 and 64 bits. -* The canonical representation uses human-readable write convention, aka big-endian (large digits first). -* These functions allow transformation of hash result into and from its canonical format. -* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. -*/ -typedef struct { unsigned char digest[4]; } XXH32_canonical_t; -typedef struct { unsigned char digest[8]; } XXH64_canonical_t; - -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); +/******* Canonical representation *******/ +typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t; XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); - -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); +/*! + * @} + * ************************************************************************ + * @defgroup xxh3_family XXH3 family + * @ingroup public + * @{ + * + * XXH3 is a more recent hash algorithm featuring: + * - Improved speed for both small and large inputs + * - True 64-bit and 128-bit outputs + * - SIMD acceleration + * - Improved 32-bit viability + * + * Speed analysis methodology is explained here: + * + * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html + * + * Compared to XXH64, expect XXH3 to run approximately + * ~2x faster on large inputs and >3x faster on small ones, + * exact differences vary depending on platform. + * + * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic, + * but does not require it. + * Any 32-bit and 64-bit targets that can run XXH32 smoothly + * can run XXH3 at competitive speeds, even without vector support. + * Further details are explained in the implementation. + * + * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8, + * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro. + * + * XXH3 implementation is portable: + * it has a generic C90 formulation that can be compiled on any platform, + * all implementations generage exactly the same hash value on all platforms. + * Starting from v0.8.0, it's also labelled "stable", meaning that + * any future version will also generate the same hash value. + * + * XXH3 offers 2 variants, _64bits and _128bits. + * + * When only 64 bits are needed, prefer invoking the _64bits variant, as it + * reduces the amount of mixing, resulting in faster speed on small inputs. + * It's also generally simpler to manipulate a scalar return type than a struct. + * + * The API supports one-shot hashing, streaming mode, and custom secrets. + */ + +/*-********************************************************************** +* XXH3 64-bit variant +************************************************************************/ + +/* XXH3_64bits(): + * default 64-bit variant, using default secret and default seed of 0. + * It's the fastest variant. */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len); + +/* + * XXH3_64bits_withSeed(): + * This variant generates a custom secret on the fly + * based on default secret altered using the `seed` value. + * While this operation is decently fast, note that it's not completely free. + * Note: seed==0 produces the same results as XXH3_64bits(). + */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); + +/*! + * The bare minimum size for a custom secret. + * + * @see + * XXH3_64bits_withSecret(), XXH3_64bits_reset_withSecret(), + * XXH3_128bits_withSecret(), XXH3_128bits_reset_withSecret(). + */ +#define XXH3_SECRET_SIZE_MIN 136 + +/* + * XXH3_64bits_withSecret(): + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing "XXH3_generateSecret()" instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); + + +/******* Streaming *******/ +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + */ + +/*! + * @brief The state struct for the XXH3 streaming API. + * + * @see XXH3_state_s for details. + */ +typedef struct XXH3_state_s XXH3_state_t; +XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void); +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr); +XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state); + +/* + * XXH3_64bits_reset(): + * Initialize with default parameters. + * digest will be equivalent to `XXH3_64bits()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr); +/* + * XXH3_64bits_reset_withSeed(): + * Generate a custom secret from `seed`, and store it into `statePtr`. + * digest will be equivalent to `XXH3_64bits_withSeed()`. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); +/* + * XXH3_64bits_reset_withSecret(): + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). + */ +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); + +XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr); + +/* note : canonical representation of XXH3 is the same as XXH64 + * since they both produce XXH64_hash_t values */ + + +/*-********************************************************************** +* XXH3 128-bit variant +************************************************************************/ + +/*! + * @brief The return value from 128-bit hashes. + * + * Stored in little endian order, although the fields themselves are in native + * endianness. + */ +typedef struct { + XXH64_hash_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */ + XXH64_hash_t high64; /*!< `value >> 64` */ +} XXH128_hash_t; + +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len); +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed); +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize); + +/******* Streaming *******/ +/* + * Streaming requires state maintenance. + * This operation costs memory and CPU. + * As a consequence, streaming is slower than one-shot hashing. + * For better performance, prefer one-shot functions whenever applicable. + * + * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits(). + * Use already declared XXH3_createState() and XXH3_freeState(). + * + * All reset and streaming functions have same meaning as their 64-bit counterpart. + */ + +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr); +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed); +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize); + +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length); +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr); + +/* Following helper functions make it possible to compare XXH128_hast_t values. + * Since XXH128_hash_t is a structure, this capability is not offered by the language. + * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ + +/*! + * XXH128_isEqual(): + * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + */ +XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); + +/*! + * XXH128_cmp(): + * + * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. + * + * return: >0 if *h128_1 > *h128_2 + * =0 if *h128_1 == *h128_2 + * <0 if *h128_1 < *h128_2 + */ +XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2); + + +/******* Canonical representation *******/ +typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t; +XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash); +XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src); + + +#endif /* XXH_NO_LONG_LONG */ + +/*! + * @} + */ #endif /* XXHASH_H_5627135585666179 */ -/* ================================================================================================ - This section contains definitions which are not guaranteed to remain stable. - They may change in future versions, becoming incompatible with a different version of the library. - They shall only be used with static linking. - Never use these definitions in association with dynamic linking ! -=================================================================================================== */ -#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXH_STATIC_H_3543687687345) -#define XXH_STATIC_H_3543687687345 +#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) +#define XXHASH_H_STATIC_13879238742 +/* **************************************************************************** + * This section contains declarations which are not guaranteed to remain stable. + * They may change in future versions, becoming incompatible with a different + * version of the library. + * These declarations should only be used with static linking. + * Never use them in association with dynamic linking! + ***************************************************************************** */ -/* These definitions are only meant to allow allocation of XXH state - statically, on stack, or in a struct for example. - Do not use members directly. */ +/* + * These definitions are only present to allow static allocation + * of XXH states, on stack or in a struct, for example. + * Never **ever** access their members directly. + */ - struct XXH32_state_s { - unsigned total_len_32; - unsigned large_len; - unsigned v1; - unsigned v2; - unsigned v3; - unsigned v4; - unsigned mem32[4]; /* buffer defined as U32 for alignment */ - unsigned memsize; - unsigned reserved; /* never read nor write, will be removed in a future version */ - }; /* typedef'd to XXH32_state_t */ - - struct XXH64_state_s { - unsigned long long total_len; - unsigned long long v1; - unsigned long long v2; - unsigned long long v3; - unsigned long long v4; - unsigned long long mem64[4]; /* buffer defined as U64 for alignment */ - unsigned memsize; - unsigned reserved[2]; /* never read nor write, will be removed in a future version */ - }; /* typedef'd to XXH64_state_t */ +/*! + * @internal + * @brief Structure for XXH32 streaming API. + * + * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY, + * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is + * an opaque type. This allows fields to safely be changed. + * + * Typedef'd to @ref XXH32_state_t. + * Do not access the members of this struct directly. + * @see XXH64_state_s, XXH3_state_s + */ +struct XXH32_state_s { + XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ + XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ + XXH32_hash_t v[4]; /*!< Accumulator lanes */ + XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ + XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ +}; /* typedef'd to XXH32_state_t */ -# ifdef XXH_PRIVATE_API -# include "xxhash.c" /* include xxhash functions as `static`, for inlining */ +#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */ + +/*! + * @internal + * @brief Structure for XXH64 streaming API. + * + * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY, + * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is + * an opaque type. This allows fields to safely be changed. + * + * Typedef'd to @ref XXH64_state_t. + * Do not access the members of this struct directly. + * @see XXH32_state_s, XXH3_state_s + */ +struct XXH64_state_s { + XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ + XXH64_hash_t v[4]; /*!< Accumulator lanes */ + XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ + XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ + XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ +}; /* typedef'd to XXH64_state_t */ + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ +# include +# define XXH_ALIGN(n) alignas(n) +#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ +/* In C++ alignas() is a keyword */ +# define XXH_ALIGN(n) alignas(n) +#elif defined(__GNUC__) +# define XXH_ALIGN(n) __attribute__ ((aligned(n))) +#elif defined(_MSC_VER) +# define XXH_ALIGN(n) __declspec(align(n)) +#else +# define XXH_ALIGN(n) /* disabled */ +#endif + +/* Old GCC versions only accept the attribute after the type in structures. */ +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \ + && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \ + && defined(__GNUC__) +# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align) +#else +# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type +#endif + +/*! + * @brief The size of the internal XXH3 buffer. + * + * This is the optimal update size for incremental hashing. + * + * @see XXH3_64b_update(), XXH3_128b_update(). + */ +#define XXH3_INTERNALBUFFER_SIZE 256 + +/*! + * @brief Default size of the secret buffer (and @ref XXH3_kSecret). + * + * This is the size used in @ref XXH3_kSecret and the seeded functions. + * + * Not to be confused with @ref XXH3_SECRET_SIZE_MIN. + */ +#define XXH3_SECRET_DEFAULT_SIZE 192 + +/*! + * @internal + * @brief Structure for XXH3 streaming API. + * + * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY, + * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. + * Otherwise it is an opaque type. + * Never use this definition in combination with dynamic library. + * This allows fields to safely be changed in the future. + * + * @note ** This structure has a strict alignment requirement of 64 bytes!! ** + * Do not allocate this with `malloc()` or `new`, + * it will not be sufficiently aligned. + * Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack allocation. + * + * Typedef'd to @ref XXH3_state_t. + * Do never access the members of this struct directly. + * + * @see XXH3_INITSTATE() for stack initialization. + * @see XXH3_createState(), XXH3_freeState(). + * @see XXH32_state_s, XXH64_state_s + */ +struct XXH3_state_s { + XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]); + /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */ + XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]); + /*!< Used to store a custom secret generated from a seed. */ + XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]); + /*!< The internal buffer. @see XXH32_state_s::mem32 */ + XXH32_hash_t bufferedSize; + /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */ + XXH32_hash_t useSeed; + /*!< Reserved field. Needed for padding on 64-bit. */ + size_t nbStripesSoFar; + /*!< Number or stripes processed. */ + XXH64_hash_t totalLen; + /*!< Total length hashed. 64-bit even on 32-bit targets. */ + size_t nbStripesPerBlock; + /*!< Number of stripes per block. */ + size_t secretLimit; + /*!< Size of @ref customSecret or @ref extSecret */ + XXH64_hash_t seed; + /*!< Seed for _withSeed variants. Must be zero otherwise, @see XXH3_INITSTATE() */ + XXH64_hash_t reserved64; + /*!< Reserved field. */ + const unsigned char* extSecret; + /*!< Reference to an external secret for the _withSecret variants, NULL + * for other variants. */ + /* note: there may be some padding at the end due to alignment on 64 bytes */ +}; /* typedef'd to XXH3_state_t */ + +#undef XXH_ALIGN_MEMBER + +/*! + * @brief Initializes a stack-allocated `XXH3_state_s`. + * + * When the @ref XXH3_state_t structure is merely emplaced on stack, + * it should be initialized with XXH3_INITSTATE() or a memset() + * in case its first reset uses XXH3_NNbits_reset_withSeed(). + * This init can be omitted if the first reset uses default or _withSecret mode. + * This operation isn't necessary when the state is created with XXH3_createState(). + * Note that this doesn't prepare the state for a streaming operation, + * it's still necessary to use XXH3_NNbits_reset*() afterwards. + */ +#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; } + + +/* XXH128() : + * simple alias to pre-selected XXH3_128bits variant + */ +XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed); + + +/* === Experimental API === */ +/* Symbols defined below must be considered tied to a specific library version. */ + +/* + * XXH3_generateSecret(): + * + * Derive a high-entropy secret from any user-defined content, named customSeed. + * The generated secret can be used in combination with `*_withSecret()` functions. + * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed, + * as it becomes much more difficult for an external actor to guess how to impact the calculation logic. + * + * The function accepts as input a custom seed of any length and any content, + * and derives from it a high-entropy secret of length @secretSize + * into an already allocated buffer @secretBuffer. + * @secretSize must be >= XXH3_SECRET_SIZE_MIN + * + * The generated secret can then be used with any `*_withSecret()` variant. + * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`, + * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()` + * are part of this list. They all accept a `secret` parameter + * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN) + * _and_ feature very high entropy (consist of random-looking bytes). + * These conditions can be a high bar to meet, so + * XXH3_generateSecret() can be employed to ensure proper quality. + * + * customSeed can be anything. It can have any size, even small ones, + * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes. + * The resulting `secret` will nonetheless provide all required qualities. + * + * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior. + */ +XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize); + + +/* + * XXH3_generateSecret_fromSeed(): + * + * Generate the same secret as the _withSeed() variants. + * + * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily). + * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes. + * + * The generated secret can be used in combination with + *`*_withSecret()` and `_withSecretandSeed()` variants. + * This generator is notably useful in combination with `_withSecretandSeed()`, + * as a way to emulate a faster `_withSeed()` variant. + */ +XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed); + +/* + * *_withSecretandSeed() : + * These variants generate hash values using either + * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) + * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * + * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. + * `_withSeed()` has to generate the secret on the fly for "large" keys. + * It's fast, but can be perceptible for "not so large" keys (< 1 KB). + * `_withSecret()` has to generate the masks on the fly for "small" keys, + * which requires more instructions than _withSeed() variants. + * Therefore, _withSecretandSeed variant combines the best of both worlds. + * + * When @secret has been generated by XXH3_generateSecret_fromSeed(), + * this variant produces *exactly* the same results as `_withSeed()` variant, + * hence offering only a pure speed benefit on "large" input, + * by skipping the need to regenerate the secret for every large input. + * + * Another usage scenario is to hash the secret to a 64-bit hash value, + * for example with XXH3_64bits(), which then becomes the seed, + * and then employ both the seed and the secret in _withSecretandSeed(). + * On top of speed, an added benefit is that each bit in the secret + * has a 50% chance to swap each bit in the output, + * via its impact to the seed. + * This is not guaranteed when using the secret directly in "small data" scenarios, + * because only portions of the secret are employed for small data. + */ +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecretandSeed(const void* data, size_t len, + const void* secret, size_t secretSize, + XXH64_hash_t seed); + +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecretandSeed(const void* data, size_t len, + const void* secret, size_t secretSize, + XXH64_hash_t seed64); + +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, + const void* secret, size_t secretSize, + XXH64_hash_t seed64); + +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, + const void* secret, size_t secretSize, + XXH64_hash_t seed64); + + +#endif /* XXH_NO_LONG_LONG */ +#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) +# define XXH_IMPLEMENTATION +#endif + +#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */ + + +/* ======================================================================== */ +/* ======================================================================== */ +/* ======================================================================== */ + + +/*-********************************************************************** + * xxHash implementation + *-********************************************************************** + * xxHash's implementation used to be hosted inside xxhash.c. + * + * However, inlining requires implementation to be visible to the compiler, + * hence be included alongside the header. + * Previously, implementation was hosted inside xxhash.c, + * which was then #included when inlining was activated. + * This construction created issues with a few build and install systems, + * as it required xxhash.c to be stored in /include directory. + * + * xxHash implementation is now directly integrated within xxhash.h. + * As a consequence, xxhash.c is no longer needed in /include. + * + * xxhash.c is still available and is still useful. + * In a "normal" setup, when xxhash is not inlined, + * xxhash.h only exposes the prototypes and public symbols, + * while xxhash.c can be built into an object file xxhash.o + * which can then be linked into the final binary. + ************************************************************************/ + +#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \ + || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387) +# define XXH_IMPLEM_13a8737387 + +/* ************************************* +* Tuning parameters +***************************************/ + +/*! + * @defgroup tuning Tuning parameters + * @{ + * + * Various macros to control xxHash's behavior. + */ +#ifdef XXH_DOXYGEN +/*! + * @brief Define this to disable 64-bit code. + * + * Useful if only using the @ref xxh32_family and you have a strict C90 compiler. + */ +# define XXH_NO_LONG_LONG +# undef XXH_NO_LONG_LONG /* don't actually */ +/*! + * @brief Controls how unaligned memory is accessed. + * + * By default, access to unaligned memory is controlled by `memcpy()`, which is + * safe and portable. + * + * Unfortunately, on some target/compiler combinations, the generated assembly + * is sub-optimal. + * + * The below switch allow selection of a different access method + * in the search for improved performance. + * + * @par Possible options: + * + * - `XXH_FORCE_MEMORY_ACCESS=0` (default): `memcpy` + * @par + * Use `memcpy()`. Safe and portable. Note that most modern compilers will + * eliminate the function call and treat it as an unaligned access. + * + * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))` + * @par + * Depends on compiler extensions and is therefore not portable. + * This method is safe _if_ your compiler supports it, + * and *generally* as fast or faster than `memcpy`. + * + * - `XXH_FORCE_MEMORY_ACCESS=2`: Direct cast + * @par + * Casts directly and dereferences. This method doesn't depend on the + * compiler, but it violates the C standard as it directly dereferences an + * unaligned pointer. It can generate buggy code on targets which do not + * support unaligned memory accesses, but in some circumstances, it's the + * only known way to get the most performance. + * + * - `XXH_FORCE_MEMORY_ACCESS=3`: Byteshift + * @par + * Also portable. This can generate the best code on old compilers which don't + * inline small `memcpy()` calls, and it might also be faster on big-endian + * systems which lack a native byteswap instruction. However, some compilers + * will emit literal byteshifts even if the target supports unaligned access. + * . + * + * @warning + * Methods 1 and 2 rely on implementation-defined behavior. Use these with + * care, as what works on one compiler/platform/optimization level may cause + * another to read garbage data or even crash. + * + * See http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details. + * + * Prefer these methods in priority order (0 > 3 > 1 > 2) + */ +# define XXH_FORCE_MEMORY_ACCESS 0 + +/*! + * @def XXH_FORCE_ALIGN_CHECK + * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32() + * and XXH64() only). + * + * This is an important performance trick for architectures without decent + * unaligned memory access performance. + * + * It checks for input alignment, and when conditions are met, uses a "fast + * path" employing direct 32-bit/64-bit reads, resulting in _dramatically + * faster_ read speed. + * + * The check costs one initial branch per hash, which is generally negligible, + * but not zero. + * + * Moreover, it's not useful to generate an additional code path if memory + * access uses the same instruction for both aligned and unaligned + * addresses (e.g. x86 and aarch64). + * + * In these cases, the alignment check can be removed by setting this macro to 0. + * Then the code will always use unaligned memory access. + * Align check is automatically disabled on x86, x64 & arm64, + * which are platforms known to offer good unaligned memory accesses performance. + * + * This option does not affect XXH3 (only XXH32 and XXH64). + */ +# define XXH_FORCE_ALIGN_CHECK 0 + +/*! + * @def XXH_NO_INLINE_HINTS + * @brief When non-zero, sets all functions to `static`. + * + * By default, xxHash tries to force the compiler to inline almost all internal + * functions. + * + * This can usually improve performance due to reduced jumping and improved + * constant folding, but significantly increases the size of the binary which + * might not be favorable. + * + * Additionally, sometimes the forced inlining can be detrimental to performance, + * depending on the architecture. + * + * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the + * compiler full control on whether to inline or not. + * + * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using + * -fno-inline with GCC or Clang, this will automatically be defined. + */ +# define XXH_NO_INLINE_HINTS 0 + +/*! + * @def XXH32_ENDJMP + * @brief Whether to use a jump for `XXH32_finalize`. + * + * For performance, `XXH32_finalize` uses multiple branches in the finalizer. + * This is generally preferable for performance, + * but depending on exact architecture, a jmp may be preferable. + * + * This setting is only possibly making a difference for very small inputs. + */ +# define XXH32_ENDJMP 0 + +/*! + * @internal + * @brief Redefines old internal names. + * + * For compatibility with code that uses xxHash's internals before the names + * were changed to improve namespacing. There is no other reason to use this. + */ +# define XXH_OLD_NAMES +# undef XXH_OLD_NAMES /* don't actually use, it is ugly. */ +#endif /* XXH_DOXYGEN */ +/*! + * @} + */ + +#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ + /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */ +# if !defined(__clang__) && \ +( \ + (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ + ( \ + defined(__GNUC__) && ( \ + (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \ + ( \ + defined(__mips__) && \ + (__mips <= 5 || __mips_isa_rev < 6) && \ + (!defined(__mips16) || defined(__mips_mips16e2)) \ + ) \ + ) \ + ) \ +) +# define XXH_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ +# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \ + || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */ +# define XXH_FORCE_ALIGN_CHECK 0 +# else +# define XXH_FORCE_ALIGN_CHECK 1 +# endif +#endif + +#ifndef XXH_NO_INLINE_HINTS +# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \ + || defined(__NO_INLINE__) /* -O0, -fno-inline */ +# define XXH_NO_INLINE_HINTS 1 +# else +# define XXH_NO_INLINE_HINTS 0 +# endif +#endif + +#ifndef XXH32_ENDJMP +/* generally preferable for performance */ +# define XXH32_ENDJMP 0 +#endif + +/*! + * @defgroup impl Implementation + * @{ + */ + + +/* ************************************* +* Includes & Memory related functions +***************************************/ +/* + * Modify the local functions below should you wish to use + * different memory routines for malloc() and free() + */ +#include + +/*! + * @internal + * @brief Modify this function to use a different routine than malloc(). + */ +static void* XXH_malloc(size_t s) { return malloc(s); } + +/*! + * @internal + * @brief Modify this function to use a different routine than free(). + */ +static void XXH_free(void* p) { free(p); } + +#include + +/*! + * @internal + * @brief Modify this function to use a different routine than memcpy(). + */ +static void* XXH_memcpy(void* dest, const void* src, size_t size) +{ + return memcpy(dest,src,size); +} + +#include /* ULLONG_MAX */ + + +/* ************************************* +* Compiler Specific Options +***************************************/ +#ifdef _MSC_VER /* Visual Studio warning fix */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + +#if XXH_NO_INLINE_HINTS /* disable inlining hints */ +# if defined(__GNUC__) || defined(__clang__) +# define XXH_FORCE_INLINE static __attribute__((unused)) +# else +# define XXH_FORCE_INLINE static +# endif +# define XXH_NO_INLINE static +/* enable inlining hints */ +#elif defined(__GNUC__) || defined(__clang__) +# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) +# define XXH_NO_INLINE static __attribute__((noinline)) +#elif defined(_MSC_VER) /* Visual Studio */ +# define XXH_FORCE_INLINE static __forceinline +# define XXH_NO_INLINE static __declspec(noinline) +#elif defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */ +# define XXH_FORCE_INLINE static inline +# define XXH_NO_INLINE static +#else +# define XXH_FORCE_INLINE static +# define XXH_NO_INLINE static +#endif + + + +/* ************************************* +* Debug +***************************************/ +/*! + * @ingroup tuning + * @def XXH_DEBUGLEVEL + * @brief Sets the debugging level. + * + * XXH_DEBUGLEVEL is expected to be defined externally, typically via the + * compiler's command line options. The value must be a number. + */ +#ifndef XXH_DEBUGLEVEL +# ifdef DEBUGLEVEL /* backwards compat */ +# define XXH_DEBUGLEVEL DEBUGLEVEL +# else +# define XXH_DEBUGLEVEL 0 +# endif +#endif + +#if (XXH_DEBUGLEVEL>=1) +# include /* note: can still be disabled with NDEBUG */ +# define XXH_ASSERT(c) assert(c) +#else +# define XXH_ASSERT(c) ((void)0) +#endif + +/* note: use after variable declarations */ +#ifndef XXH_STATIC_ASSERT +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +# include +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0) +# elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */ +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0) +# else +# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0) +# endif +# define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c) +#endif + +/*! + * @internal + * @def XXH_COMPILER_GUARD(var) + * @brief Used to prevent unwanted optimizations for @p var. + * + * It uses an empty GCC inline assembly statement with a register constraint + * which forces @p var into a general purpose register (eg eax, ebx, ecx + * on x86) and marks it as modified. + * + * This is used in a few places to avoid unwanted autovectorization (e.g. + * XXH32_round()). All vectorization we want is explicit via intrinsics, + * and _usually_ isn't wanted elsewhere. + * + * We also use it to prevent unwanted constant folding for AArch64 in + * XXH3_initCustomSecret_scalar(). + */ +#if defined(__GNUC__) || defined(__clang__) +# define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var)) +#else +# define XXH_COMPILER_GUARD(var) ((void)0) +#endif + +/* ************************************* +* Basic Types +***************************************/ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# include + typedef uint8_t xxh_u8; +#else + typedef unsigned char xxh_u8; +#endif +typedef XXH32_hash_t xxh_u32; + +#ifdef XXH_OLD_NAMES +# define BYTE xxh_u8 +# define U8 xxh_u8 +# define U32 xxh_u32 +#endif + +/* *** Memory access *** */ + +/*! + * @internal + * @fn xxh_u32 XXH_read32(const void* ptr) + * @brief Reads an unaligned 32-bit integer from @p ptr in native endianness. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * + * @param ptr The pointer to read from. + * @return The 32-bit native endian integer from the bytes at @p ptr. + */ + +/*! + * @internal + * @fn xxh_u32 XXH_readLE32(const void* ptr) + * @brief Reads an unaligned 32-bit little endian integer from @p ptr. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * + * @param ptr The pointer to read from. + * @return The 32-bit little endian integer from the bytes at @p ptr. + */ + +/*! + * @internal + * @fn xxh_u32 XXH_readBE32(const void* ptr) + * @brief Reads an unaligned 32-bit big endian integer from @p ptr. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * + * @param ptr The pointer to read from. + * @return The 32-bit big endian integer from the bytes at @p ptr. + */ + +/*! + * @internal + * @fn xxh_u32 XXH_readLE32_align(const void* ptr, XXH_alignment align) + * @brief Like @ref XXH_readLE32(), but has an option for aligned reads. + * + * Affected by @ref XXH_FORCE_MEMORY_ACCESS. + * Note that when @ref XXH_FORCE_ALIGN_CHECK == 0, the @p align parameter is + * always @ref XXH_alignment::XXH_unaligned. + * + * @param ptr The pointer to read from. + * @param align Whether @p ptr is aligned. + * @pre + * If @p align == @ref XXH_alignment::XXH_aligned, @p ptr must be 4 byte + * aligned. + * @return The 32-bit little endian integer from the bytes at @p ptr. + */ + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) +/* + * Manual byteshift. Best for old compilers which don't inline memcpy. + * We actually directly use XXH_readLE32 and XXH_readBE32. + */ +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* + * Force direct memory access. Only works on CPU which support unaligned memory + * access in hardware. + */ +static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; } + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* + * __pack instructions are safer but compiler specific, hence potentially + * problematic for some compilers. + * + * Currently only defined for GCC and ICC. + */ +#ifdef XXH_OLD_NAMES +typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +#endif +static xxh_u32 XXH_read32(const void* ptr) +{ + typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign; + return ((const xxh_unalign*)ptr)->u32; +} + +#else + +/* + * Portable and safe solution. Generally efficient. + * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html + */ +static xxh_u32 XXH_read32(const void* memPtr) +{ + xxh_u32 val; + XXH_memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + + +/* *** Endianness *** */ + +/*! + * @ingroup tuning + * @def XXH_CPU_LITTLE_ENDIAN + * @brief Whether the target is little endian. + * + * Defined to 1 if the target is little endian, or 0 if it is big endian. + * It can be defined externally, for example on the compiler command line. + * + * If it is not defined, + * a runtime check (which is usually constant folded) is used instead. + * + * @note + * This is not necessarily defined to an integer constant. + * + * @see XXH_isLittleEndian() for the runtime check. + */ +#ifndef XXH_CPU_LITTLE_ENDIAN +/* + * Try to detect endianness automatically, to avoid the nonstandard behavior + * in `XXH_isLittleEndian()` + */ +# if defined(_WIN32) /* Windows is always little endian */ \ + || defined(__LITTLE_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +# define XXH_CPU_LITTLE_ENDIAN 1 +# elif defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_CPU_LITTLE_ENDIAN 0 +# else +/*! + * @internal + * @brief Runtime check for @ref XXH_CPU_LITTLE_ENDIAN. + * + * Most compilers will constant fold this. + */ +static int XXH_isLittleEndian(void) +{ + /* + * Portable and well-defined behavior. + * Don't use static: it is detrimental to performance. + */ + const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 }; + return one.c[0]; +} +# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() +# endif +#endif + + + + +/* **************************************** +* Compiler-specific Functions and Macros +******************************************/ +#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) + +#ifdef __has_builtin +# define XXH_HAS_BUILTIN(x) __has_builtin(x) +#else +# define XXH_HAS_BUILTIN(x) 0 +#endif + +/*! + * @internal + * @def XXH_rotl32(x,r) + * @brief 32-bit rotate left. + * + * @param x The 32-bit integer to be rotated. + * @param r The number of bits to rotate. + * @pre + * @p r > 0 && @p r < 32 + * @note + * @p x and @p r may be evaluated multiple times. + * @return The rotated result. + */ +#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \ + && XXH_HAS_BUILTIN(__builtin_rotateleft64) +# define XXH_rotl32 __builtin_rotateleft32 +# define XXH_rotl64 __builtin_rotateleft64 +/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ +#elif defined(_MSC_VER) +# define XXH_rotl32(x,r) _rotl(x,r) +# define XXH_rotl64(x,r) _rotl64(x,r) +#else +# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r)))) +#endif + +/*! + * @internal + * @fn xxh_u32 XXH_swap32(xxh_u32 x) + * @brief A 32-bit byteswap. + * + * @param x The 32-bit integer to byteswap. + * @return @p x, byteswapped. + */ +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap32 _byteswap_ulong +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap32 __builtin_bswap32 +#else +static xxh_u32 XXH_swap32 (xxh_u32 x) +{ + return ((x << 24) & 0xff000000 ) | + ((x << 8) & 0x00ff0000 ) | + ((x >> 8) & 0x0000ff00 ) | + ((x >> 24) & 0x000000ff ); +} +#endif + + +/* *************************** +* Memory reads +*****************************/ + +/*! + * @internal + * @brief Enum to indicate whether a pointer is aligned. + */ +typedef enum { + XXH_aligned, /*!< Aligned */ + XXH_unaligned /*!< Possibly unaligned */ +} XXH_alignment; + +/* + * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. + * + * This is ideal for older compilers which don't inline memcpy. + */ +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) + +XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[0] + | ((xxh_u32)bytePtr[1] << 8) + | ((xxh_u32)bytePtr[2] << 16) + | ((xxh_u32)bytePtr[3] << 24); +} + +XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[3] + | ((xxh_u32)bytePtr[2] << 8) + | ((xxh_u32)bytePtr[1] << 16) + | ((xxh_u32)bytePtr[0] << 24); +} + +#else +XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); +} + +static xxh_u32 XXH_readBE32(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); +} +#endif + +XXH_FORCE_INLINE xxh_u32 +XXH_readLE32_align(const void* ptr, XXH_alignment align) +{ + if (align==XXH_unaligned) { + return XXH_readLE32(ptr); + } else { + return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr); + } +} + + +/* ************************************* +* Misc +***************************************/ +/*! @ingroup public */ +XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; } + + +/* ******************************************************************* +* 32-bit hash functions +*********************************************************************/ +/*! + * @} + * @defgroup xxh32_impl XXH32 implementation + * @ingroup impl + * @{ + */ + /* #define instead of static const, to be used as initializers */ +#define XXH_PRIME32_1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */ +#define XXH_PRIME32_2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */ +#define XXH_PRIME32_3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */ +#define XXH_PRIME32_4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */ +#define XXH_PRIME32_5 0x165667B1U /*!< 0b00010110010101100110011110110001 */ + +#ifdef XXH_OLD_NAMES +# define PRIME32_1 XXH_PRIME32_1 +# define PRIME32_2 XXH_PRIME32_2 +# define PRIME32_3 XXH_PRIME32_3 +# define PRIME32_4 XXH_PRIME32_4 +# define PRIME32_5 XXH_PRIME32_5 +#endif + +/*! + * @internal + * @brief Normal stripe processing routine. + * + * This shuffles the bits so that any bit from @p input impacts several bits in + * @p acc. + * + * @param acc The accumulator lane. + * @param input The stripe of input to mix. + * @return The mixed accumulator lane. + */ +static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) +{ + acc += input * XXH_PRIME32_2; + acc = XXH_rotl32(acc, 13); + acc *= XXH_PRIME32_1; +#if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * UGLY HACK: + * A compiler fence is the only thing that prevents GCC and Clang from + * autovectorizing the XXH32 loop (pragmas and attributes don't work for some + * reason) without globally disabling SSE4.1. + * + * The reason we want to avoid vectorization is because despite working on + * 4 integers at a time, there are multiple factors slowing XXH32 down on + * SSE4: + * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on + * newer chips!) making it slightly slower to multiply four integers at + * once compared to four integers independently. Even when pmulld was + * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE + * just to multiply unless doing a long operation. + * + * - Four instructions are required to rotate, + * movqda tmp, v // not required with VEX encoding + * pslld tmp, 13 // tmp <<= 13 + * psrld v, 19 // x >>= 19 + * por v, tmp // x |= tmp + * compared to one for scalar: + * roll v, 13 // reliably fast across the board + * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason + * + * - Instruction level parallelism is actually more beneficial here because + * the SIMD actually serializes this operation: While v1 is rotating, v2 + * can load data, while v3 can multiply. SSE forces them to operate + * together. + * + * This is also enabled on AArch64, as Clang autovectorizes it incorrectly + * and it is pointless writing a NEON implementation that is basically the + * same speed as scalar for XXH32. + */ + XXH_COMPILER_GUARD(acc); +#endif + return acc; +} + +/*! + * @internal + * @brief Mixes all bits to finalize the hash. + * + * The final mix ensures that all input bits have a chance to impact any bit in + * the output digest, resulting in an unbiased distribution. + * + * @param h32 The hash to avalanche. + * @return The avalanched hash. + */ +static xxh_u32 XXH32_avalanche(xxh_u32 h32) +{ + h32 ^= h32 >> 15; + h32 *= XXH_PRIME32_2; + h32 ^= h32 >> 13; + h32 *= XXH_PRIME32_3; + h32 ^= h32 >> 16; + return(h32); +} + +#define XXH_get32bits(p) XXH_readLE32_align(p, align) + +/*! + * @internal + * @brief Processes the last 0-15 bytes of @p ptr. + * + * There may be up to 15 bytes remaining to consume from the input. + * This final stage will digest them to ensure that all input bytes are present + * in the final mix. + * + * @param h32 The hash to finalize. + * @param ptr The pointer to the remaining input. + * @param len The remaining length, modulo 16. + * @param align Whether @p ptr is aligned. + * @return The finalized hash. + */ +static xxh_u32 +XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align) +{ +#define XXH_PROCESS1 do { \ + h32 += (*ptr++) * XXH_PRIME32_5; \ + h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \ +} while (0) + +#define XXH_PROCESS4 do { \ + h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \ + ptr += 4; \ + h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \ +} while (0) + + if (ptr==NULL) XXH_ASSERT(len == 0); + + /* Compact rerolled version; generally faster */ + if (!XXH32_ENDJMP) { + len &= 15; + while (len >= 4) { + XXH_PROCESS4; + len -= 4; + } + while (len > 0) { + XXH_PROCESS1; + --len; + } + return XXH32_avalanche(h32); + } else { + switch(len&15) /* or switch(bEnd - p) */ { + case 12: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 8: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 4: XXH_PROCESS4; + return XXH32_avalanche(h32); + + case 13: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 9: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 5: XXH_PROCESS4; + XXH_PROCESS1; + return XXH32_avalanche(h32); + + case 14: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 10: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 6: XXH_PROCESS4; + XXH_PROCESS1; + XXH_PROCESS1; + return XXH32_avalanche(h32); + + case 15: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 11: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 7: XXH_PROCESS4; + XXH_FALLTHROUGH; + case 3: XXH_PROCESS1; + XXH_FALLTHROUGH; + case 2: XXH_PROCESS1; + XXH_FALLTHROUGH; + case 1: XXH_PROCESS1; + XXH_FALLTHROUGH; + case 0: return XXH32_avalanche(h32); + } + XXH_ASSERT(0); + return h32; /* reaching this point is deemed impossible */ + } +} + +#ifdef XXH_OLD_NAMES +# define PROCESS1 XXH_PROCESS1 +# define PROCESS4 XXH_PROCESS4 +#else +# undef XXH_PROCESS1 +# undef XXH_PROCESS4 +#endif + +/*! + * @internal + * @brief The implementation for @ref XXH32(). + * + * @param input , len , seed Directly passed from @ref XXH32(). + * @param align Whether @p input is aligned. + * @return The calculated hash. + */ +XXH_FORCE_INLINE xxh_u32 +XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align) +{ + xxh_u32 h32; + + if (input==NULL) XXH_ASSERT(len == 0); + + if (len>=16) { + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + xxh_u32 v2 = seed + XXH_PRIME32_2; + xxh_u32 v3 = seed + 0; + xxh_u32 v4 = seed - XXH_PRIME32_1; + + do { + v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; + v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; + v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; + v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; + } while (input < limit); + + h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + } else { + h32 = seed + XXH_PRIME32_5; + } + + h32 += (xxh_u32)len; + + return XXH32_finalize(h32, input, len&15, align); +} + +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed) +{ +#if 0 + /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ + XXH32_state_t state; + XXH32_reset(&state, seed); + XXH32_update(&state, (const xxh_u8*)input, len); + return XXH32_digest(&state); +#else + if (XXH_FORCE_ALIGN_CHECK) { + if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ + return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned); + } } + + return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned); +#endif +} + + + +/******* Hash streaming *******/ +/*! + * @ingroup xxh32_family + */ +XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void) +{ + return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); +} +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) +{ + XXH_free(statePtr); + return XXH_OK; +} + +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState) +{ + XXH_memcpy(dstState, srcState, sizeof(*dstState)); +} + +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed) +{ + XXH_ASSERT(statePtr != NULL); + memset(statePtr, 0, sizeof(*statePtr)); + statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + statePtr->v[1] = seed + XXH_PRIME32_2; + statePtr->v[2] = seed + 0; + statePtr->v[3] = seed - XXH_PRIME32_1; + return XXH_OK; +} + + +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API XXH_errorcode +XXH32_update(XXH32_state_t* state, const void* input, size_t len) +{ + if (input==NULL) { + XXH_ASSERT(len == 0); + return XXH_OK; + } + + { const xxh_u8* p = (const xxh_u8*)input; + const xxh_u8* const bEnd = p + len; + + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + + if (state->memsize + len < 16) { /* fill in tmp buffer */ + XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); + state->memsize += (XXH32_hash_t)len; + return XXH_OK; + } + + if (state->memsize) { /* some data left from previous update */ + XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); + { const xxh_u32* p32 = state->mem32; + state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; + state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; + state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; + state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); + } + p += 16-state->memsize; + state->memsize = 0; + } + + if (p <= bEnd-16) { + const xxh_u8* const limit = bEnd - 16; + + do { + state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; + state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; + state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; + state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; + } while (p<=limit); + + } + + if (p < bEnd) { + XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + } + + return XXH_OK; +} + + +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) +{ + xxh_u32 h32; + + if (state->large_len) { + h32 = XXH_rotl32(state->v[0], 1) + + XXH_rotl32(state->v[1], 7) + + XXH_rotl32(state->v[2], 12) + + XXH_rotl32(state->v[3], 18); + } else { + h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + } + + h32 += state->total_len_32; + + return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); +} + + +/******* Canonical representation *******/ + +/*! + * @ingroup xxh32_family + * The default return values from XXH functions are unsigned 32 and 64 bit + * integers. + * + * The canonical representation uses big endian convention, the same convention + * as human-readable numbers (large digits first). + * + * This way, hash values can be written into a file or buffer, remaining + * comparable across different systems. + * + * The following functions allow transformation of hash values to and from their + * canonical format. + */ +XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); + XXH_memcpy(dst, &hash, sizeof(*dst)); +} +/*! @ingroup xxh32_family */ +XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src) +{ + return XXH_readBE32(src); +} + + +#ifndef XXH_NO_LONG_LONG + +/* ******************************************************************* +* 64-bit hash functions +*********************************************************************/ +/*! + * @} + * @ingroup impl + * @{ + */ +/******* Memory access *******/ + +typedef XXH64_hash_t xxh_u64; + +#ifdef XXH_OLD_NAMES +# define U64 xxh_u64 +#endif + +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) +/* + * Manual byteshift. Best for old compilers which don't inline memcpy. + * We actually directly use XXH_readLE64 and XXH_readBE64. + */ +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) + +/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ +static xxh_u64 XXH_read64(const void* memPtr) +{ + return *(const xxh_u64*) memPtr; +} + +#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) + +/* + * __pack instructions are safer, but compiler specific, hence potentially + * problematic for some compilers. + * + * Currently only defined for GCC and ICC. + */ +#ifdef XXH_OLD_NAMES +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +#endif +static xxh_u64 XXH_read64(const void* ptr) +{ + typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64; + return ((const xxh_unalign64*)ptr)->u64; +} + +#else + +/* + * Portable and safe solution. Generally efficient. + * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html + */ +static xxh_u64 XXH_read64(const void* memPtr) +{ + xxh_u64 val; + XXH_memcpy(&val, memPtr, sizeof(val)); + return val; +} + +#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ + +#if defined(_MSC_VER) /* Visual Studio */ +# define XXH_swap64 _byteswap_uint64 +#elif XXH_GCC_VERSION >= 403 +# define XXH_swap64 __builtin_bswap64 +#else +static xxh_u64 XXH_swap64(xxh_u64 x) +{ + return ((x << 56) & 0xff00000000000000ULL) | + ((x << 40) & 0x00ff000000000000ULL) | + ((x << 24) & 0x0000ff0000000000ULL) | + ((x << 8) & 0x000000ff00000000ULL) | + ((x >> 8) & 0x00000000ff000000ULL) | + ((x >> 24) & 0x0000000000ff0000ULL) | + ((x >> 40) & 0x000000000000ff00ULL) | + ((x >> 56) & 0x00000000000000ffULL); +} +#endif + + +/* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */ +#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3)) + +XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[0] + | ((xxh_u64)bytePtr[1] << 8) + | ((xxh_u64)bytePtr[2] << 16) + | ((xxh_u64)bytePtr[3] << 24) + | ((xxh_u64)bytePtr[4] << 32) + | ((xxh_u64)bytePtr[5] << 40) + | ((xxh_u64)bytePtr[6] << 48) + | ((xxh_u64)bytePtr[7] << 56); +} + +XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr) +{ + const xxh_u8* bytePtr = (const xxh_u8 *)memPtr; + return bytePtr[7] + | ((xxh_u64)bytePtr[6] << 8) + | ((xxh_u64)bytePtr[5] << 16) + | ((xxh_u64)bytePtr[4] << 24) + | ((xxh_u64)bytePtr[3] << 32) + | ((xxh_u64)bytePtr[2] << 40) + | ((xxh_u64)bytePtr[1] << 48) + | ((xxh_u64)bytePtr[0] << 56); +} + +#else +XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); +} + +static xxh_u64 XXH_readBE64(const void* ptr) +{ + return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); +} +#endif + +XXH_FORCE_INLINE xxh_u64 +XXH_readLE64_align(const void* ptr, XXH_alignment align) +{ + if (align==XXH_unaligned) + return XXH_readLE64(ptr); + else + return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr); +} + + +/******* xxh64 *******/ +/*! + * @} + * @defgroup xxh64_impl XXH64 implementation + * @ingroup impl + * @{ + */ +/* #define rather that static const, to be used as initializers */ +#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL /*!< 0b1001111000110111011110011011000110000101111010111100101010000111 */ +#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL /*!< 0b1100001010110010101011100011110100100111110101001110101101001111 */ +#define XXH_PRIME64_3 0x165667B19E3779F9ULL /*!< 0b0001011001010110011001111011000110011110001101110111100111111001 */ +#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL /*!< 0b1000010111101011110010100111011111000010101100101010111001100011 */ +#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL /*!< 0b0010011111010100111010110010111100010110010101100110011111000101 */ + +#ifdef XXH_OLD_NAMES +# define PRIME64_1 XXH_PRIME64_1 +# define PRIME64_2 XXH_PRIME64_2 +# define PRIME64_3 XXH_PRIME64_3 +# define PRIME64_4 XXH_PRIME64_4 +# define PRIME64_5 XXH_PRIME64_5 +#endif + +static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) +{ + acc += input * XXH_PRIME64_2; + acc = XXH_rotl64(acc, 31); + acc *= XXH_PRIME64_1; + return acc; +} + +static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val) +{ + val = XXH64_round(0, val); + acc ^= val; + acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4; + return acc; +} + +static xxh_u64 XXH64_avalanche(xxh_u64 h64) +{ + h64 ^= h64 >> 33; + h64 *= XXH_PRIME64_2; + h64 ^= h64 >> 29; + h64 *= XXH_PRIME64_3; + h64 ^= h64 >> 32; + return h64; +} + + +#define XXH_get64bits(p) XXH_readLE64_align(p, align) + +static xxh_u64 +XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align) +{ + if (ptr==NULL) XXH_ASSERT(len == 0); + len &= 31; + while (len >= 8) { + xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr)); + ptr += 8; + h64 ^= k1; + h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4; + len -= 8; + } + if (len >= 4) { + h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1; + ptr += 4; + h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3; + len -= 4; + } + while (len > 0) { + h64 ^= (*ptr++) * XXH_PRIME64_5; + h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1; + --len; + } + return XXH64_avalanche(h64); +} + +#ifdef XXH_OLD_NAMES +# define PROCESS1_64 XXH_PROCESS1_64 +# define PROCESS4_64 XXH_PROCESS4_64 +# define PROCESS8_64 XXH_PROCESS8_64 +#else +# undef XXH_PROCESS1_64 +# undef XXH_PROCESS4_64 +# undef XXH_PROCESS8_64 +#endif + +XXH_FORCE_INLINE xxh_u64 +XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align) +{ + xxh_u64 h64; + if (input==NULL) XXH_ASSERT(len == 0); + + if (len>=32) { + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + xxh_u64 v2 = seed + XXH_PRIME64_2; + xxh_u64 v3 = seed + 0; + xxh_u64 v4 = seed - XXH_PRIME64_1; + + do { + v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; + v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; + v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; + v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; + } while (inputv[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + statePtr->v[1] = seed + XXH_PRIME64_2; + statePtr->v[2] = seed + 0; + statePtr->v[3] = seed - XXH_PRIME64_1; + return XXH_OK; +} + +/*! @ingroup xxh64_family */ +XXH_PUBLIC_API XXH_errorcode +XXH64_update (XXH64_state_t* state, const void* input, size_t len) +{ + if (input==NULL) { + XXH_ASSERT(len == 0); + return XXH_OK; + } + + { const xxh_u8* p = (const xxh_u8*)input; + const xxh_u8* const bEnd = p + len; + + state->total_len += len; + + if (state->memsize + len < 32) { /* fill in tmp buffer */ + XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); + state->memsize += (xxh_u32)len; + return XXH_OK; + } + + if (state->memsize) { /* tmp buffer is full */ + XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); + state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); + state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); + state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); + state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); + p += 32 - state->memsize; + state->memsize = 0; + } + + if (p+32 <= bEnd) { + const xxh_u8* const limit = bEnd - 32; + + do { + state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; + state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; + state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; + state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; + } while (p<=limit); + + } + + if (p < bEnd) { + XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); + state->memsize = (unsigned)(bEnd-p); + } + } + + return XXH_OK; +} + + +/*! @ingroup xxh64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state) +{ + xxh_u64 h64; + + if (state->total_len >= 32) { + h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); + h64 = XXH64_mergeRound(h64, state->v[0]); + h64 = XXH64_mergeRound(h64, state->v[1]); + h64 = XXH64_mergeRound(h64, state->v[2]); + h64 = XXH64_mergeRound(h64, state->v[3]); + } else { + h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + } + + h64 += (xxh_u64) state->total_len; + + return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); +} + + +/******* Canonical representation *******/ + +/*! @ingroup xxh64_family */ +XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); + XXH_memcpy(dst, &hash, sizeof(*dst)); +} + +/*! @ingroup xxh64_family */ +XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src) +{ + return XXH_readBE64(src); +} + +#ifndef XXH_NO_XXH3 + +/* ********************************************************************* +* XXH3 +* New generation hash designed for speed on small keys and vectorization +************************************************************************ */ +/*! + * @} + * @defgroup xxh3_impl XXH3 implementation + * @ingroup impl + * @{ + */ + +/* === Compiler specifics === */ + +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#else +/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */ +# define XXH_RESTRICT /* disable */ +#endif + +#if (defined(__GNUC__) && (__GNUC__ >= 3)) \ + || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ + || defined(__clang__) +# define XXH_likely(x) __builtin_expect(x, 1) +# define XXH_unlikely(x) __builtin_expect(x, 0) +#else +# define XXH_likely(x) (x) +# define XXH_unlikely(x) (x) +#endif + +#if defined(__GNUC__) || defined(__clang__) +# if defined(__ARM_NEON__) || defined(__ARM_NEON) \ + || defined(__aarch64__) || defined(_M_ARM) \ + || defined(_M_ARM64) || defined(_M_ARM64EC) +# define inline __inline__ /* circumvent a clang bug */ +# include +# undef inline +# elif defined(__AVX2__) +# include +# elif defined(__SSE2__) +# include +# endif +#endif + +#if defined(_MSC_VER) +# include +#endif + +/* + * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while + * remaining a true 64-bit/128-bit hash function. + * + * This is done by prioritizing a subset of 64-bit operations that can be + * emulated without too many steps on the average 32-bit machine. + * + * For example, these two lines seem similar, and run equally fast on 64-bit: + * + * xxh_u64 x; + * x ^= (x >> 47); // good + * x ^= (x >> 13); // bad + * + * However, to a 32-bit machine, there is a major difference. + * + * x ^= (x >> 47) looks like this: + * + * x.lo ^= (x.hi >> (47 - 32)); + * + * while x ^= (x >> 13) looks like this: + * + * // note: funnel shifts are not usually cheap. + * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13)); + * x.hi ^= (x.hi >> 13); + * + * The first one is significantly faster than the second, simply because the + * shift is larger than 32. This means: + * - All the bits we need are in the upper 32 bits, so we can ignore the lower + * 32 bits in the shift. + * - The shift result will always fit in the lower 32 bits, and therefore, + * we can ignore the upper 32 bits in the xor. + * + * Thanks to this optimization, XXH3 only requires these features to be efficient: + * + * - Usable unaligned access + * - A 32-bit or 64-bit ALU + * - If 32-bit, a decent ADC instruction + * - A 32 or 64-bit multiply with a 64-bit result + * - For the 128-bit variant, a decent byteswap helps short inputs. + * + * The first two are already required by XXH32, and almost all 32-bit and 64-bit + * platforms which can run XXH32 can run XXH3 efficiently. + * + * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one + * notable exception. + * + * First of all, Thumb-1 lacks support for the UMULL instruction which + * performs the important long multiply. This means numerous __aeabi_lmul + * calls. + * + * Second of all, the 8 functional registers are just not enough. + * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need + * Lo registers, and this shuffling results in thousands more MOVs than A32. + * + * A32 and T32 don't have this limitation. They can access all 14 registers, + * do a 32->64 multiply with UMULL, and the flexible operand allowing free + * shifts is helpful, too. + * + * Therefore, we do a quick sanity check. + * + * If compiling Thumb-1 for a target which supports ARM instructions, we will + * emit a warning, as it is not a "sane" platform to compile for. + * + * Usually, if this happens, it is because of an accident and you probably need + * to specify -march, as you likely meant to compile for a newer architecture. + * + * Credit: large sections of the vectorial and asm source code paths + * have been contributed by @easyaspi314 + */ +#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM) +# warning "XXH3 is highly inefficient without ARM or Thumb-2." +#endif + +/* ========================================== + * Vectorization detection + * ========================================== */ + +#ifdef XXH_DOXYGEN +/*! + * @ingroup tuning + * @brief Overrides the vectorization implementation chosen for XXH3. + * + * Can be defined to 0 to disable SIMD or any of the values mentioned in + * @ref XXH_VECTOR_TYPE. + * + * If this is not defined, it uses predefined macros to determine the best + * implementation. + */ +# define XXH_VECTOR XXH_SCALAR +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Note that these are actually implemented as macros. + * + * If this is not defined, it is detected automatically. + * @ref XXH_X86DISPATCH overrides this. + */ +enum XXH_VECTOR_TYPE /* fake enum */ { + XXH_SCALAR = 0, /*!< Portable scalar version */ + XXH_SSE2 = 1, /*!< + * SSE2 for Pentium 4, Opteron, all x86_64. + * + * @note SSE2 is also guaranteed on Windows 10, macOS, and + * Android x86. + */ + XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ + XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ + XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */ + XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ +}; +/*! + * @ingroup tuning + * @brief Selects the minimum alignment for XXH3's accumulators. + * + * When using SIMD, this should match the alignment reqired for said vector + * type, so, for example, 32 for AVX2. + * + * Default: Auto detected. + */ +# define XXH_ACC_ALIGN 8 +#endif + +/* Actual definition */ +#ifndef XXH_DOXYGEN +# define XXH_SCALAR 0 +# define XXH_SSE2 1 +# define XXH_AVX2 2 +# define XXH_AVX512 3 +# define XXH_NEON 4 +# define XXH_VSX 5 +#endif + +#ifndef XXH_VECTOR /* can be defined on command line */ +# if ( \ + defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \ + || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \ + ) && ( \ + defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ + ) +# define XXH_VECTOR XXH_NEON +# elif defined(__AVX512F__) +# define XXH_VECTOR XXH_AVX512 +# elif defined(__AVX2__) +# define XXH_VECTOR XXH_AVX2 +# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2)) +# define XXH_VECTOR XXH_SSE2 +# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \ + || (defined(__s390x__) && defined(__VEC__)) \ + && defined(__GNUC__) /* TODO: IBM XL */ +# define XXH_VECTOR XXH_VSX +# else +# define XXH_VECTOR XXH_SCALAR +# endif +#endif + +/* + * Controls the alignment of the accumulator, + * for compatibility with aligned vector loads, which are usually faster. + */ +#ifndef XXH_ACC_ALIGN +# if defined(XXH_X86DISPATCH) +# define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */ +# elif XXH_VECTOR == XXH_SCALAR /* scalar */ +# define XXH_ACC_ALIGN 8 +# elif XXH_VECTOR == XXH_SSE2 /* sse2 */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX2 /* avx2 */ +# define XXH_ACC_ALIGN 32 +# elif XXH_VECTOR == XXH_NEON /* neon */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_VSX /* vsx */ +# define XXH_ACC_ALIGN 16 +# elif XXH_VECTOR == XXH_AVX512 /* avx512 */ +# define XXH_ACC_ALIGN 64 +# endif +#endif + +#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \ + || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512 +# define XXH_SEC_ALIGN XXH_ACC_ALIGN +#else +# define XXH_SEC_ALIGN 8 +#endif + +/* + * UGLY HACK: + * GCC usually generates the best code with -O3 for xxHash. + * + * However, when targeting AVX2, it is overzealous in its unrolling resulting + * in code roughly 3/4 the speed of Clang. + * + * There are other issues, such as GCC splitting _mm256_loadu_si256 into + * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which + * only applies to Sandy and Ivy Bridge... which don't even support AVX2. + * + * That is why when compiling the AVX2 version, it is recommended to use either + * -O2 -mavx2 -march=haswell + * or + * -O2 -mavx2 -mno-avx256-split-unaligned-load + * for decent performance, or to use Clang instead. + * + * Fortunately, we can control the first one with a pragma that forces GCC into + * -O2, but the other one we can't control without "failed to inline always + * inline function due to target mismatch" warnings. + */ +#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \ + && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */ +# pragma GCC push_options +# pragma GCC optimize("-O2") +#endif + + +#if XXH_VECTOR == XXH_NEON +/* + * NEON's setup for vmlal_u32 is a little more complicated than it is on + * SSE2, AVX2, and VSX. + * + * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast. + * + * To do the same operation, the 128-bit 'Q' register needs to be split into + * two 64-bit 'D' registers, performing this operation:: + * + * [ a | b ] + * | '---------. .--------' | + * | x | + * | .---------' '--------. | + * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ] + * + * Due to significant changes in aarch64, the fastest method for aarch64 is + * completely different than the fastest method for ARMv7-A. + * + * ARMv7-A treats D registers as unions overlaying Q registers, so modifying + * D11 will modify the high half of Q5. This is similar to how modifying AH + * will only affect bits 8-15 of AX on x86. + * + * VZIP takes two registers, and puts even lanes in one register and odd lanes + * in the other. + * + * On ARMv7-A, this strangely modifies both parameters in place instead of + * taking the usual 3-operand form. + * + * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the + * lower and upper halves of the Q register to end up with the high and low + * halves where we want - all in one instruction. + * + * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] } + * + * Unfortunately we need inline assembly for this: Instructions modifying two + * registers at once is not possible in GCC or Clang's IR, and they have to + * create a copy. + * + * aarch64 requires a different approach. + * + * In order to make it easier to write a decent compiler for aarch64, many + * quirks were removed, such as conditional execution. + * + * NEON was also affected by this. + * + * aarch64 cannot access the high bits of a Q-form register, and writes to a + * D-form register zero the high bits, similar to how writes to W-form scalar + * registers (or DWORD registers on x86_64) work. + * + * The formerly free vget_high intrinsics now require a vext (with a few + * exceptions) + * + * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent + * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one + * operand. + * + * The equivalent of the VZIP.32 on the lower and upper halves would be this + * mess: + * + * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] } + * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] } + * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] } + * + * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN): + * + * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32); + * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF); + * + * This is available on ARMv7-A, but is less efficient than a single VZIP.32. + */ + +/*! + * Function-like macro: + * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi) + * { + * outLo = (uint32x2_t)(in & 0xFFFFFFFF); + * outHi = (uint32x2_t)(in >> 32); + * in = UNDEFINED; + * } + */ +# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \ + && (defined(__GNUC__) || defined(__clang__)) \ + && (defined(__arm__) || defined(__thumb__) || defined(_M_ARM)) +# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ + do { \ + /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \ + /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \ + /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \ + __asm__("vzip.32 %e0, %f0" : "+w" (in)); \ + (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \ + (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \ + } while (0) +# else +# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \ + do { \ + (outLo) = vmovn_u64 (in); \ + (outHi) = vshrn_n_u64 ((in), 32); \ + } while (0) +# endif + +/*! + * @ingroup tuning + * @brief Controls the NEON to scalar ratio for XXH3 + * + * On AArch64 when not optimizing for size, XXH3 will run 6 lanes using NEON and + * 2 lanes on scalar by default. + * + * This can be set to 2, 4, 6, or 8. ARMv7 will default to all 8 NEON lanes, as the + * emulated 64-bit arithmetic is too slow. + * + * Modern ARM CPUs are _very_ sensitive to how their pipelines are used. + * + * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but it can't + * have more than 2 NEON (F0/F1) micro-ops. If you are only using NEON instructions, + * you are only using 2/3 of the CPU bandwidth. + * + * This is even more noticable on the more advanced cores like the A76 which + * can dispatch 8 micro-ops per cycle, but still only 2 NEON micro-ops at once. + * + * Therefore, @ref XXH3_NEON_LANES lanes will be processed using NEON, and the + * remaining lanes will use scalar instructions. This improves the bandwidth + * and also gives the integer pipelines something to do besides twiddling loop + * counters and pointers. + * + * This change benefits CPUs with large micro-op buffers without negatively affecting + * other CPUs: + * + * | Chipset | Dispatch type | NEON only | 6:2 hybrid | Diff. | + * |:----------------------|:--------------------|----------:|-----------:|------:| + * | Snapdragon 730 (A76) | 2 NEON/8 micro-ops | 8.8 GB/s | 10.1 GB/s | ~16% | + * | Snapdragon 835 (A73) | 2 NEON/3 micro-ops | 5.1 GB/s | 5.3 GB/s | ~5% | + * | Marvell PXA1928 (A53) | In-order dual-issue | 1.9 GB/s | 1.9 GB/s | 0% | + * + * It also seems to fix some bad codegen on GCC, making it almost as fast as clang. + * + * @see XXH3_accumulate_512_neon() + */ +# ifndef XXH3_NEON_LANES +# if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \ + && !defined(__OPTIMIZE_SIZE__) +# define XXH3_NEON_LANES 6 +# else +# define XXH3_NEON_LANES XXH_ACC_NB +# endif +# endif +#endif /* XXH_VECTOR == XXH_NEON */ + +/* + * VSX and Z Vector helpers. + * + * This is very messy, and any pull requests to clean this up are welcome. + * + * There are a lot of problems with supporting VSX and s390x, due to + * inconsistent intrinsics, spotty coverage, and multiple endiannesses. + */ +#if XXH_VECTOR == XXH_VSX +# if defined(__s390x__) +# include +# else +/* gcc's altivec.h can have the unwanted consequence to unconditionally + * #define bool, vector, and pixel keywords, + * with bad consequences for programs already using these keywords for other purposes. + * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined. + * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler, + * but it seems that, in some cases, it isn't. + * Force the build macro to be defined, so that keywords are not altered. + */ +# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__) +# define __APPLE_ALTIVEC__ +# endif +# include # endif -#endif /* XXH_STATIC_LINKING_ONLY && XXH_STATIC_H_3543687687345 */ +typedef __vector unsigned long long xxh_u64x2; +typedef __vector unsigned char xxh_u8x16; +typedef __vector unsigned xxh_u32x4; + +# ifndef XXH_VSX_BE +# if defined(__BIG_ENDIAN__) \ + || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +# define XXH_VSX_BE 1 +# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__ +# warning "-maltivec=be is not recommended. Please use native endianness." +# define XXH_VSX_BE 1 +# else +# define XXH_VSX_BE 0 +# endif +# endif /* !defined(XXH_VSX_BE) */ + +# if XXH_VSX_BE +# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__)) +# define XXH_vec_revb vec_revb +# else +/*! + * A polyfill for POWER9's vec_revb(). + */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val) +{ + xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, + 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 }; + return vec_perm(val, val, vByteSwap); +} +# endif +# endif /* XXH_VSX_BE */ + +/*! + * Performs an unaligned vector load and byte swaps it on big endian. + */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr) +{ + xxh_u64x2 ret; + XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2)); +# if XXH_VSX_BE + ret = XXH_vec_revb(ret); +# endif + return ret; +} + +/* + * vec_mulo and vec_mule are very problematic intrinsics on PowerPC + * + * These intrinsics weren't added until GCC 8, despite existing for a while, + * and they are endian dependent. Also, their meaning swap depending on version. + * */ +# if defined(__s390x__) + /* s390x is always big endian, no issue on this platform */ +# define XXH_vec_mulo vec_mulo +# define XXH_vec_mule vec_mule +# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw) +/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */ +# define XXH_vec_mulo __builtin_altivec_vmulouw +# define XXH_vec_mule __builtin_altivec_vmuleuw +# else +/* gcc needs inline assembly */ +/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */ +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b) +{ + xxh_u64x2 result; + __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b)); + return result; +} +# endif /* XXH_vec_mulo, XXH_vec_mule */ +#endif /* XXH_VECTOR == XXH_VSX */ + + +/* prefetch + * can be disabled, by declaring XXH_NO_PREFETCH build macro */ +#if defined(XXH_NO_PREFETCH) +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# else +# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */ +# endif +#endif /* XXH_NO_PREFETCH */ + + +/* ========================================== + * XXH3 default settings + * ========================================== */ + +#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */ + +#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN) +# error "default keyset is not large enough" +#endif + +/*! Pseudorandom secret taken directly from FARSH. */ +XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = { + 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, + 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, + 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, + 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, + 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, + 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, + 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, + 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, + 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, + 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, + 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, + 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e, +}; + + +#ifdef XXH_OLD_NAMES +# define kSecret XXH3_kSecret +#endif + +#ifdef XXH_DOXYGEN +/*! + * @brief Calculates a 32-bit to 64-bit long multiply. + * + * Implemented as a macro. + * + * Wraps `__emulu` on MSVC x86 because it tends to call `__allmul` when it doesn't + * need to (but it shouldn't need to anyways, it is about 7 instructions to do + * a 64x64 multiply...). Since we know that this will _always_ emit `MULL`, we + * use that instead of the normal method. + * + * If you are compiling for platforms like Thumb-1 and don't have a better option, + * you may also want to write your own long multiply routine here. + * + * @param x, y Numbers to be multiplied + * @return 64-bit product of the low 32 bits of @p x and @p y. + */ +XXH_FORCE_INLINE xxh_u64 +XXH_mult32to64(xxh_u64 x, xxh_u64 y) +{ + return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF); +} +#elif defined(_MSC_VER) && defined(_M_IX86) +# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y)) +#else +/* + * Downcast + upcast is usually better than masking on older compilers like + * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers. + * + * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands + * and perform a full 64x64 multiply -- entirely redundant on 32-bit. + */ +# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y)) +#endif + +/*! + * @brief Calculates a 64->128-bit long multiply. + * + * Uses `__uint128_t` and `_umul128` if available, otherwise uses a scalar + * version. + * + * @param lhs , rhs The 64-bit integers to be multiplied + * @return The 128-bit result represented in an @ref XXH128_hash_t. + */ +static XXH128_hash_t +XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs) +{ + /* + * GCC/Clang __uint128_t method. + * + * On most 64-bit targets, GCC and Clang define a __uint128_t type. + * This is usually the best way as it usually uses a native long 64-bit + * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64. + * + * Usually. + * + * Despite being a 32-bit platform, Clang (and emscripten) define this type + * despite not having the arithmetic for it. This results in a laggy + * compiler builtin call which calculates a full 128-bit multiply. + * In that case it is best to use the portable one. + * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677 + */ +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \ + && defined(__SIZEOF_INT128__) \ + || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128) + + __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs; + XXH128_hash_t r128; + r128.low64 = (xxh_u64)(product); + r128.high64 = (xxh_u64)(product >> 64); + return r128; + + /* + * MSVC for x64's _umul128 method. + * + * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct); + * + * This compiles to single operand MUL on x64. + */ +#elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC) + +#ifndef _MSC_VER +# pragma intrinsic(_umul128) +#endif + xxh_u64 product_high; + xxh_u64 const product_low = _umul128(lhs, rhs, &product_high); + XXH128_hash_t r128; + r128.low64 = product_low; + r128.high64 = product_high; + return r128; + + /* + * MSVC for ARM64's __umulh method. + * + * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method. + */ +#elif defined(_M_ARM64) || defined(_M_ARM64EC) + +#ifndef _MSC_VER +# pragma intrinsic(__umulh) +#endif + XXH128_hash_t r128; + r128.low64 = lhs * rhs; + r128.high64 = __umulh(lhs, rhs); + return r128; + +#else + /* + * Portable scalar method. Optimized for 32-bit and 64-bit ALUs. + * + * This is a fast and simple grade school multiply, which is shown below + * with base 10 arithmetic instead of base 0x100000000. + * + * 9 3 // D2 lhs = 93 + * x 7 5 // D2 rhs = 75 + * ---------- + * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15 + * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45 + * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21 + * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63 + * --------- + * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27 + * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67 + * --------- + * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975 + * + * The reasons for adding the products like this are: + * 1. It avoids manual carry tracking. Just like how + * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX. + * This avoids a lot of complexity. + * + * 2. It hints for, and on Clang, compiles to, the powerful UMAAL + * instruction available in ARM's Digital Signal Processing extension + * in 32-bit ARMv6 and later, which is shown below: + * + * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm) + * { + * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm; + * *RdLo = (xxh_u32)(product & 0xFFFFFFFF); + * *RdHi = (xxh_u32)(product >> 32); + * } + * + * This instruction was designed for efficient long multiplication, and + * allows this to be calculated in only 4 instructions at speeds + * comparable to some 64-bit ALUs. + * + * 3. It isn't terrible on other platforms. Usually this will be a couple + * of 32-bit ADD/ADCs. + */ + + /* First calculate all of the cross products. */ + xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF); + xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF); + xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32); + xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32); + + /* Now add the products together. These will never overflow. */ + xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi; + xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi; + xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF); + + XXH128_hash_t r128; + r128.low64 = lower; + r128.high64 = upper; + return r128; +#endif +} + +/*! + * @brief Calculates a 64-bit to 128-bit multiply, then XOR folds it. + * + * The reason for the separate function is to prevent passing too many structs + * around by value. This will hopefully inline the multiply, but we don't force it. + * + * @param lhs , rhs The 64-bit integers to multiply + * @return The low 64 bits of the product XOR'd by the high 64 bits. + * @see XXH_mult64to128() + */ +static xxh_u64 +XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs) +{ + XXH128_hash_t product = XXH_mult64to128(lhs, rhs); + return product.low64 ^ product.high64; +} + +/*! Seems to produce slightly better code on GCC for some reason. */ +XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift) +{ + XXH_ASSERT(0 <= shift && shift < 64); + return v64 ^ (v64 >> shift); +} + +/* + * This is a fast avalanche stage, + * suitable when input bits are already partially mixed + */ +static XXH64_hash_t XXH3_avalanche(xxh_u64 h64) +{ + h64 = XXH_xorshift64(h64, 37); + h64 *= 0x165667919E3779F9ULL; + h64 = XXH_xorshift64(h64, 32); + return h64; +} + +/* + * This is a stronger avalanche, + * inspired by Pelle Evensen's rrmxmx + * preferable when input has not been previously mixed + */ +static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len) +{ + /* this mix is inspired by Pelle Evensen's rrmxmx */ + h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24); + h64 *= 0x9FB21C651E98DF25ULL; + h64 ^= (h64 >> 35) + len ; + h64 *= 0x9FB21C651E98DF25ULL; + return XXH_xorshift64(h64, 28); +} + + +/* ========================================== + * Short keys + * ========================================== + * One of the shortcomings of XXH32 and XXH64 was that their performance was + * sub-optimal on short lengths. It used an iterative algorithm which strongly + * favored lengths that were a multiple of 4 or 8. + * + * Instead of iterating over individual inputs, we use a set of single shot + * functions which piece together a range of lengths and operate in constant time. + * + * Additionally, the number of multiplies has been significantly reduced. This + * reduces latency, especially when emulating 64-bit multiplies on 32-bit. + * + * Depending on the platform, this may or may not be faster than XXH32, but it + * is almost guaranteed to be faster than XXH64. + */ + +/* + * At very short lengths, there isn't enough input to fully hide secrets, or use + * the entire secret. + * + * There is also only a limited amount of mixing we can do before significantly + * impacting performance. + * + * Therefore, we use different sections of the secret and always mix two secret + * samples with an XOR. This should have no effect on performance on the + * seedless or withSeed variants because everything _should_ be constant folded + * by modern compilers. + * + * The XOR mixing hides individual parts of the secret and increases entropy. + * + * This adds an extra layer of strength for custom secrets. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combined = { input[0], 0x01, input[0], input[0] } + * len = 2: combined = { input[1], 0x02, input[0], input[1] } + * len = 3: combined = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const keyed = (xxh_u64)combined ^ bitflip; + return XXH64_avalanche(keyed); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len <= 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input1 = XXH_readLE32(input); + xxh_u32 const input2 = XXH_readLE32(input + len - 4); + xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed; + xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32); + xxh_u64 const keyed = input64 ^ bitflip; + return XXH3_rrmxmx(keyed, len); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(9 <= len && len <= 16); + { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed; + xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed; + xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1; + xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2; + xxh_u64 const acc = len + + XXH_swap64(input_lo) + input_hi + + XXH3_mul128_fold64(input_lo, input_hi); + return XXH3_avalanche(acc); + } +} + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed); + if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed); + if (len) return XXH3_len_1to3_64b(input, len, secret, seed); + return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64))); + } +} + +/* + * DISCLAIMER: There are known *seed-dependent* multicollisions here due to + * multiplication by zero, affecting hashes of lengths 17 to 240. + * + * However, they are very unlikely. + * + * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all + * unseeded non-cryptographic hashes, it does not attempt to defend itself + * against specially crafted inputs, only random inputs. + * + * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes + * cancelling out the secret is taken an arbitrary number of times (addressed + * in XXH3_accumulate_512), this collision is very unlikely with random inputs + * and/or proper seeding: + * + * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a + * function that is only called up to 16 times per hash with up to 240 bytes of + * input. + * + * This is not too bad for a non-cryptographic hash function, especially with + * only 64 bit outputs. + * + * The 128-bit variant (which trades some speed for strength) is NOT affected + * by this, although it is always a good idea to use a proper seed if you care + * about strength. + */ +XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64) +{ +#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \ + && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */ + /* + * UGLY HACK: + * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in + * slower code. + * + * By forcing seed64 into a register, we disrupt the cost model and + * cause it to scalarize. See `XXH32_round()` + * + * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600, + * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on + * GCC 9.2, despite both emitting scalar code. + * + * GCC generates much better scalar code than Clang for the rest of XXH3, + * which is why finding a more optimal codepath is an interest. + */ + XXH_COMPILER_GUARD(seed64); +#endif + { xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 const input_hi = XXH_readLE64(input+8); + return XXH3_mul128_fold64( + input_lo ^ (XXH_readLE64(secret) + seed64), + input_hi ^ (XXH_readLE64(secret+8) - seed64) + ); + } +} + +/* For mid range keys, XXH3 uses a Mum-hash variant. */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { xxh_u64 acc = len * XXH_PRIME64_1; + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc += XXH3_mix16B(input+48, secret+96, seed); + acc += XXH3_mix16B(input+len-64, secret+112, seed); + } + acc += XXH3_mix16B(input+32, secret+64, seed); + acc += XXH3_mix16B(input+len-48, secret+80, seed); + } + acc += XXH3_mix16B(input+16, secret+32, seed); + acc += XXH3_mix16B(input+len-32, secret+48, seed); + } + acc += XXH3_mix16B(input+0, secret+0, seed); + acc += XXH3_mix16B(input+len-16, secret+16, seed); + + return XXH3_avalanche(acc); + } +} + +#define XXH3_MIDSIZE_MAX 240 + +XXH_NO_INLINE XXH64_hash_t +XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + #define XXH3_MIDSIZE_STARTOFFSET 3 + #define XXH3_MIDSIZE_LASTOFFSET 17 + + { xxh_u64 acc = len * XXH_PRIME64_1; + int const nbRounds = (int)len / 16; + int i; + for (i=0; i<8; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed); + } + acc = XXH3_avalanche(acc); + XXH_ASSERT(nbRounds >= 8); +#if defined(__clang__) /* Clang */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86. + * In everywhere else, it uses scalar code. + * + * For 64->128-bit multiplies, even if the NEON was 100% optimal, it + * would still be slower than UMAAL (see XXH_mult64to128). + * + * Unfortunately, Clang doesn't handle the long multiplies properly and + * converts them to the nonexistent "vmulq_u64" intrinsic, which is then + * scalarized into an ugly mess of VMOV.32 instructions. + * + * This mess is difficult to avoid without turning autovectorization + * off completely, but they are usually relatively minor and/or not + * worth it to fix. + * + * This loop is the easiest to fix, as unlike XXH32, this pragma + * _actually works_ because it is a loop vectorization instead of an + * SLP vectorization. + */ + #pragma clang loop vectorize(disable) +#endif + for (i=8 ; i < nbRounds; i++) { + acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed); + } + /* last bytes */ + acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed); + return XXH3_avalanche(acc); + } +} + + +/* ======= Long Keys ======= */ + +#define XXH_STRIPE_LEN 64 +#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */ +#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64)) + +#ifdef XXH_OLD_NAMES +# define STRIPE_LEN XXH_STRIPE_LEN +# define ACC_NB XXH_ACC_NB +#endif + +XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64) +{ + if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64); + XXH_memcpy(dst, &v64, sizeof(v64)); +} + +/* Several intrinsic functions below are supposed to accept __int64 as argument, + * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ . + * However, several environments do not define __int64 type, + * requiring a workaround. + */ +#if !defined (__VMS) \ + && (defined (__cplusplus) \ + || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) + typedef int64_t xxh_i64; +#else + /* the following type must have a width of 64-bit */ + typedef long long xxh_i64; +#endif + + +/* + * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized. + * + * It is a hardened version of UMAC, based off of FARSH's implementation. + * + * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD + * implementations, and it is ridiculously fast. + * + * We harden it by mixing the original input to the accumulators as well as the product. + * + * This means that in the (relatively likely) case of a multiply by zero, the + * original input is preserved. + * + * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve + * cross-pollination, as otherwise the upper and lower halves would be + * essentially independent. + * + * This doesn't matter on 64-bit hashes since they all get merged together in + * the end, so we skip the extra step. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +#if (XXH_VECTOR == XXH_AVX512) \ + || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0) + +#ifndef XXH_TARGET_AVX512 +# define XXH_TARGET_AVX512 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + __m512i* const xacc = (__m512i *) acc; + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + + { + /* data_vec = input[0]; */ + __m512i const data_vec = _mm512_loadu_si512 (input); + /* key_vec = secret[0]; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + /* data_key = data_vec ^ key_vec; */ + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo); + /* xacc[0] += swap(data_vec); */ + __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2)); + __m512i const sum = _mm512_add_epi64(*xacc, data_swap); + /* xacc[0] += product; */ + *xacc = _mm512_add_epi64(product, sum); + } +} + +/* + * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing. + * + * Multiplication isn't perfect, as explained by Google in HighwayHash: + * + * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to + * // varying degrees. In descending order of goodness, bytes + * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32. + * // As expected, the upper and lower bytes are much worse. + * + * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291 + * + * Since our algorithm uses a pseudorandom secret to add some variance into the + * mix, we don't need to (or want to) mix as often or as much as HighwayHash does. + * + * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid + * extraction. + * + * Both XXH3_64bits and XXH3_128bits use this subroutine. + */ + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 63) == 0); + XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i)); + { __m512i* const xacc = (__m512i*) acc; + const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1); + + /* xacc[0] ^= (xacc[0] >> 47) */ + __m512i const acc_vec = *xacc; + __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47); + __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted); + /* xacc[0] ^= secret; */ + __m512i const key_vec = _mm512_loadu_si512 (secret); + __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec); + + /* xacc[0] *= XXH_PRIME32_1; */ + __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1)); + __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32); + __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32); + *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32)); + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX512 void +XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64); + XXH_ASSERT(((size_t)customSecret & 63) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i); + __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64)); + + const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret); + __m512i* const dest = ( __m512i*) customSecret; + int i; + XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */ + XXH_ASSERT(((size_t)dest & 63) == 0); + for (i=0; i < nbRounds; ++i) { + /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*', + * this will warn "discards 'const' qualifier". */ + union { + const __m512i* cp; + void* p; + } remote_const_void; + remote_const_void.cp = src + i; + dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_AVX2) \ + || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0) + +#ifndef XXH_TARGET_AVX2 +# define XXH_TARGET_AVX2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { __m256i* const xacc = (__m256i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xinput = (const __m256i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* data_vec = xinput[i]; */ + __m256i const data_vec = _mm256_loadu_si256 (xinput+i); + /* key_vec = xsecret[i]; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2)); + __m256i const sum = _mm256_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm256_add_epi64(product, sum); + } } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void +XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 31) == 0); + { __m256i* const xacc = (__m256i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */ + const __m256i* const xsecret = (const __m256i *) secret; + const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m256i const acc_vec = xacc[i]; + __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47); + __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted); + /* xacc[i] ^= xsecret; */ + __m256i const key_vec = _mm256_loadu_si256 (xsecret+i); + __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32); + __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0); + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6); + XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64); + (void)(&XXH_writeLE64); + XXH_PREFETCH(customSecret); + { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64); + + const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret); + __m256i* dest = ( __m256i*) customSecret; + +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + */ + XXH_COMPILER_GUARD(dest); +# endif + XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */ + XXH_ASSERT(((size_t)dest & 31) == 0); + + /* GCC -O2 need unroll loop manually */ + dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed); + dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed); + dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed); + dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed); + dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed); + dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed); + } +} + +#endif + +/* x86dispatch always generates SSE2 */ +#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH) + +#ifndef XXH_TARGET_SSE2 +# define XXH_TARGET_SSE2 /* disable attribute target */ +#endif + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + /* SSE2 is just a half-scale version of the AVX2 version. */ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { __m128i* const xacc = (__m128i *) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xinput = (const __m128i *) input; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = _mm_loadu_si128 (xinput+i); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = _mm_mul_epu32 (data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2)); + __m128i const sum = _mm_add_epi64(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = _mm_add_epi64(product, sum); + } } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void +XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { __m128i* const xacc = (__m128i*) acc; + /* Unaligned. This is mainly for pointer arithmetic, and because + * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */ + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1); + + size_t i; + for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = _mm_srli_epi64 (acc_vec, 47); + __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = _mm_loadu_si128 (xsecret+i); + __m128i const data_key = _mm_xor_si128 (data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1)); + __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32); + __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32); + xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32)); + } + } +} + +XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + (void)(&XXH_writeLE64); + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i); + +# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900 + /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */ + XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) }; + __m128i const seed = _mm_load_si128((__m128i const*)seed64x2); +# else + __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64); +# endif + int i; + + const void* const src16 = XXH3_kSecret; + __m128i* dst16 = (__m128i*) customSecret; +# if defined(__GNUC__) || defined(__clang__) + /* + * On GCC & Clang, marking 'dest' as modified will cause the compiler: + * - do not extract the secret from sse registers in the internal loop + * - use less common registers, and avoid pushing these reg into stack + */ + XXH_COMPILER_GUARD(dst16); +# endif + XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */ + XXH_ASSERT(((size_t)dst16 & 15) == 0); + + for (i=0; i < nbRounds; ++i) { + dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed); + } } +} + +#endif + +#if (XXH_VECTOR == XXH_NEON) + +/* forward declarations for the scalar routines */ +XXH_FORCE_INLINE void +XXH3_scalarRound(void* XXH_RESTRICT acc, void const* XXH_RESTRICT input, + void const* XXH_RESTRICT secret, size_t lane); + +XXH_FORCE_INLINE void +XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT secret, size_t lane); + +/*! + * @internal + * @brief The bulk processing loop for NEON. + * + * The NEON code path is actually partially scalar when running on AArch64. This + * is to optimize the pipelining and can have up to 15% speedup depending on the + * CPU, and it also mitigates some GCC codegen issues. + * + * @see XXH3_NEON_LANES for configuring this and details about this optimization. + */ +XXH_FORCE_INLINE void +XXH3_accumulate_512_neon( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0); + { + uint64x2_t* const xacc = (uint64x2_t *) acc; + /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */ + uint8_t const* const xinput = (const uint8_t *) input; + uint8_t const* const xsecret = (const uint8_t *) secret; + + size_t i; + /* NEON for the first few lanes (these loops are normally interleaved) */ + for (i=0; i < XXH3_NEON_LANES / 2; i++) { + /* data_vec = xinput[i]; */ + uint8x16_t data_vec = vld1q_u8(xinput + (i * 16)); + /* key_vec = xsecret[i]; */ + uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16)); + uint64x2_t data_key; + uint32x2_t data_key_lo, data_key_hi; + /* xacc[i] += swap(data_vec); */ + uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec); + uint64x2_t const swapped = vextq_u64(data64, data64, 1); + xacc[i] = vaddq_u64 (xacc[i], swapped); + /* data_key = data_vec ^ key_vec; */ + data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec)); + /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF); + * data_key_hi = (uint32x2_t) (data_key >> 32); + * data_key = UNDEFINED; */ + XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); + /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */ + xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi); + + } + /* Scalar for the remainder. This may be a zero iteration loop. */ + for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { + XXH3_scalarRound(acc, input, secret, i); + } + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { uint64x2_t* xacc = (uint64x2_t*) acc; + uint8_t const* xsecret = (uint8_t const*) secret; + uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1); + + size_t i; + /* NEON for the first few lanes (these loops are normally interleaved) */ + for (i=0; i < XXH3_NEON_LANES / 2; i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + uint64x2_t acc_vec = xacc[i]; + uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47); + uint64x2_t data_vec = veorq_u64 (acc_vec, shifted); + + /* xacc[i] ^= xsecret[i]; */ + uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16)); + uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec)); + + /* xacc[i] *= XXH_PRIME32_1 */ + uint32x2_t data_key_lo, data_key_hi; + /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF); + * data_key_hi = (uint32x2_t) (xacc[i] >> 32); + * xacc[i] = UNDEFINED; */ + XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi); + { /* + * prod_hi = (data_key >> 32) * XXH_PRIME32_1; + * + * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will + * incorrectly "optimize" this: + * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b)); + * shifted = vshll_n_u32(tmp, 32); + * to this: + * tmp = "vmulq_u64"(a, b); // no such thing! + * shifted = vshlq_n_u64(tmp, 32); + * + * However, unlike SSE, Clang lacks a 64-bit multiply routine + * for NEON, and it scalarizes two 64-bit multiplies instead. + * + * vmull_u32 has the same timing as vmul_u32, and it avoids + * this bug completely. + * See https://bugs.llvm.org/show_bug.cgi?id=39967 + */ + uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime); + /* xacc[i] = prod_hi << 32; */ + xacc[i] = vshlq_n_u64(prod_hi, 32); + /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */ + xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime); + } + } + /* Scalar for the remainder. This may be a zero iteration loop. */ + for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) { + XXH3_scalarScrambleRound(acc, secret, i); + } + } +} + +#endif + +#if (XXH_VECTOR == XXH_VSX) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + /* presumed aligned */ + unsigned int* const xacc = (unsigned int*) acc; + xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */ + xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */ + xxh_u64x2 const v32 = { 32, 32 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* data_vec = xinput[i]; */ + xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i); + /* key_vec = xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + /* shuffled = (data_key << 32) | (data_key >> 32); */ + xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32); + /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */ + xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled); + /* acc_vec = xacc[i]; */ + xxh_u64x2 acc_vec = (xxh_u64x2)vec_xl(0, xacc + 4 * i); + acc_vec += product; + + /* swap high and low halves */ +#ifdef __s390x__ + acc_vec += vec_permi(data_vec, data_vec, 2); +#else + acc_vec += vec_xxpermdi(data_vec, data_vec, 2); +#endif + /* xacc[i] = acc_vec; */ + vec_xst((xxh_u32x4)acc_vec, 0, xacc + 4 * i); + } +} + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + + { xxh_u64x2* const xacc = (xxh_u64x2*) acc; + const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret; + /* constants */ + xxh_u64x2 const v32 = { 32, 32 }; + xxh_u64x2 const v47 = { 47, 47 }; + xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 }; + size_t i; + for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) { + /* xacc[i] ^= (xacc[i] >> 47); */ + xxh_u64x2 const acc_vec = xacc[i]; + xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47); + + /* xacc[i] ^= xsecret[i]; */ + xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i); + xxh_u64x2 const data_key = data_vec ^ key_vec; + + /* xacc[i] *= XXH_PRIME32_1 */ + /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */ + xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime); + /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */ + xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime); + xacc[i] = prod_odd + (prod_even << v32); + } } +} + +#endif + +/* scalar variants - universal */ + +/*! + * @internal + * @brief Scalar round for @ref XXH3_accumulate_512_scalar(). + * + * This is extracted to its own function because the NEON path uses a combination + * of NEON and scalar. + */ +XXH_FORCE_INLINE void +XXH3_scalarRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT input, + void const* XXH_RESTRICT secret, + size_t lane) +{ + xxh_u64* xacc = (xxh_u64*) acc; + xxh_u8 const* xinput = (xxh_u8 const*) input; + xxh_u8 const* xsecret = (xxh_u8 const*) secret; + XXH_ASSERT(lane < XXH_ACC_NB); + XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0); + { + xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8); + xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8); + xacc[lane ^ 1] += data_val; /* swap adjacent lanes */ + xacc[lane] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32); + } +} + +/*! + * @internal + * @brief Processes a 64 byte block of data using the scalar path. + */ +XXH_FORCE_INLINE void +XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + size_t i; + for (i=0; i < XXH_ACC_NB; i++) { + XXH3_scalarRound(acc, input, secret, i); + } +} + +/*! + * @internal + * @brief Scalar scramble step for @ref XXH3_scrambleAcc_scalar(). + * + * This is extracted to its own function because the NEON path uses a combination + * of NEON and scalar. + */ +XXH_FORCE_INLINE void +XXH3_scalarScrambleRound(void* XXH_RESTRICT acc, + void const* XXH_RESTRICT secret, + size_t lane) +{ + xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */ + const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */ + XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0); + XXH_ASSERT(lane < XXH_ACC_NB); + { + xxh_u64 const key64 = XXH_readLE64(xsecret + lane * 8); + xxh_u64 acc64 = xacc[lane]; + acc64 = XXH_xorshift64(acc64, 47); + acc64 ^= key64; + acc64 *= XXH_PRIME32_1; + xacc[lane] = acc64; + } +} + +/*! + * @internal + * @brief Scrambles the accumulators after a large chunk has been read + */ +XXH_FORCE_INLINE void +XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + size_t i; + for (i=0; i < XXH_ACC_NB; i++) { + XXH3_scalarScrambleRound(acc, secret, i); + } +} + +XXH_FORCE_INLINE void +XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64) +{ + /* + * We need a separate pointer for the hack below, + * which requires a non-const pointer. + * Any decent compiler will optimize this out otherwise. + */ + const xxh_u8* kSecretPtr = XXH3_kSecret; + XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0); + +#if defined(__clang__) && defined(__aarch64__) + /* + * UGLY HACK: + * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are + * placed sequentially, in order, at the top of the unrolled loop. + * + * While MOVK is great for generating constants (2 cycles for a 64-bit + * constant compared to 4 cycles for LDR), it fights for bandwidth with + * the arithmetic instructions. + * + * I L S + * MOVK + * MOVK + * MOVK + * MOVK + * ADD + * SUB STR + * STR + * By forcing loads from memory (as the asm line causes Clang to assume + * that XXH3_kSecretPtr has been changed), the pipelines are used more + * efficiently: + * I L S + * LDR + * ADD LDR + * SUB STR + * STR + * + * See XXH3_NEON_LANES for details on the pipsline. + * + * XXH3_64bits_withSeed, len == 256, Snapdragon 835 + * without hack: 2654.4 MB/s + * with hack: 3202.9 MB/s + */ + XXH_COMPILER_GUARD(kSecretPtr); +#endif + /* + * Note: in debug mode, this overrides the asm optimization + * and Clang will emit MOVK chains again. + */ + XXH_ASSERT(kSecretPtr == XXH3_kSecret); + + { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16; + int i; + for (i=0; i < nbRounds; i++) { + /* + * The asm hack causes Clang to assume that kSecretPtr aliases with + * customSecret, and on aarch64, this prevented LDP from merging two + * loads together for free. Putting the loads together before the stores + * properly generates LDP. + */ + xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64; + xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64; + XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo); + XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi); + } } +} + + +typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*); +typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*); +typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); + + +#if (XXH_VECTOR == XXH_AVX512) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx512 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512 + +#elif (XXH_VECTOR == XXH_AVX2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_avx2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2 + +#elif (XXH_VECTOR == XXH_SSE2) + +#define XXH3_accumulate_512 XXH3_accumulate_512_sse2 +#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2 +#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2 + +#elif (XXH_VECTOR == XXH_NEON) + +#define XXH3_accumulate_512 XXH3_accumulate_512_neon +#define XXH3_scrambleAcc XXH3_scrambleAcc_neon +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#elif (XXH_VECTOR == XXH_VSX) + +#define XXH3_accumulate_512 XXH3_accumulate_512_vsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#else /* scalar */ + +#define XXH3_accumulate_512 XXH3_accumulate_512_scalar +#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + +#endif + + + +#ifndef XXH_PREFETCH_DIST +# ifdef __clang__ +# define XXH_PREFETCH_DIST 320 +# else +# if (XXH_VECTOR == XXH_AVX512) +# define XXH_PREFETCH_DIST 512 +# else +# define XXH_PREFETCH_DIST 384 +# endif +# endif /* __clang__ */ +#endif /* XXH_PREFETCH_DIST */ + +/* + * XXH3_accumulate() + * Loops over XXH3_accumulate_512(). + * Assumption: nbStripes will not overflow the secret size + */ +XXH_FORCE_INLINE void +XXH3_accumulate( xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, + const xxh_u8* XXH_RESTRICT secret, + size_t nbStripes, + XXH3_f_accumulate_512 f_acc512) +{ + size_t n; + for (n = 0; n < nbStripes; n++ ) { + const xxh_u8* const in = input + n*XXH_STRIPE_LEN; + XXH_PREFETCH(in + XXH_PREFETCH_DIST); + f_acc512(acc, + in, + secret + n*XXH_SECRET_CONSUME_RATE); + } +} + +XXH_FORCE_INLINE void +XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc, + const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE; + size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock; + size_t const nb_blocks = (len - 1) / block_len; + + size_t n; + + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + + for (n = 0; n < nb_blocks; n++) { + XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512); + f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN); + } + + /* last partial block */ + XXH_ASSERT(len > XXH_STRIPE_LEN); + { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN; + XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE)); + XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512); + + /* last stripe */ + { const xxh_u8* const p = input + len - XXH_STRIPE_LEN; +#define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */ + f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START); + } } +} + +XXH_FORCE_INLINE xxh_u64 +XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret) +{ + return XXH3_mul128_fold64( + acc[0] ^ XXH_readLE64(secret), + acc[1] ^ XXH_readLE64(secret+8) ); +} + +static XXH64_hash_t +XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) +{ + xxh_u64 result64 = start; + size_t i = 0; + + for (i = 0; i < 4; i++) { + result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i); +#if defined(__clang__) /* Clang */ \ + && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \ + && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \ + && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */ + /* + * UGLY HACK: + * Prevent autovectorization on Clang ARMv7-a. Exact same problem as + * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b. + * XXH3_64bits, len == 256, Snapdragon 835: + * without hack: 2063.7 MB/s + * with hack: 2560.7 MB/s + */ + XXH_COMPILER_GUARD(result64); +#endif + } + + return XXH3_avalanche(result64); +} + +#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ + XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, + const void* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + /* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); +} + +/* + * It's important for performance to transmit secret's size (when it's static) + * so that the compiler can properly optimize the vectorized loop. + * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * It's preferable for performance that XXH3_hashLong is not inlined, + * as it results in a smaller function for small data, easier to the instruction cache. + * Note that inside this no_inline function, we do inline the internal loop, + * and provide a statically defined secret size to allow optimization of vector loop. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * XXH3_hashLong_64b_withSeed(): + * Generate a custom key based on alteration of default XXH3_kSecret with the seed, + * and then use this key for long mode hashing. + * + * This operation is decently fast but nonetheless costs a little bit of time. + * Try to avoid it whenever possible (typically when seed==0). + * + * It's important for performance that XXH3_hashLong is not inlined. Not sure + * why (uop cache maybe?), but the difference is large and easily measurable. + */ +XXH_FORCE_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len, + XXH64_hash_t seed, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed == 0) + return XXH3_hashLong_64b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc512, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed); + return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret), + f_acc512, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH64_hash_t +XXH3_hashLong_64b_withSeed(const void* input, size_t len, + XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_64b_withSeed_internal(input, len, seed, + XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + + +typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH64_hash_t +XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong64_f f_hashLong) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secretLen` condition is not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + * Also, note that function signature doesn't offer room to return an error. + */ + if (len <= 16) + return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen); +} + + +/* === Public entry point === */ + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len) +{ + return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +{ + return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed); +} + +XXH_PUBLIC_API XXH64_hash_t +XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed) +{ + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); + return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize); +} + + +/* === XXH3 streaming === */ + +/* + * Malloc's a pointer that is always aligned to align. + * + * This must be freed with `XXH_alignedFree()`. + * + * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte + * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2 + * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON. + * + * This underalignment previously caused a rather obvious crash which went + * completely unnoticed due to XXH3_createState() not actually being tested. + * Credit to RedSpah for noticing this bug. + * + * The alignment is done manually: Functions like posix_memalign or _mm_malloc + * are avoided: To maintain portability, we would have to write a fallback + * like this anyways, and besides, testing for the existence of library + * functions without relying on external build tools is impossible. + * + * The method is simple: Overallocate, manually align, and store the offset + * to the original behind the returned pointer. + * + * Align must be a power of 2 and 8 <= align <= 128. + */ +static void* XXH_alignedMalloc(size_t s, size_t align) +{ + XXH_ASSERT(align <= 128 && align >= 8); /* range check */ + XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */ + XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */ + { /* Overallocate to make room for manual realignment and an offset byte */ + xxh_u8* base = (xxh_u8*)XXH_malloc(s + align); + if (base != NULL) { + /* + * Get the offset needed to align this pointer. + * + * Even if the returned pointer is aligned, there will always be + * at least one byte to store the offset to the original pointer. + */ + size_t offset = align - ((size_t)base & (align - 1)); /* base % align */ + /* Add the offset for the now-aligned pointer */ + xxh_u8* ptr = base + offset; + + XXH_ASSERT((size_t)ptr % align == 0); + + /* Store the offset immediately before the returned pointer. */ + ptr[-1] = (xxh_u8)offset; + return ptr; + } + return NULL; + } +} +/* + * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass + * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout. + */ +static void XXH_alignedFree(void* p) +{ + if (p != NULL) { + xxh_u8* ptr = (xxh_u8*)p; + /* Get the offset byte we added in XXH_malloc. */ + xxh_u8 offset = ptr[-1]; + /* Free the original malloc'd pointer */ + xxh_u8* base = ptr - offset; + XXH_free(base); + } +} +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) +{ + XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64); + if (state==NULL) return NULL; + XXH3_INITSTATE(state); + return state; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) +{ + XXH_alignedFree(statePtr); + return XXH_OK; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API void +XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state) +{ + XXH_memcpy(dst_state, src_state, sizeof(*dst_state)); +} + +static void +XXH3_reset_internal(XXH3_state_t* statePtr, + XXH64_hash_t seed, + const void* secret, size_t secretSize) +{ + size_t const initStart = offsetof(XXH3_state_t, bufferedSize); + size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart; + XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart); + XXH_ASSERT(statePtr != NULL); + /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */ + memset((char*)statePtr + initStart, 0, initLength); + statePtr->acc[0] = XXH_PRIME32_3; + statePtr->acc[1] = XXH_PRIME64_1; + statePtr->acc[2] = XXH_PRIME64_2; + statePtr->acc[3] = XXH_PRIME64_3; + statePtr->acc[4] = XXH_PRIME64_4; + statePtr->acc[5] = XXH_PRIME32_2; + statePtr->acc[6] = XXH_PRIME64_5; + statePtr->acc[7] = XXH_PRIME32_1; + statePtr->seed = seed; + statePtr->useSeed = (seed != 0); + statePtr->extSecret = (const unsigned char*)secret; + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); + statePtr->secretLimit = secretSize - XXH_STRIPE_LEN; + statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset(XXH3_state_t* statePtr) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +{ + if (statePtr == NULL) return XXH_ERROR; + XXH3_reset_internal(statePtr, 0, secret, secretSize); + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + return XXH_OK; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + if (statePtr == NULL) return XXH_ERROR; + if (seed==0) return XXH3_64bits_reset(statePtr); + if ((seed != statePtr->seed) || (statePtr->extSecret != NULL)) + XXH3_initCustomSecret(statePtr->customSecret, seed); + XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE); + return XXH_OK; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64) +{ + if (statePtr == NULL) return XXH_ERROR; + if (secret == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; + XXH3_reset_internal(statePtr, seed64, secret, secretSize); + statePtr->useSeed = 1; /* always, even if seed64==0 */ + return XXH_OK; +} + +/* Note : when XXH3_consumeStripes() is invoked, + * there must be a guarantee that at least one more byte must be consumed from input + * so that the function can blindly consume all stripes using the "normal" secret segment */ +XXH_FORCE_INLINE void +XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc, + size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock, + const xxh_u8* XXH_RESTRICT input, size_t nbStripes, + const xxh_u8* XXH_RESTRICT secret, size_t secretLimit, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */ + XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock); + if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) { + /* need a scrambling operation */ + size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr; + size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock; + XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512); + f_scramble(acc, secret + secretLimit); + XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512); + *nbStripesSoFarPtr = nbStripesAfterBlock; + } else { + XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512); + *nbStripesSoFarPtr += nbStripes; + } +} + +#ifndef XXH3_STREAM_USE_STACK +# ifndef __clang__ /* clang doesn't need additional stack space */ +# define XXH3_STREAM_USE_STACK 1 +# endif +#endif +/* + * Both XXH3_64bits_update and XXH3_128bits_update use this routine. + */ +XXH_FORCE_INLINE XXH_errorcode +XXH3_update(XXH3_state_t* XXH_RESTRICT const state, + const xxh_u8* XXH_RESTRICT input, size_t len, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + if (input==NULL) { + XXH_ASSERT(len == 0); + return XXH_OK; + } + + XXH_ASSERT(state != NULL); + { const xxh_u8* const bEnd = input + len; + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; +#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1 + /* For some reason, gcc and MSVC seem to suffer greatly + * when operating accumulators directly into state. + * Operating into stack space seems to enable proper optimization. + * clang, on the other hand, doesn't seem to need this trick */ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc)); +#else + xxh_u64* XXH_RESTRICT const acc = state->acc; +#endif + state->totalLen += len; + XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE); + + /* small input : just fill in tmp buffer */ + if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) { + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } + + /* total input is now > XXH3_INTERNALBUFFER_SIZE */ + #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN) + XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */ + + /* + * Internal buffer is partially filled (always, except at beginning) + * Complete it, then consume it. + */ + if (state->bufferedSize) { + size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize; + XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize); + input += loadSize; + XXH3_consumeStripes(acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc512, f_scramble); + state->bufferedSize = 0; + } + XXH_ASSERT(input < bEnd); + + /* large input to consume : ingest per full block */ + if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) { + size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN; + XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar); + /* join to current block's end */ + { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar; + XXH_ASSERT(nbStripesToEnd <= nbStripes); + XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512); + f_scramble(acc, secret + state->secretLimit); + state->nbStripesSoFar = 0; + input += nbStripesToEnd * XXH_STRIPE_LEN; + nbStripes -= nbStripesToEnd; + } + /* consume per entire blocks */ + while(nbStripes >= state->nbStripesPerBlock) { + XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512); + f_scramble(acc, secret + state->secretLimit); + input += state->nbStripesPerBlock * XXH_STRIPE_LEN; + nbStripes -= state->nbStripesPerBlock; + } + /* consume last partial block */ + XXH3_accumulate(acc, input, secret, nbStripes, f_acc512); + input += nbStripes * XXH_STRIPE_LEN; + XXH_ASSERT(input < bEnd); /* at least some bytes left */ + state->nbStripesSoFar = nbStripes; + /* buffer predecessor of last partial stripe */ + XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN); + } else { + /* content to consume <= block size */ + /* Consume input by a multiple of internal buffer size */ + if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) { + const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE; + do { + XXH3_consumeStripes(acc, + &state->nbStripesSoFar, state->nbStripesPerBlock, + input, XXH3_INTERNALBUFFER_STRIPES, + secret, state->secretLimit, + f_acc512, f_scramble); + input += XXH3_INTERNALBUFFER_SIZE; + } while (inputbuffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN); + } + } + + /* Some remaining input (always) : buffer it */ + XXH_ASSERT(input < bEnd); + XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE); + XXH_ASSERT(state->bufferedSize == 0); + XXH_memcpy(state->buffer, input, (size_t)(bEnd-input)); + state->bufferedSize = (XXH32_hash_t)(bEnd-input); +#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1 + /* save stack accumulators into state */ + memcpy(state->acc, acc, sizeof(acc)); +#endif + } + + return XXH_OK; +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + + +XXH_FORCE_INLINE void +XXH3_digest_long (XXH64_hash_t* acc, + const XXH3_state_t* state, + const unsigned char* secret) +{ + /* + * Digest on a local copy. This way, the state remains unaltered, and it can + * continue ingesting more input afterwards. + */ + XXH_memcpy(acc, state->acc, sizeof(state->acc)); + if (state->bufferedSize >= XXH_STRIPE_LEN) { + size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN; + size_t nbStripesSoFar = state->nbStripesSoFar; + XXH3_consumeStripes(acc, + &nbStripesSoFar, state->nbStripesPerBlock, + state->buffer, nbStripes, + secret, state->secretLimit, + XXH3_accumulate_512, XXH3_scrambleAcc); + /* last stripe */ + XXH3_accumulate_512(acc, + state->buffer + state->bufferedSize - XXH_STRIPE_LEN, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); + } else { /* bufferedSize < XXH_STRIPE_LEN */ + xxh_u8 lastStripe[XXH_STRIPE_LEN]; + size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize; + XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */ + XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize); + XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize); + XXH3_accumulate_512(acc, + lastStripe, + secret + state->secretLimit - XXH_SECRET_LASTACC_START); + } +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + return XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + } + /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ + if (state->useSeed) + return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} + + + +/* ========================================== + * XXH3 128 bits (a.k.a XXH128) + * ========================================== + * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant, + * even without counting the significantly larger output size. + * + * For example, extra steps are taken to avoid the seed-dependent collisions + * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B). + * + * This strength naturally comes at the cost of some speed, especially on short + * lengths. Note that longer hashes are about as fast as the 64-bit version + * due to it using only a slight modification of the 64-bit loop. + * + * XXH128 is also more oriented towards 64-bit machines. It is still extremely + * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64). + */ + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + /* A doubled version of 1to3_64b with different constants. */ + XXH_ASSERT(input != NULL); + XXH_ASSERT(1 <= len && len <= 3); + XXH_ASSERT(secret != NULL); + /* + * len = 1: combinedl = { input[0], 0x01, input[0], input[0] } + * len = 2: combinedl = { input[1], 0x02, input[0], input[1] } + * len = 3: combinedl = { input[2], 0x03, input[0], input[1] } + */ + { xxh_u8 const c1 = input[0]; + xxh_u8 const c2 = input[len >> 1]; + xxh_u8 const c3 = input[len - 1]; + xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24) + | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8); + xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13); + xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed; + xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed; + xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl; + xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph; + XXH128_hash_t h128; + h128.low64 = XXH64_avalanche(keyed_lo); + h128.high64 = XXH64_avalanche(keyed_hi); + return h128; + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(4 <= len && len <= 8); + seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32; + { xxh_u32 const input_lo = XXH_readLE32(input); + xxh_u32 const input_hi = XXH_readLE32(input + len - 4); + xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32); + xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed; + xxh_u64 const keyed = input_64 ^ bitflip; + + /* Shift len to the left to ensure it is even, this avoids even multiplies. */ + XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2)); + + m128.high64 += (m128.low64 << 1); + m128.low64 ^= (m128.high64 >> 3); + + m128.low64 = XXH_xorshift64(m128.low64, 35); + m128.low64 *= 0x9FB21C651E98DF25ULL; + m128.low64 = XXH_xorshift64(m128.low64, 28); + m128.high64 = XXH3_avalanche(m128.high64); + return m128; + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(input != NULL); + XXH_ASSERT(secret != NULL); + XXH_ASSERT(9 <= len && len <= 16); + { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed; + xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed; + xxh_u64 const input_lo = XXH_readLE64(input); + xxh_u64 input_hi = XXH_readLE64(input + len - 8); + XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1); + /* + * Put len in the middle of m128 to ensure that the length gets mixed to + * both the low and high bits in the 128x64 multiply below. + */ + m128.low64 += (xxh_u64)(len - 1) << 54; + input_hi ^= bitfliph; + /* + * Add the high 32 bits of input_hi to the high 32 bits of m128, then + * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to + * the high 64 bits of m128. + * + * The best approach to this operation is different on 32-bit and 64-bit. + */ + if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */ + /* + * 32-bit optimized version, which is more readable. + * + * On 32-bit, it removes an ADC and delays a dependency between the two + * halves of m128.high64, but it generates an extra mask on 64-bit. + */ + m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2); + } else { + /* + * 64-bit optimized (albeit more confusing) version. + * + * Uses some properties of addition and multiplication to remove the mask: + * + * Let: + * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF) + * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000) + * c = XXH_PRIME32_2 + * + * a + (b * c) + * Inverse Property: x + y - x == y + * a + (b * (1 + c - 1)) + * Distributive Property: x * (y + z) == (x * y) + (x * z) + * a + (b * 1) + (b * (c - 1)) + * Identity Property: x * 1 == x + * a + b + (b * (c - 1)) + * + * Substitute a, b, and c: + * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + * + * Since input_hi.hi + input_hi.lo == input_hi, we get this: + * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1)) + */ + m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1); + } + /* m128 ^= XXH_swap64(m128 >> 64); */ + m128.low64 ^= XXH_swap64(m128.high64); + + { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */ + XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2); + h128.high64 += m128.high64 * XXH_PRIME64_2; + + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = XXH3_avalanche(h128.high64); + return h128; + } } +} + +/* + * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed) +{ + XXH_ASSERT(len <= 16); + { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed); + if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed); + if (len) return XXH3_len_1to3_128b(input, len, secret, seed); + { XXH128_hash_t h128; + xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72); + xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88); + h128.low64 = XXH64_avalanche(seed ^ bitflipl); + h128.high64 = XXH64_avalanche( seed ^ bitfliph); + return h128; + } } +} + +/* + * A bit slower than XXH3_mix16B, but handles multiply by zero better. + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2, + const xxh_u8* secret, XXH64_hash_t seed) +{ + acc.low64 += XXH3_mix16B (input_1, secret+0, seed); + acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8); + acc.high64 += XXH3_mix16B (input_2, secret+16, seed); + acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8); + return acc; +} + + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(16 < len && len <= 128); + + { XXH128_hash_t acc; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + if (len > 32) { + if (len > 64) { + if (len > 96) { + acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed); + } + acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed); + } + acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed); + } + acc = XXH128_mix32B(acc, input, input+len-16, secret, seed); + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_NO_INLINE XXH128_hash_t +XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH64_hash_t seed) +{ + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize; + XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX); + + { XXH128_hash_t acc; + int const nbRounds = (int)len / 32; + int i; + acc.low64 = len * XXH_PRIME64_1; + acc.high64 = 0; + for (i=0; i<4; i++) { + acc = XXH128_mix32B(acc, + input + (32 * i), + input + (32 * i) + 16, + secret + (32 * i), + seed); + } + acc.low64 = XXH3_avalanche(acc.low64); + acc.high64 = XXH3_avalanche(acc.high64); + XXH_ASSERT(nbRounds >= 4); + for (i=4 ; i < nbRounds; i++) { + acc = XXH128_mix32B(acc, + input + (32 * i), + input + (32 * i) + 16, + secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)), + seed); + } + /* last bytes */ + acc = XXH128_mix32B(acc, + input + len - 16, + input + len - 32, + secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16, + 0ULL - seed); + + { XXH128_hash_t h128; + h128.low64 = acc.low64 + acc.high64; + h128.high64 = (acc.low64 * XXH_PRIME64_1) + + (acc.high64 * XXH_PRIME64_4) + + ((len - seed) * XXH_PRIME64_2); + h128.low64 = XXH3_avalanche(h128.low64); + h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64); + return h128; + } + } +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, + const xxh_u8* XXH_RESTRICT secret, size_t secretSize, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble) +{ + XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC; + + XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble); + + /* converge into final hash */ + XXH_STATIC_ASSERT(sizeof(acc) == 64); + XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)len * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + secretSize + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)len * XXH_PRIME64_2)); + return h128; + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; (void)secret; (void)secretLen; + return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/* + * It's important for performance to pass @secretLen (when it's static) + * to the compiler, so that it can properly optimize the vectorized loop. + */ +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)seed64; + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len, + XXH64_hash_t seed64, + XXH3_f_accumulate_512 f_acc512, + XXH3_f_scrambleAcc f_scramble, + XXH3_f_initCustomSecret f_initSec) +{ + if (seed64 == 0) + return XXH3_hashLong_128b_internal(input, len, + XXH3_kSecret, sizeof(XXH3_kSecret), + f_acc512, f_scramble); + { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE]; + f_initSec(secret, seed64); + return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret), + f_acc512, f_scramble); + } +} + +/* + * It's important for performance that XXH3_hashLong is not inlined. + */ +XXH_NO_INLINE XXH128_hash_t +XXH3_hashLong_128b_withSeed(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen) +{ + (void)secret; (void)secretLen; + return XXH3_hashLong_128b_withSeed_internal(input, len, seed64, + XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret); +} + +typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t, + XXH64_hash_t, const void* XXH_RESTRICT, size_t); + +XXH_FORCE_INLINE XXH128_hash_t +XXH3_128bits_internal(const void* input, size_t len, + XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen, + XXH3_hashLong128_f f_hl128) +{ + XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN); + /* + * If an action is to be taken if `secret` conditions are not respected, + * it should be done here. + * For now, it's a contract pre-condition. + * Adding a check and a branch here would cost performance at every hash. + */ + if (len <= 16) + return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64); + if (len <= 128) + return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64); + return f_hl128(input, len, seed64, secret, secretLen); +} + + +/* === Public XXH128 API === */ + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len) +{ + return XXH3_128bits_internal(input, len, 0, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_default); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize) +{ + return XXH3_128bits_internal(input, len, 0, + (const xxh_u8*)secret, secretSize, + XXH3_hashLong_128b_withSecret); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_internal(input, len, seed, + XXH3_kSecret, sizeof(XXH3_kSecret), + XXH3_hashLong_128b_withSeed); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed) +{ + if (len <= XXH3_MIDSIZE_MAX) + return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL); + return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH128(const void* input, size_t len, XXH64_hash_t seed) +{ + return XXH3_128bits_withSeed(input, len, seed); +} + + +/* === XXH3 128-bit streaming === */ + +/* + * All initialization and update functions are identical to 64-bit streaming variant. + * The only difference is the finalization routine. + */ + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset(XXH3_state_t* statePtr) +{ + return XXH3_64bits_reset(statePtr); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize) +{ + return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed) +{ + return XXH3_64bits_reset_withSeed(statePtr, seed); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed) +{ + return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len) +{ + return XXH3_update(state, (const xxh_u8*)input, len, + XXH3_accumulate_512, XXH3_scrambleAcc); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state) +{ + const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret; + if (state->totalLen > XXH3_MIDSIZE_MAX) { + XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; + XXH3_digest_long(acc, state, secret); + XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); + { XXH128_hash_t h128; + h128.low64 = XXH3_mergeAccs(acc, + secret + XXH_SECRET_MERGEACCS_START, + (xxh_u64)state->totalLen * XXH_PRIME64_1); + h128.high64 = XXH3_mergeAccs(acc, + secret + state->secretLimit + XXH_STRIPE_LEN + - sizeof(acc) - XXH_SECRET_MERGEACCS_START, + ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); + return h128; + } + } + /* len <= XXH3_MIDSIZE_MAX : short code */ + if (state->seed) + return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); + return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), + secret, state->secretLimit + XXH_STRIPE_LEN); +} + +/* 128-bit utility functions */ + +#include /* memcmp, memcpy */ + +/* return : 1 is equal, 0 if different */ +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2) +{ + /* note : XXH128_hash_t is compact, it has no padding byte */ + return !(memcmp(&h1, &h2, sizeof(h1))); +} + +/* This prototype is compatible with stdlib's qsort(). + * return : >0 if *h128_1 > *h128_2 + * <0 if *h128_1 < *h128_2 + * =0 if *h128_1 == *h128_2 */ +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2) +{ + XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1; + XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2; + int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64); + /* note : bets that, in most cases, hash values are different */ + if (hcmp) return hcmp; + return (h1.low64 > h2.low64) - (h2.low64 > h1.low64); +} + + +/*====== Canonical representation ======*/ +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API void +XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash) +{ + XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t)); + if (XXH_CPU_LITTLE_ENDIAN) { + hash.high64 = XXH_swap64(hash.high64); + hash.low64 = XXH_swap64(hash.low64); + } + XXH_memcpy(dst, &hash.high64, sizeof(hash.high64)); + XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64)); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH128_hash_t +XXH128_hashFromCanonical(const XXH128_canonical_t* src) +{ + XXH128_hash_t h; + h.high64 = XXH_readBE64(src); + h.low64 = XXH_readBE64(src->digest + 8); + return h; +} + + + +/* ========================================== + * Secret generators + * ========================================== + */ +#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x)) + +XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128) +{ + XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 ); + XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 ); +} + +/*! @ingroup xxh3_family */ +XXH_PUBLIC_API XXH_errorcode +XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize) +{ +#if (XXH_DEBUGLEVEL >= 1) + XXH_ASSERT(secretBuffer != NULL); + XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); +#else + /* production mode, assert() are disabled */ + if (secretBuffer == NULL) return XXH_ERROR; + if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR; +#endif + + if (customSeedSize == 0) { + customSeed = XXH3_kSecret; + customSeedSize = XXH_SECRET_DEFAULT_SIZE; + } +#if (XXH_DEBUGLEVEL >= 1) + XXH_ASSERT(customSeed != NULL); +#else + if (customSeed == NULL) return XXH_ERROR; +#endif + + /* Fill secretBuffer with a copy of customSeed - repeat as needed */ + { size_t pos = 0; + while (pos < secretSize) { + size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize); + memcpy((char*)secretBuffer + pos, customSeed, toCopy); + pos += toCopy; + } } + + { size_t const nbSeg16 = secretSize / 16; + size_t n; + XXH128_canonical_t scrambler; + XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0)); + for (n=0; n Date: Tue, 7 Dec 2021 14:22:36 -0500 Subject: [PATCH 300/340] Fix Up #2659; Build libzstd.pc Whenever Building the Lib on Unix --- lib/Makefile | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 561de7b2c..00fc535b0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -175,7 +175,7 @@ endif # if windows libzstd : $(LIBZSTD) .PHONY: lib -lib : libzstd.a libzstd libzstd.pc +lib : libzstd.a libzstd # note : do not define lib-mt or lib-release as .PHONY @@ -246,24 +246,12 @@ clean: $(RM) -r obj/* @echo Cleaning library completed -libzstd.pc: -libzstd.pc: libzstd.pc.in - @echo creating pkgconfig - @sed $(SED_ERE_OPT) \ - -e 's|@PREFIX@|$(PREFIX)|' \ - -e 's|@EXEC_PREFIX@|$(PCEXEC_PREFIX)|' \ - -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ - -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ - -e 's|@VERSION@|$(VERSION)|' \ - -e 's|@LIBS_PRIVATE@|$(LDFLAGS_DYNLIB)|' \ - $< >$@ - #----------------------------------------------------------------------------- # make install is validated only for below listed environments #----------------------------------------------------------------------------- ifneq (,$(filter $(UNAME),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS Haiku AIX)) -all: libzstd.pc +lib: libzstd.pc HAS_EXPLICIT_EXEC_PREFIX := $(if $(or $(EXEC_PREFIX),$(exec_prefix)),1,) @@ -308,6 +296,17 @@ INSTALL_PROGRAM ?= $(INSTALL) INSTALL_DATA ?= $(INSTALL) -m 644 +libzstd.pc: libzstd.pc.in + @echo creating pkgconfig + @sed $(SED_ERE_OPT) \ + -e 's|@PREFIX@|$(PREFIX)|' \ + -e 's|@EXEC_PREFIX@|$(PCEXEC_PREFIX)|' \ + -e 's|@INCLUDEDIR@|$(PCINCPREFIX)$(PCINCDIR)|' \ + -e 's|@LIBDIR@|$(PCLIBPREFIX)$(PCLIBDIR)|' \ + -e 's|@VERSION@|$(VERSION)|' \ + -e 's|@LIBS_PRIVATE@|$(LDFLAGS_DYNLIB)|' \ + $< >$@ + .PHONY: install install: install-pc install-static install-shared install-includes @echo zstd static and shared library installed From fb3522a3fea34ca88a6eea2dff1e588af3af08ea Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Dec 2021 09:17:06 -0800 Subject: [PATCH 301/340] fixed very minor cast warning under cygwin --- tests/fuzzer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/fuzzer.c b/tests/fuzzer.c index e2eedbcea..6d36c3393 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1984,7 +1984,9 @@ static int basicUnitTests(U32 const seed, double compressibility) DISPLAYLEVEL(3, "test%3i : flat-dictionary efficiency test : \n", testNb++); 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)); + DISPLAYLEVEL(4, "content hash : %016llx; dict hash : %016llx \n", + (unsigned long long)XXH64(contentStart, contentSize, 0), + (unsigned long long)XXH64(dict, flatdictSize, 0)); for ( ; l <= maxLevel; l++) { size_t const nodict_cSize = ZSTD_compress(compressedBuffer, compressedBufferSize, @@ -3366,7 +3368,7 @@ static int basicUnitTests(U32 const seed, double compressibility) unsigned const maxSymbolValue = 10; BYTE* outBuf = (BYTE*)malloc(outBufSize*sizeof(BYTE)); - /* Ensure that this write doesn't write out of bounds, and that + /* 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); From aa7729c9f3f0a6ed2b761d890c845d1429ca9663 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 8 Dec 2021 10:31:40 -0800 Subject: [PATCH 302/340] Fix oss-fuzz build Disable assembly when dataflow sanitizer is enabled. This regressed in PR #2893, which accidentally removed the check for dataflow sanitizer. --- lib/common/portability_macros.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/common/portability_macros.h b/lib/common/portability_macros.h index ef7987d41..627ef9eed 100644 --- a/lib/common/portability_macros.h +++ b/lib/common/portability_macros.h @@ -96,6 +96,8 @@ # if defined(__linux__) || defined(__linux) || defined(__APPLE__) # if ZSTD_MEMORY_SANITIZER # define ZSTD_ASM_SUPPORTED 0 +# elif ZSTD_DATAFLOW_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 # else # define ZSTD_ASM_SUPPORTED 1 # endif From b94407b6cf3f0f89fa157b0232851dfdb364d389 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 8 Dec 2021 10:57:30 -0800 Subject: [PATCH 303/340] Remove possible NULL pointer addition Refactor `ZSTDMT_isOverlapped()` to do NULL checks before computing the end pointer. Fixes #2906. --- lib/compress/zstdmt_compress.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 2aec41dda..f564822d4 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -1550,17 +1550,21 @@ static range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx) static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range) { BYTE const* const bufferStart = (BYTE const*)buffer.start; - BYTE const* const bufferEnd = bufferStart + buffer.capacity; BYTE const* const rangeStart = (BYTE const*)range.start; - BYTE const* const rangeEnd = range.size != 0 ? rangeStart + range.size : rangeStart; if (rangeStart == NULL || bufferStart == NULL) return 0; - /* Empty ranges cannot overlap */ - if (bufferStart == bufferEnd || rangeStart == rangeEnd) - return 0; - return bufferStart < rangeEnd && rangeStart < bufferEnd; + { + BYTE const* const bufferEnd = bufferStart + buffer.capacity; + BYTE const* const rangeEnd = rangeStart + range.size; + + /* Empty ranges cannot overlap */ + if (bufferStart == bufferEnd || rangeStart == rangeEnd) + return 0; + + return bufferStart < rangeEnd && rangeStart < bufferEnd; + } } static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window) From 27e706de8883acd81bf6ae4923ae76145a7d3af4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Dec 2021 12:51:04 -0800 Subject: [PATCH 304/340] replaces malloc / free / memcpy by Zstandard's version --- lib/common/xxhash.h | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/lib/common/xxhash.h b/lib/common/xxhash.h index a813b1813..3119a9c5b 100644 --- a/lib/common/xxhash.h +++ b/lib/common/xxhash.h @@ -1474,36 +1474,13 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, /* ************************************* * Includes & Memory related functions ***************************************/ -/* - * Modify the local functions below should you wish to use - * different memory routines for malloc() and free() - */ -#include - -/*! - * @internal - * @brief Modify this function to use a different routine than malloc(). - */ -static void* XXH_malloc(size_t s) { return malloc(s); } - -/*! - * @internal - * @brief Modify this function to use a different routine than free(). - */ -static void XXH_free(void* p) { free(p); } - -#include - -/*! - * @internal - * @brief Modify this function to use a different routine than memcpy(). - */ -static void* XXH_memcpy(void* dest, const void* src, size_t size) -{ - return memcpy(dest,src,size); -} - -#include /* ULLONG_MAX */ +/* Modify the local functions below should you wish to use some other memory routines */ +/* for ZSTD_malloc(), ZSTD_free() */ +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */ +static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); } +static void XXH_free (void* p) { ZSTD_free(p); } +static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); } /* ************************************* From a9cd6164d7b2289126b5c46936ec33728bfea90b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Dec 2021 12:56:16 -0800 Subject: [PATCH 305/340] removed declarations of XXH3 symbols when XXH_NO_XXH3 is defined on top of implementations, which were already scoped out. --- lib/common/xxhash.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/common/xxhash.h b/lib/common/xxhash.h index 3119a9c5b..1e37bfd2b 100644 --- a/lib/common/xxhash.h +++ b/lib/common/xxhash.h @@ -38,6 +38,7 @@ * Modifications are : * - Removal of XXH3 / XXH128 algorithms, unused within zstd * - prefix names of all symbols, to reduce risks of collisions + * - Replace malloc / free / memcpy by Zstandard's variants * This could be achieved at build stage, with CPPFLAGS typically, * but doing it directly within source file * make it possible for 3rd party to simply grab the directory @@ -749,6 +750,7 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src); +#ifndef XXH_NO_XXH3 /*! * @} * ************************************************************************ @@ -956,6 +958,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_has XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src); +#endif /* !XXH_NO_XXH3 */ #endif /* XXH_NO_LONG_LONG */ /*! @@ -1026,6 +1029,9 @@ struct XXH64_state_s { XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ + +#ifndef XXH_NO_XXH3 + #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ # include # define XXH_ALIGN(n) alignas(n) @@ -1237,6 +1243,7 @@ XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, XXH64_hash_t seed64); +#endif /* XXH_NO_XXH3 */ #endif /* XXH_NO_LONG_LONG */ #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # define XXH_IMPLEMENTATION From 9985e10fdaec1d3d49cb20ee78ee8a746467acb8 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 6 Dec 2021 13:47:18 -0500 Subject: [PATCH 306/340] Reject Irregular Dictionary Files I hadn't seen #2890, so I wrote my own version. I like this approach a little better, since it does an explicit check for a regular file, rather than passing a magic value. Addresses #2874. --- programs/fileio.c | 26 +++++++++++++++++++------- tests/playTests.sh | 5 +++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 29a2d66aa..379d334eb 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -732,31 +732,43 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName, FIO_p { FILE* fileHandle; U64 fileSize; + stat_t statbuf; assert(bufferPtr != NULL); *bufferPtr = NULL; if (fileName == NULL) return 0; DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName); - fileHandle = fopen(fileName, "rb"); - if (fileHandle==NULL) EXM_THROW(31, "%s: %s", fileName, strerror(errno)); - fileSize = UTIL_getFileSize(fileName); - if (fileSize == UTIL_FILESIZE_UNKNOWN) - EXM_THROW(32, "This file format is not supported : Dictionary file %s\n", fileName); + if (!UTIL_stat(fileName, &statbuf)) { + EXM_THROW(31, "Stat failed on dictionary file %s: %s", fileName, strerror(errno)); + } + + if (!UTIL_isRegularFileStat(&statbuf)) { + EXM_THROW(32, "Dictionary %s must be a regular file.", fileName); + } + + fileHandle = fopen(fileName, "rb"); + + if (fileHandle == NULL) { + EXM_THROW(33, "Couldn't open dictionary %s: %s", fileName, strerror(errno)); + } + + fileSize = UTIL_getFileSizeStat(&statbuf); { size_t const dictSizeMax = prefs->patchFromMode ? prefs->memLimit : DICTSIZE_MAX; if (fileSize > dictSizeMax) { - EXM_THROW(32, "Dictionary file %s is too large (> %u bytes)", + EXM_THROW(34, "Dictionary file %s is too large (> %u bytes)", fileName, (unsigned)dictSizeMax); /* avoid extreme cases */ } } *bufferPtr = malloc((size_t)fileSize); if (*bufferPtr==NULL) EXM_THROW(34, "%s", strerror(errno)); { size_t const readSize = fread(*bufferPtr, 1, (size_t)fileSize, fileHandle); - if (readSize != fileSize) + if (readSize != fileSize) { EXM_THROW(35, "Error reading dictionary file %s : %s", fileName, strerror(errno)); + } } fclose(fileHandle); return (size_t)fileSize; diff --git a/tests/playTests.sh b/tests/playTests.sh index 6dbfffca2..3649a86b7 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -974,6 +974,11 @@ println "- Dictionary compression with btlazy2 strategy" zstd -f tmp -D tmpDict --zstd=strategy=6 zstd -d tmp.zst -D tmpDict -fo result $DIFF "$TESTFILE" result +if [ -e /proc/self/fd/0 ]; then + println "- Test rejecting irregular dictionary file" + cat tmpDict | zstd -f tmp -D /proc/self/fd/0 && die "Piped dictionary should fail!" + cat tmpDict | zstd -d tmp.zst -D /proc/self/fd/0 -f && die "Piped dictionary should fail!" +fi if [ -n "$hasMT" ] then println "- Test dictionary compression with multithreading " From 16241b7d267300af92dd79a89e31127847189d0e Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Dec 2021 13:15:45 -0800 Subject: [PATCH 307/340] altered copyright title --- lib/common/xxhash.c | 41 ++++++++++------------------------- lib/common/xxhash.h | 53 +++++++++------------------------------------ 2 files changed, 21 insertions(+), 73 deletions(-) diff --git a/lib/common/xxhash.c b/lib/common/xxhash.c index 0fae88c5d..d49497cf1 100644 --- a/lib/common/xxhash.c +++ b/lib/common/xxhash.c @@ -1,36 +1,17 @@ /* - * xxHash - Extremely Fast Hash algorithm - * Copyright (C) 2012-2020 Yann Collet + * xxHash - Fast Hash algorithm + * Copyright (c) Yann Collet, Facebook, Inc. * - * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + * You can contact the author at : + * - xxHash homepage: http://www.xxhash.com + * - xxHash source repository : https://github.com/Cyan4973/xxHash * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You can contact the author at: - * - xxHash homepage: https://www.xxhash.com - * - xxHash source repository: https://github.com/Cyan4973/xxHash - */ + * 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. +*/ + /* diff --git a/lib/common/xxhash.h b/lib/common/xxhash.h index 1e37bfd2b..eb095b93a 100644 --- a/lib/common/xxhash.h +++ b/lib/common/xxhash.h @@ -1,50 +1,17 @@ /* - * xxHash - Extremely Fast Hash algorithm - * Header File - * Copyright (C) 2012-2020 Yann Collet + * xxHash - Fast Hash algorithm + * Copyright (c) Yann Collet, Facebook, Inc. * - * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) + * You can contact the author at : + * - xxHash homepage: http://www.xxhash.com + * - xxHash source repository : https://github.com/Cyan4973/xxHash * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You can contact the author at: - * - xxHash homepage: https://www.xxhash.com - * - xxHash source repository: https://github.com/Cyan4973/xxHash - */ + * 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. +*/ -/* Note : This is a slightly modified version of xxHash - * for zstd internal usage. - * Modifications are : - * - Removal of XXH3 / XXH128 algorithms, unused within zstd - * - prefix names of all symbols, to reduce risks of collisions - * - Replace malloc / free / memcpy by Zstandard's variants - * This could be achieved at build stage, with CPPFLAGS typically, - * but doing it directly within source file - * make it possible for 3rd party to simply grab the directory - * and compile it locally, with whichever build system they wish, - * without a need for them to configure some build flag. - */ #ifndef XXH_NO_XXH3 # define XXH_NO_XXH3 From 3ce265fea86fc8c4254892a20d136b4053832552 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Dec 2021 15:05:17 -0800 Subject: [PATCH 308/340] remove offending static assert lines no idea why visual + clang-cl + appveyor don't like them, I've not been able to reproduce the issue locally, but these static assert are very unlikely to deliver a useful signal, I can't imagine a situation where they will be wrong, and if they are, then a ton of other things will be broken way before reaching that point. --- lib/common/xxhash.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/xxhash.h b/lib/common/xxhash.h index eb095b93a..8ebbfdd62 100644 --- a/lib/common/xxhash.h +++ b/lib/common/xxhash.h @@ -2233,7 +2233,7 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { - XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); + /* XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); */ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); XXH_memcpy(dst, &hash, sizeof(*dst)); } @@ -2631,7 +2631,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state) /*! @ingroup xxh64_family */ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash) { - XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); + /* XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); */ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); XXH_memcpy(dst, &hash, sizeof(*dst)); } From 3d738307b4df617e9783d7016f4f4fbfed4aa5e0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 8 Dec 2021 16:55:38 -0800 Subject: [PATCH 309/340] Update changelog for v1.5.1 --- CHANGELOG | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 3b1516551..82c160179 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,20 @@ +v1.5.1 (Dec, 2021) +perf: rebalanced compression levels, to better match the intended speed/level curve, by @senhuang42 +perf: faster huffman decoder, using x64 assembly, by @terrelln +perf: slightly faster high speed modes (strategies fast & dfast), by @felixhandte +perf: improved binary size and faster compilation times, by @terrelln +perf: new row64 mode, used notably in levels 11 & 12, by @senhuang42 +perf: minor compression ratio improvements for small data at high levels, by @cyan4973 +perf: reduced stack usage (mostly useful for Linux Kernel), by @terrelln +perf: faster detection and skipping of incompressible blocks, by @bindhvo +perf: on-demand reduced ZSTD_DCtx state size, using build macro ZSTD_DECODER_INTERNAL_BUFFER, at a small cost of performance, by @bindhvo +build: allows hiding static symbols in the dynamic library, using build macro, by @skitt +build: support for m68k (Motorola 68000's), by @cyan4973 +build: improved AIX support, by @Helflym +build: improved meson unofficial build, by @eli-schwartz +cli : report advanced parameters information when compressing in very verbose mode (``-vv`), by @Svetlitski-FB + + v1.5.0 (May 11, 2021) api: Various functions promoted from experimental to stable API: (#2579-2581, @senhuang42) `ZSTD_defaultCLevel()` From 4cc5e2818a4db99ebf7b5bf1a46258927c5ffa3a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 9 Dec 2021 09:53:45 -0800 Subject: [PATCH 310/340] complete changelog with #2885 --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 82c160179..52f33480c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ build: support for m68k (Motorola 68000's), by @cyan4973 build: improved AIX support, by @Helflym build: improved meson unofficial build, by @eli-schwartz cli : report advanced parameters information when compressing in very verbose mode (``-vv`), by @Svetlitski-FB +cli : limit --ultra levels to 21 in 32-bit mode, to reduce risks of OOM scenarios (#2885, @yoniko) v1.5.0 (May 11, 2021) From 22501cd28323354981f5328c9de4f33bdeed874f Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 10 Dec 2021 15:44:39 -0500 Subject: [PATCH 311/340] Stagger Application of `stepSize` in ZSTD_fast This replicates the behavior of @terrelln's `ZSTD_fast` implementation. That is, it always looks at adjacent pairs of positions, and only applies the acceleration every other position. This produces a more fine-grained acceleration. --- lib/compress/zstd_fast.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 87de17f81..8e26cc703 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -99,7 +99,7 @@ ZSTD_compressBlock_fast_noDict_generic( U32* const hashTable = ms->hashTable; U32 const hlog = cParams->hashLog; /* support stepSize of 0 */ - size_t const stepSize = cParams->targetLength + !(cParams->targetLength); + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) - 1; const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); @@ -144,13 +144,13 @@ ZSTD_compressBlock_fast_noDict_generic( /* start each op */ _start: /* Requires: ip0 */ - step = stepSize; + step = 1; nextStep = ip0 + kStepIncr; /* calculate positions, ip0 - anchor == 0, so we skip step calc */ - ip1 = ip0 + stepSize; - ip2 = ip1 + stepSize; - ip3 = ip2 + stepSize; + ip1 = ip0 + step; + ip2 = ip1 + step + stepSize; + ip3 = ip2 + step; if (ip3 >= ilimit) { goto _cleanup; @@ -241,7 +241,7 @@ _start: /* Requires: ip0 */ /* advance to next positions */ ip0 = ip1; ip1 = ip2; - ip2 = ip2 + step; + ip2 = ip2 + step + stepSize; ip3 = ip2 + step; } while (ip3 < ilimit); From ace6a7e746f40a1d525f8f04e3dee0ebfb12e97b Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Fri, 10 Dec 2021 15:52:30 -0500 Subject: [PATCH 312/340] Decompose `step` into Two Variables This avoids an additional addition, at the cost of an additional variable. --- lib/compress/zstd_fast.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 8e26cc703..918b72997 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -99,7 +99,7 @@ ZSTD_compressBlock_fast_noDict_generic( U32* const hashTable = ms->hashTable; U32 const hlog = cParams->hashLog; /* support stepSize of 0 */ - size_t const stepSize = cParams->targetLength + !(cParams->targetLength) - 1; + 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); @@ -128,7 +128,8 @@ ZSTD_compressBlock_fast_noDict_generic( const BYTE* match0; size_t mLength; - size_t step; + size_t step0; + size_t step1; const BYTE* nextStep; const size_t kStepIncr = (1 << (kSearchStrength - 1)); @@ -144,13 +145,14 @@ ZSTD_compressBlock_fast_noDict_generic( /* start each op */ _start: /* Requires: ip0 */ - step = 1; + step0 = 1; + step1 = stepSize; nextStep = ip0 + kStepIncr; /* calculate positions, ip0 - anchor == 0, so we skip step calc */ - ip1 = ip0 + step; - ip2 = ip1 + step + stepSize; - ip3 = ip2 + step; + ip1 = ip0 + step0; + ip2 = ip1 + step1; + ip3 = ip2 + step0; if (ip3 >= ilimit) { goto _cleanup; @@ -234,15 +236,16 @@ _start: /* Requires: ip0 */ if (ip2 >= nextStep) { PREFETCH_L1(ip1 + 64); PREFETCH_L1(ip1 + 128); - step++; + step0++; + step1++; nextStep += kStepIncr; } /* advance to next positions */ ip0 = ip1; ip1 = ip2; - ip2 = ip2 + step + stepSize; - ip3 = ip2 + step; + ip2 = ip2 + step1; + ip3 = ip2 + step0; } while (ip3 < ilimit); _cleanup: From c94cda283ccf42293bc2752fa9f9ac7122ff3326 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 10 Dec 2021 20:56:20 -0800 Subject: [PATCH 313/340] added x32 compatibility test --- .github/workflows/dev-short-tests.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index 4ff9cac93..b5cd2415d 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -37,6 +37,18 @@ jobs: APT_PACKAGES="gcc-multilib" make apt-install CFLAGS="-m32 -O1 -fstack-protector" make check V=1 + check-x32: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: make check on x32 ABI # https://en.wikipedia.org/wiki/X32_ABI + env: + CHECK_CONSTRAINED_MEM: true + run: | + sudo apt update + APT_PACKAGES="gcc-multilib" make apt-install + CFLAGS="-mx32 -O1 -fstack-protector" make check V=1 + gcc-7-libzstd: runs-on: ubuntu-latest steps: From e1ab2200ffe30467af09140f72ece76708c0eb31 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 10 Dec 2021 21:02:17 -0800 Subject: [PATCH 314/340] fixed x32 compatibility --- lib/decompress/huf_decompress.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index a00f938ce..fa61968ba 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -172,8 +172,9 @@ static size_t HUF_DecompressAsmArgs_init(HUF_DecompressAsmArgs* args, void* dst, BYTE* const oend = (BYTE*)dst + dstSize; - /* We're assuming x86-64 BMI2 - assure that this is the case. */ - assert(MEM_isLittleEndian() && !MEM_32bits()); + /* The following condition is false on x32 platform, + * but HUF_asm is not compatible with this ABI */ + if (!(MEM_isLittleEndian() && !MEM_32bits())) return 1; /* strict minimum : jump table + 1 byte per stream */ if (srcSize < 10) From e0f9dc0dde79b62b5ab4fa35e48cd8ff7adcbb3a Mon Sep 17 00:00:00 2001 From: Adrian Castro <562969+IAL32@users.noreply.github.com> Date: Sat, 11 Dec 2021 12:02:23 +0100 Subject: [PATCH 315/340] typo: Small spelling mistake in example Just a couple of characters: `main` -> `may` --- examples/streaming_compression.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c index 87cb887de..ff1875829 100644 --- a/examples/streaming_compression.c +++ b/examples/streaming_compression.c @@ -135,6 +135,6 @@ int main(int argc, const char** argv) compressFile_orDie(inFilename, outFilename, cLevel, nbThreads); free(outFilename); /* not strictly required, since program execution stops there, - * but some static analyzer main complain otherwise */ + * but some static analyzer may complain otherwise */ return 0; } From c69d13eb992f74ba775cd96bcdc62122e4e09355 Mon Sep 17 00:00:00 2001 From: zx123123 Date: Mon, 13 Dec 2021 08:58:42 +0800 Subject: [PATCH 316/340] Update playTests.sh --- tests/playTests.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index f3c45fa24..8a285b4e3 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -184,7 +184,7 @@ fi println "\n===> simple tests " -datagen + datagen > tmp zstd -h zstd -H @@ -793,6 +793,8 @@ cat hello.tmp world.tmp > helloworld.tmp zstd -c hello.tmp > hello.zst zstd -c world.tmp > world.zst zstd -c hello.tmp world.tmp > helloworld.zst +zstd -dc helloworld.zst > result.tmp +$DIFF helloworld.tmp result.tmp cat hello.zst world.zst > helloworld.zst zstd -dc helloworld.zst > result.tmp cat result.tmp @@ -1565,11 +1567,11 @@ if [ -n "$hasMT" ] then println "\n===> adaptive mode " roundTripTest -g270000000 " --adapt" - roundTripTest -g270000000 " --adapt=" && die "invalid compression parameter" 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 --adapt= tmp && die "invalid compression parameter" zstd -f -vv --adapt=min=10,max=9 tmp && die "--adapt must fail on incoherent bounds" println "\n===> rsyncable mode " From b8434cb754ea6c6f2869f035f2d97a112df7fa68 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 13 Dec 2021 14:46:57 -0500 Subject: [PATCH 317/340] Allow Templating `ZSTD_fast` Matchfinders on Acceleration (Lvl < -1) --- lib/compress/zstd_fast.c | 99 +++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 37 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 918b72997..b8e578bc7 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -93,7 +93,7 @@ FORCE_INLINE_TEMPLATE size_t 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) + U32 const mls, U32 const hasStep) { const ZSTD_compressionParameters* const cParams = &ms->cParams; U32* const hashTable = ms->hashTable; @@ -313,18 +313,23 @@ _match: /* Requires: ip0, match0, offcode */ goto _start; } -#define ZSTD_GEN_FAST_FN(dictMode, mls) \ - static size_t ZSTD_compressBlock_fast_##dictMode##_##mls( \ +#define ZSTD_GEN_FAST_FN(dictMode, mls, step) \ + static size_t ZSTD_compressBlock_fast_##dictMode##_##mls##_##step( \ 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); \ + return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls, step); \ } -ZSTD_GEN_FAST_FN(noDict, 4) -ZSTD_GEN_FAST_FN(noDict, 5) -ZSTD_GEN_FAST_FN(noDict, 6) -ZSTD_GEN_FAST_FN(noDict, 7) +ZSTD_GEN_FAST_FN(noDict, 4, 1) +ZSTD_GEN_FAST_FN(noDict, 5, 1) +ZSTD_GEN_FAST_FN(noDict, 6, 1) +ZSTD_GEN_FAST_FN(noDict, 7, 1) + +ZSTD_GEN_FAST_FN(noDict, 4, 0) +ZSTD_GEN_FAST_FN(noDict, 5, 0) +ZSTD_GEN_FAST_FN(noDict, 6, 0) +ZSTD_GEN_FAST_FN(noDict, 7, 0) size_t ZSTD_compressBlock_fast( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -332,24 +337,40 @@ size_t ZSTD_compressBlock_fast( { U32 const mls = ms->cParams.minMatch; assert(ms->dictMatchState == NULL); - switch(mls) - { - default: /* includes case 3 */ - case 4 : - return ZSTD_compressBlock_fast_noDict_4(ms, seqStore, rep, src, srcSize); - case 5 : - return ZSTD_compressBlock_fast_noDict_5(ms, seqStore, rep, src, srcSize); - case 6 : - return ZSTD_compressBlock_fast_noDict_6(ms, seqStore, rep, src, srcSize); - case 7 : - return ZSTD_compressBlock_fast_noDict_7(ms, seqStore, rep, src, srcSize); + if (ms->cParams.targetLength > 1) { + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize); + } + } else { + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize); + } + } } FORCE_INLINE_TEMPLATE size_t ZSTD_compressBlock_fast_dictMatchState_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize, U32 const mls) + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) { const ZSTD_compressionParameters* const cParams = &ms->cParams; U32* const hashTable = ms->hashTable; @@ -385,6 +406,8 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( assert(endIndex - prefixStartIndex <= maxDistance); (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */ + (void)hasStep; /* not currently specialized on whether it's accelerated */ + /* ensure there will be no underflow * when translating a dict index into a local index */ assert(prefixStartIndex >= (U32)(dictEnd - dictBase)); @@ -495,10 +518,10 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic( } -ZSTD_GEN_FAST_FN(dictMatchState, 4) -ZSTD_GEN_FAST_FN(dictMatchState, 5) -ZSTD_GEN_FAST_FN(dictMatchState, 6) -ZSTD_GEN_FAST_FN(dictMatchState, 7) +ZSTD_GEN_FAST_FN(dictMatchState, 4, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 5, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 6, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 7, 0) size_t ZSTD_compressBlock_fast_dictMatchState( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -510,20 +533,20 @@ size_t ZSTD_compressBlock_fast_dictMatchState( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_dictMatchState_4(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_fast_dictMatchState_5(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_fast_dictMatchState_6(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_fast_dictMatchState_7(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize); } } static size_t ZSTD_compressBlock_fast_extDict_generic( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], - void const* src, size_t srcSize, U32 const mls) + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) { const ZSTD_compressionParameters* const cParams = &ms->cParams; U32* const hashTable = ms->hashTable; @@ -547,6 +570,8 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( const BYTE* const ilimit = iend - 8; U32 offset_1=rep[0], offset_2=rep[1]; + (void)hasStep; /* not currently specialized on whether it's accelerated */ + DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1); /* switch to "regular" variant if extDict is invalidated due to maxDistance */ @@ -624,10 +649,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) +ZSTD_GEN_FAST_FN(extDict, 4, 0) +ZSTD_GEN_FAST_FN(extDict, 5, 0) +ZSTD_GEN_FAST_FN(extDict, 6, 0) +ZSTD_GEN_FAST_FN(extDict, 7, 0) size_t ZSTD_compressBlock_fast_extDict( ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], @@ -638,12 +663,12 @@ size_t ZSTD_compressBlock_fast_extDict( { default: /* includes case 3 */ case 4 : - return ZSTD_compressBlock_fast_extDict_4(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize); case 5 : - return ZSTD_compressBlock_fast_extDict_5(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize); case 6 : - return ZSTD_compressBlock_fast_extDict_6(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize); case 7 : - return ZSTD_compressBlock_fast_extDict_7(ms, seqStore, rep, src, srcSize); + return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize); } } From 6ca5f424025d0f34cf1234cde0ba13b20469da46 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 13 Dec 2021 14:48:26 -0500 Subject: [PATCH 318/340] Rewrite `step` to Track Increment Between Pairs of Positions The position updates are rewritten from `ip[N] = ip[N-1] + step` to be `ip[N] = ip[N-2] + step`. This lets us only deal with the asymmetric spacing of gaps at setup and then we only have to keep a single `step` variable. This seems to work quite well on GCC and Clang! --- lib/compress/zstd_fast.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index b8e578bc7..852f4286f 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -99,7 +99,7 @@ ZSTD_compressBlock_fast_noDict_generic( U32* const hashTable = ms->hashTable; U32 const hlog = cParams->hashLog; /* support stepSize of 0 */ - size_t const stepSize = cParams->targetLength + !(cParams->targetLength); + size_t const stepSize = hasStep ? (cParams->targetLength + !(cParams->targetLength) + 1) : 2; const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); @@ -128,8 +128,11 @@ ZSTD_compressBlock_fast_noDict_generic( const BYTE* match0; size_t mLength; - size_t step0; - size_t step1; + /* ip0 and ip1 are always adjacent. The targetLength skipping and + * uncompressibility acceleration is applied to every other position, + * matching the behavior of #1562. step therefore represents the gap + * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */ + size_t step; const BYTE* nextStep; const size_t kStepIncr = (1 << (kSearchStrength - 1)); @@ -145,14 +148,13 @@ ZSTD_compressBlock_fast_noDict_generic( /* start each op */ _start: /* Requires: ip0 */ - step0 = 1; - step1 = stepSize; + step = stepSize; nextStep = ip0 + kStepIncr; /* calculate positions, ip0 - anchor == 0, so we skip step calc */ - ip1 = ip0 + step0; - ip2 = ip1 + step1; - ip3 = ip2 + step0; + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; if (ip3 >= ilimit) { goto _cleanup; @@ -236,16 +238,15 @@ _start: /* Requires: ip0 */ if (ip2 >= nextStep) { PREFETCH_L1(ip1 + 64); PREFETCH_L1(ip1 + 128); - step0++; - step1++; + step += 2; nextStep += kStepIncr; } /* advance to next positions */ ip0 = ip1; ip1 = ip2; - ip2 = ip2 + step1; - ip3 = ip2 + step0; + ip2 = ip0 + step; + ip3 = ip1 + step; } while (ip3 < ilimit); _cleanup: From 82a49c88f917c73b56780398fee65665a6e2a25e Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 13 Dec 2021 15:46:41 -0500 Subject: [PATCH 319/340] Increment Step by 1 not 2 I couldn't find a good way to spread `ip0` and `ip1` apart when we accelerate due to incompressible inputs. (The methods I tried slowed things down quite a bit.) Since we aren't splaying ip0 and ip1 apart (which would be like `0_1_2_3_`, as opposed to the `01__23__` we were actually doing), it's a big ambitious to increment `step` by 2. Instead, let's increment it by 1, which has the benefit sliiightly improving compression. Speed remains pretty much unchanged. --- lib/compress/zstd_fast.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index 852f4286f..2bae2f70e 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -234,19 +234,19 @@ _start: /* Requires: ip0 */ hash0 = hash1; hash1 = ZSTD_hashPtr(ip2, hlog, mls); - /* calculate step */ - if (ip2 >= nextStep) { - PREFETCH_L1(ip1 + 64); - PREFETCH_L1(ip1 + 128); - step += 2; - nextStep += kStepIncr; - } - /* advance to next positions */ ip0 = ip1; ip1 = ip2; ip2 = ip0 + step; ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } } while (ip3 < ilimit); _cleanup: From 450fca97048349b18241a074c49641bab8de9331 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Mon, 13 Dec 2021 17:29:32 -0500 Subject: [PATCH 320/340] Update Regression Tests w/ New Sizes --- tests/fuzzer.c | 2 +- tests/regression/results.csv | 224 +++++++++++++++++------------------ 2 files changed, 113 insertions(+), 113 deletions(-) diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 6d36c3393..c35be8e26 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -1970,7 +1970,7 @@ static int basicUnitTests(U32 const seed, double compressibility) 3742, 3675, 3674, 3665, 3664, 3663, 3662, 3661, 3660, 3660, 3660, 3660, 3660 }; - size_t const target_wdict_cSize[22+1] = { 2830, 2896, 2890, 2820, 2940, + size_t const target_wdict_cSize[22+1] = { 2830, 2896, 2893, 2820, 2940, 2950, 2950, 2925, 2900, 2891, 2910, 2910, 2910, 2780, 2775, 2765, 2760, 2755, 2754, 2753, diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 9a19d33cc..f9b46bd68 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, 7359401 -silesia.tar, level -3, compress simple, 6901672 -silesia.tar, level -1, compress simple, 6182241 +silesia.tar, level -5, compress simple, 6853608 +silesia.tar, level -3, compress simple, 6505969 +silesia.tar, level -1, compress simple, 6179026 silesia.tar, level 0, compress simple, 4854086 -silesia.tar, level 1, compress simple, 5331946 +silesia.tar, level 1, compress simple, 5327373 silesia.tar, level 3, compress simple, 4854086 silesia.tar, level 4, compress simple, 4791503 silesia.tar, level 5, compress simple, 4649987 @@ -15,9 +15,9 @@ silesia.tar, level 16, compress silesia.tar, level 19, compress simple, 4267266 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 +silesia.tar, huffman literals, compress simple, 6179026 +github.tar, level -5, compress simple, 52110 +github.tar, level -3, compress simple, 45678 github.tar, level -1, compress simple, 42560 github.tar, level 0, compress simple, 38831 github.tar, level 1, compress simple, 39200 @@ -33,11 +33,11 @@ github.tar, level 19, compress 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 -5, compress cctx, 6852424 +silesia, level -3, compress cctx, 6503413 +silesia, level -1, compress cctx, 6172178 silesia, level 0, compress cctx, 4842075 -silesia, level 1, compress cctx, 5309098 +silesia, level 1, compress cctx, 5306426 silesia, level 3, compress cctx, 4842075 silesia, level 4, compress cctx, 4779186 silesia, level 5, compress cctx, 4638691 @@ -56,11 +56,11 @@ silesia, small chain log, compress silesia, explicit params, compress cctx, 4794052 silesia, uncompressed literals, compress cctx, 4842075 silesia, uncompressed literals optimal, compress cctx, 4296880 -silesia, huffman literals, compress cctx, 6177565 +silesia, huffman literals, compress cctx, 6172178 silesia, multithreaded with advanced params, compress cctx, 4842075 -github, level -5, compress cctx, 232315 +github, level -5, compress cctx, 204411 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 220760 +github, level -3, compress cctx, 193253 github, level -3 with dict, compress cctx, 48047 github, level -1, compress cctx, 175468 github, level -1 with dict, compress cctx, 43527 @@ -97,11 +97,11 @@ github, uncompressed literals, compress github, uncompressed literals optimal, compress cctx, 134064 github, huffman literals, compress cctx, 175468 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 -5, zstdcli, 6852472 +silesia, level -3, zstdcli, 6503461 +silesia, level -1, zstdcli, 6172226 silesia, level 0, zstdcli, 4842123 -silesia, level 1, zstdcli, 5309146 +silesia, level 1, zstdcli, 5306474 silesia, level 3, zstdcli, 4842123 silesia, level 4, zstdcli, 4779234 silesia, level 5, zstdcli, 4638739 @@ -120,13 +120,13 @@ silesia, small chain log, zstdcli, silesia, explicit params, zstdcli, 4795432 silesia, uncompressed literals, zstdcli, 5120614 silesia, uncompressed literals optimal, zstdcli, 4319566 -silesia, huffman literals, zstdcli, 5326394 +silesia, huffman literals, zstdcli, 5321394 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 -5, zstdcli, 6853994 +silesia.tar, level -3, zstdcli, 6506742 +silesia.tar, level -1, zstdcli, 6179765 silesia.tar, level 0, zstdcli, 4854164 -silesia.tar, level 1, zstdcli, 5333183 +silesia.tar, level 1, zstdcli, 5328534 silesia.tar, level 3, zstdcli, 4854164 silesia.tar, level 4, zstdcli, 4792352 silesia.tar, level 5, zstdcli, 4650946 @@ -146,11 +146,11 @@ silesia.tar, small chain log, zstdcli, silesia.tar, explicit params, zstdcli, 4820713 silesia.tar, uncompressed literals, zstdcli, 5122571 silesia.tar, uncompressed literals optimal, zstdcli, 4310145 -silesia.tar, huffman literals, zstdcli, 5344915 +silesia.tar, huffman literals, zstdcli, 5342054 silesia.tar, multithreaded with advanced params, zstdcli, 5122571 -github, level -5, zstdcli, 234315 +github, level -5, zstdcli, 206411 github, level -5 with dict, zstdcli, 48718 -github, level -3, zstdcli, 222760 +github, level -3, zstdcli, 195253 github, level -3 with dict, zstdcli, 47395 github, level -1, zstdcli, 177468 github, level -1 with dict, zstdcli, 45170 @@ -187,10 +187,10 @@ github, uncompressed literals, zstdcli, github, uncompressed literals optimal, zstdcli, 159227 github, huffman literals, zstdcli, 144365 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 -5, zstdcli, 52114 +github.tar, level -5 with dict, zstdcli, 46502 +github.tar, level -3, zstdcli, 45682 +github.tar, level -3 with dict, zstdcli, 42181 github.tar, level -1, zstdcli, 42564 github.tar, level -1 with dict, zstdcli, 41140 github.tar, level 0, zstdcli, 38835 @@ -228,11 +228,11 @@ github.tar, uncompressed literals, zstdcli, github.tar, uncompressed literals optimal, zstdcli, 35401 github.tar, huffman literals, zstdcli, 38857 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 -5, advanced one pass, 6852424 +silesia, level -3, advanced one pass, 6503413 +silesia, level -1, advanced one pass, 6172178 silesia, level 0, advanced one pass, 4842075 -silesia, level 1, advanced one pass, 5309098 +silesia, level 1, advanced one pass, 5306426 silesia, level 3, advanced one pass, 4842075 silesia, level 4, advanced one pass, 4779186 silesia, level 5 row 1, advanced one pass, 4638691 @@ -260,13 +260,13 @@ silesia, small chain log, advanced silesia, explicit params, advanced one pass, 4795432 silesia, uncompressed literals, advanced one pass, 5120566 silesia, uncompressed literals optimal, advanced one pass, 4319518 -silesia, huffman literals, advanced one pass, 5326346 +silesia, huffman literals, advanced one pass, 5321346 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 -5, advanced one pass, 6853608 +silesia.tar, level -3, advanced one pass, 6505969 +silesia.tar, level -1, advanced one pass, 6179026 silesia.tar, level 0, advanced one pass, 4854086 -silesia.tar, level 1, advanced one pass, 5331946 +silesia.tar, level 1, advanced one pass, 5327373 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 @@ -294,11 +294,11 @@ silesia.tar, small chain log, advanced silesia.tar, explicit params, advanced one pass, 4806855 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, huffman literals, advanced one pass, 5341685 silesia.tar, multithreaded with advanced params, advanced one pass, 5122567 -github, level -5, advanced one pass, 232315 +github, level -5, advanced one pass, 204411 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 220760 +github, level -3, advanced one pass, 193253 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 @@ -421,10 +421,10 @@ github, uncompressed literals, advanced github, uncompressed literals optimal, advanced one pass, 157227 github, huffman literals, advanced one pass, 142365 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 -5, advanced one pass, 52110 +github.tar, level -5 with dict, advanced one pass, 46498 +github.tar, level -3, advanced one pass, 45678 +github.tar, level -3 with dict, advanced one pass, 42177 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, 38831 @@ -546,11 +546,11 @@ github.tar, uncompressed literals, advanced 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, 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 -5, advanced one pass small out, 6852424 +silesia, level -3, advanced one pass small out, 6503413 +silesia, level -1, advanced one pass small out, 6172178 silesia, level 0, advanced one pass small out, 4842075 -silesia, level 1, advanced one pass small out, 5309098 +silesia, level 1, advanced one pass small out, 5306426 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 @@ -578,13 +578,13 @@ silesia, small chain log, advanced silesia, explicit params, advanced one pass small out, 4795432 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, huffman literals, advanced one pass small out, 5321346 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 -5, advanced one pass small out, 6853608 +silesia.tar, level -3, advanced one pass small out, 6505969 +silesia.tar, level -1, advanced one pass small out, 6179026 silesia.tar, level 0, advanced one pass small out, 4854086 -silesia.tar, level 1, advanced one pass small out, 5331946 +silesia.tar, level 1, advanced one pass small out, 5327373 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 @@ -612,11 +612,11 @@ silesia.tar, small chain log, advanced silesia.tar, explicit params, advanced one pass small out, 4806855 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, huffman literals, advanced one pass small out, 5341685 silesia.tar, multithreaded with advanced params, advanced one pass small out, 5122567 -github, level -5, advanced one pass small out, 232315 +github, level -5, advanced one pass small out, 204411 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, 193253 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 @@ -739,10 +739,10 @@ github, uncompressed literals, advanced 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, 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 -5, advanced one pass small out, 52110 +github.tar, level -5 with dict, advanced one pass small out, 46498 +github.tar, level -3, advanced one pass small out, 45678 +github.tar, level -3 with dict, advanced one pass small out, 42177 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, 38831 @@ -864,11 +864,11 @@ github.tar, uncompressed literals, advanced 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, 41525 -silesia, level -5, advanced streaming, 7292053 -silesia, level -3, advanced streaming, 6867875 -silesia, level -1, advanced streaming, 6183923 +silesia, level -5, advanced streaming, 6963781 +silesia, level -3, advanced streaming, 6610376 +silesia, level -1, advanced streaming, 6179294 silesia, level 0, advanced streaming, 4842075 -silesia, level 1, advanced streaming, 5312694 +silesia, level 1, advanced streaming, 5310178 silesia, level 3, advanced streaming, 4842075 silesia, level 4, advanced streaming, 4779186 silesia, level 5 row 1, advanced streaming, 4638691 @@ -896,13 +896,13 @@ silesia, small chain log, advanced silesia, explicit params, advanced streaming, 4795452 silesia, uncompressed literals, advanced streaming, 5120566 silesia, uncompressed literals optimal, advanced streaming, 4319518 -silesia, huffman literals, advanced streaming, 5332234 +silesia, huffman literals, advanced streaming, 5327881 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 -5, advanced streaming, 7043687 +silesia.tar, level -3, advanced streaming, 6671317 +silesia.tar, level -1, advanced streaming, 6187457 silesia.tar, level 0, advanced streaming, 4859271 -silesia.tar, level 1, advanced streaming, 5334890 +silesia.tar, level 1, advanced streaming, 5333896 silesia.tar, level 3, advanced streaming, 4859271 silesia.tar, level 4, advanced streaming, 4797470 silesia.tar, level 5 row 1, advanced streaming, 4649992 @@ -930,11 +930,11 @@ silesia.tar, small chain log, advanced silesia.tar, explicit params, advanced streaming, 4806873 silesia.tar, uncompressed literals, advanced streaming, 5127423 silesia.tar, uncompressed literals optimal, advanced streaming, 4310141 -silesia.tar, huffman literals, advanced streaming, 5350519 +silesia.tar, huffman literals, advanced streaming, 5349624 silesia.tar, multithreaded with advanced params, advanced streaming, 5122567 -github, level -5, advanced streaming, 232315 +github, level -5, advanced streaming, 204411 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 220760 +github, level -3, advanced streaming, 193253 github, level -3 with dict, advanced streaming, 45395 github, level -1, advanced streaming, 175468 github, level -1 with dict, advanced streaming, 43170 @@ -1057,10 +1057,10 @@ github, uncompressed literals, advanced github, uncompressed literals optimal, advanced streaming, 157227 github, huffman literals, advanced streaming, 142365 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 -5, advanced streaming, 51420 +github.tar, level -5 with dict, advanced streaming, 45495 +github.tar, level -3, advanced streaming, 45077 +github.tar, level -3 with dict, advanced streaming, 41627 github.tar, level -1, advanced streaming, 42536 github.tar, level -1 with dict, advanced streaming, 41198 github.tar, level 0, advanced streaming, 38831 @@ -1182,11 +1182,11 @@ github.tar, uncompressed literals, advanced github.tar, uncompressed literals optimal, advanced streaming, 35397 github.tar, huffman literals, advanced streaming, 38874 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 -5, old streaming, 6963781 +silesia, level -3, old streaming, 6610376 +silesia, level -1, old streaming, 6179294 silesia, level 0, old streaming, 4842075 -silesia, level 1, old streaming, 5312694 +silesia, level 1, old streaming, 5310178 silesia, level 3, old streaming, 4842075 silesia, level 4, old streaming, 4779186 silesia, level 5, old streaming, 4638691 @@ -1199,12 +1199,12 @@ silesia, level 19, old stre 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, huffman literals, old streaming, 6179294 +silesia.tar, level -5, old streaming, 7043687 +silesia.tar, level -3, old streaming, 6671317 +silesia.tar, level -1, old streaming, 6187457 silesia.tar, level 0, old streaming, 4859271 -silesia.tar, level 1, old streaming, 5334890 +silesia.tar, level 1, old streaming, 5333896 silesia.tar, level 3, old streaming, 4859271 silesia.tar, level 4, old streaming, 4797470 silesia.tar, level 5, old streaming, 4649992 @@ -1217,10 +1217,10 @@ silesia.tar, level 19, old stre 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 +silesia.tar, huffman literals, old streaming, 6187457 +github, level -5, old streaming, 204411 github, level -5 with dict, old streaming, 46718 -github, level -3, old streaming, 220760 +github, level -3, old streaming, 193253 github, level -3 with dict, old streaming, 45395 github, level -1, old streaming, 175468 github, level -1 with dict, old streaming, 43170 @@ -1251,10 +1251,10 @@ github, no source size with dict, old stre 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 -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 -5, old streaming, 51420 +github.tar, level -5 with dict, old streaming, 45495 +github.tar, level -3, old streaming, 45077 +github.tar, level -3 with dict, old streaming, 41627 github.tar, level -1, old streaming, 42536 github.tar, level -1 with dict, old streaming, 41198 github.tar, level 0, old streaming, 38831 @@ -1284,11 +1284,11 @@ github.tar, no source size with dict, old stre 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 -5, old streaming advanced, 6963781 +silesia, level -3, old streaming advanced, 6610376 +silesia, level -1, old streaming advanced, 6179294 silesia, level 0, old streaming advanced, 4842075 -silesia, level 1, old streaming advanced, 5312694 +silesia, level 1, old streaming advanced, 5310178 silesia, level 3, old streaming advanced, 4842075 silesia, level 4, old streaming advanced, 4779186 silesia, level 5, old streaming advanced, 4638691 @@ -1308,13 +1308,13 @@ silesia, small chain log, old stre silesia, explicit params, old streaming advanced, 4795452 silesia, uncompressed literals, old streaming advanced, 4842075 silesia, uncompressed literals optimal, old streaming advanced, 4296880 -silesia, huffman literals, old streaming advanced, 6183923 +silesia, huffman literals, old streaming advanced, 6179294 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 -5, old streaming advanced, 7043687 +silesia.tar, level -3, old streaming advanced, 6671317 +silesia.tar, level -1, old streaming advanced, 6187457 silesia.tar, level 0, old streaming advanced, 4859271 -silesia.tar, level 1, old streaming advanced, 5334890 +silesia.tar, level 1, old streaming advanced, 5333896 silesia.tar, level 3, old streaming advanced, 4859271 silesia.tar, level 4, old streaming advanced, 4797470 silesia.tar, level 5, old streaming advanced, 4649992 @@ -1334,11 +1334,11 @@ silesia.tar, small chain log, old stre silesia.tar, explicit params, old streaming advanced, 4806873 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, huffman literals, old streaming advanced, 6187457 silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 -github, level -5, old streaming advanced, 241214 +github, level -5, old streaming advanced, 213265 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 222937 +github, level -3, old streaming advanced, 196126 github, level -3 with dict, old streaming advanced, 44956 github, level -1, old streaming advanced, 181107 github, level -1 with dict, old streaming advanced, 42383 @@ -1377,10 +1377,10 @@ github, uncompressed literals, old stre github, uncompressed literals optimal, old streaming advanced, 134064 github, huffman literals, old streaming advanced, 181107 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 -5, old streaming advanced, 51420 +github.tar, level -5 with dict, old streaming advanced, 46091 +github.tar, level -3, old streaming advanced, 45077 +github.tar, level -3 with dict, old streaming advanced, 42222 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, 38831 @@ -1433,8 +1433,8 @@ 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 -5 with dict, old streaming cdict, 46276 +github.tar, level -3 with dict, old streaming cdict, 42354 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, 38761 From 05430b25a860534f5cac2629d97b2d6a34922c89 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 14 Dec 2021 02:12:09 -0800 Subject: [PATCH 321/340] roll SSE implementation of row_lazy match finder mostly for maintenance convenience. Performance wise, there is very little change, slightly faster for slog 3 & 4, neutral or very slightly negative for slot 5 & 6. --- lib/compress/zstd_lazy.c | 80 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 5326ec5f3..a585b79d4 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -417,7 +417,7 @@ void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const B U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; U32* const tmpHashTable = hashTable; U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog); - U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; + U32 const tmpChainSize = (U32)((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx; U32 hashIdx; @@ -982,47 +982,45 @@ void ZSTD_row_update(ZSTD_matchState_t* const ms, const BYTE* ip) { ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* dont use cache */); } +#if defined(ZSTD_ARCH_X86_SSE2) +FORCE_INLINE_TEMPLATE ZSTD_VecMask +ZSTD_row_getSSEMask(int nbChunks, const BYTE* const src, const BYTE tag, const U32 head) +{ + const __m128i comparisonMask = _mm_set1_epi8((char)tag); + int matches[4] = {0}; + int i; + assert(nbChunks == 1 || nbChunks == 2 || nbChunks == 4); + for (i=0; ianchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ @@ -1670,7 +1668,7 @@ ZSTD_compressBlock_lazy_generic( } /* store sequence */ _storeSequence: - { size_t const litLength = start - anchor; + { size_t const litLength = (size_t)(start - anchor); ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } @@ -2003,7 +2001,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( /* catch up */ if (offset) { - U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE)); + U32 const matchIndex = (U32)((size_t)(start-base) - (offset - ZSTD_REP_MOVE)); const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ @@ -2012,7 +2010,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( /* store sequence */ _storeSequence: - { size_t const litLength = start - anchor; + { size_t const litLength = (size_t)(start - anchor); ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH); anchor = ip = start + matchLength; } From 71c0c07c190fcb354ac16feef2a5afd7616422c2 Mon Sep 17 00:00:00 2001 From: Elliot Gorokhovsky Date: Fri, 10 Dec 2021 16:19:40 -0500 Subject: [PATCH 322/340] Allow user to specify memory limit for dictionary training --- programs/dibio.c | 7 ++++++- programs/dibio.h | 2 +- programs/zstd.1.md | 6 ++++++ programs/zstdcli.c | 6 +++--- tests/playTests.sh | 7 +++++++ 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/programs/dibio.c b/programs/dibio.c index e7fb905ec..04860dbbf 100644 --- a/programs/dibio.c +++ b/programs/dibio.c @@ -309,7 +309,7 @@ static fileStats DiB_fileStats(const char** fileNamesTable, int nbFiles, size_t 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) + ZDICT_fastCover_params_t* fastCoverParams, int optimize, unsigned memLimit) { fileStats fs; size_t* sampleSizes; /* vector of sample sizes. Each sample can be up to SAMPLESIZE_MAX */ @@ -341,6 +341,11 @@ int DiB_trainFromFiles(const char* dictFileName, size_t maxDictSize, /* Limit the size of the training data to 2GB */ /* TODO: there is opportunity to stop DiB_fileStats() early when the data limit is reached */ loadedSize = (size_t)MIN( MIN((S64)maxMem, fs.totalSizeToLoad), MAX_SAMPLES_SIZE ); + if (memLimit != 0) { + DISPLAYLEVEL(2, "! Warning : setting manual memory limit for dictionary training data at %u MB \n", + (unsigned)(memLimit / (1 MB))); + loadedSize = (size_t)MIN(loadedSize, memLimit); + } srcBuffer = malloc(loadedSize+NOISELENGTH); sampleSizes = (size_t*)malloc(fs.nbSamples * sizeof(size_t)); } diff --git a/programs/dibio.h b/programs/dibio.h index 03ec80e59..666c1e661 100644 --- a/programs/dibio.h +++ b/programs/dibio.h @@ -34,6 +34,6 @@ 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); + ZDICT_fastCover_params_t* fastCoverParams, int optimize, unsigned memLimit); #endif diff --git a/programs/zstd.1.md b/programs/zstd.1.md index ef37fef32..e343ec044 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -190,6 +190,10 @@ the last one takes effect. 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). + + Additionally, this can be used to limit memory for dictionary training. This parameter + overrides the default limit of 2 GB. zstd will load training samples up to the memory limit + and ignore the rest. * `--stream-size=#` : 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. @@ -329,6 +333,8 @@ Compression of small files similar to the sample set will be greatly improved. resulting in a _small_ compression ratio improvement for this level. * `-B#`: Split input files into blocks of size # (default: no split) +* `-M#`, `--memory=#`: + Limit the amount of sample data loaded for training (default: 2 GB). See above for details. * `--dictID=#`: A dictionary ID is a locally unique ID that a decoder can use to verify it is using the right dictionary. diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 4d1978c80..bfe18c0c1 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -1327,18 +1327,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, (int)filenames->tableSize, blockSize, NULL, &coverParams, NULL, optimize); + operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, &coverParams, NULL, optimize, memLimit); } 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, (int)filenames->tableSize, blockSize, NULL, NULL, &fastCoverParams, optimize); + operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, NULL, NULL, &fastCoverParams, optimize, memLimit); } else { ZDICT_legacy_params_t dictParams; memset(&dictParams, 0, sizeof(dictParams)); dictParams.selectivityLevel = dictSelect; dictParams.zParams = zParams; - operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, &dictParams, NULL, NULL, 0); + operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenames->fileNames, (int)filenames->tableSize, blockSize, &dictParams, NULL, NULL, 0, memLimit); } #else (void)dictCLevel; (void)dictSelect; (void)dictID; (void)maxDictSize; /* not used when ZSTD_NODICT set */ diff --git a/tests/playTests.sh b/tests/playTests.sh index f6b6ac8f2..ebe7bf289 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1029,6 +1029,13 @@ then fi rm -f tmp* dictionary +println "- Test --memory for dictionary compression" +datagen -g12M -P90 > tmpCorpusHighCompress +zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=10K && die "Dictionary training should fail : --memory too low (10K)" +zstd --train -B2K tmpCorpusHighCompress -o tmpDictHighCompress --memory=5MB 2> zstTrainWithMemLimitStdErr +cat zstTrainWithMemLimitStdErr | grep "setting manual memory limit for dictionary training data at 5 MB" +cat zstTrainWithMemLimitStdErr | grep "Training samples set too large (12 MB); training on 5 MB only..." +rm zstTrainWithMemLimitStdErr println "\n===> fastCover dictionary builder : advanced options " TESTFILE="$PRGDIR"/zstdcli.c From 64205b7832fa0b4433214e26c294545b4c962834 Mon Sep 17 00:00:00 2001 From: binhdvo Date: Tue, 14 Dec 2021 15:53:50 -0500 Subject: [PATCH 323/340] Fix performance degradation with -m32 (#2926) --- lib/common/zstd_internal.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 9073df422..3dc14bb14 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -188,8 +188,13 @@ static void ZSTD_copy16(void* dst, const void* src) { 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 +#elif defined(__clang__) ZSTD_memmove(dst, src, 16); +#else + /* ZSTD_memmove is not inlined properly by gcc */ + BYTE copy16_buf[16]; + ZSTD_memcpy(copy16_buf, src, 16); + ZSTD_memcpy(dst, copy16_buf, 16); #endif } #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; } From 99923dfc1a93479d7024289a87ac5a4749c701a7 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Tue, 14 Dec 2021 22:33:39 +0100 Subject: [PATCH 324/340] Add typedefs for 8bit (un)signed To make code more expressive, add U8 and S8 typedefs --- contrib/linux-kernel/mem.h | 2 ++ lib/common/mem.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/contrib/linux-kernel/mem.h b/contrib/linux-kernel/mem.h index dcdd586a9..1d9cc0392 100644 --- a/contrib/linux-kernel/mem.h +++ b/contrib/linux-kernel/mem.h @@ -30,6 +30,8 @@ * Basic Types *****************************************************************/ typedef uint8_t BYTE; +typedef uint8_t U8; +typedef int8_t S8; typedef uint16_t U16; typedef int16_t S16; typedef uint32_t U32; diff --git a/lib/common/mem.h b/lib/common/mem.h index 1c61b7e52..85581c384 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -51,6 +51,8 @@ extern "C" { # include /* intptr_t */ # endif typedef uint8_t BYTE; + typedef uint8_t U8; + typedef int8_t S8; typedef uint16_t U16; typedef int16_t S16; typedef uint32_t U32; @@ -63,6 +65,8 @@ extern "C" { # error "this implementation requires char to be exactly 8-bit type" #endif typedef unsigned char BYTE; + typedef unsigned char U8; + typedef signed char S8; #if USHRT_MAX != 65535 # error "this implementation requires short to be exactly 16-bit type" #endif From 2fbb1d10c164fb927ebaa0b488470eedbf754175 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Tue, 14 Dec 2021 22:33:49 +0100 Subject: [PATCH 325/340] Reduce bit tables to 8bit This saves some 1.7Kb in rodata section (x86_64, zstd tool), while assembler code stays the same except the type of a few load/extend instructions. Should not have negative performance implications. --- lib/common/zstd_internal.h | 4 ++-- lib/compress/zstd_compress.c | 2 +- lib/compress/zstd_compress_superblock.c | 2 +- lib/decompress/zstd_decompress_block.c | 18 +++++++++--------- lib/decompress/zstd_decompress_block.h | 2 +- lib/decompress/zstd_decompress_internal.h | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 3dc14bb14..1c053b412 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -119,7 +119,7 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy /* Each table cannot take more than #symbols * FSELog bits */ #define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8) -static UNUSED_ATTR const U32 LL_bits[MaxLL+1] = { +static UNUSED_ATTR const U8 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, @@ -136,7 +136,7 @@ static UNUSED_ATTR const S16 LL_defaultNorm[MaxLL+1] = { #define LL_DEFAULTNORMLOG 6 /* for static allocation */ static UNUSED_ATTR const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG; -static UNUSED_ATTR const U32 ML_bits[MaxML+1] = { +static UNUSED_ATTR const U8 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f9466e1ed..e3d40c540 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3263,7 +3263,7 @@ static size_t ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSiz static size_t ZSTD_estimateBlockSize_symbolType(symbolEncodingType_e type, const BYTE* codeTable, size_t nbSeq, unsigned maxCode, const FSE_CTable* fseCTable, - const U32* additionalBits, + const U8* additionalBits, short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, void* workspace, size_t wkspSize) { diff --git a/lib/compress/zstd_compress_superblock.c b/lib/compress/zstd_compress_superblock.c index bcbe158b7..67e1abb11 100644 --- a/lib/compress/zstd_compress_superblock.c +++ b/lib/compress/zstd_compress_superblock.c @@ -325,7 +325,7 @@ static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t lit static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type, const BYTE* codeTable, unsigned maxCode, size_t nbSeq, const FSE_CTable* fseCTable, - const U32* additionalBits, + const U8* additionalBits, short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, void* workspace, size_t wkspSize) { diff --git a/lib/decompress/zstd_decompress_block.c b/lib/decompress/zstd_decompress_block.c index e548844ce..2e44d30d2 100644 --- a/lib/decompress/zstd_decompress_block.c +++ b/lib/decompress/zstd_decompress_block.c @@ -419,7 +419,7 @@ static const ZSTD_seqSymbol ML_defaultDTable[(1<nbBits = 0; cell->nextState = 0; assert(nbAddBits < 255); - cell->nbAdditionalBits = (BYTE)nbAddBits; + cell->nbAdditionalBits = nbAddBits; cell->baseValue = baseValue; } @@ -443,7 +443,7 @@ static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddB FORCE_INLINE_TEMPLATE void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, - const U32* baseValue, const U32* nbAdditionalBits, + const U32* baseValue, const U8* nbAdditionalBits, unsigned tableLog, void* wksp, size_t wkspSize) { ZSTD_seqSymbol* const tableDecode = dt+1; @@ -554,7 +554,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) ); tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize); assert(nbAdditionalBits[symbol] < 255); - tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol]; + tableDecode[u].nbAdditionalBits = nbAdditionalBits[symbol]; tableDecode[u].baseValue = baseValue[symbol]; } } @@ -563,7 +563,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, /* Avoids the FORCE_INLINE of the _body() function. */ static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, - const U32* baseValue, const U32* nbAdditionalBits, + const U32* baseValue, const U8* nbAdditionalBits, unsigned tableLog, void* wksp, size_t wkspSize) { ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue, @@ -573,7 +573,7 @@ static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt, #if DYNAMIC_BMI2 BMI2_TARGET_ATTRIBUTE static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, - const U32* baseValue, const U32* nbAdditionalBits, + const U32* baseValue, const U8* nbAdditionalBits, unsigned tableLog, void* wksp, size_t wkspSize) { ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue, @@ -583,7 +583,7 @@ BMI2_TARGET_ATTRIBUTE static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* d void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, - const U32* baseValue, const U32* nbAdditionalBits, + const U32* baseValue, const U8* nbAdditionalBits, unsigned tableLog, void* wksp, size_t wkspSize, int bmi2) { #if DYNAMIC_BMI2 @@ -605,7 +605,7 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr, symbolEncodingType_e type, unsigned max, U32 maxLog, const void* src, size_t srcSize, - const U32* baseValue, const U32* nbAdditionalBits, + const U32* baseValue, const U8* nbAdditionalBits, const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable, int ddictIsCold, int nbSeq, U32* wksp, size_t wkspSize, int bmi2) @@ -617,7 +617,7 @@ static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymb RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected, ""); { U32 const symbol = *(const BYTE*)src; U32 const baseline = baseValue[symbol]; - U32 const nbBits = nbAdditionalBits[symbol]; + U8 const nbBits = nbAdditionalBits[symbol]; ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); } *DTablePtr = DTableSpace; diff --git a/lib/decompress/zstd_decompress_block.h b/lib/decompress/zstd_decompress_block.h index 4828d6a9f..c61a9d0c4 100644 --- a/lib/decompress/zstd_decompress_block.h +++ b/lib/decompress/zstd_decompress_block.h @@ -60,7 +60,7 @@ size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, */ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, const short* normalizedCounter, unsigned maxSymbolValue, - const U32* baseValue, const U32* nbAdditionalBits, + const U32* baseValue, const U8* nbAdditionalBits, unsigned tableLog, void* wksp, size_t wkspSize, int bmi2); diff --git a/lib/decompress/zstd_decompress_internal.h b/lib/decompress/zstd_decompress_internal.h index 51dc34729..2b5a53850 100644 --- a/lib/decompress/zstd_decompress_internal.h +++ b/lib/decompress/zstd_decompress_internal.h @@ -40,7 +40,7 @@ static UNUSED_ATTR const U32 OF_base[MaxOff+1] = { 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; -static UNUSED_ATTR const U32 OF_bits[MaxOff+1] = { +static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, From 622fee6140044edfc0a40d29a0f7df285428671c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 15 Dec 2021 11:56:11 -0800 Subject: [PATCH 326/340] minor changelog update, for clarity --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 52f33480c..e182b5cf4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,7 +6,7 @@ perf: improved binary size and faster compilation times, by @terrelln perf: new row64 mode, used notably in levels 11 & 12, by @senhuang42 perf: minor compression ratio improvements for small data at high levels, by @cyan4973 perf: reduced stack usage (mostly useful for Linux Kernel), by @terrelln -perf: faster detection and skipping of incompressible blocks, by @bindhvo +perf: faster compression speed on incompressible data, by @bindhvo perf: on-demand reduced ZSTD_DCtx state size, using build macro ZSTD_DECODER_INTERNAL_BUFFER, at a small cost of performance, by @bindhvo build: allows hiding static symbols in the dynamic library, using build macro, by @skitt build: support for m68k (Motorola 68000's), by @cyan4973 From c8d6067615999827235d7df15b035c689f9e7311 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 15 Dec 2021 14:37:05 -0800 Subject: [PATCH 327/340] fixed incorrect rowlog initialization the variable has only very limited usage, being only used once at the beginning of the block for prefetching only, hence the error had no impact on compression ratio. --- lib/compress/zstd_lazy.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index a585b79d4..c40473cad 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -1440,8 +1440,15 @@ ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_VTABLE) *********************************/ typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e; +/** + * This table is indexed first by the four ZSTD_dictMode_e values, and then + * by the two searchMethod_e values. NULLs are placed for configurations + * that should never occur (extDict modes go to the other implementation + * below and there is no DDSS for binary tree search yet). + */ -static ZSTD_LazyVTable const* ZSTD_selectLazyVTable(ZSTD_matchState_t const* ms, searchMethod_e searchMethod, ZSTD_dictMode_e dictMode) +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); @@ -1475,19 +1482,10 @@ ZSTD_compressBlock_lazy_generic( const BYTE* ip = istart; const BYTE* anchor = istart; const BYTE* const iend = istart + srcSize; - const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const ilimit = (searchMethod == search_rowHash) ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; const BYTE* const base = ms->window.base; const U32 prefixLowestIndex = ms->window.dictLimit; const BYTE* const prefixLowest = base + prefixLowestIndex; - const U32 rowLog = ms->cParams.searchLog < 5 ? 4 : 5; - - - /** - * This table is indexed first by the four ZSTD_dictMode_e values, and then - * by the two searchMethod_e values. NULLs are placed for configurations - * that should never occur (extDict modes go to the other implementation - * below and there is no DDSS for binary tree search yet). - */ searchMax_f const searchMax = ZSTD_selectLazyVTable(ms, searchMethod, dictMode)->searchMax; U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0; @@ -1524,6 +1522,7 @@ ZSTD_compressBlock_lazy_generic( } if (searchMethod == search_rowHash) { + const U32 rowLog = MAX(4, MIN(6, ms->cParams.searchLog)); ZSTD_row_fillHashCache(ms, base, rowLog, MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */), ms->nextToUpdate, ilimit); From db1b408a2f1681dc86d95be652a765f9fc624c0e Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 15 Dec 2021 21:33:31 -0800 Subject: [PATCH 328/340] rebalance lazy compression levels --- lib/compress/clevels.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/compress/clevels.h b/lib/compress/clevels.h index 38622f1a1..d509d07a3 100644 --- a/lib/compress/clevels.h +++ b/lib/compress/clevels.h @@ -31,14 +31,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, 4, 5, 2, ZSTD_greedy }, /* level 5 */ - { 21, 19, 20, 5, 5, 4, ZSTD_greedy }, /* level 6 */ + { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */ + { 21, 19, 19, 3, 5, 4, ZSTD_lazy }, /* 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 */ + { 21, 20, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */ + { 22, 21, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */ + { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */ + { 22, 22, 23, 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 */ From 7a347769dcf3f02e619ed7e5c7315d59de33189a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 15 Dec 2021 21:45:30 -0800 Subject: [PATCH 329/340] minor changelog update --- CHANGELOG | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index e182b5cf4..c208e3793 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,7 +3,8 @@ perf: rebalanced compression levels, to better match the intended speed/level cu perf: faster huffman decoder, using x64 assembly, by @terrelln perf: slightly faster high speed modes (strategies fast & dfast), by @felixhandte perf: improved binary size and faster compilation times, by @terrelln -perf: new row64 mode, used notably in levels 11 & 12, by @senhuang42 +perf: new row64 mode, used notably in level 12, by @senhuang42 +perf: faster mid-level compression speed in presence of highly repetitive patterns, by @senhuang42 perf: minor compression ratio improvements for small data at high levels, by @cyan4973 perf: reduced stack usage (mostly useful for Linux Kernel), by @terrelln perf: faster compression speed on incompressible data, by @bindhvo From 8a724f91cbe256e981e018f9a1002e8430cd6c51 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 01:07:15 -0800 Subject: [PATCH 330/340] minor changelog update --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index c208e3793..ad9c07957 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ build: allows hiding static symbols in the dynamic library, using build macro, b build: support for m68k (Motorola 68000's), by @cyan4973 build: improved AIX support, by @Helflym build: improved meson unofficial build, by @eli-schwartz +cli : custom memory limit when training dictionary (#2925), by @embg cli : report advanced parameters information when compressing in very verbose mode (``-vv`), by @Svetlitski-FB cli : limit --ultra levels to 21 in 32-bit mode, to reduce risks of OOM scenarios (#2885, @yoniko) From 5c6309626989516f437a777d0f386a836e400eb5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 04:46:21 -0800 Subject: [PATCH 331/340] updated benchmark for v1.5.1 answers #2764 --- README.md | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 44cce47ee..e8117a99d 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ a list of known ports and bindings is provided on [Zstandard homepage](http://ww ## Benchmarks For reference, several fast compression algorithms were tested and compared -on a server running Arch Linux (`Linux version 5.5.11-arch1-1`), -with a Core i9-9900K CPU @ 5.0GHz, +on a desktop running Ubuntu 20.04 (`Linux 5.11.0-41-generic`), +with a Core i7-9700K CPU @ 4.9GHz, using [lzbench], an open-source in-memory benchmark by @inikep compiled with [gcc] 9.3.0, on the [Silesia compression corpus]. @@ -44,25 +44,24 @@ on the [Silesia compression corpus]. | Compressor name | Ratio | Compression| Decompress.| | --------------- | ------| -----------| ---------- | -| **zstd 1.4.5 -1** | 2.884 | 500 MB/s | 1660 MB/s | -| zlib 1.2.11 -1 | 2.743 | 90 MB/s | 400 MB/s | -| brotli 1.0.7 -0 | 2.703 | 400 MB/s | 450 MB/s | -| **zstd 1.4.5 --fast=1** | 2.434 | 570 MB/s | 2200 MB/s | -| **zstd 1.4.5 --fast=3** | 2.312 | 640 MB/s | 2300 MB/s | -| quicklz 1.5.0 -1 | 2.238 | 560 MB/s | 710 MB/s | -| **zstd 1.4.5 --fast=5** | 2.178 | 700 MB/s | 2420 MB/s | -| lzo1x 2.10 -1 | 2.106 | 690 MB/s | 820 MB/s | -| lz4 1.9.2 | 2.101 | 740 MB/s | 4530 MB/s | -| **zstd 1.4.5 --fast=7** | 2.096 | 750 MB/s | 2480 MB/s | -| lzf 3.6 -1 | 2.077 | 410 MB/s | 860 MB/s | -| snappy 1.1.8 | 2.073 | 560 MB/s | 1790 MB/s | +| **zstd 1.5.1 -1** | 2.887 | 530 MB/s | 1700 MB/s | +| [zlib] 1.2.11 -1 | 2.743 | 95 MB/s | 400 MB/s | +| brotli 1.0.9 -0 | 2.702 | 395 MB/s | 450 MB/s | +| **zstd 1.4.5 --fast=1** | 2.437 | 600 MB/s | 2150 MB/s | +| **zstd 1.4.5 --fast=3** | 2.239 | 670 MB/s | 2250 MB/s | +| quicklz 1.5.0 -1 | 2.238 | 540 MB/s | 760 MB/s | +| **zstd 1.4.5 --fast=4** | 2.148 | 710 MB/s | 2300 MB/s | +| lzo1x 2.10 -1 | 2.106 | 660 MB/s | 845 MB/s | +| [lz4] 1.9.3 | 2.101 | 740 MB/s | 4500 MB/s | +| lzf 3.6 -1 | 2.077 | 410 MB/s | 830 MB/s | +| snappy 1.1.9 | 2.073 | 550 MB/s | 1750 MB/s | [zlib]: http://www.zlib.net/ -[LZ4]: http://www.lz4.org/ +[lz4]: http://www.lz4.org/ The negative compression levels, specified with `--fast=#`, -offer faster compression and decompression speed in exchange for some loss in -compression ratio compared to level 1, as seen in the table above. +offer faster compression and decompression speed +at the cost of compression ratio (compared to level 1). Zstd can also offer stronger compression ratios at the cost of compression speed. Speed vs Compression trade-off is configurable by small increments. From f829c322584f2985c6af594afb421d0e4f61a511 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 11:37:40 -0800 Subject: [PATCH 332/340] forgot the chainlog is effectively a "fake" value with rowHash the only value which makes sense is `hashlog-1` as it mimics the real memory usage. --- lib/compress/clevels.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compress/clevels.h b/lib/compress/clevels.h index d509d07a3..c2ceb6384 100644 --- a/lib/compress/clevels.h +++ b/lib/compress/clevels.h @@ -32,10 +32,10 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */ - { 21, 19, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */ + { 21, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */ { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ - { 21, 20, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */ - { 22, 21, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */ + { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */ { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */ { 22, 22, 23, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ From 925649b2d0ca8ca00c017139ef8fcf359b6b868d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 11:52:43 -0800 Subject: [PATCH 333/340] fixed version number for fast modes --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e8117a99d..69720ba2c 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,10 @@ on the [Silesia compression corpus]. | **zstd 1.5.1 -1** | 2.887 | 530 MB/s | 1700 MB/s | | [zlib] 1.2.11 -1 | 2.743 | 95 MB/s | 400 MB/s | | brotli 1.0.9 -0 | 2.702 | 395 MB/s | 450 MB/s | -| **zstd 1.4.5 --fast=1** | 2.437 | 600 MB/s | 2150 MB/s | -| **zstd 1.4.5 --fast=3** | 2.239 | 670 MB/s | 2250 MB/s | +| **zstd 1.5.1 --fast=1** | 2.437 | 600 MB/s | 2150 MB/s | +| **zstd 1.5.1 --fast=3** | 2.239 | 670 MB/s | 2250 MB/s | | quicklz 1.5.0 -1 | 2.238 | 540 MB/s | 760 MB/s | -| **zstd 1.4.5 --fast=4** | 2.148 | 710 MB/s | 2300 MB/s | +| **zstd 1.5.1 --fast=4** | 2.148 | 710 MB/s | 2300 MB/s | | lzo1x 2.10 -1 | 2.106 | 660 MB/s | 845 MB/s | | [lz4] 1.9.3 | 2.101 | 740 MB/s | 4500 MB/s | | lzf 3.6 -1 | 2.077 | 410 MB/s | 830 MB/s | From 9a32492730a8c5df8ea41b18a7f398baec4457c3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 14:39:30 -0800 Subject: [PATCH 334/340] updated regression results.csv --- tests/regression/results.csv | 1356 +++++++++++++++++----------------- 1 file changed, 678 insertions(+), 678 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index f9b46bd68..b4a76538b 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -1,74 +1,74 @@ Data, Config, Method, Total compressed size -silesia.tar, level -5, compress simple, 6853608 -silesia.tar, level -3, compress simple, 6505969 -silesia.tar, level -1, compress simple, 6179026 -silesia.tar, level 0, compress simple, 4854086 -silesia.tar, level 1, compress simple, 5327373 -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 -silesia.tar, level 9, compress simple, 4552381 -silesia.tar, level 13, compress simple, 4502956 -silesia.tar, level 16, compress simple, 4360527 +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, 5331946 +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, 4576828 +silesia.tar, level 9, compress simple, 4552584 +silesia.tar, level 13, compress simple, 4502955 +silesia.tar, level 16, compress simple, 4360526 silesia.tar, level 19, compress simple, 4267266 -silesia.tar, uncompressed literals, compress simple, 4854086 +silesia.tar, uncompressed literals, compress simple, 4861423 silesia.tar, uncompressed literals optimal, compress simple, 4267266 -silesia.tar, huffman literals, compress simple, 6179026 -github.tar, level -5, compress simple, 52110 -github.tar, level -3, compress simple, 45678 +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, 38831 +github.tar, level 0, compress simple, 38441 github.tar, level 1, compress simple, 39200 -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 -github.tar, level 9, compress simple, 36760 +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, uncompressed literals, compress simple, 38831 +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, 6852424 -silesia, level -3, compress cctx, 6503413 -silesia, level -1, compress cctx, 6172178 -silesia, level 0, compress cctx, 4842075 -silesia, level 1, compress cctx, 5306426 -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 -silesia, level 9, compress cctx, 4543018 +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 6, compress cctx, 4605369 +silesia, level 7, compress cctx, 4567203 +silesia, level 9, compress cctx, 4543311 silesia, level 13, compress cctx, 4493990 silesia, level 16, compress cctx, 4359864 silesia, level 19, compress cctx, 4296880 -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, 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, 4794052 -silesia, uncompressed literals, compress cctx, 4842075 +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, 4296880 -silesia, huffman literals, compress cctx, 6172178 -silesia, multithreaded with advanced params, compress cctx, 4842075 -github, level -5, compress cctx, 204411 +silesia, huffman literals, compress cctx, 6177565 +silesia, multithreaded with advanced params, compress cctx, 4849551 +github, level -5, compress cctx, 232315 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 193253 +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, 136332 +github, level 0, compress cctx, 136335 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, 136332 +github, level 3, compress cctx, 136335 github, level 3 with dict, compress cctx, 41534 github, level 4, compress cctx, 136199 github, level 4 with dict, compress cctx, 41725 @@ -86,17 +86,17 @@ 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, 141069 -github, multithreaded, compress cctx, 141069 -github, multithreaded long distance mode, compress cctx, 141069 -github, small window log, compress cctx, 141069 +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, small hash log, compress cctx, 138949 github, small chain log, compress cctx, 139242 github, explicit params, compress cctx, 140932 -github, uncompressed literals, compress cctx, 136332 +github, uncompressed literals, compress cctx, 136335 github, uncompressed literals optimal, compress cctx, 134064 github, huffman literals, compress cctx, 175468 -github, multithreaded with advanced params, compress cctx, 141069 +github, multithreaded with advanced params, compress cctx, 141102 silesia, level -5, zstdcli, 6852472 silesia, level -3, zstdcli, 6503461 silesia, level -1, zstdcli, 6172226 @@ -228,81 +228,81 @@ github.tar, uncompressed literals, zstdcli, github.tar, uncompressed literals optimal, zstdcli, 35401 github.tar, huffman literals, zstdcli, 38857 github.tar, multithreaded with advanced params, zstdcli, 41529 -silesia, level -5, advanced one pass, 6852424 -silesia, level -3, advanced one pass, 6503413 -silesia, level -1, advanced one pass, 6172178 -silesia, level 0, advanced one pass, 4842075 -silesia, level 1, advanced one pass, 5306426 -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 -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 -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 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 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 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, 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, 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, 4795432 -silesia, uncompressed literals, advanced one pass, 5120566 +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, 4319518 -silesia, huffman literals, advanced one pass, 5321346 -silesia, multithreaded with advanced params, advanced one pass, 5120566 -silesia.tar, level -5, advanced one pass, 6853608 -silesia.tar, level -3, advanced one pass, 6505969 -silesia.tar, level -1, advanced one pass, 6179026 -silesia.tar, level 0, advanced one pass, 4854086 -silesia.tar, level 1, advanced one pass, 5327373 -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 -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, huffman literals, advanced one pass, 5326346 +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, 4861423 +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 +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 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, 4502955 +silesia.tar, level 16, advanced one pass, 4360526 silesia.tar, level 19, advanced one pass, 4267266 -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, 5122473 +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, 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, 4310141 -silesia.tar, huffman literals, advanced one pass, 5341685 -silesia.tar, multithreaded with advanced params, advanced one pass, 5122567 -github, level -5, advanced one pass, 204411 +silesia.tar, huffman literals, advanced one pass, 5344545 +silesia.tar, multithreaded with advanced params, advanced one pass, 5129555 +github, level -5, advanced one pass, 232315 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 193253 +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, 136332 +github, level 0, advanced one pass, 136335 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, 136332 +github, level 3, advanced one pass, 136335 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 @@ -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 @@ -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, 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, 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 copy, advanced one pass, 39948 github, level 13 with dict load, advanced one pass, 42626 github, level 16, advanced one pass, 134064 @@ -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, 136332 +github, no source size, advanced one pass, 136335 github, no source size with dict, advanced one pass, 41148 -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, 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, 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, 165911 +github, uncompressed literals, advanced one pass, 165915 github, uncompressed literals optimal, advanced one pass, 157227 github, huffman literals, advanced one pass, 142365 -github, multithreaded with advanced params, advanced one pass, 165911 -github.tar, level -5, advanced one pass, 52110 -github.tar, level -5 with dict, advanced one pass, 46498 -github.tar, level -3, advanced one pass, 45678 -github.tar, level -3 with dict, advanced one pass, 42177 +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 0, advanced one pass, 38831 +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 @@ -439,86 +439,86 @@ 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, 38831 +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 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, 38893 +github.tar, level 4, advanced one pass, 38467 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 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, 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 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, 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, 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, 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 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, 36455 +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, 36419 -github.tar, level 12 row 1, advanced one pass, 36081 +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, 36434 -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, 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, 36459 +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, 37130 -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 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 @@ -533,94 +533,94 @@ 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, 38831 +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, 40252 -github.tar, multithreaded, advanced one pass, 38831 -github.tar, multithreaded long distance mode, advanced one pass, 40232 +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, 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, 41525 +github.tar, explicit params, advanced one pass, 41227 +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, multithreaded with advanced params, advanced one pass, 41525 -silesia, level -5, advanced one pass small out, 6852424 -silesia, level -3, advanced one pass small out, 6503413 -silesia, level -1, advanced one pass small out, 6172178 -silesia, level 0, advanced one pass small out, 4842075 -silesia, level 1, advanced one pass small out, 5306426 -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 -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 +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, 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 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 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 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, 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, 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, 4795432 -silesia, uncompressed literals, advanced one pass small out, 5120566 +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, 4319518 -silesia, huffman literals, advanced one pass small out, 5321346 -silesia, multithreaded with advanced params, advanced one pass small out, 5120566 -silesia.tar, level -5, advanced one pass small out, 6853608 -silesia.tar, level -3, advanced one pass small out, 6505969 -silesia.tar, level -1, advanced one pass small out, 6179026 -silesia.tar, level 0, advanced one pass small out, 4854086 -silesia.tar, level 1, advanced one pass small out, 5327373 -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 -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, 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, 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, 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 +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 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, 4502955 +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, 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, 5122473 +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, 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, 4310141 -silesia.tar, huffman literals, advanced one pass small out, 5341685 -silesia.tar, multithreaded with advanced params, advanced one pass small out, 5122567 -github, level -5, advanced one pass small out, 204411 +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, 232315 github, level -5 with dict, advanced one pass small out, 46718 -github, level -3, advanced one pass small out, 193253 +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, 136332 +github, level 0, advanced one pass small out, 136335 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, 136332 +github, level 3, advanced one pass small out, 136335 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 @@ -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 @@ -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, 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, 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 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 @@ -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, 136332 +github, no source size, advanced one pass small out, 136335 github, no source size with dict, advanced one pass small out, 41148 -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, 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, 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, 165911 +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, multithreaded with advanced params, advanced one pass small out, 165911 -github.tar, level -5, advanced one pass small out, 52110 -github.tar, level -5 with dict, advanced one pass small out, 46498 -github.tar, level -3, advanced one pass small out, 45678 -github.tar, level -3 with dict, advanced one pass small out, 42177 +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 0, advanced one pass small out, 38831 +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 @@ -757,86 +757,86 @@ 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, 38831 +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 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, 38893 +github.tar, level 4, advanced one pass small out, 38467 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 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, 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 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, 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, 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, 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 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, 36455 +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, 36419 -github.tar, level 12 row 1, advanced one pass small out, 36081 +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, 36434 -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, 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, 36459 +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, 37130 -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 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 @@ -851,94 +851,94 @@ 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, 38831 +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, 40252 -github.tar, multithreaded, advanced one pass small out, 38831 -github.tar, multithreaded long distance mode, advanced one pass small out, 40232 +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, 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, 41525 +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, 35397 github.tar, huffman literals, advanced one pass small out, 38853 -github.tar, multithreaded with advanced params, advanced one pass small out, 41525 -silesia, level -5, advanced streaming, 6963781 -silesia, level -3, advanced streaming, 6610376 -silesia, level -1, advanced streaming, 6179294 -silesia, level 0, advanced streaming, 4842075 -silesia, level 1, advanced streaming, 5310178 -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 -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 +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, 4849551 +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 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 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 13, advanced streaming, 4493990 silesia, level 16, advanced streaming, 4359864 silesia, level 19, advanced streaming, 4296880 -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, 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, 4795452 -silesia, uncompressed literals, advanced streaming, 5120566 +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, 4319518 -silesia, huffman literals, advanced streaming, 5327881 -silesia, multithreaded with advanced params, advanced streaming, 5120566 -silesia.tar, level -5, advanced streaming, 7043687 -silesia.tar, level -3, advanced streaming, 6671317 -silesia.tar, level -1, advanced streaming, 6187457 -silesia.tar, level 0, advanced streaming, 4859271 -silesia.tar, level 1, advanced streaming, 5333896 -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 -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, huffman literals, advanced streaming, 5332234 +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, 4861425 +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 +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 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, 4502955 +silesia.tar, level 16, advanced streaming, 4360526 silesia.tar, level 19, advanced streaming, 4267266 -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, 5127423 +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, 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, 4310141 -silesia.tar, huffman literals, advanced streaming, 5349624 -silesia.tar, multithreaded with advanced params, advanced streaming, 5122567 -github, level -5, advanced streaming, 204411 +silesia.tar, huffman literals, advanced streaming, 5350519 +silesia.tar, multithreaded with advanced params, advanced streaming, 5129555 +github, level -5, advanced streaming, 232315 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 193253 +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, 136332 +github, level 0, advanced streaming, 136335 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, 136332 +github, level 3, advanced streaming, 136335 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 @@ -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 @@ -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, 39900 -github, level 13 with dict dms, advanced streaming, 39900 -github, level 13 with dict dds, advanced streaming, 39900 +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 copy, advanced streaming, 39948 github, level 13 with dict load, advanced streaming, 42626 github, level 16, advanced streaming, 134064 @@ -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, 136332 +github, no source size, advanced streaming, 136335 github, no source size with dict, advanced streaming, 41148 -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, 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, small hash log, advanced streaming, 135590 github, small chain log, advanced streaming, 136341 github, explicit params, advanced streaming, 137727 -github, uncompressed literals, advanced streaming, 165911 +github, uncompressed literals, advanced streaming, 165915 github, uncompressed literals optimal, advanced streaming, 157227 github, huffman literals, advanced streaming, 142365 -github, multithreaded with advanced params, advanced streaming, 165911 -github.tar, level -5, advanced streaming, 51420 -github.tar, level -5 with dict, advanced streaming, 45495 -github.tar, level -3, advanced streaming, 45077 -github.tar, level -3 with dict, advanced streaming, 41627 +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 0, advanced streaming, 38831 +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 @@ -1075,86 +1075,86 @@ 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, 38831 +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 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, 38893 +github.tar, level 4, advanced streaming, 38467 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 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, 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 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, 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, 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, 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 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, 36455 +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, 36419 -github.tar, level 12 row 1, advanced streaming, 36081 +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, 36434 -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, 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, 36459 +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, 37130 -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 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 @@ -1169,66 +1169,66 @@ 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, 38828 +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, 40252 -github.tar, multithreaded, advanced streaming, 38831 -github.tar, multithreaded long distance mode, advanced streaming, 40232 +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, 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, 41525 +github.tar, explicit params, advanced streaming, 41227 +github.tar, uncompressed literals, advanced streaming, 41122 github.tar, uncompressed literals optimal, advanced streaming, 35397 github.tar, huffman literals, advanced streaming, 38874 -github.tar, multithreaded with advanced params, advanced streaming, 41525 -silesia, level -5, old streaming, 6963781 -silesia, level -3, old streaming, 6610376 -silesia, level -1, old streaming, 6179294 -silesia, level 0, old streaming, 4842075 -silesia, level 1, old streaming, 5310178 -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 -silesia, level 9, old streaming, 4543018 +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, 4849551 +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 6, old streaming, 4605369 +silesia, level 7, old streaming, 4567203 +silesia, level 9, old streaming, 4543311 silesia, level 13, old streaming, 4493990 silesia, level 16, old streaming, 4359864 silesia, level 19, old streaming, 4296880 -silesia, no source size, old streaming, 4842039 -silesia, uncompressed literals, old streaming, 4842075 +silesia, no source size, old streaming, 4849515 +silesia, uncompressed literals, old streaming, 4849551 silesia, uncompressed literals optimal, old streaming, 4296880 -silesia, huffman literals, old streaming, 6179294 -silesia.tar, level -5, old streaming, 7043687 -silesia.tar, level -3, old streaming, 6671317 -silesia.tar, level -1, old streaming, 6187457 -silesia.tar, level 0, old streaming, 4859271 -silesia.tar, level 1, old streaming, 5333896 -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 -silesia.tar, level 9, old streaming, 4552386 -silesia.tar, level 13, old streaming, 4502956 -silesia.tar, level 16, old streaming, 4360527 +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, 5334890 +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, 4576830 +silesia.tar, level 9, old streaming, 4552590 +silesia.tar, level 13, old streaming, 4502955 +silesia.tar, level 16, old streaming, 4360526 silesia.tar, level 19, old streaming, 4267266 -silesia.tar, no source size, old streaming, 4859267 -silesia.tar, uncompressed literals, old streaming, 4859271 +silesia.tar, no source size, old streaming, 4861421 +silesia.tar, uncompressed literals, old streaming, 4861425 silesia.tar, uncompressed literals optimal, old streaming, 4267266 -silesia.tar, huffman literals, old streaming, 6187457 -github, level -5, old streaming, 204411 +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, 193253 +github, level -3, old streaming, 220760 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, 136332 +github, level 0, old streaming, 136335 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, 136332 +github, level 3, old streaming, 136335 github, level 3 with dict, old streaming, 41148 github, level 4, old streaming, 136199 github, level 4 with dict, old streaming, 41251 @@ -1241,104 +1241,104 @@ 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, 39900 +github, level 13 with dict, old streaming, 39743 github, level 16, old streaming, 134064 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, 140599 +github, no source size, old streaming, 140632 github, no source size with dict, old streaming, 40654 -github, uncompressed literals, old streaming, 136332 +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, 51420 -github.tar, level -5 with dict, old streaming, 45495 -github.tar, level -3, old streaming, 45077 -github.tar, level -3 with dict, old streaming, 41627 +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, 38831 +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 3, old streaming, 38831 +github.tar, level 3, old streaming, 38441 github.tar, level 3 with dict, old streaming, 37995 -github.tar, level 4, old streaming, 38893 +github.tar, level 4, old streaming, 38467 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 -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 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, no source size, old streaming, 38828 +github.tar, no source size, old streaming, 38438 github.tar, no source size with dict, old streaming, 38000 -github.tar, uncompressed literals, old streaming, 38831 +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, 6963781 -silesia, level -3, old streaming advanced, 6610376 -silesia, level -1, old streaming advanced, 6179294 -silesia, level 0, old streaming advanced, 4842075 -silesia, level 1, old streaming advanced, 5310178 -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 -silesia, level 9, old streaming advanced, 4543018 +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, 5312694 +silesia, level 3, old streaming advanced, 4849551 +silesia, level 4, old streaming advanced, 4786969 +silesia, level 5, old streaming advanced, 4638960 +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, 4493990 silesia, level 16, old streaming advanced, 4359864 silesia, level 19, old streaming advanced, 4296880 -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, 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, 4795452 -silesia, uncompressed literals, old streaming advanced, 4842075 +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, 4296880 -silesia, huffman literals, old streaming advanced, 6179294 -silesia, multithreaded with advanced params, old streaming advanced, 4842075 -silesia.tar, level -5, old streaming advanced, 7043687 -silesia.tar, level -3, old streaming advanced, 6671317 -silesia.tar, level -1, old streaming advanced, 6187457 -silesia.tar, level 0, old streaming advanced, 4859271 -silesia.tar, level 1, old streaming advanced, 5333896 -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 -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, huffman literals, old streaming advanced, 6183923 +silesia, multithreaded with advanced params, old streaming advanced, 4849551 +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, 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 +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, 4502955 +silesia.tar, level 16, old streaming advanced, 4360526 silesia.tar, level 19, old streaming advanced, 4267266 -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, 4859271 +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, 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, 4267266 -silesia.tar, huffman literals, old streaming advanced, 6187457 -silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 -github, level -5, old streaming advanced, 213265 +silesia.tar, huffman literals, old streaming advanced, 6187938 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4861425 +github, level -5, old streaming advanced, 241214 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 196126 +github, level -3, old streaming advanced, 222937 github, level -3 with dict, old streaming advanced, 44956 github, level -1, old streaming advanced, 181107 github, level -1 with dict, old streaming advanced, 42383 @@ -1359,12 +1359,12 @@ 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, 39725 +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 github, level 19 with dict, old streaming advanced, 37576 -github, no source size, old streaming advanced, 140599 +github, no source size, old streaming advanced, 140632 github, no source size with dict, old streaming advanced, 40608 github, long distance mode, old streaming advanced, 141104 github, multithreaded, old streaming advanced, 141104 @@ -1377,47 +1377,47 @@ github, uncompressed literals, old stre github, uncompressed literals optimal, old streaming advanced, 134064 github, huffman literals, old streaming advanced, 181107 github, multithreaded with advanced params, old streaming advanced, 141104 -github.tar, level -5, old streaming advanced, 51420 -github.tar, level -5 with dict, old streaming advanced, 46091 -github.tar, level -3, old streaming advanced, 45077 -github.tar, level -3 with dict, old streaming advanced, 42222 +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, 38831 +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 3, old streaming advanced, 38831 +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, 38893 +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, 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 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, no source size, old streaming advanced, 38828 +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, 38831 -github.tar, multithreaded, old streaming advanced, 38831 -github.tar, multithreaded long distance mode, old streaming advanced, 38831 +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, 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, 38831 +github.tar, explicit params, old streaming advanced, 41227 +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, multithreaded with advanced params, old streaming advanced, 38831 +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 github, level -1 with dict, old streaming cdict, 43170 @@ -1429,21 +1429,21 @@ 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, 39900 +github, level 13 with dict, old streaming cdict, 39743 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, 46276 -github.tar, level -3 with dict, old streaming cdict, 42354 +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, 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, 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 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 @@ -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, 39725 +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,10 +1470,10 @@ 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, 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 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 From 7c7b9244d6753b8eb85b9ae0184b6c9f607355fe Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 16:07:54 -0800 Subject: [PATCH 335/340] update regression results --- 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 b4a76538b..503e5cef2 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, 6852472 -silesia, level -3, zstdcli, 6503461 -silesia, level -1, zstdcli, 6172226 -silesia, level 0, zstdcli, 4842123 -silesia, level 1, zstdcli, 5306474 -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 -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, 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, 5120614 -silesia, uncompressed literals optimal, zstdcli, 4319566 -silesia, huffman literals, zstdcli, 5321394 -silesia, multithreaded with advanced params, zstdcli, 5120614 -silesia.tar, level -5, zstdcli, 6853994 -silesia.tar, level -3, zstdcli, 6506742 -silesia.tar, level -1, zstdcli, 6179765 -silesia.tar, level 0, zstdcli, 4854164 -silesia.tar, level 1, zstdcli, 5328534 -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 -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, 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, 5122571 -silesia.tar, uncompressed literals optimal, zstdcli, 4310145 -silesia.tar, huffman literals, zstdcli, 5342054 -silesia.tar, multithreaded with advanced params, zstdcli, 5122571 -github, level -5, zstdcli, 206411 -github, level -5 with dict, zstdcli, 48718 -github, level -3, zstdcli, 195253 -github, level -3 with dict, zstdcli, 47395 -github, level -1, zstdcli, 177468 -github, level -1 with dict, zstdcli, 45170 -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, 138332 -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, 41900 -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, 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, 167911 -github, uncompressed literals optimal, zstdcli, 159227 -github, huffman literals, zstdcli, 144365 -github, multithreaded with advanced params, zstdcli, 167911 -github.tar, level -5, zstdcli, 52114 -github.tar, level -5 with dict, zstdcli, 46502 -github.tar, level -3, zstdcli, 45682 -github.tar, level -3 with dict, zstdcli, 42181 -github.tar, level -1, zstdcli, 42564 -github.tar, level -1 with dict, zstdcli, 41140 -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, 38835 -github.tar, level 3 with dict, zstdcli, 37999 -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 -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, 38832 -github.tar, no source size with dict, zstdcli, 38004 -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, 41529 -github.tar, uncompressed literals optimal, zstdcli, 35401 -github.tar, huffman literals, zstdcli, 38857 -github.tar, multithreaded with advanced params, zstdcli, 41529 +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, advanced one pass, 7354675 silesia, level -3, advanced one pass, 6902374 silesia, level -1, advanced one pass, 6177565 From 01adddc3e0e90f09d1cf95aa07ae7e991164b430 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 20:43:23 -0800 Subject: [PATCH 336/340] update regression results --- tests/regression/results.csv | 1634 +++++++++++++++++----------------- 1 file changed, 817 insertions(+), 817 deletions(-) diff --git a/tests/regression/results.csv b/tests/regression/results.csv index 503e5cef2..f43129e6c 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -1,74 +1,74 @@ 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, 4861423 -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 -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, 4502955 -silesia.tar, level 16, compress simple, 4360526 +silesia.tar, level -5, compress simple, 6853608 +silesia.tar, level -3, compress simple, 6505969 +silesia.tar, level -1, compress simple, 6179026 +silesia.tar, level 0, compress simple, 4854086 +silesia.tar, level 1, compress simple, 5327373 +silesia.tar, level 3, compress simple, 4854086 +silesia.tar, level 4, compress simple, 4791503 +silesia.tar, level 5, compress simple, 4677740 +silesia.tar, level 6, compress simple, 4613242 +silesia.tar, level 7, compress simple, 4576661 +silesia.tar, level 9, compress simple, 4552899 +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, 4861423 +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 +silesia.tar, huffman literals, compress simple, 6179026 +github.tar, level -5, compress simple, 52110 +github.tar, level -3, compress simple, 45678 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 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 3, compress simple, 38831 +github.tar, level 4, compress simple, 38893 +github.tar, level 5, compress simple, 39651 +github.tar, level 6, compress simple, 39282 +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, 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, 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 6, compress cctx, 4605369 -silesia, level 7, compress cctx, 4567203 -silesia, level 9, compress cctx, 4543311 +silesia, level -5, compress cctx, 6852424 +silesia, level -3, compress cctx, 6503413 +silesia, level -1, compress cctx, 6172178 +silesia, level 0, compress cctx, 4842075 +silesia, level 1, compress cctx, 5306426 +silesia, level 3, compress cctx, 4842075 +silesia, level 4, compress cctx, 4779186 +silesia, level 5, compress cctx, 4666323 +silesia, level 6, compress cctx, 4603066 +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, 4849551 -silesia, multithreaded, compress cctx, 4849551 -silesia, multithreaded long distance mode, compress cctx, 4849551 -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, 4912199 -silesia, explicit params, compress cctx, 4794480 -silesia, uncompressed literals, compress cctx, 4849551 +silesia, small chain log, compress cctx, 4912197 +silesia, explicit params, compress cctx, 4794052 +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, 4849551 -github, level -5, compress cctx, 232315 +silesia, huffman literals, compress cctx, 6172178 +silesia, multithreaded with advanced params, compress cctx, 4842075 +github, level -5, compress cctx, 204411 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 220760 +github, level -3, compress cctx, 193253 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,223 +86,223 @@ 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 -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, 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 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 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 +github, multithreaded with advanced params, compress cctx, 141069 +silesia, level -5, zstdcli, 6852472 +silesia, level -3, zstdcli, 6503461 +silesia, level -1, zstdcli, 6172226 +silesia, level 0, zstdcli, 4842123 +silesia, level 1, zstdcli, 5306474 +silesia, level 3, zstdcli, 4842123 +silesia, level 4, zstdcli, 4779234 +silesia, level 5, zstdcli, 4666371 +silesia, level 6, zstdcli, 4603114 +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, 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, 5120614 +silesia, uncompressed literals optimal, zstdcli, 4319566 +silesia, huffman literals, zstdcli, 5321394 +silesia, multithreaded with advanced params, zstdcli, 5120614 +silesia.tar, level -5, zstdcli, 6853994 +silesia.tar, level -3, zstdcli, 6506742 +silesia.tar, level -1, zstdcli, 6179765 +silesia.tar, level 0, zstdcli, 4854164 +silesia.tar, level 1, zstdcli, 5328534 +silesia.tar, level 3, zstdcli, 4854164 +silesia.tar, level 4, zstdcli, 4792352 +silesia.tar, level 5, zstdcli, 4678682 +silesia.tar, level 6, zstdcli, 4614125 +silesia.tar, level 7, zstdcli, 4578719 +silesia.tar, level 9, zstdcli, 4552903 +silesia.tar, level 13, zstdcli, 4502960 +silesia.tar, level 16, zstdcli, 4360531 +silesia.tar, level 19, zstdcli, 4267270 +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, 5122571 +silesia.tar, uncompressed literals optimal, zstdcli, 4310145 +silesia.tar, huffman literals, zstdcli, 5342054 +silesia.tar, multithreaded with advanced params, zstdcli, 5122571 +github, level -5, zstdcli, 206411 +github, level -5 with dict, zstdcli, 48718 +github, level -3, zstdcli, 195253 +github, level -3 with dict, zstdcli, 47395 +github, level -1, zstdcli, 177468 +github, level -1 with dict, zstdcli, 45170 +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, 138332 +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, 41900 +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, 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, 167911 +github, uncompressed literals optimal, zstdcli, 159227 +github, huffman literals, zstdcli, 144365 +github, multithreaded with advanced params, zstdcli, 167911 +github.tar, level -5, zstdcli, 52114 +github.tar, level -5 with dict, zstdcli, 46502 +github.tar, level -3, zstdcli, 45682 +github.tar, level -3 with dict, zstdcli, 42181 +github.tar, level -1, zstdcli, 42564 +github.tar, level -1 with dict, zstdcli, 41140 +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, 38835 +github.tar, level 3 with dict, zstdcli, 37999 +github.tar, level 4, zstdcli, 38897 +github.tar, level 4 with dict, zstdcli, 37952 +github.tar, level 5, zstdcli, 39655 +github.tar, level 5 with dict, zstdcli, 39071 +github.tar, level 6, zstdcli, 39286 +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, 38832 +github.tar, no source size with dict, zstdcli, 38004 +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, 41529 +github.tar, uncompressed literals optimal, zstdcli, 35401 +github.tar, huffman literals, zstdcli, 38857 +github.tar, multithreaded with advanced params, zstdcli, 41529 +silesia, level -5, advanced one pass, 6852424 +silesia, level -3, advanced one pass, 6503413 +silesia, level -1, advanced one pass, 6172178 +silesia, level 0, advanced one pass, 4842075 +silesia, level 1, advanced one pass, 5306426 +silesia, level 3, advanced one pass, 4842075 +silesia, level 4, advanced one pass, 4779186 +silesia, level 5 row 1, advanced one pass, 4666323 +silesia, level 5 row 2, advanced one pass, 4670136 +silesia, level 5, advanced one pass, 4666323 +silesia, level 6, advanced one pass, 4603066 +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, 4505046 +silesia, level 11 row 2, advanced one pass, 4503116 +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, 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, 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, 4912199 -silesia, explicit params, advanced one pass, 4795856 -silesia, uncompressed literals, advanced one pass, 5127982 +silesia, small chain log, advanced one pass, 4912197 +silesia, explicit params, advanced one pass, 4795432 +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.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, 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 -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 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, 4502955 -silesia.tar, level 16, advanced one pass, 4360526 +silesia, huffman literals, advanced one pass, 5321346 +silesia, multithreaded with advanced params, advanced one pass, 5120566 +silesia.tar, level -5, advanced one pass, 6853608 +silesia.tar, level -3, advanced one pass, 6505969 +silesia.tar, level -1, advanced one pass, 6179026 +silesia.tar, level 0, advanced one pass, 4854086 +silesia.tar, level 1, advanced one pass, 5327373 +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, 4677740 +silesia.tar, level 5 row 2, advanced one pass, 4682161 +silesia.tar, level 5, advanced one pass, 4677740 +silesia.tar, level 6, advanced one pass, 4613242 +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, 4552899 +silesia.tar, level 11 row 1, advanced one pass, 4514432 +silesia.tar, level 11 row 2, advanced one pass, 4513604 +silesia.tar, level 12 row 1, advanced one pass, 4514049 +silesia.tar, level 12 row 2, advanced one pass, 4513797 +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, 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, 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, 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, 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 -github, level -5, advanced one pass, 232315 +silesia.tar, huffman literals, advanced one pass, 5341685 +silesia.tar, multithreaded with advanced params, advanced one pass, 5122567 +github, level -5, advanced one pass, 204411 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 220760 +github, level -3, advanced one pass, 193253 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 @@ -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 @@ -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 @@ -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.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, multithreaded with advanced params, advanced one pass, 165911 +github.tar, level -5, advanced one pass, 52110 +github.tar, level -5 with dict, advanced one pass, 46498 +github.tar, level -3, advanced one pass, 45678 +github.tar, level -3 with dict, advanced one pass, 42177 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,86 +439,86 @@ 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 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, 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, 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, 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 11 row 1, advanced one pass, 36435 +github.tar, level 5 row 1, advanced one pass, 39651 +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, 38999 +github.tar, level 5 row 2, advanced one pass, 39701 +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, 39158 +github.tar, level 5, advanced one pass, 39651 +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, 38999 +github.tar, level 6, advanced one pass, 39282 +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, 38648 +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, 36081 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 1 with dict load, advanced one pass, 36434 +github.tar, level 11 row 2, advanced one pass, 36110 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, 36459 +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, 36105 +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, 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 -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 @@ -533,94 +533,94 @@ 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, 41227 -github.tar, uncompressed literals, advanced one pass, 41122 +github.tar, explicit params, advanced one pass, 41385 +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 -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 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 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 +github.tar, multithreaded with advanced params, advanced one pass, 41525 +silesia, level -5, advanced one pass small out, 6852424 +silesia, level -3, advanced one pass small out, 6503413 +silesia, level -1, advanced one pass small out, 6172178 +silesia, level 0, advanced one pass small out, 4842075 +silesia, level 1, advanced one pass small out, 5306426 +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, 4666323 +silesia, level 5 row 2, advanced one pass small out, 4670136 +silesia, level 5, advanced one pass small out, 4666323 +silesia, level 6, advanced one pass small out, 4603066 +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, 4505046 +silesia, level 11 row 2, advanced one pass small out, 4503116 +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, 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, 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, 4912199 -silesia, explicit params, advanced one pass small out, 4795856 -silesia, uncompressed literals, advanced one pass small out, 5127982 +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, 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.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, 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 -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 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, 4502955 -silesia.tar, level 16, advanced one pass small out, 4360526 +silesia, huffman literals, advanced one pass small out, 5321346 +silesia, multithreaded with advanced params, advanced one pass small out, 5120566 +silesia.tar, level -5, advanced one pass small out, 6853608 +silesia.tar, level -3, advanced one pass small out, 6505969 +silesia.tar, level -1, advanced one pass small out, 6179026 +silesia.tar, level 0, advanced one pass small out, 4854086 +silesia.tar, level 1, advanced one pass small out, 5327373 +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, 4677740 +silesia.tar, level 5 row 2, advanced one pass small out, 4682161 +silesia.tar, level 5, advanced one pass small out, 4677740 +silesia.tar, level 6, advanced one pass small out, 4613242 +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, 4552899 +silesia.tar, level 11 row 1, advanced one pass small out, 4514432 +silesia.tar, level 11 row 2, advanced one pass small out, 4513604 +silesia.tar, level 12 row 1, advanced one pass small out, 4514049 +silesia.tar, level 12 row 2, advanced one pass small out, 4513797 +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, 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, 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, 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, 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 -github, level -5, advanced one pass small out, 232315 +silesia.tar, huffman literals, advanced one pass small out, 5341685 +silesia.tar, multithreaded with advanced params, advanced one pass small out, 5122567 +github, level -5, advanced one pass small out, 204411 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, 193253 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 @@ -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 @@ -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 @@ -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.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, multithreaded with advanced params, advanced one pass small out, 165911 +github.tar, level -5, advanced one pass small out, 52110 +github.tar, level -5 with dict, advanced one pass small out, 46498 +github.tar, level -3, advanced one pass small out, 45678 +github.tar, level -3 with dict, advanced one pass small out, 42177 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,86 +757,86 @@ 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 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, 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, 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, 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 11 row 1, advanced one pass small out, 36435 +github.tar, level 5 row 1, advanced one pass small out, 39651 +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, 38999 +github.tar, level 5 row 2, advanced one pass small out, 39701 +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, 39158 +github.tar, level 5, advanced one pass small out, 39651 +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, 38999 +github.tar, level 6, advanced one pass small out, 39282 +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, 38648 +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, 36081 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 1 with dict load, advanced one pass small out, 36434 +github.tar, level 11 row 2, advanced one pass small out, 36110 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, 36459 +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, 36105 +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, 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 -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 @@ -851,94 +851,94 @@ 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, 41227 -github.tar, uncompressed literals, advanced one pass small out, 41122 +github.tar, explicit params, advanced one pass small out, 41385 +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 -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, 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 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 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 +github.tar, multithreaded with advanced params, advanced one pass small out, 41525 +silesia, level -5, advanced streaming, 6963781 +silesia, level -3, advanced streaming, 6610376 +silesia, level -1, advanced streaming, 6179294 +silesia, level 0, advanced streaming, 4842075 +silesia, level 1, advanced streaming, 5310178 +silesia, level 3, advanced streaming, 4842075 +silesia, level 4, advanced streaming, 4779186 +silesia, level 5 row 1, advanced streaming, 4666323 +silesia, level 5 row 2, advanced streaming, 4670136 +silesia, level 5, advanced streaming, 4666323 +silesia, level 6, advanced streaming, 4603066 +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, 4505046 +silesia, level 11 row 2, advanced streaming, 4503116 +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, 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, 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, 4912199 -silesia, explicit params, advanced streaming, 4795884 -silesia, uncompressed literals, advanced streaming, 5127982 +silesia, small chain log, advanced streaming, 4912197 +silesia, explicit params, advanced streaming, 4795452 +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.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, 5334890 -silesia.tar, level 3, advanced streaming, 4861425 -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 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, 4502955 -silesia.tar, level 16, advanced streaming, 4360526 +silesia, huffman literals, advanced streaming, 5327881 +silesia, multithreaded with advanced params, advanced streaming, 5120566 +silesia.tar, level -5, advanced streaming, 7043687 +silesia.tar, level -3, advanced streaming, 6671317 +silesia.tar, level -1, advanced streaming, 6187457 +silesia.tar, level 0, advanced streaming, 4859271 +silesia.tar, level 1, advanced streaming, 5333896 +silesia.tar, level 3, advanced streaming, 4859271 +silesia.tar, level 4, advanced streaming, 4797470 +silesia.tar, level 5 row 1, advanced streaming, 4677748 +silesia.tar, level 5 row 2, advanced streaming, 4682169 +silesia.tar, level 5, advanced streaming, 4677748 +silesia.tar, level 6, advanced streaming, 4613246 +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, 4552900 +silesia.tar, level 11 row 1, advanced streaming, 4514433 +silesia.tar, level 11 row 2, advanced streaming, 4513604 +silesia.tar, level 12 row 1, advanced streaming, 4514049 +silesia.tar, level 12 row 2, advanced streaming, 4513797 +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, 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, 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, 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, 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 -github, level -5, advanced streaming, 232315 +silesia.tar, huffman literals, advanced streaming, 5349624 +silesia.tar, multithreaded with advanced params, advanced streaming, 5122567 +github, level -5, advanced streaming, 204411 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 220760 +github, level -3, advanced streaming, 193253 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 @@ -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 @@ -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 @@ -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.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, multithreaded with advanced params, advanced streaming, 165911 +github.tar, level -5, advanced streaming, 51420 +github.tar, level -5 with dict, advanced streaming, 45495 +github.tar, level -3, advanced streaming, 45077 +github.tar, level -3 with dict, advanced streaming, 41627 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,86 +1075,86 @@ 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 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, 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, 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, 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 11 row 1, advanced streaming, 36435 +github.tar, level 5 row 1, advanced streaming, 39651 +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, 38999 +github.tar, level 5 row 2, advanced streaming, 39701 +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, 39158 +github.tar, level 5, advanced streaming, 39651 +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, 38999 +github.tar, level 6, advanced streaming, 39282 +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, 38648 +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, 36081 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 1 with dict load, advanced streaming, 36434 +github.tar, level 11 row 2, advanced streaming, 36110 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, 36459 +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, 36105 +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, 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 -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 @@ -1169,66 +1169,66 @@ 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, 41227 -github.tar, uncompressed literals, advanced streaming, 41122 +github.tar, explicit params, advanced streaming, 41385 +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 -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, 5312694 -silesia, level 3, old streaming, 4849551 -silesia, level 4, old streaming, 4786969 -silesia, level 5, old streaming, 4638960 -silesia, level 6, old streaming, 4605369 -silesia, level 7, old streaming, 4567203 -silesia, level 9, old streaming, 4543311 +github.tar, multithreaded with advanced params, advanced streaming, 41525 +silesia, level -5, old streaming, 6963781 +silesia, level -3, old streaming, 6610376 +silesia, level -1, old streaming, 6179294 +silesia, level 0, old streaming, 4842075 +silesia, level 1, old streaming, 5310178 +silesia, level 3, old streaming, 4842075 +silesia, level 4, old streaming, 4779186 +silesia, level 5, old streaming, 4666323 +silesia, level 6, old streaming, 4603066 +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, 4849515 -silesia, uncompressed literals, old streaming, 4849551 +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, 4861425 -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 -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, 4502955 -silesia.tar, level 16, old streaming, 4360526 +silesia, huffman literals, old streaming, 6179294 +silesia.tar, level -5, old streaming, 7043687 +silesia.tar, level -3, old streaming, 6671317 +silesia.tar, level -1, old streaming, 6187457 +silesia.tar, level 0, old streaming, 4859271 +silesia.tar, level 1, old streaming, 5333896 +silesia.tar, level 3, old streaming, 4859271 +silesia.tar, level 4, old streaming, 4797470 +silesia.tar, level 5, old streaming, 4677748 +silesia.tar, level 6, old streaming, 4613246 +silesia.tar, level 7, old streaming, 4576664 +silesia.tar, level 9, old streaming, 4552900 +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, 4861421 -silesia.tar, uncompressed literals, old streaming, 4861425 +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 +silesia.tar, huffman literals, old streaming, 6187457 +github, level -5, old streaming, 204411 github, level -5 with dict, old streaming, 46718 -github, level -3, old streaming, 220760 +github, level -3, old streaming, 193253 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 @@ -1241,104 +1241,104 @@ 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 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 -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 -5, old streaming, 51420 +github.tar, level -5 with dict, old streaming, 45495 +github.tar, level -3, old streaming, 45077 +github.tar, level -3 with dict, old streaming, 41627 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, 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 5, old streaming, 39651 +github.tar, level 5 with dict, old streaming, 39082 +github.tar, level 6, old streaming, 39282 +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, 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, 4849551 -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 6, old streaming advanced, 4605369 -silesia, level 7, old streaming advanced, 4567203 -silesia, level 9, old streaming advanced, 4543311 +silesia, level -5, old streaming advanced, 6963781 +silesia, level -3, old streaming advanced, 6610376 +silesia, level -1, old streaming advanced, 6179294 +silesia, level 0, old streaming advanced, 4842075 +silesia, level 1, old streaming advanced, 5310178 +silesia, level 3, old streaming advanced, 4842075 +silesia, level 4, old streaming advanced, 4779186 +silesia, level 5, old streaming advanced, 4666323 +silesia, level 6, old streaming advanced, 4603066 +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, 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, 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, 4912199 -silesia, explicit params, old streaming advanced, 4795884 -silesia, uncompressed literals, old streaming advanced, 4849551 +silesia, small chain log, old streaming advanced, 4912197 +silesia, explicit params, old streaming advanced, 4795452 +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, 4849551 -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, 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 -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, 4502955 -silesia.tar, level 16, old streaming advanced, 4360526 +silesia, huffman literals, old streaming advanced, 6179294 +silesia, multithreaded with advanced params, old streaming advanced, 4842075 +silesia.tar, level -5, old streaming advanced, 7043687 +silesia.tar, level -3, old streaming advanced, 6671317 +silesia.tar, level -1, old streaming advanced, 6187457 +silesia.tar, level 0, old streaming advanced, 4859271 +silesia.tar, level 1, old streaming advanced, 5333896 +silesia.tar, level 3, old streaming advanced, 4859271 +silesia.tar, level 4, old streaming advanced, 4797470 +silesia.tar, level 5, old streaming advanced, 4677748 +silesia.tar, level 6, old streaming advanced, 4613246 +silesia.tar, level 7, old streaming advanced, 4576664 +silesia.tar, level 9, old streaming advanced, 4552900 +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, 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, 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, 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, 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, 4861425 -github, level -5, old streaming advanced, 241214 +silesia.tar, huffman literals, old streaming advanced, 6187457 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 +github, level -5, old streaming advanced, 213265 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 222937 +github, level -3, old streaming advanced, 196126 github, level -3 with dict, old streaming advanced, 44956 github, level -1, old streaming advanced, 181107 github, level -1 with dict, old streaming advanced, 42383 @@ -1351,20 +1351,20 @@ github, level 3 with dict, old stre github, level 4, old streaming advanced, 141104 github, level 4 with dict, old streaming advanced, 41084 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, 39363 +github, level 5 with dict, old streaming advanced, 38723 +github, level 6, old streaming advanced, 138676 +github, level 6 with dict, old streaming advanced, 38744 github, level 7, old streaming advanced, 138676 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 -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 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 @@ -1377,47 +1377,47 @@ github, uncompressed literals, old stre github, uncompressed literals optimal, old streaming advanced, 134064 github, huffman literals, old streaming advanced, 181107 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 -5, old streaming advanced, 51420 +github.tar, level -5 with dict, old streaming advanced, 46091 +github.tar, level -3, old streaming advanced, 45077 +github.tar, level -3 with dict, old streaming advanced, 42222 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, 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 5, old streaming advanced, 39651 +github.tar, level 5 with dict, old streaming advanced, 38997 +github.tar, level 6, old streaming advanced, 39282 +github.tar, level 6 with dict, old streaming advanced, 38640 +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, 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, 41227 -github.tar, uncompressed literals, old streaming advanced, 38441 +github.tar, explicit params, old streaming advanced, 41385 +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 @@ -1429,21 +1429,21 @@ 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 -github.tar, level -5 with dict, old streaming cdict, 49146 -github.tar, level -3 with dict, old streaming cdict, 43468 +github.tar, level -5 with dict, old streaming cdict, 46276 +github.tar, level -3 with dict, old streaming cdict, 42354 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, 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 -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 5 with dict, old streaming cdict, 38999 +github.tar, level 6 with dict, old streaming cdict, 38648 +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 @@ -1455,11 +1455,11 @@ 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, 38805 -github, level 6 with dict, old streaming advanced cdict, 39363 +github, level 5 with dict, old streaming advanced cdict, 38723 +github, level 6 with dict, old streaming advanced cdict, 38744 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 @@ -1470,10 +1470,10 @@ 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 5 with dict, old streaming advanced cdict, 38997 +github.tar, level 6 with dict, old streaming advanced cdict, 38640 +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 From 9fc7f38e122d6f57bb4a756f7998a3bbc06d6229 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 16 Dec 2021 21:01:10 -0800 Subject: [PATCH 337/340] added target update_regressionResults to automate the creation of updated tests/regression/results.csv --- Makefile | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 77bb4ce87..83ab37dcc 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ VOID = /dev/null # fail on other tested distros (ubuntu, debian) even # without manually specifying the TARGET_SYSTEM. TARGET_SYSTEM ?= $(OS) +CP ?= cp ifneq (,$(filter Windows%,$(TARGET_SYSTEM))) EXT =.exe @@ -69,7 +70,7 @@ zstd zstd-release: .PHONY: zstdmt zstdmt: $(Q)$(MAKE) -C $(PRGDIR) $@ - $(Q)cp $(PRGDIR)/zstd$(EXT) ./zstdmt$(EXT) + $(Q)$(CP) $(PRGDIR)/zstd$(EXT) ./zstdmt$(EXT) .PHONY: zlibwrapper zlibwrapper: lib @@ -152,6 +153,8 @@ ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD Dr HOST_OS = POSIX +MKDIR ?= mkdir -p + HAVE_COLORNEVER = $(shell echo a | egrep --color=never a > /dev/null 2> /dev/null && echo 1 || echo 0) EGREP_OPTIONS ?= ifeq ($HAVE_COLORNEVER, 1) @@ -284,6 +287,22 @@ uasanregressiontest: msanregressiontest: $(MAKE) -C $(FUZZDIR) regressiontest CC=clang CXX=clang++ CFLAGS="-O3 -fsanitize=memory" CXXFLAGS="-O3 -fsanitize=memory" +update_regressionResults : REGRESS_RESULTS_DIR := /tmp/regress_results_dir/ +update_regressionResults: + $(MAKE) -C programs zstd + $(MAKE) -C tests/regression test + $(RM) -rf $(REGRESS_RESULTS_DIR) + $(MKDIR) $(REGRESS_RESULTS_DIR) + ./tests/regression/test \ + --cache tests/regression/cache \ + --output $(REGRESS_RESULTS_DIR)/results.csv \ + --zstd programs/zstd + echo "Showing results differences" + diff tests/regression/results.csv $(REGRESS_RESULTS_DIR)/results.csv + echo "Updating results.csv" + $(CP) $(REGRESS_RESULTS_DIR)/results.csv tests/regression/results.csv + + # run UBsan with -fsanitize-recover=pointer-overflow # this only works with recent compilers such as gcc 8+ usan: clean @@ -372,7 +391,7 @@ ifneq (,$(filter $(HOST_OS),MSYS POSIX)) cmakebuild: cmake --version $(RM) -r $(BUILDIR)/cmake/build - mkdir $(BUILDIR)/cmake/build + $(MKDIR) $(BUILDIR)/cmake/build cd $(BUILDIR)/cmake/build; cmake -DCMAKE_INSTALL_PREFIX:PATH=~/install_test_dir $(CMAKE_PARAMS) .. $(MAKE) -C $(BUILDIR)/cmake/build -j4; $(MAKE) -C $(BUILDIR)/cmake/build install; From 80a28f207808b11d39baf495aa76effd6b65e09d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 20 Dec 2021 07:54:57 -0800 Subject: [PATCH 338/340] update regression results --- Makefile | 2 +- tests/regression/results.csv | 1356 +++++++++++++++++----------------- 2 files changed, 679 insertions(+), 679 deletions(-) diff --git a/Makefile b/Makefile index 83ab37dcc..9b5451d3d 100644 --- a/Makefile +++ b/Makefile @@ -298,7 +298,7 @@ update_regressionResults: --output $(REGRESS_RESULTS_DIR)/results.csv \ --zstd programs/zstd echo "Showing results differences" - diff tests/regression/results.csv $(REGRESS_RESULTS_DIR)/results.csv + ! diff tests/regression/results.csv $(REGRESS_RESULTS_DIR)/results.csv echo "Updating results.csv" $(CP) $(REGRESS_RESULTS_DIR)/results.csv tests/regression/results.csv diff --git a/tests/regression/results.csv b/tests/regression/results.csv index b4a76538b..f9b46bd68 100644 --- a/tests/regression/results.csv +++ b/tests/regression/results.csv @@ -1,74 +1,74 @@ 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, 4861423 -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 -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, 4502955 -silesia.tar, level 16, compress simple, 4360526 +silesia.tar, level -5, compress simple, 6853608 +silesia.tar, level -3, compress simple, 6505969 +silesia.tar, level -1, compress simple, 6179026 +silesia.tar, level 0, compress simple, 4854086 +silesia.tar, level 1, compress simple, 5327373 +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 +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, 4861423 +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 +silesia.tar, huffman literals, compress simple, 6179026 +github.tar, level -5, compress simple, 52110 +github.tar, level -3, compress simple, 45678 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 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 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 +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, 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, 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 6, compress cctx, 4605369 -silesia, level 7, compress cctx, 4567203 -silesia, level 9, compress cctx, 4543311 +silesia, level -5, compress cctx, 6852424 +silesia, level -3, compress cctx, 6503413 +silesia, level -1, compress cctx, 6172178 +silesia, level 0, compress cctx, 4842075 +silesia, level 1, compress cctx, 5306426 +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 +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, 4849551 -silesia, multithreaded, compress cctx, 4849551 -silesia, multithreaded long distance mode, compress cctx, 4849551 -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, 4912199 -silesia, explicit params, compress cctx, 4794480 -silesia, uncompressed literals, compress cctx, 4849551 +silesia, small chain log, compress cctx, 4912197 +silesia, explicit params, compress cctx, 4794052 +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, 4849551 -github, level -5, compress cctx, 232315 +silesia, huffman literals, compress cctx, 6172178 +silesia, multithreaded with advanced params, compress cctx, 4842075 +github, level -5, compress cctx, 204411 github, level -5 with dict, compress cctx, 47294 -github, level -3, compress cctx, 220760 +github, level -3, compress cctx, 193253 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,17 +86,17 @@ 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, 6852472 silesia, level -3, zstdcli, 6503461 silesia, level -1, zstdcli, 6172226 @@ -228,81 +228,81 @@ github.tar, uncompressed literals, zstdcli, github.tar, uncompressed literals optimal, zstdcli, 35401 github.tar, huffman literals, zstdcli, 38857 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, 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 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 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 -5, advanced one pass, 6852424 +silesia, level -3, advanced one pass, 6503413 +silesia, level -1, advanced one pass, 6172178 +silesia, level 0, advanced one pass, 4842075 +silesia, level 1, advanced one pass, 5306426 +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 +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, 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, 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, 4912199 -silesia, explicit params, advanced one pass, 4795856 -silesia, uncompressed literals, advanced one pass, 5127982 +silesia, small chain log, advanced one pass, 4912197 +silesia, explicit params, advanced one pass, 4795432 +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.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, 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 -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 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, 4502955 -silesia.tar, level 16, advanced one pass, 4360526 +silesia, huffman literals, advanced one pass, 5321346 +silesia, multithreaded with advanced params, advanced one pass, 5120566 +silesia.tar, level -5, advanced one pass, 6853608 +silesia.tar, level -3, advanced one pass, 6505969 +silesia.tar, level -1, advanced one pass, 6179026 +silesia.tar, level 0, advanced one pass, 4854086 +silesia.tar, level 1, advanced one pass, 5327373 +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 +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, 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, 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, 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, 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 -github, level -5, advanced one pass, 232315 +silesia.tar, huffman literals, advanced one pass, 5341685 +silesia.tar, multithreaded with advanced params, advanced one pass, 5122567 +github, level -5, advanced one pass, 204411 github, level -5 with dict, advanced one pass, 46718 -github, level -3, advanced one pass, 220760 +github, level -3, advanced one pass, 193253 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 @@ -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 @@ -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 @@ -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.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, multithreaded with advanced params, advanced one pass, 165911 +github.tar, level -5, advanced one pass, 52110 +github.tar, level -5 with dict, advanced one pass, 46498 +github.tar, level -3, advanced one pass, 45678 +github.tar, level -3 with dict, advanced one pass, 42177 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,86 +439,86 @@ 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 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, 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, 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, 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 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 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, 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, 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, 36105 +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, 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 -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 @@ -533,94 +533,94 @@ 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, 41227 -github.tar, uncompressed literals, advanced one pass, 41122 +github.tar, explicit params, advanced one pass, 41385 +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 -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 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 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 +github.tar, multithreaded with advanced params, advanced one pass, 41525 +silesia, level -5, advanced one pass small out, 6852424 +silesia, level -3, advanced one pass small out, 6503413 +silesia, level -1, advanced one pass small out, 6172178 +silesia, level 0, advanced one pass small out, 4842075 +silesia, level 1, advanced one pass small out, 5306426 +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 +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, 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, 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, 4912199 -silesia, explicit params, advanced one pass small out, 4795856 -silesia, uncompressed literals, advanced one pass small out, 5127982 +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, 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.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, 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 -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 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, 4502955 -silesia.tar, level 16, advanced one pass small out, 4360526 +silesia, huffman literals, advanced one pass small out, 5321346 +silesia, multithreaded with advanced params, advanced one pass small out, 5120566 +silesia.tar, level -5, advanced one pass small out, 6853608 +silesia.tar, level -3, advanced one pass small out, 6505969 +silesia.tar, level -1, advanced one pass small out, 6179026 +silesia.tar, level 0, advanced one pass small out, 4854086 +silesia.tar, level 1, advanced one pass small out, 5327373 +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 +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, 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, 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, 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, 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 -github, level -5, advanced one pass small out, 232315 +silesia.tar, huffman literals, advanced one pass small out, 5341685 +silesia.tar, multithreaded with advanced params, advanced one pass small out, 5122567 +github, level -5, advanced one pass small out, 204411 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, 193253 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 @@ -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 @@ -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 @@ -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.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, multithreaded with advanced params, advanced one pass small out, 165911 +github.tar, level -5, advanced one pass small out, 52110 +github.tar, level -5 with dict, advanced one pass small out, 46498 +github.tar, level -3, advanced one pass small out, 45678 +github.tar, level -3 with dict, advanced one pass small out, 42177 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,86 +757,86 @@ 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 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, 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, 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, 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 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 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, 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, 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, 36105 +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, 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 -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 @@ -851,94 +851,94 @@ 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, 41227 -github.tar, uncompressed literals, advanced one pass small out, 41122 +github.tar, explicit params, advanced one pass small out, 41385 +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 -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, 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 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 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 +github.tar, multithreaded with advanced params, advanced one pass small out, 41525 +silesia, level -5, advanced streaming, 6963781 +silesia, level -3, advanced streaming, 6610376 +silesia, level -1, advanced streaming, 6179294 +silesia, level 0, advanced streaming, 4842075 +silesia, level 1, advanced streaming, 5310178 +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 +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, 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, 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, 4912199 -silesia, explicit params, advanced streaming, 4795884 -silesia, uncompressed literals, advanced streaming, 5127982 +silesia, small chain log, advanced streaming, 4912197 +silesia, explicit params, advanced streaming, 4795452 +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.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, 5334890 -silesia.tar, level 3, advanced streaming, 4861425 -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 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, 4502955 -silesia.tar, level 16, advanced streaming, 4360526 +silesia, huffman literals, advanced streaming, 5327881 +silesia, multithreaded with advanced params, advanced streaming, 5120566 +silesia.tar, level -5, advanced streaming, 7043687 +silesia.tar, level -3, advanced streaming, 6671317 +silesia.tar, level -1, advanced streaming, 6187457 +silesia.tar, level 0, advanced streaming, 4859271 +silesia.tar, level 1, advanced streaming, 5333896 +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 +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, 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, 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, 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, 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 -github, level -5, advanced streaming, 232315 +silesia.tar, huffman literals, advanced streaming, 5349624 +silesia.tar, multithreaded with advanced params, advanced streaming, 5122567 +github, level -5, advanced streaming, 204411 github, level -5 with dict, advanced streaming, 46718 -github, level -3, advanced streaming, 220760 +github, level -3, advanced streaming, 193253 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 @@ -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 @@ -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 @@ -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.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, multithreaded with advanced params, advanced streaming, 165911 +github.tar, level -5, advanced streaming, 51420 +github.tar, level -5 with dict, advanced streaming, 45495 +github.tar, level -3, advanced streaming, 45077 +github.tar, level -3 with dict, advanced streaming, 41627 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,86 +1075,86 @@ 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 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, 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, 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, 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 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 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, 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, 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, 36105 +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, 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 -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 @@ -1169,66 +1169,66 @@ 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, 41227 -github.tar, uncompressed literals, advanced streaming, 41122 +github.tar, explicit params, advanced streaming, 41385 +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 -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, 5312694 -silesia, level 3, old streaming, 4849551 -silesia, level 4, old streaming, 4786969 -silesia, level 5, old streaming, 4638960 -silesia, level 6, old streaming, 4605369 -silesia, level 7, old streaming, 4567203 -silesia, level 9, old streaming, 4543311 +github.tar, multithreaded with advanced params, advanced streaming, 41525 +silesia, level -5, old streaming, 6963781 +silesia, level -3, old streaming, 6610376 +silesia, level -1, old streaming, 6179294 +silesia, level 0, old streaming, 4842075 +silesia, level 1, old streaming, 5310178 +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 +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, 4849515 -silesia, uncompressed literals, old streaming, 4849551 +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, 4861425 -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 -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, 4502955 -silesia.tar, level 16, old streaming, 4360526 +silesia, huffman literals, old streaming, 6179294 +silesia.tar, level -5, old streaming, 7043687 +silesia.tar, level -3, old streaming, 6671317 +silesia.tar, level -1, old streaming, 6187457 +silesia.tar, level 0, old streaming, 4859271 +silesia.tar, level 1, old streaming, 5333896 +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 +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, 4861421 -silesia.tar, uncompressed literals, old streaming, 4861425 +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 +silesia.tar, huffman literals, old streaming, 6187457 +github, level -5, old streaming, 204411 github, level -5 with dict, old streaming, 46718 -github, level -3, old streaming, 220760 +github, level -3, old streaming, 193253 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 @@ -1241,104 +1241,104 @@ 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 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 -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 -5, old streaming, 51420 +github.tar, level -5 with dict, old streaming, 45495 +github.tar, level -3, old streaming, 45077 +github.tar, level -3 with dict, old streaming, 41627 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, 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 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, 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, 4849551 -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 6, old streaming advanced, 4605369 -silesia, level 7, old streaming advanced, 4567203 -silesia, level 9, old streaming advanced, 4543311 +silesia, level -5, old streaming advanced, 6963781 +silesia, level -3, old streaming advanced, 6610376 +silesia, level -1, old streaming advanced, 6179294 +silesia, level 0, old streaming advanced, 4842075 +silesia, level 1, old streaming advanced, 5310178 +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 +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, 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, 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, 4912199 -silesia, explicit params, old streaming advanced, 4795884 -silesia, uncompressed literals, old streaming advanced, 4849551 +silesia, small chain log, old streaming advanced, 4912197 +silesia, explicit params, old streaming advanced, 4795452 +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, 4849551 -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, 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 -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, 4502955 -silesia.tar, level 16, old streaming advanced, 4360526 +silesia, huffman literals, old streaming advanced, 6179294 +silesia, multithreaded with advanced params, old streaming advanced, 4842075 +silesia.tar, level -5, old streaming advanced, 7043687 +silesia.tar, level -3, old streaming advanced, 6671317 +silesia.tar, level -1, old streaming advanced, 6187457 +silesia.tar, level 0, old streaming advanced, 4859271 +silesia.tar, level 1, old streaming advanced, 5333896 +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 +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, 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, 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, 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, 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, 4861425 -github, level -5, old streaming advanced, 241214 +silesia.tar, huffman literals, old streaming advanced, 6187457 +silesia.tar, multithreaded with advanced params, old streaming advanced, 4859271 +github, level -5, old streaming advanced, 213265 github, level -5 with dict, old streaming advanced, 49562 -github, level -3, old streaming advanced, 222937 +github, level -3, old streaming advanced, 196126 github, level -3 with dict, old streaming advanced, 44956 github, level -1, old streaming advanced, 181107 github, level -1 with dict, old streaming advanced, 42383 @@ -1359,12 +1359,12 @@ 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 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 @@ -1377,47 +1377,47 @@ github, uncompressed literals, old stre github, uncompressed literals optimal, old streaming advanced, 134064 github, huffman literals, old streaming advanced, 181107 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 -5, old streaming advanced, 51420 +github.tar, level -5 with dict, old streaming advanced, 46091 +github.tar, level -3, old streaming advanced, 45077 +github.tar, level -3 with dict, old streaming advanced, 42222 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, 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 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, 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, 41227 -github.tar, uncompressed literals, old streaming advanced, 38441 +github.tar, explicit params, old streaming advanced, 41385 +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 @@ -1429,21 +1429,21 @@ 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 -github.tar, level -5 with dict, old streaming cdict, 49146 -github.tar, level -3 with dict, old streaming cdict, 43468 +github.tar, level -5 with dict, old streaming cdict, 46276 +github.tar, level -3 with dict, old streaming cdict, 42354 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, 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 -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 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 @@ -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 @@ -1470,10 +1470,10 @@ 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 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 From a9e43b37d0801aa1455b5d3c024946dcb73f150b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 20 Dec 2021 11:43:14 -0800 Subject: [PATCH 339/340] Revert "Limit `ZSTD_maxCLevel` to 21 for 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, 5 insertions(+), 13 deletions(-) diff --git a/.github/workflows/dev-short-tests.yml b/.github/workflows/dev-short-tests.yml index b5cd2415d..f06dfdb61 100644 --- a/.github/workflows/dev-short-tests.yml +++ b/.github/workflows/dev-short-tests.yml @@ -30,8 +30,6 @@ 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 7d2e1c6ca..3d62f5952 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 22 in most cases. Levels >= 20, labeled `--ultra`, should be used with + which is currently 22. 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 c2ceb6384..7ed2e0049 100644 --- a/lib/compress/clevels.h +++ b/lib/compress/clevels.h @@ -16,8 +16,7 @@ /*-===== Pre-defined compression levels =====-*/ -#define ZSTD_MAX_CLEVEL 22 -#define ZSTD_MAX_32BIT_CLEVEL 21 +#define ZSTD_MAX_CLEVEL 22 #ifdef __GNUC__ __attribute__((__unused__)) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e3d40c540..34f8e970f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -6165,7 +6165,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) /*-===== Pre-defined compression levels =====-*/ #include "clevels.h" -int ZSTD_maxCLevel(void) { return MEM_32bits() ? ZSTD_MAX_32BIT_CLEVEL : ZSTD_MAX_CLEVEL; } +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; } @@ -6261,7 +6261,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_maxCLevel()) row = ZSTD_maxCLevel(); + else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; else row = compressionLevel; { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; diff --git a/tests/fuzzer.c b/tests/fuzzer.c index c35be8e26..d168d6576 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 == (MEM_32bits() ? 21 : 22)); + assert(maxLevel == 22); RDG_genBuffer(CNBuffer, flatdictSize + contentSize, compressibility, 0., seed); DISPLAYLEVEL(4, "content hash : %016llx; dict hash : %016llx \n", (unsigned long long)XXH64(contentStart, contentSize, 0), diff --git a/tests/playTests.sh b/tests/playTests.sh index 11240898e..a772b61ff 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -1568,11 +1568,6 @@ 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 1219b7f3e396fcaa53e8b6c3ca2cca51e8e40f16 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 20 Dec 2021 12:28:27 -0800 Subject: [PATCH 340/340] updated changelog for v1.5.1 --- CHANGELOG | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ad9c07957..31e9007b8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,8 +15,6 @@ build: improved AIX support, by @Helflym build: improved meson unofficial build, by @eli-schwartz cli : custom memory limit when training dictionary (#2925), by @embg cli : report advanced parameters information when compressing in very verbose mode (``-vv`), by @Svetlitski-FB -cli : limit --ultra levels to 21 in 32-bit mode, to reduce risks of OOM scenarios (#2885, @yoniko) - v1.5.0 (May 11, 2021) api: Various functions promoted from experimental to stable API: (#2579-2581, @senhuang42)