Merge branch 'dev' into huf_rename

This commit is contained in:
Yann Collet 2018-06-14 20:42:10 -04:00
commit d8462ecba2
20 changed files with 340 additions and 101 deletions

View File

@ -20,14 +20,18 @@ matrix:
- env: Cmd='make clang38install && CC=clang-3.8 make clean msan-fuzztest' - env: Cmd='make clang38install && CC=clang-3.8 make clean msan-fuzztest'
- env: Cmd='make clang38install && CC=clang-3.8 make clean tsan-test-zstream' - env: Cmd='make clang38install && CC=clang-3.8 make clean tsan-test-zstream'
- env: Cmd='make -C tests test-fuzzer-stackmode'
- env: Cmd='make valgrindinstall && make -C tests clean valgrindTest' - env: Cmd='make valgrindinstall && make -C tests clean valgrindTest'
- env: Cmd='make arminstall && make armfuzz' - env: Cmd='make arminstall && make armfuzz'
# Following test is disabled, as there is a bug in Travis' ld # Following test is disabled, as there is a bug in Travis' ld
# preventing aarch64 compilation to complete. # preventing aarch64 compilation to complete.
# > collect2: error: ld terminated with signal 11 [Segmentation fault], core dumped # > collect2: error: ld terminated with signal 11 [Segmentation fault], core dumped
# to be re-enabled in a few commit, as it's possible that a random code change circumvent the ld bug # to be re-enabled in a few commit, as it's possible that a random code change circumvent the ld bug
# - env: Cmd='make arminstall && make aarch64fuzz' # - env: Cmd='make arminstall && make aarch64fuzz'
- env: Cmd='make ppcinstall && make ppcfuzz' - env: Cmd='make ppcinstall && make ppcfuzz'
- env: Cmd='make ppcinstall && make ppc64fuzz' - env: Cmd='make ppcinstall && make ppc64fuzz'
- env: Cmd='make -j uasanregressiontest && make clean && make -j msanregressiontest' - env: Cmd='make -j uasanregressiontest && make clean && make -j msanregressiontest'
@ -35,6 +39,7 @@ matrix:
- env: Cmd='make lz4install && make -C tests test-lz4' - env: Cmd='make lz4install && make -C tests test-lz4'
- env: Cmd='bash tests/libzstd_partial_builds.sh' - env: Cmd='bash tests/libzstd_partial_builds.sh'
# tag-specific test # tag-specific test
- if: tag =~ ^v[0-9]\.[0-9] - if: tag =~ ^v[0-9]\.[0-9]
env: Cmd='make -C tests checkTag && tests/checkTag $TRAVIS_BRANCH' env: Cmd='make -C tests checkTag && tests/checkTag $TRAVIS_BRANCH'

View File

@ -332,6 +332,10 @@
RelativePath="..\..\..\lib\common\entropy_common.c" RelativePath="..\..\..\lib\common\entropy_common.c"
> >
</File> </File>
<File
RelativePath="..\..\..\lib\compress\hist.c"
>
</File>
<File <File
RelativePath="..\..\..\lib\common\error_private.c" RelativePath="..\..\..\lib\common\error_private.c"
> >

View File

@ -352,6 +352,10 @@
RelativePath="..\..\..\lib\common\entropy_common.c" RelativePath="..\..\..\lib\common\entropy_common.c"
> >
</File> </File>
<File
RelativePath="..\..\..\lib\compress\hist.c"
>
</File>
<File <File
RelativePath="..\..\..\lib\common\error_private.c" RelativePath="..\..\..\lib\common\error_private.c"
> >

View File

@ -356,6 +356,10 @@
RelativePath="..\..\..\lib\common\entropy_common.c" RelativePath="..\..\..\lib\common\entropy_common.c"
> >
</File> </File>
<File
RelativePath="..\..\..\lib\compress\hist.c"
>
</File>
<File <File
RelativePath="..\..\..\lib\common\error_private.c" RelativePath="..\..\..\lib\common\error_private.c"
> >

View File

@ -348,6 +348,10 @@
RelativePath="..\..\..\lib\common\entropy_common.c" RelativePath="..\..\..\lib\common\entropy_common.c"
> >
</File> </File>
<File
RelativePath="..\..\..\lib\compress\hist.c"
>
</File>
<File <File
RelativePath="..\..\..\lib\common\error_private.c" RelativePath="..\..\..\lib\common\error_private.c"
> >

View File

