From: Yann Collet Date: Wed, 27 Jan 2016 23:18:06 +0000 (+0100) Subject: changed dictionary format X-Git-Tag: v0.5.0~1^2~3^2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb810d6053a5ae1a5a772015cb5945896bebfe01;p=thirdparty%2Fzstd.git changed dictionary format --- diff --git a/NEWS b/NEWS index 8aaf02d99..f146eb140 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +v0.5.0 +Changed streaming & dictionary API + v0.4.7 Improved : small compression speed improvement in HC mode Changed : `zstd_decompress.c` has ZSTD_LEGACY_SUPPORT to 0 by default diff --git a/lib/fse.c b/lib/fse.c index e74c1e833..309b28caf 100644 --- a/lib/fse.c +++ b/lib/fse.c @@ -425,10 +425,7 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ } -static short FSE_abs(short a) -{ - return a<0 ? -a : a; -} +static short FSE_abs(short a) { return a<0 ? -a : a; } static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, @@ -457,14 +454,11 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, threshold = tableSize; nbBits = tableLog+1; - while (remaining>1) /* stops at 1 */ - { - if (previous0) - { + while (remaining>1) { /* stops at 1 */ + if (previous0) { unsigned start = charnum; while (!normalizedCounter[charnum]) charnum++; - while (charnum >= start+24) - { + while (charnum >= start+24) { start+=24; bitStream += 0xFFFFU << bitCount; if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ @@ -473,24 +467,21 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, out+=2; bitStream>>=16; } - while (charnum >= start+3) - { + while (charnum >= start+3) { start+=3; bitStream += 3 << bitCount; bitCount += 2; } bitStream += (charnum-start) << bitCount; bitCount += 2; - if (bitCount>16) - { + if (bitCount>16) { if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ out[0] = (BYTE)bitStream; out[1] = (BYTE)(bitStream>>8); out += 2; bitStream >>= 16; bitCount -= 16; - } - } + } } { short count = normalizedCounter[charnum++]; const short max = (short)((2*threshold-1)-remaining); @@ -504,8 +495,7 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize, previous0 = (count==1); while (remaining>=1; } - if (bitCount>16) - { + if (bitCount>16) { if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */ out[0] = (BYTE)bitStream; out[1] = (BYTE)(bitStream>>8); @@ -564,27 +554,19 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t threshold = 1<1) && (charnum<=*maxSVPtr)) - { - if (previous0) - { + while ((remaining>1) && (charnum<=*maxSVPtr)) { + if (previous0) { unsigned n0 = charnum; - while ((bitStream & 0xFFFF) == 0xFFFF) - { + while ((bitStream & 0xFFFF) == 0xFFFF) { n0+=24; - if (ip < iend-5) - { + if (ip < iend-5) { ip+=2; bitStream = MEM_readLE32(ip) >> bitCount; - } - else - { + } else { bitStream >>= 16; bitCount+=16; - } - } - while ((bitStream & 3) == 3) - { + } } + while ((bitStream & 3) == 3) { n0+=3; bitStream>>=2; bitCount+=2; @@ -593,8 +575,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t bitCount += 2; if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); while (charnum < n0) normalizedCounter[charnum++] = 0; - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) - { + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { ip += bitCount>>3; bitCount &= 7; bitStream = MEM_readLE32(ip) >> bitCount; @@ -606,13 +587,10 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t const short max = (short)((2*threshold-1)-remaining); short count; - if ((bitStream & (threshold-1)) < (U32)max) - { + if ((bitStream & (threshold-1)) < (U32)max) { count = (short)(bitStream & (threshold-1)); bitCount += nbBits-1; - } - else - { + } else { count = (short)(bitStream & (2*threshold-1)); if (count >= threshold) count -= max; bitCount += nbBits; @@ -622,27 +600,20 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t remaining -= FSE_abs(count); normalizedCounter[charnum++] = count; previous0 = !count; - while (remaining < threshold) - { + while (remaining < threshold) { nbBits--; threshold >>= 1; } - { - if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) - { - ip += bitCount>>3; - bitCount &= 7; - } - else - { - bitCount -= (int)(8 * (iend - 4 - ip)); - ip = iend - 4; - } - bitStream = MEM_readLE32(ip) >> (bitCount & 31); + if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + ip = iend - 4; } - } - } + bitStream = MEM_readLE32(ip) >> (bitCount & 31); + } } if (remaining != 1) return ERROR(GENERIC); *maxSVPtr = charnum-1; @@ -723,22 +694,18 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, U32 lowThreshold = (U32)(total >> tableLog); U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); - for (s=0; s<=maxSymbolValue; s++) - { - if (count[s] == 0) - { + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == 0) { norm[s]=0; continue; } - if (count[s] <= lowThreshold) - { + if (count[s] <= lowThreshold) { norm[s] = -1; distributed++; total -= count[s]; continue; } - if (count[s] <= lowOne) - { + if (count[s] <= lowOne) { norm[s] = 1; distributed++; total -= count[s]; @@ -748,25 +715,20 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, } ToDistribute = (1 << tableLog) - distributed; - if ((total / ToDistribute) > lowOne) - { + if ((total / ToDistribute) > lowOne) { /* risk of rounding to zero */ lowOne = (U32)((total * 3) / (ToDistribute * 2)); - for (s=0; s<=maxSymbolValue; s++) - { - if ((norm[s] == -2) && (count[s] <= lowOne)) - { + for (s=0; s<=maxSymbolValue; s++) { + if ((norm[s] == -2) && (count[s] <= lowOne)) { norm[s] = 1; distributed++; total -= count[s]; continue; - } - } + } } ToDistribute = (1 << tableLog) - distributed; } - if (distributed == maxSymbolValue+1) - { + if (distributed == maxSymbolValue+1) { /* all values are pretty poor; probably incompressible data (should have already been detected); find max, then give all remaining points to max */ @@ -782,10 +744,8 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, U64 const mid = (1ULL << (vStepLog-1)) - 1; U64 const rStep = ((((U64)1<> vStepLog); U32 sEnd = (U32)(end >> vStepLog); @@ -794,9 +754,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, return ERROR(GENERIC); norm[s] = (short)weight; tmpTotal = end; - } - } - } + } } } return 0; } @@ -809,7 +767,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, /* Sanity checks */ if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ - if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ { @@ -823,38 +781,23 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, short largestP=0; U32 lowThreshold = (U32)(total >> tableLog); - for (s=0; s<=maxSymbolValue; s++) - { - if (count[s] == total) return 0; - if (count[s] == 0) - { - normalizedCounter[s]=0; - continue; - } - if (count[s] <= lowThreshold) - { + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == total) return 0; /* rle special case */ + if (count[s] == 0) { normalizedCounter[s]=0; continue; } + if (count[s] <= lowThreshold) { normalizedCounter[s] = -1; stillToDistribute--; - } - else - { + } else { short proba = (short)((count[s]*step) >> scale); - if (proba<8) - { + if (proba<8) { U64 restToBeat = vStep * rtbTable[proba]; proba += (count[s]*step) - ((U64)proba< restToBeat; } - if (proba > largestP) - { - largestP=proba; - largest=s; - } + if (proba > largestP) largestP=proba, largest=s; normalizedCounter[s] = proba; stillToDistribute -= proba; - } - } - if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) - { + } } + if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { /* corner case, need another normalization method */ size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue); if (FSE_isError(errorCode)) return errorCode; @@ -904,8 +847,7 @@ size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits) tableU16[s] = (U16)(tableSize + s); /* Build Symbol Transformation Table */ - for (s=0; s<=maxSymbolValue; s++) - { + for (s=0; s<=maxSymbolValue; s++) { symbolTT[s].deltaNbBits = nbBits << 16; symbolTT[s].deltaFindState = s-1; } diff --git a/lib/fse.h b/lib/fse.h index dd1190f86..e98f1a54a 100644 --- a/lib/fse.h +++ b/lib/fse.h @@ -46,7 +46,7 @@ extern "C" { #include /* size_t, ptrdiff_t */ -/* ***************************************** +/*-**************************************** * FSE simple functions ******************************************/ size_t FSE_compress(void* dst, size_t maxDstSize, diff --git a/lib/fse_static.h b/lib/fse_static.h index a881e351f..3028a2f40 100644 --- a/lib/fse_static.h +++ b/lib/fse_static.h @@ -223,8 +223,7 @@ static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t /* ***************************************** * Implementation of inlined functions *******************************************/ -typedef struct -{ +typedef struct { int deltaFindState; U32 deltaNbBits; } FSE_symbolCompressionTransform; /* total 8 bytes */ diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 8ebd58beb..2c67c8ae0 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -126,7 +126,10 @@ struct ZSTD_CCtx_s U32* hashTable; U32* contentTable; HUF_CElt* hufTable; - U32 flagHufTable; + U32 flagStaticTables; + FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; + FSE_CTable matchlengthCTable [FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; + FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; }; @@ -158,8 +161,7 @@ void ZSTD_validateParams(ZSTD_parameters* params) if (params->windowLog < ZSTD_WINDOWLOG_MIN) params->windowLog = ZSTD_WINDOWLOG_MIN; /* correct params, to use less memory */ - if ((params->srcSize > 0) && (params->srcSize < (1<srcSize > 0) && (params->srcSize < (1<srcSize)-1) + 1; if (params->windowLog > srcLog) params->windowLog = srcLog; } @@ -188,8 +190,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog; const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32); const size_t neededSpace = tableSpace + (256*sizeof(U32)) + (3*blockSize); - if (zc->workSpaceSize < neededSpace) - { + if (zc->workSpaceSize < neededSpace) { free(zc->workSpace); zc->workSpace = malloc(neededSpace); if (zc->workSpace == NULL) return ERROR(memory_allocation); @@ -200,7 +201,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, zc->contentTable = zc->hashTable + ((size_t)1 << params.hashLog); zc->seqStore.buffer = zc->contentTable + ((size_t)1 << contentLog); zc->hufTable = (HUF_CElt*)zc->seqStore.buffer; - zc->flagHufTable = 0; + zc->flagStaticTables = 0; zc->seqStore.buffer = (U32*)(zc->seqStore.buffer) + 256; } @@ -253,9 +254,14 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx) dstCCtx->dictLimit = srcCCtx->dictLimit; dstCCtx->lowLimit = srcCCtx->lowLimit; - dstCCtx->flagHufTable = srcCCtx->flagHufTable; - if (dstCCtx->flagHufTable) + /* copy entropy tables */ + dstCCtx->flagStaticTables = srcCCtx->flagStaticTables; + if (dstCCtx->flagStaticTables) { memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4); + memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable)); + memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable)); + memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable)); + } return 0; } @@ -271,8 +277,7 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, U32* table32 = zc->hashTable; U32 index; - for (index=0 ; index < tableSpaceU32 ; index++) - { + for (index=0 ; index < tableSpaceU32 ; index++) { if (table32[index] < reducerValue) table32[index] = 0; else table32[index] -= reducerValue; } @@ -338,15 +343,35 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, 1.2.1) Huff0 block, using sizes from header See Huff0 format - 1.2.2) Raw content + 1.2.2) Huff0 block, using prepared table - 1.2.3) single byte + 1.2.3) Raw content - 1.2.4) _usingDTable variant ? + 1.2.4) single byte 2) Sequences section - TO DO + + - Nb Sequences : 2 bytes, little endian + - Control Token : 1 byte (see below) + - Dumps Length : 1 or 2 bytes (depending on control token) + - Dumps : as stated by dumps length + - Literal Lengths FSE table (as needed depending on encoding method) + - Offset Codes FSE table (as needed depending on encoding method) + - Match Lengths FSE table (as needed depending on encoding method) + + 2.1) Control Token + 8 bits, divided as : + 0-1 : dumpsLength + 2-3 : MatchLength, FSE encoding method + 4-5 : Offset Codes, FSE encoding method + 6-7 : Literal Lengths, FSE encoding method + + FSE encoding method : + FSE_ENCODING_RAW : uncompressed; no header + FSE_ENCODING_RLE : single repeated value; header 1 byte + FSE_ENCODING_STATIC : use prepared table; no header + FSE_ENCODING_DYNAMIC : read NCount */ size_t ZSTD_noCompressBlock (void* dst, size_t maxDstSize, const void* src, size_t srcSize) @@ -399,7 +424,7 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t maxDstSize, const BYTE* const ostart = (BYTE* const)dst; U32 flSize = 1 + (srcSize>31) + (srcSize>4095); - (void)maxDstSize; /* maxDstSize guaranteed to be >=4, hence large enough ? */ + (void)maxDstSize; /* maxDstSize guaranteed to be >=4, hence large enough */ switch(flSize) { @@ -438,14 +463,11 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc, if (maxDstSize < 4) return ERROR(dstSize_tooSmall); /* not enough space for compression */ - if (zc->flagHufTable && (lhSize==3)) - { + if (zc->flagStaticTables && (lhSize==3)) { hType = IS_PCH; singleStream = 1; clitSize = HUF_compress1X_usingCTable(ostart+lhSize, maxDstSize-lhSize, src, srcSize, zc->hufTable); - } - else - { + } else { clitSize = singleStream ? HUF_compress1X(ostart+lhSize, maxDstSize-lhSize, src, srcSize, 255, 12) : HUF_compress2 (ostart+lhSize, maxDstSize-lhSize, src, srcSize, 255, 12); } @@ -491,11 +513,10 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, U32 count[MaxSeq+1]; S16 norm[MaxSeq+1]; size_t mostFrequent; - U32 max = 255; - U32 tableLog = 11; - U32 CTable_LitLength [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL )]; - U32 CTable_OffsetBits [FSE_CTABLE_SIZE_U32(OffFSELog,MaxOff)]; - U32 CTable_MatchLength[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML )]; + U32 max; + FSE_CTable* CTable_LitLength = zc->litlengthCTable; + FSE_CTable* CTable_OffsetBits = zc->offcodeCTable; + FSE_CTable* CTable_MatchLength = zc->matchlengthCTable; U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */ const BYTE* const op_lit_start = seqStorePtr->litStart; const BYTE* const llTable = seqStorePtr->litLengthStart; @@ -516,7 +537,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, { size_t cSize; size_t litSize = seqStorePtr->lit - op_lit_start; - const size_t minLitSize = zc->flagHufTable ? 6 : LITERAL_NOENTROPY; + const size_t minLitSize = zc->flagStaticTables ? 6 : LITERAL_NOENTROPY; if (litSize <= minLitSize) cSize = ZSTD_noCompressLiterals(op, maxDstSize, op_lit_start, litSize); @@ -535,14 +556,11 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, /* dumps : contains too large lengths */ { size_t dumpsLength = seqStorePtr->dumps - seqStorePtr->dumpsStart; - if (dumpsLength < 512) - { + if (dumpsLength < 512) { op[0] = (BYTE)(dumpsLength >> 8); op[1] = (BYTE)(dumpsLength); op += 2; - } - else - { + } else { op[0] = 2; op[1] = (BYTE)(dumpsLength>>8); op[2] = (BYTE)(dumpsLength); @@ -553,94 +571,86 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, op += dumpsLength; } +#define MIN_SEQ_FOR_DYNAMIC_FSE 64 +#define MAX_SEQ_FOR_STATIC_FSE 1000 + /* CTable for Literal Lengths */ max = MaxLL; mostFrequent = FSE_countFast(count, &max, seqStorePtr->litLengthStart, nbSeq); - if ((mostFrequent == nbSeq) && (nbSeq > 2)) - { + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = *(seqStorePtr->litLengthStart); FSE_buildCTable_rle(CTable_LitLength, (BYTE)max); - LLtype = bt_rle; - } - else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (LLbits-1)))) - { + LLtype = FSE_ENCODING_RLE; + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + LLtype = FSE_ENCODING_STATIC; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LLbits-1)))) { FSE_buildCTable_raw(CTable_LitLength, LLbits); - LLtype = bt_raw; - } - else - { + LLtype = FSE_ENCODING_RAW; + } else { size_t NCountSize; - tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max); + U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max); FSE_normalizeCount(norm, tableLog, count, nbSeq, max); NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ if (FSE_isError(NCountSize)) return ERROR(GENERIC); op += NCountSize; FSE_buildCTable(CTable_LitLength, norm, max, tableLog); - LLtype = bt_compressed; + LLtype = FSE_ENCODING_DYNAMIC; } - /* CTable for Offsets codes */ - { - /* create Offset codes */ - size_t i; - max = MaxOff; - for (i=0; i 2)) - { + max = MaxOff; + mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = *offCodeTable; FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max); - Offtype = bt_rle; - } - else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (Offbits-1)))) - { + Offtype = FSE_ENCODING_RLE; + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + Offtype = FSE_ENCODING_STATIC; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (Offbits-1)))) { FSE_buildCTable_raw(CTable_OffsetBits, Offbits); - Offtype = bt_raw; - } - else - { + Offtype = FSE_ENCODING_RAW; + } else { size_t NCountSize; - tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max); + U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max); FSE_normalizeCount(norm, tableLog, count, nbSeq, max); NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ if (FSE_isError(NCountSize)) return ERROR(GENERIC); op += NCountSize; FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog); - Offtype = bt_compressed; + Offtype = FSE_ENCODING_DYNAMIC; } /* CTable for MatchLengths */ max = MaxML; mostFrequent = FSE_countFast(count, &max, seqStorePtr->matchLengthStart, nbSeq); - if ((mostFrequent == nbSeq) && (nbSeq > 2)) - { + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = *seqStorePtr->matchLengthStart; FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max); - MLtype = bt_rle; - } - else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (MLbits-1)))) - { + MLtype = FSE_ENCODING_RLE; + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + MLtype = FSE_ENCODING_STATIC; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (MLbits-1)))) { FSE_buildCTable_raw(CTable_MatchLength, MLbits); - MLtype = bt_raw; - } - else - { + MLtype = FSE_ENCODING_RAW; + } else { size_t NCountSize; - tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max); + U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max); FSE_normalizeCount(norm, tableLog, count, nbSeq, max); NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ if (FSE_isError(NCountSize)) return ERROR(GENERIC); op += NCountSize; FSE_buildCTable(CTable_MatchLength, norm, max, tableLog); - MLtype = bt_compressed; + MLtype = FSE_ENCODING_DYNAMIC; } seqHead[0] += (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); + zc->flagStaticTables = 0; /* Encoding Sequences */ { @@ -657,14 +667,13 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc, FSE_initCState(&stateOffsetBits, CTable_OffsetBits); FSE_initCState(&stateLitLength, CTable_LitLength); - for (i=(int)nbSeq-1; i>=0; i--) - { - BYTE matchLength = mlTable[i]; + for (i=(int)nbSeq-1; i>=0; i--) { + BYTE mlCode = mlTable[i]; U32 offset = offsetTable[i]; BYTE offCode = offCodeTable[i]; /* 32b*/ /* 64b*/ U32 nbBits = (offCode-1) * (!!offCode); BYTE litLength = llTable[i]; /* (7)*/ /* (7)*/ - FSE_encodeSymbol(&blockStream, &stateMatchLength, matchLength); /* 17 */ /* 17 */ + FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 17 */ /* 17 */ if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */ BIT_addBits(&blockStream, offset, nbBits); /* 31 */ /* 42 */ /* 24 bits max in 32-bits mode */ if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */ @@ -699,7 +708,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B #if 0 static const BYTE* g_start = NULL; if (g_start==NULL) g_start = literals; - if (literals - g_start == 8695) + //if (literals - g_start == 8695) printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode); #endif @@ -709,34 +718,28 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B seqStorePtr->lit += litLength; /* literal Length */ - if (litLength >= MaxLL) - { + if (litLength >= MaxLL) { *(seqStorePtr->litLength++) = MaxLL; - if (litLength<255 + MaxLL) + if (litLength<255 + MaxLL) { *(seqStorePtr->dumps++) = (BYTE)(litLength - MaxLL); - else - { + } else { *(seqStorePtr->dumps++) = 255; MEM_writeLE32(seqStorePtr->dumps, (U32)litLength); seqStorePtr->dumps += 3; - } - } + } } else *(seqStorePtr->litLength++) = (BYTE)litLength; /* match offset */ *(seqStorePtr->offset++) = (U32)offsetCode; /* match Length */ - if (matchCode >= MaxML) - { + if (matchCode >= MaxML) { *(seqStorePtr->matchLength++) = MaxML; - if (matchCode < 255+MaxML) + if (matchCode < 255+MaxML) { *(seqStorePtr->dumps++) = (BYTE)(matchCode - MaxML); - else - { + } else { *(seqStorePtr->dumps++) = 255; MEM_writeLE32(seqStorePtr->dumps, (U32)matchCode); seqStorePtr->dumps += 3; - } - } + } } else *(seqStorePtr->matchLength++) = (BYTE)matchCode; } @@ -841,8 +844,7 @@ static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLim { const BYTE* const pStart = pIn; - while ((pInnextToUpdate; const BYTE* const iend = (const BYTE*) end; - while(ip <= iend) - { + while(ip <= iend) { hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base); ip += FILLHASHSTEP; } @@ -947,8 +948,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, /* init */ ZSTD_resetSeqStore(seqStorePtr); - if (ip < lowest+4) - { + if (ip < lowest+4) { hashTable[ZSTD_hashPtr(lowest+1, hBits, mls)] = lowIndex+1; hashTable[ZSTD_hashPtr(lowest+2, hBits, mls)] = lowIndex+2; hashTable[ZSTD_hashPtr(lowest+3, hBits, mls)] = lowIndex+3; @@ -956,8 +956,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, } /* Main Search Loop */ - while (ip < ilimit) /* < instead of <=, because repcode check at (ip+1) */ - { + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ size_t mlCode; size_t offset; const size_t h = ZSTD_hashPtr(ip, hBits, mls); @@ -966,17 +965,13 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, const U32 current = (U32)(ip-base); hashTable[h] = current; /* update hash table */ - if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) /* note : by construction, offset_1 <= current */ - { + if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) { /* note : by construction, offset_1 <= current */ mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend); ip++; offset = 0; - } - else - { + } else { if ( (matchIndex <= lowIndex) || - (MEM_read32(match) != MEM_read32(ip)) ) - { + (MEM_read32(match) != MEM_read32(ip)) ) { ip += ((ip-anchor) >> g_searchStrength) + 1; continue; } @@ -992,15 +987,13 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, ip += mlCode + MINMATCH; anchor = ip; - if (ip <= ilimit) - { + if (ip <= ilimit) { /* Fill Table */ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base); /* check immediate repcode */ while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) - { + && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { /* store sequence */ size_t rlCode = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); size_t tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ @@ -1009,9 +1002,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc, ip += rlCode+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ - } - } - } + } } } /* Last Literals */ { @@ -1067,18 +1058,15 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, /* init */ ZSTD_resetSeqStore(seqStorePtr); - { - /* skip first 4 positions to avoid read overflow during repcode match check */ - hashTable[ZSTD_hashPtr(ip+0, hBits, mls)] = (U32)(ip-base+0); - hashTable[ZSTD_hashPtr(ip+1, hBits, mls)] = (U32)(ip-base+1); - hashTable[ZSTD_hashPtr(ip+2, hBits, mls)] = (U32)(ip-base+2); - hashTable[ZSTD_hashPtr(ip+3, hBits, mls)] = (U32)(ip-base+3); - ip += 4; - } + /* skip first 4 positions to avoid read overflow during repcode match check */ + hashTable[ZSTD_hashPtr(ip+0, hBits, mls)] = (U32)(ip-base+0); + hashTable[ZSTD_hashPtr(ip+1, hBits, mls)] = (U32)(ip-base+1); + hashTable[ZSTD_hashPtr(ip+2, hBits, mls)] = (U32)(ip-base+2); + hashTable[ZSTD_hashPtr(ip+3, hBits, mls)] = (U32)(ip-base+3); + ip += 4; /* Main Search Loop */ - while (ip < ilimit) /* < instead of <=, because (ip+1) */ - { + while (ip < ilimit) { /* < instead of <=, because (ip+1) */ const size_t h = ZSTD_hashPtr(ip, hBits, mls); const U32 matchIndex = hashTable[h]; const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base; @@ -1092,15 +1080,12 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, hashTable[h] = current; /* update hash table */ if ( ((repIndex <= dictLimit-4) || (repIndex >= dictLimit)) - && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) - { + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend; mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr); ip++; offset = 0; - } - else - { + } else { if ( (matchIndex < lowLimit) || (MEM_read32(match) != MEM_read32(ip)) ) { ip += ((ip-anchor) >> g_searchStrength) + 1; continue; } @@ -1108,32 +1093,28 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend; const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr; mlCode = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iend, matchEnd, lowPrefixPtr); - while ((ip>anchor) && (match>lowMatchPtr) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; } /* catch up */ + while ((ip>anchor) && (match>lowMatchPtr) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; } /* catch up */ offset = current - matchIndex; offset_2 = offset_1; offset_1 = offset; - } - } + } } /* found a match : store it */ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode); ip += mlCode + MINMATCH; anchor = ip; - if (ip <= ilimit) - { + if (ip <= ilimit) { /* Fill Table */ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base); /* check immediate repcode */ - while (ip <= ilimit) - { + while (ip <= ilimit) { U32 current2 = (U32)(ip-base); const U32 repIndex2 = current2 - offset_2; const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2; if ( ((repIndex2 <= dictLimit-4) || (repIndex2 >= dictLimit)) - && (MEM_read32(repMatch2) == MEM_read32(ip)) ) - { + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend; size_t repLength2 = ZSTD_count_2segments(ip+MINMATCH, repMatch2+MINMATCH, iend, repEnd2, lowPrefixPtr); U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ @@ -1144,9 +1125,7 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx, continue; } break; - } - } - } + } } } /* Last Literals */ { @@ -1213,14 +1192,13 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co hashTable[h] = current; /* Update Hash Table */ - while (nbCompares-- && (matchIndex > windowLow)) - { + while (nbCompares-- && (matchIndex > windowLow)) { U32* nextPtr = bt + 2*(matchIndex & btMask); const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ - if (matchIndex == predictedSmall) - { /* no need to check length, result known */ + if (matchIndex == predictedSmall) { + /* no need to check length, result known */ *smallerPtr = matchIndex; if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ @@ -1229,8 +1207,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co continue; } - if (matchIndex == predictedLarge) - { + if (matchIndex == predictedLarge) { *largerPtr = matchIndex; if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ largerPtr = nextPtr; @@ -1239,14 +1216,11 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co continue; } - if ((!extDict) || (matchIndex+matchLength >= dictLimit)) - { + if ((!extDict) || (matchIndex+matchLength >= dictLimit)) { match = base + matchIndex; if (match[matchLength] == ip[matchLength]) matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1; - } - else - { + } else { match = dictBase + matchIndex; matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); if (matchIndex+matchLength >= dictLimit) @@ -1259,25 +1233,21 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co if (ip+matchLength == iend) /* equal : no way to know if inf or sup */ break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */ - if (match[matchLength] < ip[matchLength]) /* necessarily within correct buffer */ - { + if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */ /* match is smaller than current */ *smallerPtr = matchIndex; /* update smaller idx */ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ - } - else - { + } else { /* match is larger than current */ *largerPtr = matchIndex; commonLengthLarger = matchLength; if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ largerPtr = nextPtr; matchIndex = nextPtr[0]; - } - } + } } *smallerPtr = *largerPtr = 0; return (matchEndIdx > current + 8) ? matchEndIdx - current - 8 : 1; @@ -1326,28 +1296,23 @@ size_t ZSTD_insertBtAndFindBestMatch ( hashTable[h] = current; /* Update Hash Table */ - while (nbCompares-- && (matchIndex > windowLow)) - { + while (nbCompares-- && (matchIndex > windowLow)) { U32* nextPtr = bt + 2*(matchIndex & btMask); size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ const BYTE* match; - if ((!extDict) || (matchIndex+matchLength >= dictLimit)) - { + if ((!extDict) || (matchIndex+matchLength >= dictLimit)) { match = base + matchIndex; if (match[matchLength] == ip[matchLength]) matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1; - } - else - { + } else { match = dictBase + matchIndex; matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); if (matchIndex+matchLength >= dictLimit) match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ } - if (matchLength > bestLength) - { + if (matchLength > bestLength) { if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength; if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) ) @@ -1356,17 +1321,14 @@ size_t ZSTD_insertBtAndFindBestMatch ( break; /* drop, to guarantee consistency (miss a little bit of compression) */ } - if (match[matchLength] < ip[matchLength]) - { + if (match[matchLength] < ip[matchLength]) { /* match is smaller than current */ *smallerPtr = matchIndex; /* update smaller idx */ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ - } - else - { + } else { /* match is larger than current */ *largerPtr = matchIndex; commonLengthLarger = matchLength; @@ -1472,8 +1434,7 @@ static U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls) const U32 target = (U32)(ip - base); U32 idx = zc->nextToUpdate; - while(idx < target) - { + while(idx < target) { size_t h = ZSTD_hashPtr(base+idx, hashLog, mls); NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; hashTable[h] = idx; @@ -1511,18 +1472,14 @@ size_t ZSTD_HcFindBestMatch_generic ( /* HC4 match finder */ matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls); - while ((matchIndex>lowLimit) && (nbAttempts)) - { + while ((matchIndex>lowLimit) && (nbAttempts)) { size_t currentMl=0; nbAttempts--; - if ((!extDict) || matchIndex >= dictLimit) - { + if ((!extDict) || matchIndex >= dictLimit) { match = base + matchIndex; if (match[ml] == ip[ml]) /* potentially better */ currentMl = ZSTD_count(ip, match, iLimit); - } - else - { + } else { match = dictBase + matchIndex; if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH; @@ -1601,15 +1558,13 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE; /* Match Loop */ - while (ip < ilimit) - { + while (ip < ilimit) { size_t matchLength=0; size_t offset=0; const BYTE* start=ip+1; /* check repCode */ - if (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1)) - { + if (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1)) { /* repcode : we take it */ matchLength = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend) + MINMATCH; if (depth==0) goto _storeSequence; @@ -1623,19 +1578,16 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx, matchLength = ml2, start = ip, offset=offsetFound; } - if (matchLength < MINMATCH) - { + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } /* let's try to find a better solution */ if (depth>=1) - while (ip= MINMATCH) && (gain2 > gain1)) - { + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ - } - } + } } /* let's find an even better one */ - if ((depth==2) && (ip= MINMATCH) && (gain2 > gain1)) - { + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; - } - } - } + } } } break; /* nothing found : store previous solution */ } /* catch up */ - if (offset) - { + if (offset) { while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */ { start--; matchLength++; } offset_2 = offset_1; offset_1 = offset; @@ -1699,8 +1643,7 @@ _storeSequence: /* check immediate repcode */ while ( (ip <= ilimit) - && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) - { + && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { /* store sequence */ matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend); offset = offset_2; @@ -1710,8 +1653,7 @@ _storeSequence: ip += matchLength+MINMATCH; anchor = ip; continue; /* faster when present ... (?) */ - } - } + } } /* Last Literals */ { @@ -1774,8 +1716,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE; /* Match Loop */ - while (ip < ilimit) - { + while (ip < ilimit) { size_t matchLength=0; size_t offset=0; const BYTE* start=ip+1; @@ -1787,14 +1728,12 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - if (MEM_read32(ip+1) == MEM_read32(repMatch)) - { + if (MEM_read32(ip+1) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; matchLength = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; if (depth==0) goto _storeSequence; - } - } + } } { /* first search (depth 0) */ @@ -1804,27 +1743,23 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, matchLength = ml2, start = ip, offset=offsetFound; } - if (matchLength < MINMATCH) - { + if (matchLength < MINMATCH) { ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */ continue; } /* let's try to find a better solution */ if (depth>=1) - while (ip= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) - { + if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; @@ -1832,8 +1767,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1); if ((repLength >= MINMATCH) && (gain2 > gain1)) matchLength = repLength, offset = 0, start = ip; - } - } + } } /* search match, depth 1 */ { @@ -1841,27 +1775,22 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) - { + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; /* search a better one */ - } - } + } } /* let's find an even better one */ - if ((depth==2) && (ip= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) - { + if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; @@ -1869,8 +1798,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1); if ((repLength >= MINMATCH) && (gain2 > gain1)) matchLength = repLength, offset = 0, start = ip; - } - } + } } /* search match, depth 2 */ { @@ -1878,19 +1806,15 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx, size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls); int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */ int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7); - if ((ml2 >= MINMATCH) && (gain2 > gain1)) - { + if ((ml2 >= MINMATCH) && (gain2 > gain1)) { matchLength = ml2, offset = offset2, start = ip; continue; - } - } - } + } } } break; /* nothing found : store previous solution */ } /* catch up */ - if (offset) - { + if (offset) { U32 matchIndex = (U32)((start-base) - offset); const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; @@ -1907,14 +1831,12 @@ _storeSequence: } /* check immediate repcode */ - while (ip <= ilimit) - { + while (ip <= ilimit) { const U32 repIndex = (U32)((ip-base) - offset_2); const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; const BYTE* const repMatch = repBase + repIndex; if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */ - if (MEM_read32(ip) == MEM_read32(repMatch)) - { + if (MEM_read32(ip) == MEM_read32(repMatch)) { /* repcode detected we should take it */ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH; @@ -1925,8 +1847,7 @@ _storeSequence: continue; /* faster when present ... (?) */ } break; - } - } + } } /* Last Literals */ { @@ -2161,12 +2082,43 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* zc, const void* dict, size_t dictSize) { /* note : magic number already checked */ + size_t offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize, errorCode; + short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog; + short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog; + short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog; + const size_t hufHeaderSize = HUF_readCTable(zc->hufTable, 255, dict, dictSize); if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted); - zc->flagHufTable = 1; - return hufHeaderSize; + zc->flagStaticTables = 1; + dict = (const char*)dict + hufHeaderSize; + dictSize -= hufHeaderSize; + + offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize); + if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); + errorCode = FSE_buildCTable(zc->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + dict = (const char*)dict + offcodeHeaderSize; + dictSize -= offcodeHeaderSize; + + matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize); + if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); + errorCode = FSE_buildCTable(zc->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + dict = (const char*)dict + matchlengthHeaderSize; + dictSize -= matchlengthHeaderSize; + + litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize); + if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); + errorCode = FSE_buildCTable(zc->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + + return hufHeaderSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize; } + static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize) { if (dict && dictSize) @@ -2240,8 +2192,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* zc, void* dst, size_t maxDstSize) size_t hbSize = 0; /* empty frame */ - if (zc->stage==0) - { + if (zc->stage==0) { hbSize = zc->hbSize; if (maxDstSize <= hbSize) return ERROR(dstSize_tooSmall); zc->stage = 1; diff --git a/lib/zstd_decompress.c b/lib/zstd_decompress.c index 93e82884c..b50e474fb 100644 --- a/lib/zstd_decompress.c +++ b/lib/zstd_decompress.c @@ -51,7 +51,7 @@ #endif -/* ******************************************************* +/*-******************************************************* * Includes *********************************************************/ #include /* calloc */ @@ -67,7 +67,8 @@ # include "zstd_legacy.h" #endif -/* ******************************************************* + +/*-******************************************************* * Compiler specifics *********************************************************/ #ifdef _MSC_VER /* Visual Studio */ @@ -85,7 +86,7 @@ #endif -/* ************************************* +/*-************************************* * Local types ***************************************/ typedef struct @@ -123,10 +124,10 @@ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, struct ZSTD_DCtx_s { - U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; - U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; - U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; - U32 hufTableX4[HUF_DTABLE_SIZE(HufLog)]; + FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; + FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; + FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; + unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)]; const void* previousDstEnd; const void* base; const void* vBase; @@ -134,9 +135,9 @@ struct ZSTD_DCtx_s size_t expected; size_t headerSize; ZSTD_parameters params; - blockType_t bType; + blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */ ZSTD_dStage stage; - U32 flagHufTable; + U32 flagStaticTables; const BYTE* litPtr; size_t litBufSize; size_t litSize; @@ -144,6 +145,8 @@ struct ZSTD_DCtx_s BYTE headerBuffer[ZSTD_frameHeaderSize_max]; }; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */ +size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); } + size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) { dctx->expected = ZSTD_frameHeaderSize_min; @@ -153,7 +156,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) dctx->vBase = NULL; dctx->dictEnd = NULL; dctx->hufTableX4[0] = HufLog; - dctx->flagHufTable = 0; + dctx->flagStaticTables = 0; return 0; } @@ -197,27 +200,66 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) */ /* Block format description - Literal Section - Sequences Section + + Block = Literal Section - Sequences Section + Prerequisite : size of (compressed) block, maximum size of regenerated data + 1) Literal Section - 1.1) Header : up to 5 bytes - flags: + + 1.1) Header : 1-5 bytes + flags: 2 bits 00 compressed by Huff0 - 01 is Raw (uncompressed) - 10 is Rle - 11 unused - Note : using 11 for Huff0 with precomputed table ? + 01 unused + 10 is Raw (uncompressed) + 11 is Rle + Note : using 01 => Huff0 with precomputed table ? Note : delta map ? => compressed ? - Note 2 : 19 bits for sizes, seems a bit larger than necessary - Note 3 : RLE blocks ? + + 1.1.1) Huff0-compressed literal block : 3-5 bytes + srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream + srcSize < 1 KB => 3 bytes (2-2-10-10) + srcSize < 16KB => 4 bytes (2-2-14-14) + else => 5 bytes (2-2-18-18) + big endian convention + + 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes + size : 5 bits: (IS_RAW<<6) + (0<<4) + size + 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8) + size&255 + 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16) + size>>8&255 + size&255 + + 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes + size : 5 bits: (IS_RLE<<6) + (0<<4) + size + 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8) + size&255 + 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16) + size>>8&255 + size&255 + + 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes + srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream + srcSize < 1 KB => 3 bytes (2-2-10-10) + srcSize < 16KB => 4 bytes (2-2-14-14) + else => 5 bytes (2-2-18-18) + big endian convention + + 1- CTable available (stored into workspace ?) + 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?) + + + 1.2) Literal block content 1.2.1) Huff0 block, using sizes from header See Huff0 format - 1.2.2) Huff0 block, using precomputed DTable - _usingDTable variants + 1.2.2) Huff0 block, using prepared table + + 1.2.3) Raw content + + 1.2.4) single byte - 1.2.3) uncompressed blocks - as the name says (both 2 or 3 bytes variants) 2) Sequences section TO DO @@ -331,7 +373,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4]; break; } - if (litSize > BLOCKSIZE) return ERROR(corruption_detected);; + if (litSize > BLOCKSIZE) return ERROR(corruption_detected); if (HUF_isError(singleStream ? HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) : @@ -350,7 +392,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, U32 lhSize = ((istart[0]) >> 4) & 3; if (lhSize != 1) /* only case supported for now : small litSize, single stream */ return ERROR(corruption_detected); - if (!dctx->flagHufTable) + if (!dctx->flagStaticTables) return ERROR(dictionary_corrupted); /* 2 - 2 - 10 - 10 */ @@ -448,14 +490,11 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen LLtype = *ip >> 6; Offtype = (*ip >> 4) & 3; MLtype = (*ip >> 2) & 3; - if (*ip & 2) - { + if (*ip & 2) { dumpsLength = ip[2]; dumpsLength += ip[1] << 8; ip += 3; - } - else - { + } else { dumpsLength = ip[1]; dumpsLength += (ip[0] & 1) << 8; ip += 2; @@ -476,13 +515,18 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen switch(LLtype) { U32 max; - case bt_rle : + case FSE_ENCODING_RLE : LLlog = 0; - FSE_buildDTable_rle(DTableLL, *ip++); break; - case bt_raw : + FSE_buildDTable_rle(DTableLL, *ip++); + break; + case FSE_ENCODING_RAW : LLlog = LLbits; - FSE_buildDTable_raw(DTableLL, LLbits); break; - default : + FSE_buildDTable_raw(DTableLL, LLbits); + break; + case FSE_ENCODING_STATIC: + break; + case FSE_ENCODING_DYNAMIC : + default : /* impossible */ max = MaxLL; headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip); if (FSE_isError(headerSize)) return ERROR(GENERIC); @@ -494,15 +538,19 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen switch(Offtype) { U32 max; - case bt_rle : + case FSE_ENCODING_RLE : Offlog = 0; if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */ FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */ break; - case bt_raw : + case FSE_ENCODING_RAW : Offlog = Offbits; - FSE_buildDTable_raw(DTableOffb, Offbits); break; - default : + FSE_buildDTable_raw(DTableOffb, Offbits); + break; + case FSE_ENCODING_STATIC: + break; + case FSE_ENCODING_DYNAMIC : + default : /* impossible */ max = MaxOff; headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip); if (FSE_isError(headerSize)) return ERROR(GENERIC); @@ -514,22 +562,26 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen switch(MLtype) { U32 max; - case bt_rle : + case FSE_ENCODING_RLE : MLlog = 0; if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */ - FSE_buildDTable_rle(DTableML, *ip++); break; - case bt_raw : + FSE_buildDTable_rle(DTableML, *ip++); + break; + case FSE_ENCODING_RAW : MLlog = MLbits; - FSE_buildDTable_raw(DTableML, MLbits); break; - default : + FSE_buildDTable_raw(DTableML, MLbits); + break; + case FSE_ENCODING_STATIC: + break; + case FSE_ENCODING_DYNAMIC : + default : /* impossible */ max = MaxML; headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip); if (FSE_isError(headerSize)) return ERROR(GENERIC); if (MLlog > MLFSELog) return ERROR(corruption_detected); ip += headerSize; FSE_buildDTable(DTableML, norm, max, MLlog); - } - } + } } return ip-istart; } @@ -564,12 +616,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) /* Literal length */ litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); prevOffset = litLength ? seq->offset : seqState->prevOffset; - if (litLength == MaxLL) - { + if (litLength == MaxLL) { U32 add = *dumps++; if (add < 255) litLength += add; - else - { + else { litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */ dumps += 3; } @@ -595,12 +645,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) /* MatchLength */ matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream)); - if (matchLength == MaxML) - { + if (matchLength == MaxML) { U32 add = *dumps++; if (add < 255) matchLength += add; - else - { + else { matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */ dumps += 3; } @@ -613,6 +661,15 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState) seq->offset = offset; seq->matchLength = matchLength; seqState->dumps = dumps; + +#if 0 + { + static U64 totalDecoded = 0; + printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", + (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset); + totalDecoded += litLength + matchLength; + } +#endif } @@ -657,8 +714,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, op = oLitEnd + length1; sequence.matchLength -= length1; match = base; - } - } + } } /* match within prefix */ if (sequence.offset < 8) { @@ -671,8 +727,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, match += dec32table[sequence.offset]; ZSTD_copy4(op+4, match); match -= sub2; - } - else { + } else { ZSTD_copy8(op, match); } op += 8; match += 8; @@ -683,9 +738,9 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op, match += oend_8 - op; op = oend_8; } - while (op < oMatchEnd) *op++ = *match++; - } - else { + while (op < oMatchEnd) + *op++ = *match++; + } else { ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */ } return sequenceLength; @@ -718,7 +773,7 @@ static size_t ZSTD_decompressSequences( /* Build Decoding Tables */ errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength, DTableLL, DTableML, DTableOffb, - ip, iend-ip); + ip, seqSize); if (ZSTD_isError(errorCode)) return errorCode; ip += errorCode; @@ -757,8 +812,7 @@ static size_t ZSTD_decompressSequences( if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall); if (op != litPtr) memcpy(op, litPtr, lastLLSize); op += lastLLSize; - } - } + } } return op-ostart; } @@ -1018,10 +1072,40 @@ static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSi static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) { - size_t hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize); + size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize; + short offcodeNCount[MaxOff+1]; + U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog; + short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog; + short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog; + + hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize); if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); - dctx->flagHufTable = 1; - return hSize; + dict = (const char*)dict + hSize; + dictSize -= hSize; + + offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize); + if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); + errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + dict = (const char*)dict + offcodeHeaderSize; + dictSize -= offcodeHeaderSize; + + matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize); + if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); + errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + dict = (const char*)dict + matchlengthHeaderSize; + dictSize -= matchlengthHeaderSize; + + litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize); + if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); + errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + + dctx->flagStaticTables = 1; + return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize; } static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) diff --git a/lib/zstd_internal.h b/lib/zstd_internal.h index 38bda786e..7eda81366 100644 --- a/lib/zstd_internal.h +++ b/lib/zstd_internal.h @@ -94,6 +94,12 @@ static const size_t ZSTD_frameHeaderSize_min = 5; #define OffFSELog 9 #define MaxSeq MAX(MaxLL, MaxML) +#define FSE_ENCODING_RAW 0 +#define FSE_ENCODING_RLE 1 +#define FSE_ENCODING_STATIC 2 +#define FSE_ENCODING_DYNAMIC 3 + + #define HufLog 12 #define MIN_SEQUENCES_SIZE (2 /*seqNb*/ + 2 /*dumps*/ + 3 /*seqTables*/ + 1 /*bitStream*/) @@ -104,9 +110,9 @@ static const size_t ZSTD_frameHeaderSize_min = 5; typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t; -/* ****************************************** +/*-******************************************* * Shared functions to include for inlining -********************************************/ +*********************************************/ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); } #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; } diff --git a/programs/bench.c b/programs/bench.c index 1f35301f0..efb9d69f4 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -293,11 +293,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, milliTime = BMK_GetMilliStart(); while (BMK_GetMilliStart() == milliTime); milliTime = BMK_GetMilliStart(); - while (BMK_GetMilliSpan(milliTime) < TIMELOOP) - { + while (BMK_GetMilliSpan(milliTime) < TIMELOOP) { ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, dictBufferSize+largestBlockSize)); - for (blockNb=0; blockNb %6u bytes (%08X) \n", + blockNb, (U32)blockTable[blockNb].srcSize, (U32)blockTable[blockNb].cSize, XXH32(blockTable[blockNb].cPtr, blockTable[blockNb].cSize, 0)); } nbLoops++; } @@ -340,7 +343,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, blockTable[blockNb].cPtr, blockTable[blockNb].cSize); if (ZSTD_isError(regenSize)) - EXM_THROW(3, "ZSTD_decompress_usingDict() failed : %s", ZSTD_getErrorName(regenSize)); + EXM_THROW(3, "ZSTD_decompress_usingPreparedDCtx() failed on block %u : %s", + blockNb, ZSTD_getErrorName(regenSize)); blockTable[blockNb].resSize = regenSize; } } @@ -364,8 +368,11 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, } pos = (U32)(u - bacc); bNb = pos / (128 KB); - printf("(segment %u, block %u, pos %u) \n", segNb, bNb, pos); + printf("(block %u, sub %u, pos %u) \n", segNb, bNb, pos); break; + } + if (u==srcSize-1) { /* should never happen */ + printf("no difference detected\n"); } } break; } @@ -375,7 +382,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, if (crcOrig == crcCheck) DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, displayName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.); else - DISPLAY("\n"); + DISPLAY("%2i-\n", cLevel); } /* clean up */