@@ -488,7 +488,7 @@ size_t ZSTD_compressSequences(void* dst, size_t maxDstSize,
488488 BYTE litLength = llTable [i ]; /* (7)*/ /* (7)*/
489489 FSE_encodeSymbol (& blockStream , & stateMatchLength , matchLength ); /* 17 */ /* 17 */
490490 if (MEM_32bits ()) BIT_flushBits (& blockStream ); /* 7 */
491- BIT_addBits (& blockStream , offset , nbBits ); /* 32 */ /* 42 */
491+ BIT_addBits (& blockStream , offset , nbBits ); /* 31 */ /* 42 */ /* 24 bits max in 32-bits mode */
492492 if (MEM_32bits ()) BIT_flushBits (& blockStream ); /* 7 */
493493 FSE_encodeSymbol (& blockStream , & stateOffsetBits , offCode ); /* 16 */ /* 51 */
494494 FSE_encodeSymbol (& blockStream , & stateLitLength , litLength ); /* 26 */ /* 61 */
@@ -730,13 +730,30 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
730730* Fast Scan
731731***************************************/
732732
733+ #define FILLHASHSTEP 3
734+ static void ZSTD_fillHashTable (ZSTD_CCtx * zc , const void * end , const U32 mls )
735+ {
736+ U32 * const hashTable = zc -> hashTable ;
737+ const U32 hBits = zc -> params .hashLog ;
738+ const BYTE * const base = zc -> base ;
739+ const BYTE * ip = base + zc -> nextToUpdate ;
740+ const BYTE * const iend = (const BYTE * ) end ;
741+
742+ while (ip <= iend )
743+ {
744+ hashTable [ZSTD_hashPtr (ip , hBits , mls )] = (U32 )(ip - base );
745+ ip += FILLHASHSTEP ;
746+ }
747+ }
748+
749+
733750FORCE_INLINE
734751size_t ZSTD_compressBlock_fast_generic (ZSTD_CCtx * zc ,
735752 void * dst , size_t maxDstSize ,
736753 const void * src , size_t srcSize ,
737754 const U32 mls )
738755{
739- U32 * hashTable = zc -> hashTable ;
756+ U32 * const hashTable = zc -> hashTable ;
740757 const U32 hBits = zc -> params .hashLog ;
741758 seqStore_t * seqStorePtr = & (zc -> seqStore );
742759 const BYTE * const base = zc -> base ;
@@ -752,12 +769,12 @@ size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
752769
753770 /* init */
754771 ZSTD_resetSeqStore (seqStorePtr );
755- if (ip < base + 4 )
772+ if (ip < lowest + 4 )
756773 {
757- hashTable [ZSTD_hashPtr (base + 1 , hBits , mls )] = 1 ;
758- hashTable [ZSTD_hashPtr (base + 2 , hBits , mls )] = 2 ;
759- hashTable [ZSTD_hashPtr (base + 3 , hBits , mls )] = 3 ;
760- ip = base + 4 ;
774+ hashTable [ZSTD_hashPtr (lowest + 1 , hBits , mls )] = zc -> dictLimit + 1 ;
775+ hashTable [ZSTD_hashPtr (lowest + 2 , hBits , mls )] = zc -> dictLimit + 2 ;
776+ hashTable [ZSTD_hashPtr (lowest + 3 , hBits , mls )] = zc -> dictLimit + 3 ;
777+ ip = lowest + 4 ;
761778 }
762779
763780 /* Main Search Loop */
@@ -1518,6 +1535,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
15181535 const BYTE * anchor = istart ;
15191536 const BYTE * const iend = istart + srcSize ;
15201537 const BYTE * const ilimit = iend - 8 ;
1538+ const BYTE * const base = ctx -> base + ctx -> dictLimit ;
15211539
15221540 size_t offset_2 = REPCODE_STARTVALUE , offset_1 = REPCODE_STARTVALUE ;
15231541 const U32 maxSearches = 1 << ctx -> params .searchLog ;
@@ -1530,7 +1548,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
15301548
15311549 /* init */
15321550 ZSTD_resetSeqStore (seqStorePtr );
1533- if ((( ip - ctx -> base ) - ctx -> dictLimit ) < REPCODE_STARTVALUE ) ip += REPCODE_STARTVALUE ;
1551+ if ((ip - base ) < REPCODE_STARTVALUE ) ip = base + REPCODE_STARTVALUE ;
15341552
15351553 /* Match Loop */
15361554 while (ip < ilimit )
@@ -1555,7 +1573,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
15551573 matchLength = ml2 , start = ip , offset = offsetFound ;
15561574 }
15571575
1558- if (matchLength < MINMATCH )
1576+ if (matchLength < MINMATCH )
15591577 {
15601578 ip += ((ip - anchor ) >> g_searchStrength ) + 1 ; /* jump faster over incompressible sections */
15611579 continue ;
@@ -1616,7 +1634,7 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
16161634 /* catch up */
16171635 if (offset )
16181636 {
1619- while ((start > anchor ) && (start > ctx -> base + offset ) && (start [-1 ] == start [-1 - offset ])) /* only search for offset within prefix */
1637+ while ((start > anchor ) && (start > base + offset ) && (start [-1 ] == start [-1 - offset ])) /* only search for offset within prefix */
16201638 { start -- ; matchLength ++ ; }
16211639 offset_2 = offset_1 ; offset_1 = offset ;
16221640 }
@@ -1975,8 +1993,21 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
19751993{
19761994 const BYTE * const ip = (const BYTE * ) src ;
19771995
1996+ /* Check if blocks follow each other */
1997+ if (src != zc -> nextSrc )
1998+ {
1999+ /* not contiguous */
2000+ size_t delta = zc -> nextSrc - ip ;
2001+ zc -> lowLimit = zc -> dictLimit ;
2002+ zc -> dictLimit = (U32 )(zc -> nextSrc - zc -> base );
2003+ zc -> dictBase = zc -> base ;
2004+ zc -> base -= delta ;
2005+ zc -> nextToUpdate = zc -> dictLimit ;
2006+ if (zc -> dictLimit - zc -> lowLimit < 8 ) zc -> lowLimit = zc -> dictLimit ; /* too small extDict */
2007+ }
2008+
19782009 /* preemptive overflow correction */
1979- if ((zc -> base > ( const BYTE * ) src ) || (zc -> lowLimit > (1 <<30 ) ))
2010+ if ((zc -> base > ip ) || (zc -> lowLimit > (1 <<30 ) ))
19802011 {
19812012 U32 correction = zc -> lowLimit - 1 ;
19822013 ZSTD_reduceIndex (zc , correction );
@@ -1988,17 +2019,6 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
19882019 else zc -> nextToUpdate -= correction ;
19892020 }
19902021
1991- /* Check if blocks follow each other */
1992- if (src != zc -> nextSrc )
1993- {
1994- /* not contiguous */
1995- zc -> lowLimit = zc -> dictLimit ;
1996- zc -> dictLimit = (U32 )(zc -> nextSrc - zc -> base );
1997- zc -> dictBase = zc -> base ;
1998- zc -> base += ip - zc -> nextSrc ;
1999- zc -> nextToUpdate = zc -> dictLimit ;
2000- }
2001-
20022022 /* input-dictionary overlap */
20032023 if ((ip + srcSize > zc -> dictBase + zc -> lowLimit ) && (ip < zc -> dictBase + zc -> dictLimit ))
20042024 {
@@ -2011,8 +2031,46 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
20112031 return ZSTD_compress_generic (zc , dst , dstSize , src , srcSize );
20122032}
20132033
2034+ size_t ZSTD_compress_insertDictionary (ZSTD_CCtx * zc , const void * src , size_t srcSize )
2035+ {
2036+ const BYTE * const ip = (const BYTE * ) src ;
2037+ const BYTE * const iend = ip + srcSize ;
2038+
2039+ /* input becomes current prefix */
2040+ zc -> lowLimit = zc -> dictLimit ;
2041+ zc -> dictLimit = (U32 )(zc -> nextSrc - zc -> base );
2042+ zc -> dictBase = zc -> base ;
2043+ zc -> base += ip - zc -> nextSrc ;
2044+ zc -> nextToUpdate = zc -> dictLimit ;
2045+
2046+ zc -> nextSrc = iend ;
2047+ if (srcSize <= 8 ) return 0 ;
2048+
2049+ switch (zc -> params .strategy )
2050+ {
2051+ case ZSTD_fast :
2052+ ZSTD_fillHashTable (zc , iend - 8 , zc -> params .searchLength );
2053+ break ;
2054+
2055+ case ZSTD_greedy :
2056+ case ZSTD_lazy :
2057+ case ZSTD_lazy2 :
2058+ ZSTD_insertAndFindFirstIndex (zc , iend - 8 , zc -> params .searchLength );
2059+ break ;
2060+
2061+ case ZSTD_btlazy2 :
2062+ ZSTD_updateTree (zc , iend - 8 , iend , 1 << zc -> params .searchLog , zc -> params .searchLength );
2063+ break ;
2064+
2065+ default :
2066+ return ERROR (GENERIC ); /* strategy doesn't exist; impossible */
2067+ }
2068+
2069+ return 0 ;
2070+ }
2071+
20142072
2015- /** ZSTD_compressBegin_advanced
2073+ /*! ZSTD_compressBegin_advanced
20162074* Write frame header, according to params
20172075* @return : nb of bytes written */
20182076size_t ZSTD_compressBegin_advanced (ZSTD_CCtx * ctx ,
0 commit comments