@ -156,6 +156,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\lib\common\entropy_common.c" /> <ClCompile Include="..\..\..\lib\common\entropy_common.c" />
<ClCompile Include="..\..\..\lib\compress\hist.c" />
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" /> <ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
<ClCompile Include="..\..\..\lib\common\zstd_common.c" /> <ClCompile Include="..\..\..\lib\common\zstd_common.c" />
<ClCompile Include="..\..\..\lib\common\error_private.c" /> <ClCompile Include="..\..\..\lib\common\error_private.c" />

View File

@ -158,6 +158,7 @@
<ClCompile Include="..\..\..\lib\common\pool.c" /> <ClCompile Include="..\..\..\lib\common\pool.c" />
<ClCompile Include="..\..\..\lib\common\threading.c" /> <ClCompile Include="..\..\..\lib\common\threading.c" />
<ClCompile Include="..\..\..\lib\common\entropy_common.c" /> <ClCompile Include="..\..\..\lib\common\entropy_common.c" />
<ClCompile Include="..\..\..\lib\compress\hist.c" />
<ClCompile Include="..\..\..\lib\common\error_private.c" /> <ClCompile Include="..\..\..\lib\common\error_private.c" />
<ClCompile Include="..\..\..\lib\common\fse_decompress.c" /> <ClCompile Include="..\..\..\lib\common\fse_decompress.c" />
<ClCompile Include="..\..\..\lib\common\xxhash.c" /> <ClCompile Include="..\..\..\lib\common\xxhash.c" />

View File

@ -22,6 +22,7 @@
<ClCompile Include="..\..\..\lib\common\pool.c" /> <ClCompile Include="..\..\..\lib\common\pool.c" />
<ClCompile Include="..\..\..\lib\common\threading.c" /> <ClCompile Include="..\..\..\lib\common\threading.c" />
<ClCompile Include="..\..\..\lib\common\entropy_common.c" /> <ClCompile Include="..\..\..\lib\common\entropy_common.c" />
<ClCompile Include="..\..\..\lib\compress\hist.c" />
<ClCompile Include="..\..\..\lib\common\error_private.c" /> <ClCompile Include="..\..\..\lib\common\error_private.c" />
<ClCompile Include="..\..\..\lib\common\xxhash.c" /> <ClCompile Include="..\..\..\lib\common\xxhash.c" />
<ClCompile Include="..\..\..\lib\common\zstd_common.c" /> <ClCompile Include="..\..\..\lib\common\zstd_common.c" />

View File

@ -22,6 +22,7 @@
<ClCompile Include="..\..\..\lib\common\pool.c" /> <ClCompile Include="..\..\..\lib\common\pool.c" />
<ClCompile Include="..\..\..\lib\common\threading.c" /> <ClCompile Include="..\..\..\lib\common\threading.c" />
<ClCompile Include="..\..\..\lib\common\entropy_common.c" /> <ClCompile Include="..\..\..\lib\common\entropy_common.c" />
<ClCompile Include="..\..\..\lib\compress\hist.c" />
<ClCompile Include="..\..\..\lib\common\error_private.c" /> <ClCompile Include="..\..\..\lib\common\error_private.c" />
<ClCompile Include="..\..\..\lib\common\xxhash.c" /> <ClCompile Include="..\..\..\lib\common\xxhash.c" />
<ClCompile Include="..\..\..\lib\common\zstd_common.c" /> <ClCompile Include="..\..\..\lib\common\zstd_common.c" />

View File

@ -20,6 +20,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\..\lib\common\entropy_common.c" /> <ClCompile Include="..\..\..\lib\common\entropy_common.c" />
<ClCompile Include="..\..\..\lib\compress\hist.c" />
<ClCompile Include="..\..\..\lib\common\error_private.c" /> <ClCompile Include="..\..\..\lib\common\error_private.c" />
<ClCompile Include="..\..\..\lib\common\pool.c" /> <ClCompile Include="..\..\..\lib\common\pool.c" />
<ClCompile Include="..\..\..\lib\common\threading.c" /> <ClCompile Include="..\..\..\lib\common\threading.c" />

View File

@ -55,6 +55,7 @@ SET(Sources
SET(Headers SET(Headers
${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/zstd.h
${LIBRARY_DIR}/common/debug.h
${LIBRARY_DIR}/common/pool.h ${LIBRARY_DIR}/common/pool.h
${LIBRARY_DIR}/common/threading.h ${LIBRARY_DIR}/common/threading.h
${LIBRARY_DIR}/common/bitstream.h ${LIBRARY_DIR}/common/bitstream.h

View File

@ -42,7 +42,7 @@ PZSTD_LDFLAGS =
EXTRA_FLAGS = EXTRA_FLAGS =
ALL_CFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CFLAGS) $(PZSTD_CFLAGS) ALL_CFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CFLAGS) $(PZSTD_CFLAGS)
ALL_CXXFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CXXFLAGS) $(PZSTD_CXXFLAGS) ALL_CXXFLAGS = $(EXTRA_FLAGS) $(CPPFLAGS) $(PZSTD_CPPFLAGS) $(CXXFLAGS) $(PZSTD_CXXFLAGS)
ALL_LDFLAGS = $(EXTRA_FLAGS) $(LDFLAGS) $(PZSTD_LDFLAGS) ALL_LDFLAGS = $(EXTRA_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(PZSTD_LDFLAGS)
# gtest libraries need to go before "-lpthread" because they depend on it. # gtest libraries need to go before "-lpthread" because they depend on it.

View File

@ -93,18 +93,18 @@ extern "C" {
#if (DEBUGLEVEL>=2) #if (DEBUGLEVEL>=2)
# include <stdio.h> # include <stdio.h>
extern int g_debug_level; /* here, this variable is only declared, extern int g_debuglevel; /* here, this variable is only declared,
it actually lives in debug.c, it actually lives in debug.c,
and is shared by the whole process. and is shared by the whole process.
It's typically used to enable very verbose levels It's typically used to enable very verbose levels
on selective conditions (such as position in src) */ on selective conditions (such as position in src) */
# define RAWLOG(l, ...) { \ # define RAWLOG(l, ...) { \
if (l<=g_debug_level) { \ if (l<=g_debuglevel) { \
fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, __VA_ARGS__); \
} } } }
# define DEBUGLOG(l, ...) { \ # define DEBUGLOG(l, ...) { \
if (l<=g_debug_level) { \ if (l<=g_debuglevel) { \
fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ fprintf(stderr, __FILE__ ": " __VA_ARGS__); \
fprintf(stderr, " \n"); \ fprintf(stderr, " \n"); \
} } } }

View File

@ -46,14 +46,6 @@ unsigned HIST_isError(size_t code) { return ERR_isError(code); }
/*-************************************************************** /*-**************************************************************
* Histogram functions * Histogram functions
****************************************************************/ ****************************************************************/
/*! HIST_count_simple :
Counts byte values within `src`, storing histogram into table `count`.
Doesn't use any additional memory, very limited stack usage.
But unsafe : doesn't check that all values within `src` fit into `count`.
For this reason, prefer using a table `count` of size 256.
@return : count of most numerous element.
this function doesn't produce any error (i.e. it must succeed).
*/
unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize) const void* src, size_t srcSize)
{ {
@ -83,7 +75,10 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
/* HIST_count_parallel_wksp() : /* HIST_count_parallel_wksp() :
* Same as HIST_count_parallel(), but using an externally provided scratch buffer. * store histogram into 4 intermediate tables, recombined at the end.
* this design makes better use of OoO cpus,
* and is noticeably faster when some values are heavily repeated.
* But it needs some additional workspace for intermediate tables.
* `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32. * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32.
* @return : largest histogram frequency, * @return : largest histogram frequency,
* or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */ * or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */

View File

@ -81,10 +81,12 @@ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
unsigned* workSpace); unsigned* workSpace);
/*! HIST_count_simple() : /*! HIST_count_simple() :
* Same as HIST_countFast(), but does not use any additional memory (not even on stack). * Same as HIST_countFast(), this function is unsafe,
* This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr`. * and will segfault if any value within `src` is `> *maxSymbolValuePtr`.
* It is also a bit slower for large inputs. * It is also a bit slower for large inputs.
* This function doesn't produce any error (i.e. it must succeed). * However, it does not need any additional memory (not even on stack).
* @return : count of the most frequent symbol.
* Note this function doesn't produce any error (i.e. it must succeed).
*/ */
unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize); const void* src, size_t srcSize);

View File

@ -1234,18 +1234,18 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
8 KB, /* unused */ 8 KB, /* unused */
8 KB, /* ZSTD_fast */ 8 KB, /* ZSTD_fast */
16 KB, /* ZSTD_dfast */ 16 KB, /* ZSTD_dfast */
16 KB, /* ZSTD_greedy */ 32 KB, /* ZSTD_greedy */
16 KB, /* ZSTD_lazy */ 32 KB, /* ZSTD_lazy */
16 KB, /* ZSTD_lazy2 */ 32 KB, /* ZSTD_lazy2 */
16 KB, /* ZSTD_btlazy2 */ 256 KB, /* ZSTD_btlazy2 */
16 KB, /* ZSTD_btopt */ 256 KB, /* ZSTD_btopt */
16 KB /* ZSTD_btultra */ 256 KB /* ZSTD_btultra */
}; };
const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy] const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy]
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN ) || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN )
&& !params.forceWindow /* dictMatchState isn't correctly && !params.forceWindow /* dictMatchState isn't correctly
* handled in _enforceMaxDist */ * handled in _enforceMaxDist */
&& cdict->cParams.strategy <= ZSTD_dfast && cdict->cParams.strategy <= ZSTD_lazy2
&& ZSTD_equivalentCParams(cctx->appliedParams.cParams, && ZSTD_equivalentCParams(cctx->appliedParams.cParams,
cdict->cParams); cdict->cParams);
@ -2231,17 +2231,31 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMo
{ {
static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = { static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = {
{ ZSTD_compressBlock_fast /* default for 0 */, { ZSTD_compressBlock_fast /* default for 0 */,
ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_fast,
ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_doubleFast,
ZSTD_compressBlock_btopt, ZSTD_compressBlock_btultra }, ZSTD_compressBlock_greedy,
ZSTD_compressBlock_lazy,
ZSTD_compressBlock_lazy2,
ZSTD_compressBlock_btlazy2,
ZSTD_compressBlock_btopt,
ZSTD_compressBlock_btultra },
{ ZSTD_compressBlock_fast_extDict /* default for 0 */, { ZSTD_compressBlock_fast_extDict /* default for 0 */,
ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_fast_extDict,
ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_doubleFast_extDict,
ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict }, ZSTD_compressBlock_greedy_extDict,
ZSTD_compressBlock_lazy_extDict,
ZSTD_compressBlock_lazy2_extDict,
ZSTD_compressBlock_btlazy2_extDict,
ZSTD_compressBlock_btopt_extDict,
ZSTD_compressBlock_btultra_extDict },
{ ZSTD_compressBlock_fast_dictMatchState /* default for 0 */, { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */,
ZSTD_compressBlock_fast_dictMatchState, ZSTD_compressBlock_fast_dictMatchState,
ZSTD_compressBlock_doubleFast_dictMatchState, ZSTD_compressBlock_doubleFast_dictMatchState,
NULL, NULL, NULL, NULL, NULL, NULL /* unimplemented as of yet */ } ZSTD_compressBlock_greedy_dictMatchState,
ZSTD_compressBlock_lazy_dictMatchState,
ZSTD_compressBlock_lazy2_dictMatchState,
ZSTD_compressBlock_btlazy2_dictMatchState,
NULL, NULL /* unimplemented as of yet */ }
}; };
ZSTD_blockCompressor selectedCompressor; ZSTD_blockCompressor selectedCompressor;
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);

View File

@ -62,7 +62,7 @@ void ZSTD_updateDUBT(
static void ZSTD_insertDUBT1( static void ZSTD_insertDUBT1(
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
U32 current, const BYTE* inputEnd, U32 current, const BYTE* inputEnd,
U32 nbCompares, U32 btLow, int extDict) U32 nbCompares, U32 btLow, const ZSTD_dictMode_e dictMode)
{ {
U32* const bt = ms->chainTable; U32* const bt = ms->chainTable;
U32 const btLog = cParams->chainLog - 1; U32 const btLog = cParams->chainLog - 1;
@ -92,10 +92,12 @@ static void ZSTD_insertDUBT1(
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
assert(matchIndex < current); assert(matchIndex < current);
if ( (!extDict) if ( (dictMode != ZSTD_extDict)
|| (matchIndex+matchLength >= dictLimit) /* both in current segment*/ || (matchIndex+matchLength >= dictLimit) /* both in current segment*/
|| (current < dictLimit) /* both in extDict */) { || (current < dictLimit) /* both in extDict */) {
const BYTE* const mBase = !extDict || ((matchIndex+matchLength) >= dictLimit) ? base : dictBase; const BYTE* const mBase = ( (dictMode != ZSTD_extDict)
|| (matchIndex+matchLength >= dictLimit)) ?
base : dictBase;
assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */ assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */
|| (current < dictLimit) ); || (current < dictLimit) );
match = mBase + matchIndex; match = mBase + matchIndex;
@ -143,7 +145,7 @@ static size_t ZSTD_DUBT_findBestMatch (
const BYTE* const ip, const BYTE* const iend, const BYTE* const ip, const BYTE* const iend,
size_t* offsetPtr, size_t* offsetPtr,
U32 const mls, U32 const mls,
U32 const extDict) const ZSTD_dictMode_e dictMode)
{ {
U32* const hashTable = ms->hashTable; U32* const hashTable = ms->hashTable;
U32 const hashLog = cParams->hashLog; U32 const hashLog = cParams->hashLog;
@ -196,7 +198,7 @@ static size_t ZSTD_DUBT_findBestMatch (
U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1; U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1;
U32 const nextCandidateIdx = *nextCandidateIdxPtr; U32 const nextCandidateIdx = *nextCandidateIdxPtr;
ZSTD_insertDUBT1(ms, cParams, matchIndex, iend, ZSTD_insertDUBT1(ms, cParams, matchIndex, iend,
nbCandidates, unsortLimit, extDict); nbCandidates, unsortLimit, dictMode);
matchIndex = nextCandidateIdx; matchIndex = nextCandidateIdx;
nbCandidates++; nbCandidates++;
} }
@ -221,7 +223,7 @@ static size_t ZSTD_DUBT_findBestMatch (
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
const BYTE* match; const BYTE* match;
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) { if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) {
match = base + matchIndex; match = base + matchIndex;
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
} else { } else {
@ -276,12 +278,13 @@ static size_t ZSTD_BtFindBestMatch (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* const ip, const BYTE* const iLimit, const BYTE* const ip, const BYTE* const iLimit,
size_t* offsetPtr, size_t* offsetPtr,
const U32 mls /* template */) const U32 mls /* template */,
const ZSTD_dictMode_e dictMode)
{ {
DEBUGLOG(7, "ZSTD_BtFindBestMatch"); DEBUGLOG(7, "ZSTD_BtFindBestMatch");
if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
ZSTD_updateDUBT(ms, cParams, ip, iLimit, mls); ZSTD_updateDUBT(ms, cParams, ip, iLimit, mls);
return ZSTD_DUBT_findBestMatch(ms, cParams, ip, iLimit, offsetPtr, mls, 0); return ZSTD_DUBT_findBestMatch(ms, cParams, ip, iLimit, offsetPtr, mls, dictMode);
} }
@ -293,29 +296,15 @@ static size_t ZSTD_BtFindBestMatch_selectMLS (
switch(cParams->searchLength) switch(cParams->searchLength)
{ {
default : /* includes case 3 */ default : /* includes case 3 */
case 4 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 4); case 4 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 4, ZSTD_noDict);
case 5 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 5); case 5 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 5, ZSTD_noDict);
case 7 : case 7 :
case 6 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 6); case 6 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 6, ZSTD_noDict);
} }
} }
/** Tree updater, providing best match */ static size_t ZSTD_BtFindBestMatch_dictMatchState_selectMLS (
static size_t ZSTD_BtFindBestMatch_extDict (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* const ip, const BYTE* const iLimit,
size_t* offsetPtr,
const U32 mls)
{
DEBUGLOG(7, "ZSTD_BtFindBestMatch_extDict");
if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
ZSTD_updateDUBT(ms, cParams, ip, iLimit, mls);
return ZSTD_DUBT_findBestMatch(ms, cParams, ip, iLimit, offsetPtr, mls, 1);
}
static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* ip, const BYTE* const iLimit, const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr) size_t* offsetPtr)
@ -323,10 +312,26 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
switch(cParams->searchLength) switch(cParams->searchLength)
{ {
default : /* includes case 3 */ default : /* includes case 3 */
case 4 : return ZSTD_BtFindBestMatch_extDict(ms, cParams, ip, iLimit, offsetPtr, 4); case 4 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);
case 5 : return ZSTD_BtFindBestMatch_extDict(ms, cParams, ip, iLimit, offsetPtr, 5); case 5 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);
case 7 : case 7 :
case 6 : return ZSTD_BtFindBestMatch_extDict(ms, cParams, ip, iLimit, offsetPtr, 6); case 6 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);
}
}
static size_t ZSTD_BtFindBestMatch_extDict_selectMLS (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr)
{
switch(cParams->searchLength)
{
default : /* includes case 3 */
case 4 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 4, ZSTD_extDict);
case 5 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 5, ZSTD_extDict);
case 7 :
case 6 : return ZSTD_BtFindBestMatch(ms, cParams, ip, iLimit, offsetPtr, 6, ZSTD_extDict);
} }
} }
@ -376,7 +381,7 @@ size_t ZSTD_HcFindBestMatch_generic (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* const ip, const BYTE* const iLimit, const BYTE* const ip, const BYTE* const iLimit,
size_t* offsetPtr, size_t* offsetPtr,
const U32 mls, const U32 extDict) const U32 mls, const ZSTD_dictMode_e dictMode)
{ {
U32* const chainTable = ms->chainTable; U32* const chainTable = ms->chainTable;
const U32 chainSize = (1 << cParams->chainLog); const U32 chainSize = (1 << cParams->chainLog);
@ -397,7 +402,7 @@ size_t ZSTD_HcFindBestMatch_generic (
for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) { for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
size_t currentMl=0; size_t currentMl=0;
if ((!extDict) || matchIndex >= dictLimit) { if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
const BYTE* const match = base + matchIndex; const BYTE* const match = base + matchIndex;
if (match[ml] == ip[ml]) /* potentially better */ if (match[ml] == ip[ml]) /* potentially better */
currentMl = ZSTD_count(ip, match, iLimit); currentMl = ZSTD_count(ip, match, iLimit);
@ -419,6 +424,37 @@ size_t ZSTD_HcFindBestMatch_generic (
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
} }
if (dictMode == ZSTD_dictMatchState) {
const ZSTD_matchState_t* const dms = ms->dictMatchState;
const U32* const dmsChainTable = dms->chainTable;
const U32 dmsLowestIndex = dms->window.dictLimit;
const BYTE* const dmsBase = dms->window.base;
const BYTE* const dmsEnd = dms->window.nextSrc;
const U32 dmsSize = (U32)(dmsEnd - dmsBase);
const U32 dmsIndexDelta = dictLimit - dmsSize;
const U32 dmsMinChain = dmsSize > chainSize ? dmsSize - chainSize : 0;
matchIndex = dms->hashTable[ZSTD_hashPtr(ip, cParams->hashLog, mls)];
for ( ; (matchIndex>dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
size_t currentMl=0;
const BYTE* const match = dmsBase + matchIndex;
assert(match+4 <= dmsEnd);
if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4;
/* save best solution */
if (currentMl > ml) {
ml = currentMl;
*offsetPtr = current - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
}
if (matchIndex <= dmsMinChain) break;
matchIndex = dmsChainTable[matchIndex & chainMask];
}
}
return ml; return ml;
} }
@ -431,10 +467,26 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
switch(cParams->searchLength) switch(cParams->searchLength)
{ {
default : /* includes case 3 */ default : /* includes case 3 */
case 4 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 4, 0); case 4 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 4, ZSTD_noDict);
case 5 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 5, 0); case 5 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 5, ZSTD_noDict);
case 7 : case 7 :
case 6 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 6, 0); case 6 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 6, ZSTD_noDict);
}
}
static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* ip, const BYTE* const iLimit,
size_t* offsetPtr)
{
switch(cParams->searchLength)
{
default : /* includes case 3 */
case 4 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);
case 5 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);
case 7 :
case 6 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);
} }
} }
@ -442,15 +494,15 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS ( FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* ip, const BYTE* const iLimit, const BYTE* ip, const BYTE* const iLimit,
size_t* const offsetPtr) size_t* offsetPtr)
{ {
switch(cParams->searchLength) switch(cParams->searchLength)
{ {
default : /* includes case 3 */ default : /* includes case 3 */
case 4 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 4, 1); case 4 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 4, ZSTD_extDict);
case 5 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 5, 1); case 5 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 5, ZSTD_extDict);
case 7 : case 7 :
case 6 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 6, 1); case 6 : return ZSTD_HcFindBestMatch_generic(ms, cParams, ip, iLimit, offsetPtr, 6, ZSTD_extDict);
} }
} }
@ -464,28 +516,56 @@ size_t ZSTD_compressBlock_lazy_generic(
U32 rep[ZSTD_REP_NUM], U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, ZSTD_compressionParameters const* cParams,
const void* src, size_t srcSize, const void* src, size_t srcSize,
const U32 searchMethod, const U32 depth) const U32 searchMethod, const U32 depth,
ZSTD_dictMode_e const dictMode)
{ {
const BYTE* const istart = (const BYTE*)src; const BYTE* const istart = (const BYTE*)src;
const BYTE* ip = istart; const BYTE* ip = istart;
const BYTE* anchor = istart; const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize; const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - 8; const BYTE* const ilimit = iend - 8;
const BYTE* const base = ms->window.base + ms->window.dictLimit; const BYTE* const base = ms->window.base;
const U32 prefixLowestIndex = ms->window.dictLimit;
const BYTE* const prefixLowest = base + prefixLowestIndex;
typedef size_t (*searchMax_f)( typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS; searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ?
(searchMethod ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
(searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS);
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0; U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
const ZSTD_matchState_t* const dms = ms->dictMatchState;
const U32 dictLowestIndex = dictMode == ZSTD_dictMatchState ?
dms->window.dictLimit : 0;
const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ?
dms->window.base : NULL;
const BYTE* const dictLowest = dictMode == ZSTD_dictMatchState ?
dictBase + dictLowestIndex : 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 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictLowest);
(void)dictMode;
/* init */ /* init */
ip += (ip==base); ip += (dictAndPrefixLength == 0);
ms->nextToUpdate3 = ms->nextToUpdate; ms->nextToUpdate3 = ms->nextToUpdate;
{ U32 const maxRep = (U32)(ip-base); if (dictMode == ZSTD_noDict) {
U32 const maxRep = (U32)(ip - prefixLowest);
if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0; if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0; if (offset_1 > maxRep) savedOffset = 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);
}
/* Match Loop */ /* Match Loop */
while (ip < ilimit) { while (ip < ilimit) {
@ -494,8 +574,21 @@ size_t ZSTD_compressBlock_lazy_generic(
const BYTE* start=ip+1; const BYTE* start=ip+1;
/* check repCode */ /* check repCode */
if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) { if (dictMode == ZSTD_dictMatchState) {
/* repcode : we take it */ const U32 repIndex = (U32)(ip - base) + 1 - offset_1;
const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
&& repIndex < prefixLowestIndex) ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
if (depth==0) goto _storeSequence;
}
}
if ( dictMode == ZSTD_noDict
&& ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
if (depth==0) goto _storeSequence; if (depth==0) goto _storeSequence;
} }
@ -516,13 +609,29 @@ size_t ZSTD_compressBlock_lazy_generic(
if (depth>=1) if (depth>=1)
while (ip<ilimit) { while (ip<ilimit) {
ip ++; ip ++;
if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { if ( (dictMode == ZSTD_noDict)
&& (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
int const gain2 = (int)(mlRep * 3); int const gain2 = (int)(mlRep * 3);
int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1); int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
if ((mlRep >= 4) && (gain2 > gain1)) if ((mlRep >= 4) && (gain2 > gain1))
matchLength = mlRep, offset = 0, start = ip; matchLength = mlRep, offset = 0, start = ip;
} }
if (dictMode == ZSTD_dictMatchState) {
const U32 repIndex = (U32)(ip - base) - offset_1;
const BYTE* repMatch = repIndex < prefixLowestIndex ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
&& (MEM_read32(repMatch) == MEM_read32(ip)) ) {
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
int const gain2 = (int)(mlRep * 3);
int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
if ((mlRep >= 4) && (gain2 > gain1))
matchLength = mlRep, offset = 0, start = ip;
}
}
{ size_t offset2=99999999; { size_t offset2=99999999;
size_t const ml2 = searchMax(ms, cParams, ip, iend, &offset2); size_t const ml2 = searchMax(ms, cParams, ip, iend, &offset2);
int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
@ -535,12 +644,28 @@ size_t ZSTD_compressBlock_lazy_generic(
/* let's find an even better one */ /* let's find an even better one */
if ((depth==2) && (ip<ilimit)) { if ((depth==2) && (ip<ilimit)) {
ip ++; ip ++;
if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { if ( (dictMode == ZSTD_noDict)
size_t const ml2 = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
int const gain2 = (int)(ml2 * 4); size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
int const gain2 = (int)(mlRep * 4);
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1); int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
if ((ml2 >= 4) && (gain2 > gain1)) if ((mlRep >= 4) && (gain2 > gain1))
matchLength = ml2, offset = 0, start = ip; matchLength = mlRep, offset = 0, start = ip;
}
if (dictMode == ZSTD_dictMatchState) {
const U32 repIndex = (U32)(ip - base) - offset_1;
const BYTE* repMatch = repIndex < prefixLowestIndex ?
dictBase + (repIndex - dictIndexDelta) :
base + repIndex;
if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
&& (MEM_read32(repMatch) == MEM_read32(ip)) ) {
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
int const gain2 = (int)(mlRep * 4);
int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
if ((mlRep >= 4) && (gain2 > gain1))
matchLength = mlRep, offset = 0, start = ip;
}
} }
{ size_t offset2=99999999; { size_t offset2=99999999;
size_t const ml2 = searchMax(ms, cParams, ip, iend, &offset2); size_t const ml2 = searchMax(ms, cParams, ip, iend, &offset2);
@ -560,9 +685,17 @@ size_t ZSTD_compressBlock_lazy_generic(
*/ */
/* catch up */ /* catch up */
if (offset) { if (offset) {
while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > base)) if (dictMode == ZSTD_noDict) {
&& (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */ while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > prefixLowest))
{ start--; matchLength++; } && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
{ start--; matchLength++; }
}
if (dictMode == ZSTD_dictMatchState) {
U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
}
offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE); offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
} }
/* store sequence */ /* store sequence */
@ -573,16 +706,39 @@ _storeSequence:
} }
/* check immediate repcode */ /* check immediate repcode */
while ( ((ip <= ilimit) & (offset_2>0)) if (dictMode == ZSTD_dictMatchState) {
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { while (ip <= ilimit) {
/* store sequence */ U32 const current2 = (U32)(ip-base);
matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; U32 const repIndex = current2 - offset_2;
offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */ const BYTE* repMatch = dictMode == ZSTD_dictMatchState
ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH); && repIndex < prefixLowestIndex ?
ip += matchLength; dictBase - dictIndexDelta + repIndex :
anchor = ip; base + repIndex;
continue; /* faster when present ... (?) */ if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)
} } && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend;
matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4;
offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset_2 <=> offset_1 */
ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
ip += matchLength;
anchor = ip;
continue;
}
break;
}
}
if (dictMode == ZSTD_noDict) {
while ( ((ip <= ilimit) & (offset_2>0))
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
/* store sequence */
matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
ip += matchLength;
anchor = ip;
continue; /* faster when present ... (?) */
} } }
/* Save reps for next block */ /* Save reps for next block */
rep[0] = offset_1 ? offset_1 : savedOffset; rep[0] = offset_1 ? offset_1 : savedOffset;
@ -597,28 +753,56 @@ size_t ZSTD_compressBlock_btlazy2(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize) ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{ {
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 1, 2); return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 1, 2, ZSTD_noDict);
} }
size_t ZSTD_compressBlock_lazy2( size_t ZSTD_compressBlock_lazy2(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize) ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{ {
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 2); return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 2, ZSTD_noDict);
} }
size_t ZSTD_compressBlock_lazy( size_t ZSTD_compressBlock_lazy(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize) ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{ {
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 1); return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 1, ZSTD_noDict);
} }
size_t ZSTD_compressBlock_greedy( size_t ZSTD_compressBlock_greedy(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize) ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{ {
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 0); return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 0, ZSTD_noDict);
}
size_t ZSTD_compressBlock_btlazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 1, 2, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_lazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 2, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_lazy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 1, ZSTD_dictMatchState);
}
size_t ZSTD_compressBlock_greedy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize)
{
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, cParams, src, srcSize, 0, 0, ZSTD_dictMatchState);
} }
@ -646,7 +830,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
typedef size_t (*searchMax_f)( typedef size_t (*searchMax_f)(
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr); const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS; searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
U32 offset_1 = rep[0], offset_2 = rep[1]; U32 offset_1 = rep[0], offset_2 = rep[1];

View File

@ -36,6 +36,19 @@ size_t ZSTD_compressBlock_greedy(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize); ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
size_t ZSTD_compressBlock_btlazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy2_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
size_t ZSTD_compressBlock_lazy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_dictMatchState(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);
size_t ZSTD_compressBlock_greedy_extDict( size_t ZSTD_compressBlock_greedy_extDict(
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize); ZSTD_compressionParameters const* cParams, void const* src, size_t srcSize);

View File

@ -192,6 +192,8 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
dctx->inBuffSize = 0; dctx->inBuffSize = 0;
dctx->outBuffSize = 0; dctx->outBuffSize = 0;
dctx->streamStage = zdss_init; dctx->streamStage = zdss_init;
dctx->legacyContext = NULL;
dctx->previousLegacyVersion = 0;
dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
} }
@ -215,8 +217,6 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
{ ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem); { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);
if (!dctx) return NULL; if (!dctx) return NULL;
dctx->customMem = customMem; dctx->customMem = customMem;
dctx->legacyContext = NULL;
dctx->previousLegacyVersion = 0;
ZSTD_initDCtx_internal(dctx); ZSTD_initDCtx_internal(dctx);
return dctx; return dctx;
} }
@ -1996,6 +1996,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
return regenSize; return regenSize;
#else /* stack mode */ #else /* stack mode */
ZSTD_DCtx dctx; ZSTD_DCtx dctx;
ZSTD_initDCtx_internal(&dctx);
return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize); return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
#endif #endif
} }

View File

@ -360,6 +360,9 @@ test-fullbench32: fullbench32 datagen
test-fuzzer: fuzzer test-fuzzer: fuzzer
$(QEMU_SYS) ./fuzzer -v $(FUZZERTEST) $(FUZZER_FLAGS) $(QEMU_SYS) ./fuzzer -v $(FUZZERTEST) $(FUZZER_FLAGS)
test-fuzzer-stackmode: MOREFLAGS += -DZSTD_HEAPMODE=0
test-fuzzer-stackmode: test-fuzzer
test-fuzzer32: fuzzer32 test-fuzzer32: fuzzer32
$(QEMU_SYS) ./fuzzer32 -v $(FUZZERTEST) $(FUZZER_FLAGS) $(QEMU_SYS) ./fuzzer32 -v $(FUZZERTEST) $(FUZZER_FLAGS)