changed dictionary format
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
v0.5.0
|
||||||
|
Changed streaming & dictionary API
|
||||||
|
|
||||||
v0.4.7
|
v0.4.7
|
||||||
Improved : small compression speed improvement in HC mode
|
Improved : small compression speed improvement in HC mode
|
||||||
Changed : `zstd_decompress.c` has ZSTD_LEGACY_SUPPORT to 0 by default
|
Changed : `zstd_decompress.c` has ZSTD_LEGACY_SUPPORT to 0 by default
|
||||||
|
|||||||
@@ -425,10 +425,7 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
|
|||||||
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
|
||||||
}
|
}
|
||||||
|
|
||||||
static short FSE_abs(short a)
|
static short FSE_abs(short a) { return a<0 ? -a : a; }
|
||||||
{
|
|
||||||
return a<0 ? -a : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
||||||
const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
|
const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
|
||||||
@@ -457,14 +454,11 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
|
|||||||
threshold = tableSize;
|
threshold = tableSize;
|
||||||
nbBits = tableLog+1;
|
nbBits = tableLog+1;
|
||||||
|
|
||||||
while (remaining>1) /* stops at 1 */
|
while (remaining>1) { /* stops at 1 */
|
||||||
{
|
if (previous0) {
|
||||||
if (previous0)
|
|
||||||
{
|
|
||||||
unsigned start = charnum;
|
unsigned start = charnum;
|
||||||
while (!normalizedCounter[charnum]) charnum++;
|
while (!normalizedCounter[charnum]) charnum++;
|
||||||
while (charnum >= start+24)
|
while (charnum >= start+24) {
|
||||||
{
|
|
||||||
start+=24;
|
start+=24;
|
||||||
bitStream += 0xFFFFU << bitCount;
|
bitStream += 0xFFFFU << bitCount;
|
||||||
if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
|
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;
|
out+=2;
|
||||||
bitStream>>=16;
|
bitStream>>=16;
|
||||||
}
|
}
|
||||||
while (charnum >= start+3)
|
while (charnum >= start+3) {
|
||||||
{
|
|
||||||
start+=3;
|
start+=3;
|
||||||
bitStream += 3 << bitCount;
|
bitStream += 3 << bitCount;
|
||||||
bitCount += 2;
|
bitCount += 2;
|
||||||
}
|
}
|
||||||
bitStream += (charnum-start) << bitCount;
|
bitStream += (charnum-start) << bitCount;
|
||||||
bitCount += 2;
|
bitCount += 2;
|
||||||
if (bitCount>16)
|
if (bitCount>16) {
|
||||||
{
|
|
||||||
if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
|
if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
|
||||||
out[0] = (BYTE)bitStream;
|
out[0] = (BYTE)bitStream;
|
||||||
out[1] = (BYTE)(bitStream>>8);
|
out[1] = (BYTE)(bitStream>>8);
|
||||||
out += 2;
|
out += 2;
|
||||||
bitStream >>= 16;
|
bitStream >>= 16;
|
||||||
bitCount -= 16;
|
bitCount -= 16;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
{
|
{
|
||||||
short count = normalizedCounter[charnum++];
|
short count = normalizedCounter[charnum++];
|
||||||
const short max = (short)((2*threshold-1)-remaining);
|
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);
|
previous0 = (count==1);
|
||||||
while (remaining<threshold) nbBits--, threshold>>=1;
|
while (remaining<threshold) nbBits--, threshold>>=1;
|
||||||
}
|
}
|
||||||
if (bitCount>16)
|
if (bitCount>16) {
|
||||||
{
|
|
||||||
if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
|
if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
|
||||||
out[0] = (BYTE)bitStream;
|
out[0] = (BYTE)bitStream;
|
||||||
out[1] = (BYTE)(bitStream>>8);
|
out[1] = (BYTE)(bitStream>>8);
|
||||||
@@ -564,27 +554,19 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
threshold = 1<<nbBits;
|
threshold = 1<<nbBits;
|
||||||
nbBits++;
|
nbBits++;
|
||||||
|
|
||||||
while ((remaining>1) && (charnum<=*maxSVPtr))
|
while ((remaining>1) && (charnum<=*maxSVPtr)) {
|
||||||
{
|
if (previous0) {
|
||||||
if (previous0)
|
|
||||||
{
|
|
||||||
unsigned n0 = charnum;
|
unsigned n0 = charnum;
|
||||||
while ((bitStream & 0xFFFF) == 0xFFFF)
|
while ((bitStream & 0xFFFF) == 0xFFFF) {
|
||||||
{
|
|
||||||
n0+=24;
|
n0+=24;
|
||||||
if (ip < iend-5)
|
if (ip < iend-5) {
|
||||||
{
|
|
||||||
ip+=2;
|
ip+=2;
|
||||||
bitStream = MEM_readLE32(ip) >> bitCount;
|
bitStream = MEM_readLE32(ip) >> bitCount;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
bitStream >>= 16;
|
bitStream >>= 16;
|
||||||
bitCount+=16;
|
bitCount+=16;
|
||||||
}
|
} }
|
||||||
}
|
while ((bitStream & 3) == 3) {
|
||||||
while ((bitStream & 3) == 3)
|
|
||||||
{
|
|
||||||
n0+=3;
|
n0+=3;
|
||||||
bitStream>>=2;
|
bitStream>>=2;
|
||||||
bitCount+=2;
|
bitCount+=2;
|
||||||
@@ -593,8 +575,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
bitCount += 2;
|
bitCount += 2;
|
||||||
if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
|
if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
|
||||||
while (charnum < n0) normalizedCounter[charnum++] = 0;
|
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;
|
ip += bitCount>>3;
|
||||||
bitCount &= 7;
|
bitCount &= 7;
|
||||||
bitStream = MEM_readLE32(ip) >> bitCount;
|
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);
|
const short max = (short)((2*threshold-1)-remaining);
|
||||||
short count;
|
short count;
|
||||||
|
|
||||||
if ((bitStream & (threshold-1)) < (U32)max)
|
if ((bitStream & (threshold-1)) < (U32)max) {
|
||||||
{
|
|
||||||
count = (short)(bitStream & (threshold-1));
|
count = (short)(bitStream & (threshold-1));
|
||||||
bitCount += nbBits-1;
|
bitCount += nbBits-1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
count = (short)(bitStream & (2*threshold-1));
|
count = (short)(bitStream & (2*threshold-1));
|
||||||
if (count >= threshold) count -= max;
|
if (count >= threshold) count -= max;
|
||||||
bitCount += nbBits;
|
bitCount += nbBits;
|
||||||
@@ -622,27 +600,20 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
|
|||||||
remaining -= FSE_abs(count);
|
remaining -= FSE_abs(count);
|
||||||
normalizedCounter[charnum++] = count;
|
normalizedCounter[charnum++] = count;
|
||||||
previous0 = !count;
|
previous0 = !count;
|
||||||
while (remaining < threshold)
|
while (remaining < threshold) {
|
||||||
{
|
|
||||||
nbBits--;
|
nbBits--;
|
||||||
threshold >>= 1;
|
threshold >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
|
||||||
if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))
|
ip += bitCount>>3;
|
||||||
{
|
bitCount &= 7;
|
||||||
ip += bitCount>>3;
|
} else {
|
||||||
bitCount &= 7;
|
bitCount -= (int)(8 * (iend - 4 - ip));
|
||||||
}
|
ip = iend - 4;
|
||||||
else
|
|
||||||
{
|
|
||||||
bitCount -= (int)(8 * (iend - 4 - ip));
|
|
||||||
ip = iend - 4;
|
|
||||||
}
|
|
||||||
bitStream = MEM_readLE32(ip) >> (bitCount & 31);
|
|
||||||
}
|
}
|
||||||
}
|
bitStream = MEM_readLE32(ip) >> (bitCount & 31);
|
||||||
}
|
} }
|
||||||
if (remaining != 1) return ERROR(GENERIC);
|
if (remaining != 1) return ERROR(GENERIC);
|
||||||
*maxSVPtr = charnum-1;
|
*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 lowThreshold = (U32)(total >> tableLog);
|
||||||
U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
|
U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
|
||||||
|
|
||||||
for (s=0; s<=maxSymbolValue; s++)
|
for (s=0; s<=maxSymbolValue; s++) {
|
||||||
{
|
if (count[s] == 0) {
|
||||||
if (count[s] == 0)
|
|
||||||
{
|
|
||||||
norm[s]=0;
|
norm[s]=0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (count[s] <= lowThreshold)
|
if (count[s] <= lowThreshold) {
|
||||||
{
|
|
||||||
norm[s] = -1;
|
norm[s] = -1;
|
||||||
distributed++;
|
distributed++;
|
||||||
total -= count[s];
|
total -= count[s];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (count[s] <= lowOne)
|
if (count[s] <= lowOne) {
|
||||||
{
|
|
||||||
norm[s] = 1;
|
norm[s] = 1;
|
||||||
distributed++;
|
distributed++;
|
||||||
total -= count[s];
|
total -= count[s];
|
||||||
@@ -748,25 +715,20 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
|
|||||||
}
|
}
|
||||||
ToDistribute = (1 << tableLog) - distributed;
|
ToDistribute = (1 << tableLog) - distributed;
|
||||||
|
|
||||||
if ((total / ToDistribute) > lowOne)
|
if ((total / ToDistribute) > lowOne) {
|
||||||
{
|
|
||||||
/* risk of rounding to zero */
|
/* risk of rounding to zero */
|
||||||
lowOne = (U32)((total * 3) / (ToDistribute * 2));
|
lowOne = (U32)((total * 3) / (ToDistribute * 2));
|
||||||
for (s=0; s<=maxSymbolValue; s++)
|
for (s=0; s<=maxSymbolValue; s++) {
|
||||||
{
|
if ((norm[s] == -2) && (count[s] <= lowOne)) {
|
||||||
if ((norm[s] == -2) && (count[s] <= lowOne))
|
|
||||||
{
|
|
||||||
norm[s] = 1;
|
norm[s] = 1;
|
||||||
distributed++;
|
distributed++;
|
||||||
total -= count[s];
|
total -= count[s];
|
||||||
continue;
|
continue;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
ToDistribute = (1 << tableLog) - distributed;
|
ToDistribute = (1 << tableLog) - distributed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (distributed == maxSymbolValue+1)
|
if (distributed == maxSymbolValue+1) {
|
||||||
{
|
|
||||||
/* all values are pretty poor;
|
/* all values are pretty poor;
|
||||||
probably incompressible data (should have already been detected);
|
probably incompressible data (should have already been detected);
|
||||||
find max, then give all remaining points to max */
|
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 mid = (1ULL << (vStepLog-1)) - 1;
|
||||||
U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
|
U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
|
||||||
U64 tmpTotal = mid;
|
U64 tmpTotal = mid;
|
||||||
for (s=0; s<=maxSymbolValue; s++)
|
for (s=0; s<=maxSymbolValue; s++) {
|
||||||
{
|
if (norm[s]==-2) {
|
||||||
if (norm[s]==-2)
|
|
||||||
{
|
|
||||||
U64 end = tmpTotal + (count[s] * rStep);
|
U64 end = tmpTotal + (count[s] * rStep);
|
||||||
U32 sStart = (U32)(tmpTotal >> vStepLog);
|
U32 sStart = (U32)(tmpTotal >> vStepLog);
|
||||||
U32 sEnd = (U32)(end >> 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);
|
return ERROR(GENERIC);
|
||||||
norm[s] = (short)weight;
|
norm[s] = (short)weight;
|
||||||
tmpTotal = end;
|
tmpTotal = end;
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -809,7 +767,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
|
|||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
|
||||||
if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */
|
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 */
|
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;
|
short largestP=0;
|
||||||
U32 lowThreshold = (U32)(total >> tableLog);
|
U32 lowThreshold = (U32)(total >> tableLog);
|
||||||
|
|
||||||
for (s=0; s<=maxSymbolValue; s++)
|
for (s=0; s<=maxSymbolValue; s++) {
|
||||||
{
|
if (count[s] == total) return 0; /* rle special case */
|
||||||
if (count[s] == total) return 0;
|
if (count[s] == 0) { normalizedCounter[s]=0; continue; }
|
||||||
if (count[s] == 0)
|
if (count[s] <= lowThreshold) {
|
||||||
{
|
|
||||||
normalizedCounter[s]=0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (count[s] <= lowThreshold)
|
|
||||||
{
|
|
||||||
normalizedCounter[s] = -1;
|
normalizedCounter[s] = -1;
|
||||||
stillToDistribute--;
|
stillToDistribute--;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
short proba = (short)((count[s]*step) >> scale);
|
short proba = (short)((count[s]*step) >> scale);
|
||||||
if (proba<8)
|
if (proba<8) {
|
||||||
{
|
|
||||||
U64 restToBeat = vStep * rtbTable[proba];
|
U64 restToBeat = vStep * rtbTable[proba];
|
||||||
proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
|
proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
|
||||||
}
|
}
|
||||||
if (proba > largestP)
|
if (proba > largestP) largestP=proba, largest=s;
|
||||||
{
|
|
||||||
largestP=proba;
|
|
||||||
largest=s;
|
|
||||||
}
|
|
||||||
normalizedCounter[s] = proba;
|
normalizedCounter[s] = proba;
|
||||||
stillToDistribute -= proba;
|
stillToDistribute -= proba;
|
||||||
}
|
} }
|
||||||
}
|
if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
|
||||||
if (-stillToDistribute >= (normalizedCounter[largest] >> 1))
|
|
||||||
{
|
|
||||||
/* corner case, need another normalization method */
|
/* corner case, need another normalization method */
|
||||||
size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
|
size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
|
||||||
if (FSE_isError(errorCode)) return errorCode;
|
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);
|
tableU16[s] = (U16)(tableSize + s);
|
||||||
|
|
||||||
/* Build Symbol Transformation Table */
|
/* Build Symbol Transformation Table */
|
||||||
for (s=0; s<=maxSymbolValue; s++)
|
for (s=0; s<=maxSymbolValue; s++) {
|
||||||
{
|
|
||||||
symbolTT[s].deltaNbBits = nbBits << 16;
|
symbolTT[s].deltaNbBits = nbBits << 16;
|
||||||
symbolTT[s].deltaFindState = s-1;
|
symbolTT[s].deltaFindState = s-1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ extern "C" {
|
|||||||
#include <stddef.h> /* size_t, ptrdiff_t */
|
#include <stddef.h> /* size_t, ptrdiff_t */
|
||||||
|
|
||||||
|
|
||||||
/* *****************************************
|
/*-****************************************
|
||||||
* FSE simple functions
|
* FSE simple functions
|
||||||
******************************************/
|
******************************************/
|
||||||
size_t FSE_compress(void* dst, size_t maxDstSize,
|
size_t FSE_compress(void* dst, size_t maxDstSize,
|
||||||
|
|||||||
+1
-2
@@ -223,8 +223,7 @@ static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t
|
|||||||
/* *****************************************
|
/* *****************************************
|
||||||
* Implementation of inlined functions
|
* Implementation of inlined functions
|
||||||
*******************************************/
|
*******************************************/
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int deltaFindState;
|
int deltaFindState;
|
||||||
U32 deltaNbBits;
|
U32 deltaNbBits;
|
||||||
} FSE_symbolCompressionTransform; /* total 8 bytes */
|
} FSE_symbolCompressionTransform; /* total 8 bytes */
|
||||||
|
|||||||
+209
-258
@@ -126,7 +126,10 @@ struct ZSTD_CCtx_s
|
|||||||
U32* hashTable;
|
U32* hashTable;
|
||||||
U32* contentTable;
|
U32* contentTable;
|
||||||
HUF_CElt* hufTable;
|
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;
|
if (params->windowLog < ZSTD_WINDOWLOG_MIN) params->windowLog = ZSTD_WINDOWLOG_MIN;
|
||||||
|
|
||||||
/* correct params, to use less memory */
|
/* correct params, to use less memory */
|
||||||
if ((params->srcSize > 0) && (params->srcSize < (1<<ZSTD_WINDOWLOG_MAX)))
|
if ((params->srcSize > 0) && (params->srcSize < (1<<ZSTD_WINDOWLOG_MAX))) {
|
||||||
{
|
|
||||||
U32 srcLog = ZSTD_highbit((U32)(params->srcSize)-1) + 1;
|
U32 srcLog = ZSTD_highbit((U32)(params->srcSize)-1) + 1;
|
||||||
if (params->windowLog > srcLog) params->windowLog = srcLog;
|
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 U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog;
|
||||||
const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32);
|
const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32);
|
||||||
const size_t neededSpace = tableSpace + (256*sizeof(U32)) + (3*blockSize);
|
const size_t neededSpace = tableSpace + (256*sizeof(U32)) + (3*blockSize);
|
||||||
if (zc->workSpaceSize < neededSpace)
|
if (zc->workSpaceSize < neededSpace) {
|
||||||
{
|
|
||||||
free(zc->workSpace);
|
free(zc->workSpace);
|
||||||
zc->workSpace = malloc(neededSpace);
|
zc->workSpace = malloc(neededSpace);
|
||||||
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
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->contentTable = zc->hashTable + ((size_t)1 << params.hashLog);
|
||||||
zc->seqStore.buffer = zc->contentTable + ((size_t)1 << contentLog);
|
zc->seqStore.buffer = zc->contentTable + ((size_t)1 << contentLog);
|
||||||
zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
|
zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
|
||||||
zc->flagHufTable = 0;
|
zc->flagStaticTables = 0;
|
||||||
zc->seqStore.buffer = (U32*)(zc->seqStore.buffer) + 256;
|
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->dictLimit = srcCCtx->dictLimit;
|
||||||
dstCCtx->lowLimit = srcCCtx->lowLimit;
|
dstCCtx->lowLimit = srcCCtx->lowLimit;
|
||||||
|
|
||||||
dstCCtx->flagHufTable = srcCCtx->flagHufTable;
|
/* copy entropy tables */
|
||||||
if (dstCCtx->flagHufTable)
|
dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
|
||||||
|
if (dstCCtx->flagStaticTables) {
|
||||||
memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -271,8 +277,7 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc,
|
|||||||
U32* table32 = zc->hashTable;
|
U32* table32 = zc->hashTable;
|
||||||
U32 index;
|
U32 index;
|
||||||
|
|
||||||
for (index=0 ; index < tableSpaceU32 ; index++)
|
for (index=0 ; index < tableSpaceU32 ; index++) {
|
||||||
{
|
|
||||||
if (table32[index] < reducerValue) table32[index] = 0;
|
if (table32[index] < reducerValue) table32[index] = 0;
|
||||||
else table32[index] -= reducerValue;
|
else table32[index] -= reducerValue;
|
||||||
}
|
}
|
||||||
@@ -338,15 +343,35 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc,
|
|||||||
1.2.1) Huff0 block, using sizes from header
|
1.2.1) Huff0 block, using sizes from header
|
||||||
See Huff0 format
|
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
|
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)
|
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;
|
BYTE* const ostart = (BYTE* const)dst;
|
||||||
U32 flSize = 1 + (srcSize>31) + (srcSize>4095);
|
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)
|
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 (maxDstSize < 4) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
||||||
|
|
||||||
if (zc->flagHufTable && (lhSize==3))
|
if (zc->flagStaticTables && (lhSize==3)) {
|
||||||
{
|
|
||||||
hType = IS_PCH;
|
hType = IS_PCH;
|
||||||
singleStream = 1;
|
singleStream = 1;
|
||||||
clitSize = HUF_compress1X_usingCTable(ostart+lhSize, maxDstSize-lhSize, src, srcSize, zc->hufTable);
|
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)
|
clitSize = singleStream ? HUF_compress1X(ostart+lhSize, maxDstSize-lhSize, src, srcSize, 255, 12)
|
||||||
: HUF_compress2 (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];
|
U32 count[MaxSeq+1];
|
||||||
S16 norm[MaxSeq+1];
|
S16 norm[MaxSeq+1];
|
||||||
size_t mostFrequent;
|
size_t mostFrequent;
|
||||||
U32 max = 255;
|
U32 max;
|
||||||
U32 tableLog = 11;
|
FSE_CTable* CTable_LitLength = zc->litlengthCTable;
|
||||||
U32 CTable_LitLength [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL )];
|
FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
|
||||||
U32 CTable_OffsetBits [FSE_CTABLE_SIZE_U32(OffFSELog,MaxOff)];
|
FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
|
||||||
U32 CTable_MatchLength[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML )];
|
|
||||||
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
|
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
|
||||||
const BYTE* const op_lit_start = seqStorePtr->litStart;
|
const BYTE* const op_lit_start = seqStorePtr->litStart;
|
||||||
const BYTE* const llTable = seqStorePtr->litLengthStart;
|
const BYTE* const llTable = seqStorePtr->litLengthStart;
|
||||||
@@ -516,7 +537,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
{
|
{
|
||||||
size_t cSize;
|
size_t cSize;
|
||||||
size_t litSize = seqStorePtr->lit - op_lit_start;
|
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)
|
if (litSize <= minLitSize)
|
||||||
cSize = ZSTD_noCompressLiterals(op, maxDstSize, op_lit_start, litSize);
|
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 */
|
/* dumps : contains too large lengths */
|
||||||
{
|
{
|
||||||
size_t dumpsLength = seqStorePtr->dumps - seqStorePtr->dumpsStart;
|
size_t dumpsLength = seqStorePtr->dumps - seqStorePtr->dumpsStart;
|
||||||
if (dumpsLength < 512)
|
if (dumpsLength < 512) {
|
||||||
{
|
|
||||||
op[0] = (BYTE)(dumpsLength >> 8);
|
op[0] = (BYTE)(dumpsLength >> 8);
|
||||||
op[1] = (BYTE)(dumpsLength);
|
op[1] = (BYTE)(dumpsLength);
|
||||||
op += 2;
|
op += 2;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
op[0] = 2;
|
op[0] = 2;
|
||||||
op[1] = (BYTE)(dumpsLength>>8);
|
op[1] = (BYTE)(dumpsLength>>8);
|
||||||
op[2] = (BYTE)(dumpsLength);
|
op[2] = (BYTE)(dumpsLength);
|
||||||
@@ -553,94 +571,86 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
op += dumpsLength;
|
op += dumpsLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MIN_SEQ_FOR_DYNAMIC_FSE 64
|
||||||
|
#define MAX_SEQ_FOR_STATIC_FSE 1000
|
||||||
|
|
||||||
/* CTable for Literal Lengths */
|
/* CTable for Literal Lengths */
|
||||||
max = MaxLL;
|
max = MaxLL;
|
||||||
mostFrequent = FSE_countFast(count, &max, seqStorePtr->litLengthStart, nbSeq);
|
mostFrequent = FSE_countFast(count, &max, seqStorePtr->litLengthStart, nbSeq);
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
||||||
{
|
|
||||||
*op++ = *(seqStorePtr->litLengthStart);
|
*op++ = *(seqStorePtr->litLengthStart);
|
||||||
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
||||||
LLtype = bt_rle;
|
LLtype = FSE_ENCODING_RLE;
|
||||||
}
|
} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
||||||
else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (LLbits-1))))
|
LLtype = FSE_ENCODING_STATIC;
|
||||||
{
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LLbits-1)))) {
|
||||||
FSE_buildCTable_raw(CTable_LitLength, LLbits);
|
FSE_buildCTable_raw(CTable_LitLength, LLbits);
|
||||||
LLtype = bt_raw;
|
LLtype = FSE_ENCODING_RAW;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t NCountSize;
|
size_t NCountSize;
|
||||||
tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
|
U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
||||||
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
||||||
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
||||||
op += NCountSize;
|
op += NCountSize;
|
||||||
FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
|
FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
|
||||||
LLtype = bt_compressed;
|
LLtype = FSE_ENCODING_DYNAMIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CTable for Offsets codes */
|
/* CTable for Offset codes */
|
||||||
{
|
{ /* create Offset codes */
|
||||||
/* create Offset codes */
|
size_t i; for (i=0; i<nbSeq; i++) {
|
||||||
size_t i;
|
|
||||||
max = MaxOff;
|
|
||||||
for (i=0; i<nbSeq; i++)
|
|
||||||
{
|
|
||||||
offCodeTable[i] = (BYTE)ZSTD_highbit(offsetTable[i]) + 1;
|
offCodeTable[i] = (BYTE)ZSTD_highbit(offsetTable[i]) + 1;
|
||||||
if (offsetTable[i]==0) offCodeTable[i]=0;
|
if (offsetTable[i]==0) offCodeTable[i]=0;
|
||||||
}
|
}
|
||||||
mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq);
|
|
||||||
}
|
}
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
max = MaxOff;
|
||||||
{
|
mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq);
|
||||||
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
||||||
*op++ = *offCodeTable;
|
*op++ = *offCodeTable;
|
||||||
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
||||||
Offtype = bt_rle;
|
Offtype = FSE_ENCODING_RLE;
|
||||||
}
|
} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
||||||
else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (Offbits-1))))
|
Offtype = FSE_ENCODING_STATIC;
|
||||||
{
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (Offbits-1)))) {
|
||||||
FSE_buildCTable_raw(CTable_OffsetBits, Offbits);
|
FSE_buildCTable_raw(CTable_OffsetBits, Offbits);
|
||||||
Offtype = bt_raw;
|
Offtype = FSE_ENCODING_RAW;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t NCountSize;
|
size_t NCountSize;
|
||||||
tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
|
U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
||||||
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
||||||
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
||||||
op += NCountSize;
|
op += NCountSize;
|
||||||
FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
|
FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
|
||||||
Offtype = bt_compressed;
|
Offtype = FSE_ENCODING_DYNAMIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CTable for MatchLengths */
|
/* CTable for MatchLengths */
|
||||||
max = MaxML;
|
max = MaxML;
|
||||||
mostFrequent = FSE_countFast(count, &max, seqStorePtr->matchLengthStart, nbSeq);
|
mostFrequent = FSE_countFast(count, &max, seqStorePtr->matchLengthStart, nbSeq);
|
||||||
if ((mostFrequent == nbSeq) && (nbSeq > 2))
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
||||||
{
|
|
||||||
*op++ = *seqStorePtr->matchLengthStart;
|
*op++ = *seqStorePtr->matchLengthStart;
|
||||||
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
||||||
MLtype = bt_rle;
|
MLtype = FSE_ENCODING_RLE;
|
||||||
}
|
} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
||||||
else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (MLbits-1))))
|
MLtype = FSE_ENCODING_STATIC;
|
||||||
{
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (MLbits-1)))) {
|
||||||
FSE_buildCTable_raw(CTable_MatchLength, MLbits);
|
FSE_buildCTable_raw(CTable_MatchLength, MLbits);
|
||||||
MLtype = bt_raw;
|
MLtype = FSE_ENCODING_RAW;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t NCountSize;
|
size_t NCountSize;
|
||||||
tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
|
U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
|
||||||
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
|
||||||
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
||||||
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
||||||
op += NCountSize;
|
op += NCountSize;
|
||||||
FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
|
FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
|
||||||
MLtype = bt_compressed;
|
MLtype = FSE_ENCODING_DYNAMIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
seqHead[0] += (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
seqHead[0] += (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
||||||
|
zc->flagStaticTables = 0;
|
||||||
|
|
||||||
/* Encoding Sequences */
|
/* Encoding Sequences */
|
||||||
{
|
{
|
||||||
@@ -657,14 +667,13 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|||||||
FSE_initCState(&stateOffsetBits, CTable_OffsetBits);
|
FSE_initCState(&stateOffsetBits, CTable_OffsetBits);
|
||||||
FSE_initCState(&stateLitLength, CTable_LitLength);
|
FSE_initCState(&stateLitLength, CTable_LitLength);
|
||||||
|
|
||||||
for (i=(int)nbSeq-1; i>=0; i--)
|
for (i=(int)nbSeq-1; i>=0; i--) {
|
||||||
{
|
BYTE mlCode = mlTable[i];
|
||||||
BYTE matchLength = mlTable[i];
|
|
||||||
U32 offset = offsetTable[i];
|
U32 offset = offsetTable[i];
|
||||||
BYTE offCode = offCodeTable[i]; /* 32b*/ /* 64b*/
|
BYTE offCode = offCodeTable[i]; /* 32b*/ /* 64b*/
|
||||||
U32 nbBits = (offCode-1) * (!!offCode);
|
U32 nbBits = (offCode-1) * (!!offCode);
|
||||||
BYTE litLength = llTable[i]; /* (7)*/ /* (7)*/
|
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 */
|
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
||||||
BIT_addBits(&blockStream, offset, nbBits); /* 31 */ /* 42 */ /* 24 bits max in 32-bits mode */
|
BIT_addBits(&blockStream, offset, nbBits); /* 31 */ /* 42 */ /* 24 bits max in 32-bits mode */
|
||||||
if (MEM_32bits()) BIT_flushBits(&blockStream); /* 7 */
|
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
|
#if 0
|
||||||
static const BYTE* g_start = NULL;
|
static const BYTE* g_start = NULL;
|
||||||
if (g_start==NULL) g_start = literals;
|
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",
|
printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
|
||||||
(U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode);
|
(U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode);
|
||||||
#endif
|
#endif
|
||||||
@@ -709,34 +718,28 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B
|
|||||||
seqStorePtr->lit += litLength;
|
seqStorePtr->lit += litLength;
|
||||||
|
|
||||||
/* literal Length */
|
/* literal Length */
|
||||||
if (litLength >= MaxLL)
|
if (litLength >= MaxLL) {
|
||||||
{
|
|
||||||
*(seqStorePtr->litLength++) = MaxLL;
|
*(seqStorePtr->litLength++) = MaxLL;
|
||||||
if (litLength<255 + MaxLL)
|
if (litLength<255 + MaxLL) {
|
||||||
*(seqStorePtr->dumps++) = (BYTE)(litLength - MaxLL);
|
*(seqStorePtr->dumps++) = (BYTE)(litLength - MaxLL);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
*(seqStorePtr->dumps++) = 255;
|
*(seqStorePtr->dumps++) = 255;
|
||||||
MEM_writeLE32(seqStorePtr->dumps, (U32)litLength); seqStorePtr->dumps += 3;
|
MEM_writeLE32(seqStorePtr->dumps, (U32)litLength); seqStorePtr->dumps += 3;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
else *(seqStorePtr->litLength++) = (BYTE)litLength;
|
else *(seqStorePtr->litLength++) = (BYTE)litLength;
|
||||||
|
|
||||||
/* match offset */
|
/* match offset */
|
||||||
*(seqStorePtr->offset++) = (U32)offsetCode;
|
*(seqStorePtr->offset++) = (U32)offsetCode;
|
||||||
|
|
||||||
/* match Length */
|
/* match Length */
|
||||||
if (matchCode >= MaxML)
|
if (matchCode >= MaxML) {
|
||||||
{
|
|
||||||
*(seqStorePtr->matchLength++) = MaxML;
|
*(seqStorePtr->matchLength++) = MaxML;
|
||||||
if (matchCode < 255+MaxML)
|
if (matchCode < 255+MaxML) {
|
||||||
*(seqStorePtr->dumps++) = (BYTE)(matchCode - MaxML);
|
*(seqStorePtr->dumps++) = (BYTE)(matchCode - MaxML);
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
*(seqStorePtr->dumps++) = 255;
|
*(seqStorePtr->dumps++) = 255;
|
||||||
MEM_writeLE32(seqStorePtr->dumps, (U32)matchCode); seqStorePtr->dumps += 3;
|
MEM_writeLE32(seqStorePtr->dumps, (U32)matchCode); seqStorePtr->dumps += 3;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
else *(seqStorePtr->matchLength++) = (BYTE)matchCode;
|
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;
|
const BYTE* const pStart = pIn;
|
||||||
|
|
||||||
while ((pIn<pInLimit-(sizeof(size_t)-1)))
|
while ((pIn<pInLimit-(sizeof(size_t)-1))) {
|
||||||
{
|
|
||||||
size_t diff = ZSTD_read_ARCH(pMatch) ^ ZSTD_read_ARCH(pIn);
|
size_t diff = ZSTD_read_ARCH(pMatch) ^ ZSTD_read_ARCH(pIn);
|
||||||
if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
|
if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
|
||||||
pIn += ZSTD_NbCommonBytes(diff);
|
pIn += ZSTD_NbCommonBytes(diff);
|
||||||
@@ -917,8 +919,7 @@ static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
|
|||||||
const BYTE* ip = base + zc->nextToUpdate;
|
const BYTE* ip = base + zc->nextToUpdate;
|
||||||
const BYTE* const iend = (const BYTE*) end;
|
const BYTE* const iend = (const BYTE*) end;
|
||||||
|
|
||||||
while(ip <= iend)
|
while(ip <= iend) {
|
||||||
{
|
|
||||||
hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
|
hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
|
||||||
ip += FILLHASHSTEP;
|
ip += FILLHASHSTEP;
|
||||||
}
|
}
|
||||||
@@ -947,8 +948,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
if (ip < lowest+4)
|
if (ip < lowest+4) {
|
||||||
{
|
|
||||||
hashTable[ZSTD_hashPtr(lowest+1, hBits, mls)] = lowIndex+1;
|
hashTable[ZSTD_hashPtr(lowest+1, hBits, mls)] = lowIndex+1;
|
||||||
hashTable[ZSTD_hashPtr(lowest+2, hBits, mls)] = lowIndex+2;
|
hashTable[ZSTD_hashPtr(lowest+2, hBits, mls)] = lowIndex+2;
|
||||||
hashTable[ZSTD_hashPtr(lowest+3, hBits, mls)] = lowIndex+3;
|
hashTable[ZSTD_hashPtr(lowest+3, hBits, mls)] = lowIndex+3;
|
||||||
@@ -956,8 +956,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Main Search Loop */
|
/* 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 mlCode;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
const size_t h = ZSTD_hashPtr(ip, hBits, mls);
|
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);
|
const U32 current = (U32)(ip-base);
|
||||||
hashTable[h] = current; /* update hash table */
|
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);
|
mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend);
|
||||||
ip++;
|
ip++;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( (matchIndex <= lowIndex) ||
|
if ( (matchIndex <= lowIndex) ||
|
||||||
(MEM_read32(match) != MEM_read32(ip)) )
|
(MEM_read32(match) != MEM_read32(ip)) ) {
|
||||||
{
|
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
ip += ((ip-anchor) >> g_searchStrength) + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -992,15 +987,13 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
ip += mlCode + MINMATCH;
|
ip += mlCode + MINMATCH;
|
||||||
anchor = ip;
|
anchor = ip;
|
||||||
|
|
||||||
if (ip <= ilimit)
|
if (ip <= ilimit) {
|
||||||
{
|
|
||||||
/* Fill Table */
|
/* Fill Table */
|
||||||
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
|
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);
|
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while ( (ip <= ilimit)
|
while ( (ip <= ilimit)
|
||||||
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )
|
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
|
||||||
{
|
|
||||||
/* store sequence */
|
/* store sequence */
|
||||||
size_t rlCode = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend);
|
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 */
|
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;
|
ip += rlCode+MINMATCH;
|
||||||
anchor = ip;
|
anchor = ip;
|
||||||
continue; /* faster when present ... (?) */
|
continue; /* faster when present ... (?) */
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{
|
{
|
||||||
@@ -1067,18 +1058,15 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
ZSTD_resetSeqStore(seqStorePtr);
|
ZSTD_resetSeqStore(seqStorePtr);
|
||||||
{
|
/* skip first 4 positions to avoid read overflow during repcode match check */
|
||||||
/* 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+0, hBits, mls)] = (U32)(ip-base+0);
|
hashTable[ZSTD_hashPtr(ip+1, hBits, mls)] = (U32)(ip-base+1);
|
||||||
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+2, hBits, mls)] = (U32)(ip-base+2);
|
hashTable[ZSTD_hashPtr(ip+3, hBits, mls)] = (U32)(ip-base+3);
|
||||||
hashTable[ZSTD_hashPtr(ip+3, hBits, mls)] = (U32)(ip-base+3);
|
ip += 4;
|
||||||
ip += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main Search Loop */
|
/* 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 size_t h = ZSTD_hashPtr(ip, hBits, mls);
|
||||||
const U32 matchIndex = hashTable[h];
|
const U32 matchIndex = hashTable[h];
|
||||||
const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
|
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 */
|
hashTable[h] = current; /* update hash table */
|
||||||
|
|
||||||
if ( ((repIndex <= dictLimit-4) || (repIndex >= dictLimit))
|
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;
|
const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr);
|
mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr);
|
||||||
ip++;
|
ip++;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( (matchIndex < lowLimit) ||
|
if ( (matchIndex < lowLimit) ||
|
||||||
(MEM_read32(match) != MEM_read32(ip)) )
|
(MEM_read32(match) != MEM_read32(ip)) )
|
||||||
{ ip += ((ip-anchor) >> g_searchStrength) + 1; continue; }
|
{ 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* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
|
||||||
const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
|
const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
|
||||||
mlCode = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iend, matchEnd, 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 = current - matchIndex;
|
||||||
offset_2 = offset_1;
|
offset_2 = offset_1;
|
||||||
offset_1 = offset;
|
offset_1 = offset;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* found a match : store it */
|
/* found a match : store it */
|
||||||
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode);
|
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode);
|
||||||
ip += mlCode + MINMATCH;
|
ip += mlCode + MINMATCH;
|
||||||
anchor = ip;
|
anchor = ip;
|
||||||
|
|
||||||
if (ip <= ilimit)
|
if (ip <= ilimit) {
|
||||||
{
|
|
||||||
/* Fill Table */
|
/* Fill Table */
|
||||||
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
|
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
|
||||||
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while (ip <= ilimit)
|
while (ip <= ilimit) {
|
||||||
{
|
|
||||||
U32 current2 = (U32)(ip-base);
|
U32 current2 = (U32)(ip-base);
|
||||||
const U32 repIndex2 = current2 - offset_2;
|
const U32 repIndex2 = current2 - offset_2;
|
||||||
const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
|
const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
|
||||||
if ( ((repIndex2 <= dictLimit-4) || (repIndex2 >= dictLimit))
|
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;
|
const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
|
||||||
size_t repLength2 = ZSTD_count_2segments(ip+MINMATCH, repMatch2+MINMATCH, iend, repEnd2, lowPrefixPtr);
|
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 */
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Last Literals */
|
/* 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 */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow))
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
||||||
{
|
|
||||||
U32* nextPtr = bt + 2*(matchIndex & btMask);
|
U32* nextPtr = bt + 2*(matchIndex & btMask);
|
||||||
const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
|
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 */
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
||||||
|
|
||||||
if (matchIndex == predictedSmall)
|
if (matchIndex == predictedSmall) {
|
||||||
{ /* no need to check length, result known */
|
/* no need to check length, result known */
|
||||||
*smallerPtr = matchIndex;
|
*smallerPtr = matchIndex;
|
||||||
if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
||||||
smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchIndex == predictedLarge)
|
if (matchIndex == predictedLarge) {
|
||||||
{
|
|
||||||
*largerPtr = matchIndex;
|
*largerPtr = matchIndex;
|
||||||
if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
||||||
largerPtr = nextPtr;
|
largerPtr = nextPtr;
|
||||||
@@ -1239,14 +1216,11 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!extDict) || (matchIndex+matchLength >= dictLimit))
|
if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
||||||
{
|
|
||||||
match = base + matchIndex;
|
match = base + matchIndex;
|
||||||
if (match[matchLength] == ip[matchLength])
|
if (match[matchLength] == ip[matchLength])
|
||||||
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
|
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
match = dictBase + matchIndex;
|
match = dictBase + matchIndex;
|
||||||
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
||||||
if (matchIndex+matchLength >= dictLimit)
|
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 */
|
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 */
|
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 */
|
/* match is smaller than current */
|
||||||
*smallerPtr = matchIndex; /* update smaller idx */
|
*smallerPtr = matchIndex; /* update smaller idx */
|
||||||
commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
|
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 */
|
if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
||||||
smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
|
smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
|
||||||
matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
|
matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* match is larger than current */
|
/* match is larger than current */
|
||||||
*largerPtr = matchIndex;
|
*largerPtr = matchIndex;
|
||||||
commonLengthLarger = matchLength;
|
commonLengthLarger = matchLength;
|
||||||
if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
||||||
largerPtr = nextPtr;
|
largerPtr = nextPtr;
|
||||||
matchIndex = nextPtr[0];
|
matchIndex = nextPtr[0];
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
*smallerPtr = *largerPtr = 0;
|
*smallerPtr = *largerPtr = 0;
|
||||||
return (matchEndIdx > current + 8) ? matchEndIdx - current - 8 : 1;
|
return (matchEndIdx > current + 8) ? matchEndIdx - current - 8 : 1;
|
||||||
@@ -1326,28 +1296,23 @@ size_t ZSTD_insertBtAndFindBestMatch (
|
|||||||
|
|
||||||
hashTable[h] = current; /* Update Hash Table */
|
hashTable[h] = current; /* Update Hash Table */
|
||||||
|
|
||||||
while (nbCompares-- && (matchIndex > windowLow))
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
||||||
{
|
|
||||||
U32* nextPtr = bt + 2*(matchIndex & btMask);
|
U32* nextPtr = bt + 2*(matchIndex & btMask);
|
||||||
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 ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
|
||||||
{
|
|
||||||
match = base + matchIndex;
|
match = base + matchIndex;
|
||||||
if (match[matchLength] == ip[matchLength])
|
if (match[matchLength] == ip[matchLength])
|
||||||
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
|
matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
match = dictBase + matchIndex;
|
match = dictBase + matchIndex;
|
||||||
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
|
||||||
if (matchIndex+matchLength >= dictLimit)
|
if (matchIndex+matchLength >= dictLimit)
|
||||||
match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
|
match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchLength > bestLength)
|
if (matchLength > bestLength) {
|
||||||
{
|
|
||||||
if (matchLength > matchEndIdx - matchIndex)
|
if (matchLength > matchEndIdx - matchIndex)
|
||||||
matchEndIdx = matchIndex + (U32)matchLength;
|
matchEndIdx = matchIndex + (U32)matchLength;
|
||||||
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) )
|
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) */
|
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 */
|
/* match is smaller than current */
|
||||||
*smallerPtr = matchIndex; /* update smaller idx */
|
*smallerPtr = matchIndex; /* update smaller idx */
|
||||||
commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
|
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 */
|
if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
|
||||||
smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
|
smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
|
||||||
matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
|
matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* match is larger than current */
|
/* match is larger than current */
|
||||||
*largerPtr = matchIndex;
|
*largerPtr = matchIndex;
|
||||||
commonLengthLarger = matchLength;
|
commonLengthLarger = matchLength;
|
||||||
@@ -1472,8 +1434,7 @@ static U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
|
|||||||
const U32 target = (U32)(ip - base);
|
const U32 target = (U32)(ip - base);
|
||||||
U32 idx = zc->nextToUpdate;
|
U32 idx = zc->nextToUpdate;
|
||||||
|
|
||||||
while(idx < target)
|
while(idx < target) {
|
||||||
{
|
|
||||||
size_t h = ZSTD_hashPtr(base+idx, hashLog, mls);
|
size_t h = ZSTD_hashPtr(base+idx, hashLog, mls);
|
||||||
NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
|
NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
|
||||||
hashTable[h] = idx;
|
hashTable[h] = idx;
|
||||||
@@ -1511,18 +1472,14 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|||||||
/* HC4 match finder */
|
/* HC4 match finder */
|
||||||
matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
|
matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
|
||||||
|
|
||||||
while ((matchIndex>lowLimit) && (nbAttempts))
|
while ((matchIndex>lowLimit) && (nbAttempts)) {
|
||||||
{
|
|
||||||
size_t currentMl=0;
|
size_t currentMl=0;
|
||||||
nbAttempts--;
|
nbAttempts--;
|
||||||
if ((!extDict) || matchIndex >= dictLimit)
|
if ((!extDict) || matchIndex >= dictLimit) {
|
||||||
{
|
|
||||||
match = base + matchIndex;
|
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);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
match = dictBase + matchIndex;
|
match = dictBase + matchIndex;
|
||||||
if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
|
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;
|
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;
|
if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE;
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit)
|
while (ip < ilimit) {
|
||||||
{
|
|
||||||
size_t matchLength=0;
|
size_t matchLength=0;
|
||||||
size_t offset=0;
|
size_t offset=0;
|
||||||
const BYTE* start=ip+1;
|
const BYTE* start=ip+1;
|
||||||
|
|
||||||
/* check repCode */
|
/* 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 */
|
/* repcode : we take it */
|
||||||
matchLength = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend) + MINMATCH;
|
matchLength = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend) + MINMATCH;
|
||||||
if (depth==0) goto _storeSequence;
|
if (depth==0) goto _storeSequence;
|
||||||
@@ -1623,19 +1578,16 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
matchLength = ml2, start = ip, offset=offsetFound;
|
matchLength = ml2, start = ip, offset=offsetFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchLength < MINMATCH)
|
if (matchLength < MINMATCH) {
|
||||||
{
|
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let's try to find a better solution */
|
/* let's try to find a better solution */
|
||||||
if (depth>=1)
|
if (depth>=1)
|
||||||
while (ip<ilimit)
|
while (ip<ilimit) {
|
||||||
{
|
|
||||||
ip ++;
|
ip ++;
|
||||||
if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1)))
|
if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1))) {
|
||||||
{
|
|
||||||
size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
|
size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
|
||||||
int gain2 = (int)(mlRep * 3);
|
int gain2 = (int)(mlRep * 3);
|
||||||
int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
|
int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
|
||||||
@@ -1647,19 +1599,15 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
||||||
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4);
|
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;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue; /* search a better one */
|
continue; /* search a better one */
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* 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) && (MEM_read32(ip) == MEM_read32(ip - offset_1)))
|
if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1))) {
|
||||||
{
|
|
||||||
size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
|
size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
|
||||||
int gain2 = (int)(ml2 * 4);
|
int gain2 = (int)(ml2 * 4);
|
||||||
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
|
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
|
||||||
@@ -1671,19 +1619,15 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
|
|||||||
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
||||||
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
|
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;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue;
|
continue;
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
}
|
|
||||||
break; /* nothing found : store previous solution */
|
break; /* nothing found : store previous solution */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* catch up */
|
/* catch up */
|
||||||
if (offset)
|
if (offset) {
|
||||||
{
|
|
||||||
while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */
|
while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset])) /* only search for offset within prefix */
|
||||||
{ start--; matchLength++; }
|
{ start--; matchLength++; }
|
||||||
offset_2 = offset_1; offset_1 = offset;
|
offset_2 = offset_1; offset_1 = offset;
|
||||||
@@ -1699,8 +1643,7 @@ _storeSequence:
|
|||||||
|
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while ( (ip <= ilimit)
|
while ( (ip <= ilimit)
|
||||||
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )
|
&& (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
|
||||||
{
|
|
||||||
/* store sequence */
|
/* store sequence */
|
||||||
matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend);
|
matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend);
|
||||||
offset = offset_2;
|
offset = offset_2;
|
||||||
@@ -1710,8 +1653,7 @@ _storeSequence:
|
|||||||
ip += matchLength+MINMATCH;
|
ip += matchLength+MINMATCH;
|
||||||
anchor = ip;
|
anchor = ip;
|
||||||
continue; /* faster when present ... (?) */
|
continue; /* faster when present ... (?) */
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* Last Literals */
|
/* Last Literals */
|
||||||
{
|
{
|
||||||
@@ -1774,8 +1716,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
|
||||||
|
|
||||||
/* Match Loop */
|
/* Match Loop */
|
||||||
while (ip < ilimit)
|
while (ip < ilimit) {
|
||||||
{
|
|
||||||
size_t matchLength=0;
|
size_t matchLength=0;
|
||||||
size_t offset=0;
|
size_t offset=0;
|
||||||
const BYTE* start=ip+1;
|
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 repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
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 */
|
/* repcode detected we should take it */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
matchLength = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
|
matchLength = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
|
||||||
if (depth==0) goto _storeSequence;
|
if (depth==0) goto _storeSequence;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* first search (depth 0) */
|
/* first search (depth 0) */
|
||||||
@@ -1804,27 +1743,23 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
|
|||||||
matchLength = ml2, start = ip, offset=offsetFound;
|
matchLength = ml2, start = ip, offset=offsetFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchLength < MINMATCH)
|
if (matchLength < MINMATCH) {
|
||||||
{
|
|
||||||
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* let's try to find a better solution */
|
/* let's try to find a better solution */
|
||||||
if (depth>=1)
|
if (depth>=1)
|
||||||
while (ip<ilimit)
|
while (ip<ilimit) {
|
||||||
{
|
|
||||||
ip ++;
|
ip ++;
|
||||||
current++;
|
current++;
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
if (offset)
|
if (offset) {
|
||||||
{
|
|
||||||
const U32 repIndex = (U32)(current - offset_1);
|
const U32 repIndex = (U32)(current - offset_1);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
||||||
if (MEM_read32(ip) == MEM_read32(repMatch))
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
||||||
{
|
|
||||||
/* repcode detected */
|
/* repcode detected */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
|
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);
|
int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
|
||||||
if ((repLength >= MINMATCH) && (gain2 > gain1))
|
if ((repLength >= MINMATCH) && (gain2 > gain1))
|
||||||
matchLength = repLength, offset = 0, start = ip;
|
matchLength = repLength, offset = 0, start = ip;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* search match, depth 1 */
|
/* 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);
|
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
||||||
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4);
|
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;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue; /* search a better one */
|
continue; /* search a better one */
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 ++;
|
||||||
current++;
|
current++;
|
||||||
/* check repCode */
|
/* check repCode */
|
||||||
if (offset)
|
if (offset) {
|
||||||
{
|
|
||||||
const U32 repIndex = (U32)(current - offset_1);
|
const U32 repIndex = (U32)(current - offset_1);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
||||||
if (MEM_read32(ip) == MEM_read32(repMatch))
|
if (MEM_read32(ip) == MEM_read32(repMatch)) {
|
||||||
{
|
|
||||||
/* repcode detected */
|
/* repcode detected */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
|
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);
|
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
|
||||||
if ((repLength >= MINMATCH) && (gain2 > gain1))
|
if ((repLength >= MINMATCH) && (gain2 > gain1))
|
||||||
matchLength = repLength, offset = 0, start = ip;
|
matchLength = repLength, offset = 0, start = ip;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* search match, depth 2 */
|
/* 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);
|
size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
|
||||||
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1)); /* raw approx */
|
||||||
int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
|
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;
|
matchLength = ml2, offset = offset2, start = ip;
|
||||||
continue;
|
continue;
|
||||||
}
|
} } }
|
||||||
}
|
|
||||||
}
|
|
||||||
break; /* nothing found : store previous solution */
|
break; /* nothing found : store previous solution */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* catch up */
|
/* catch up */
|
||||||
if (offset)
|
if (offset) {
|
||||||
{
|
|
||||||
U32 matchIndex = (U32)((start-base) - offset);
|
U32 matchIndex = (U32)((start-base) - offset);
|
||||||
const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
|
const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
|
||||||
const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
|
const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
|
||||||
@@ -1907,14 +1831,12 @@ _storeSequence:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while (ip <= ilimit)
|
while (ip <= ilimit) {
|
||||||
{
|
|
||||||
const U32 repIndex = (U32)((ip-base) - offset_2);
|
const U32 repIndex = (U32)((ip-base) - offset_2);
|
||||||
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
||||||
const BYTE* const repMatch = repBase + repIndex;
|
const BYTE* const repMatch = repBase + repIndex;
|
||||||
if ((U32)((dictLimit-1) - repIndex) >= 3) /* intentional overflow */
|
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 */
|
/* repcode detected we should take it */
|
||||||
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
|
||||||
matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
|
matchLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
|
||||||
@@ -1925,8 +1847,7 @@ _storeSequence:
|
|||||||
continue; /* faster when present ... (?) */
|
continue; /* faster when present ... (?) */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* Last Literals */
|
/* 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)
|
static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
/* note : magic number already checked */
|
/* 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);
|
const size_t hufHeaderSize = HUF_readCTable(zc->hufTable, 255, dict, dictSize);
|
||||||
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
||||||
zc->flagHufTable = 1;
|
zc->flagStaticTables = 1;
|
||||||
return hufHeaderSize;
|
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)
|
static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
|
||||||
{
|
{
|
||||||
if (dict && dictSize)
|
if (dict && dictSize)
|
||||||
@@ -2240,8 +2192,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* zc, void* dst, size_t maxDstSize)
|
|||||||
size_t hbSize = 0;
|
size_t hbSize = 0;
|
||||||
|
|
||||||
/* empty frame */
|
/* empty frame */
|
||||||
if (zc->stage==0)
|
if (zc->stage==0) {
|
||||||
{
|
|
||||||
hbSize = zc->hbSize;
|
hbSize = zc->hbSize;
|
||||||
if (maxDstSize <= hbSize) return ERROR(dstSize_tooSmall);
|
if (maxDstSize <= hbSize) return ERROR(dstSize_tooSmall);
|
||||||
zc->stage = 1;
|
zc->stage = 1;
|
||||||
|
|||||||
+151
-67
@@ -51,7 +51,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* *******************************************************
|
/*-*******************************************************
|
||||||
* Includes
|
* Includes
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#include <stdlib.h> /* calloc */
|
#include <stdlib.h> /* calloc */
|
||||||
@@ -67,7 +67,8 @@
|
|||||||
# include "zstd_legacy.h"
|
# include "zstd_legacy.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* *******************************************************
|
|
||||||
|
/*-*******************************************************
|
||||||
* Compiler specifics
|
* Compiler specifics
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
#ifdef _MSC_VER /* Visual Studio */
|
#ifdef _MSC_VER /* Visual Studio */
|
||||||
@@ -85,7 +86,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/*-*************************************
|
||||||
* Local types
|
* Local types
|
||||||
***************************************/
|
***************************************/
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -123,10 +124,10 @@ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
|
|||||||
|
|
||||||
struct ZSTD_DCtx_s
|
struct ZSTD_DCtx_s
|
||||||
{
|
{
|
||||||
U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
|
||||||
U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
|
||||||
U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
|
||||||
U32 hufTableX4[HUF_DTABLE_SIZE(HufLog)];
|
unsigned hufTableX4[HUF_DTABLE_SIZE(HufLog)];
|
||||||
const void* previousDstEnd;
|
const void* previousDstEnd;
|
||||||
const void* base;
|
const void* base;
|
||||||
const void* vBase;
|
const void* vBase;
|
||||||
@@ -134,9 +135,9 @@ struct ZSTD_DCtx_s
|
|||||||
size_t expected;
|
size_t expected;
|
||||||
size_t headerSize;
|
size_t headerSize;
|
||||||
ZSTD_parameters params;
|
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;
|
ZSTD_dStage stage;
|
||||||
U32 flagHufTable;
|
U32 flagStaticTables;
|
||||||
const BYTE* litPtr;
|
const BYTE* litPtr;
|
||||||
size_t litBufSize;
|
size_t litBufSize;
|
||||||
size_t litSize;
|
size_t litSize;
|
||||||
@@ -144,6 +145,8 @@ struct ZSTD_DCtx_s
|
|||||||
BYTE headerBuffer[ZSTD_frameHeaderSize_max];
|
BYTE headerBuffer[ZSTD_frameHeaderSize_max];
|
||||||
}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
|
}; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
|
||||||
|
|
||||||
|
size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
|
||||||
|
|
||||||
size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
||||||
{
|
{
|
||||||
dctx->expected = ZSTD_frameHeaderSize_min;
|
dctx->expected = ZSTD_frameHeaderSize_min;
|
||||||
@@ -153,7 +156,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
|||||||
dctx->vBase = NULL;
|
dctx->vBase = NULL;
|
||||||
dctx->dictEnd = NULL;
|
dctx->dictEnd = NULL;
|
||||||
dctx->hufTableX4[0] = HufLog;
|
dctx->hufTableX4[0] = HufLog;
|
||||||
dctx->flagHufTable = 0;
|
dctx->flagStaticTables = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,27 +200,66 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Block format description
|
/* 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) Literal Section
|
||||||
1.1) Header : up to 5 bytes
|
|
||||||
flags:
|
1.1) Header : 1-5 bytes
|
||||||
|
flags: 2 bits
|
||||||
00 compressed by Huff0
|
00 compressed by Huff0
|
||||||
01 is Raw (uncompressed)
|
01 unused
|
||||||
10 is Rle
|
10 is Raw (uncompressed)
|
||||||
11 unused
|
11 is Rle
|
||||||
Note : using 11 for Huff0 with precomputed table ?
|
Note : using 01 => Huff0 with precomputed table ?
|
||||||
Note : delta map ? => compressed ?
|
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
|
1.2.1) Huff0 block, using sizes from header
|
||||||
See Huff0 format
|
See Huff0 format
|
||||||
|
|
||||||
1.2.2) Huff0 block, using precomputed DTable
|
1.2.2) Huff0 block, using prepared table
|
||||||
_usingDTable variants
|
|
||||||
|
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
|
2) Sequences section
|
||||||
TO DO
|
TO DO
|
||||||
@@ -331,7 +373,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|||||||
litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
|
litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);;
|
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
|
||||||
|
|
||||||
if (HUF_isError(singleStream ?
|
if (HUF_isError(singleStream ?
|
||||||
HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
|
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;
|
U32 lhSize = ((istart[0]) >> 4) & 3;
|
||||||
if (lhSize != 1) /* only case supported for now : small litSize, single stream */
|
if (lhSize != 1) /* only case supported for now : small litSize, single stream */
|
||||||
return ERROR(corruption_detected);
|
return ERROR(corruption_detected);
|
||||||
if (!dctx->flagHufTable)
|
if (!dctx->flagStaticTables)
|
||||||
return ERROR(dictionary_corrupted);
|
return ERROR(dictionary_corrupted);
|
||||||
|
|
||||||
/* 2 - 2 - 10 - 10 */
|
/* 2 - 2 - 10 - 10 */
|
||||||
@@ -448,14 +490,11 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen
|
|||||||
LLtype = *ip >> 6;
|
LLtype = *ip >> 6;
|
||||||
Offtype = (*ip >> 4) & 3;
|
Offtype = (*ip >> 4) & 3;
|
||||||
MLtype = (*ip >> 2) & 3;
|
MLtype = (*ip >> 2) & 3;
|
||||||
if (*ip & 2)
|
if (*ip & 2) {
|
||||||
{
|
|
||||||
dumpsLength = ip[2];
|
dumpsLength = ip[2];
|
||||||
dumpsLength += ip[1] << 8;
|
dumpsLength += ip[1] << 8;
|
||||||
ip += 3;
|
ip += 3;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
dumpsLength = ip[1];
|
dumpsLength = ip[1];
|
||||||
dumpsLength += (ip[0] & 1) << 8;
|
dumpsLength += (ip[0] & 1) << 8;
|
||||||
ip += 2;
|
ip += 2;
|
||||||
@@ -476,13 +515,18 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen
|
|||||||
switch(LLtype)
|
switch(LLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
U32 max;
|
||||||
case bt_rle :
|
case FSE_ENCODING_RLE :
|
||||||
LLlog = 0;
|
LLlog = 0;
|
||||||
FSE_buildDTable_rle(DTableLL, *ip++); break;
|
FSE_buildDTable_rle(DTableLL, *ip++);
|
||||||
case bt_raw :
|
break;
|
||||||
|
case FSE_ENCODING_RAW :
|
||||||
LLlog = LLbits;
|
LLlog = LLbits;
|
||||||
FSE_buildDTable_raw(DTableLL, LLbits); break;
|
FSE_buildDTable_raw(DTableLL, LLbits);
|
||||||
default :
|
break;
|
||||||
|
case FSE_ENCODING_STATIC:
|
||||||
|
break;
|
||||||
|
case FSE_ENCODING_DYNAMIC :
|
||||||
|
default : /* impossible */
|
||||||
max = MaxLL;
|
max = MaxLL;
|
||||||
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
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)
|
switch(Offtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
U32 max;
|
||||||
case bt_rle :
|
case FSE_ENCODING_RLE :
|
||||||
Offlog = 0;
|
Offlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
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 */
|
FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
|
||||||
break;
|
break;
|
||||||
case bt_raw :
|
case FSE_ENCODING_RAW :
|
||||||
Offlog = Offbits;
|
Offlog = Offbits;
|
||||||
FSE_buildDTable_raw(DTableOffb, Offbits); break;
|
FSE_buildDTable_raw(DTableOffb, Offbits);
|
||||||
default :
|
break;
|
||||||
|
case FSE_ENCODING_STATIC:
|
||||||
|
break;
|
||||||
|
case FSE_ENCODING_DYNAMIC :
|
||||||
|
default : /* impossible */
|
||||||
max = MaxOff;
|
max = MaxOff;
|
||||||
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
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)
|
switch(MLtype)
|
||||||
{
|
{
|
||||||
U32 max;
|
U32 max;
|
||||||
case bt_rle :
|
case FSE_ENCODING_RLE :
|
||||||
MLlog = 0;
|
MLlog = 0;
|
||||||
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
|
||||||
FSE_buildDTable_rle(DTableML, *ip++); break;
|
FSE_buildDTable_rle(DTableML, *ip++);
|
||||||
case bt_raw :
|
break;
|
||||||
|
case FSE_ENCODING_RAW :
|
||||||
MLlog = MLbits;
|
MLlog = MLbits;
|
||||||
FSE_buildDTable_raw(DTableML, MLbits); break;
|
FSE_buildDTable_raw(DTableML, MLbits);
|
||||||
default :
|
break;
|
||||||
|
case FSE_ENCODING_STATIC:
|
||||||
|
break;
|
||||||
|
case FSE_ENCODING_DYNAMIC :
|
||||||
|
default : /* impossible */
|
||||||
max = MaxML;
|
max = MaxML;
|
||||||
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
|
||||||
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
if (FSE_isError(headerSize)) return ERROR(GENERIC);
|
||||||
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
if (MLlog > MLFSELog) return ERROR(corruption_detected);
|
||||||
ip += headerSize;
|
ip += headerSize;
|
||||||
FSE_buildDTable(DTableML, norm, max, MLlog);
|
FSE_buildDTable(DTableML, norm, max, MLlog);
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
return ip-istart;
|
return ip-istart;
|
||||||
}
|
}
|
||||||
@@ -564,12 +616,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|||||||
/* Literal length */
|
/* Literal length */
|
||||||
litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
|
litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
|
||||||
prevOffset = litLength ? seq->offset : seqState->prevOffset;
|
prevOffset = litLength ? seq->offset : seqState->prevOffset;
|
||||||
if (litLength == MaxLL)
|
if (litLength == MaxLL) {
|
||||||
{
|
|
||||||
U32 add = *dumps++;
|
U32 add = *dumps++;
|
||||||
if (add < 255) litLength += add;
|
if (add < 255) litLength += add;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
||||||
dumps += 3;
|
dumps += 3;
|
||||||
}
|
}
|
||||||
@@ -595,12 +645,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|||||||
|
|
||||||
/* MatchLength */
|
/* MatchLength */
|
||||||
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
|
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
|
||||||
if (matchLength == MaxML)
|
if (matchLength == MaxML) {
|
||||||
{
|
|
||||||
U32 add = *dumps++;
|
U32 add = *dumps++;
|
||||||
if (add < 255) matchLength += add;
|
if (add < 255) matchLength += add;
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
|
||||||
dumps += 3;
|
dumps += 3;
|
||||||
}
|
}
|
||||||
@@ -613,6 +661,15 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
|
|||||||
seq->offset = offset;
|
seq->offset = offset;
|
||||||
seq->matchLength = matchLength;
|
seq->matchLength = matchLength;
|
||||||
seqState->dumps = dumps;
|
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;
|
op = oLitEnd + length1;
|
||||||
sequence.matchLength -= length1;
|
sequence.matchLength -= length1;
|
||||||
match = base;
|
match = base;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
/* match within prefix */
|
/* match within prefix */
|
||||||
if (sequence.offset < 8) {
|
if (sequence.offset < 8) {
|
||||||
@@ -671,8 +727,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
|
|||||||
match += dec32table[sequence.offset];
|
match += dec32table[sequence.offset];
|
||||||
ZSTD_copy4(op+4, match);
|
ZSTD_copy4(op+4, match);
|
||||||
match -= sub2;
|
match -= sub2;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ZSTD_copy8(op, match);
|
ZSTD_copy8(op, match);
|
||||||
}
|
}
|
||||||
op += 8; match += 8;
|
op += 8; match += 8;
|
||||||
@@ -683,9 +738,9 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
|
|||||||
match += oend_8 - op;
|
match += oend_8 - op;
|
||||||
op = oend_8;
|
op = oend_8;
|
||||||
}
|
}
|
||||||
while (op < oMatchEnd) *op++ = *match++;
|
while (op < oMatchEnd)
|
||||||
}
|
*op++ = *match++;
|
||||||
else {
|
} else {
|
||||||
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
ZSTD_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
|
||||||
}
|
}
|
||||||
return sequenceLength;
|
return sequenceLength;
|
||||||
@@ -718,7 +773,7 @@ static size_t ZSTD_decompressSequences(
|
|||||||
/* Build Decoding Tables */
|
/* Build Decoding Tables */
|
||||||
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
|
||||||
DTableLL, DTableML, DTableOffb,
|
DTableLL, DTableML, DTableOffb,
|
||||||
ip, iend-ip);
|
ip, seqSize);
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
if (ZSTD_isError(errorCode)) return errorCode;
|
||||||
ip += errorCode;
|
ip += errorCode;
|
||||||
|
|
||||||
@@ -757,8 +812,7 @@ static size_t ZSTD_decompressSequences(
|
|||||||
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
|
||||||
if (op != litPtr) memcpy(op, litPtr, lastLLSize);
|
if (op != litPtr) memcpy(op, litPtr, lastLLSize);
|
||||||
op += lastLLSize;
|
op += lastLLSize;
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
|
|
||||||
return op-ostart;
|
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)
|
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);
|
if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
|
||||||
dctx->flagHufTable = 1;
|
dict = (const char*)dict + hSize;
|
||||||
return 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)
|
static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
||||||
|
|||||||
+8
-2
@@ -94,6 +94,12 @@ static const size_t ZSTD_frameHeaderSize_min = 5;
|
|||||||
#define OffFSELog 9
|
#define OffFSELog 9
|
||||||
#define MaxSeq MAX(MaxLL, MaxML)
|
#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 HufLog 12
|
||||||
|
|
||||||
#define MIN_SEQUENCES_SIZE (2 /*seqNb*/ + 2 /*dumps*/ + 3 /*seqTables*/ + 1 /*bitStream*/)
|
#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;
|
typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************
|
/*-*******************************************
|
||||||
* Shared functions to include for inlining
|
* Shared functions to include for inlining
|
||||||
********************************************/
|
*********************************************/
|
||||||
static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
|
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; }
|
#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
|
||||||
|
|||||||
+14
-7
@@ -293,11 +293,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
milliTime = BMK_GetMilliStart();
|
milliTime = BMK_GetMilliStart();
|
||||||
while (BMK_GetMilliStart() == milliTime);
|
while (BMK_GetMilliStart() == milliTime);
|
||||||
milliTime = BMK_GetMilliStart();
|
milliTime = BMK_GetMilliStart();
|
||||||
while (BMK_GetMilliSpan(milliTime) < TIMELOOP)
|
while (BMK_GetMilliSpan(milliTime) < TIMELOOP) {
|
||||||
{
|
|
||||||
ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, dictBufferSize+largestBlockSize));
|
ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, dictBufferSize+largestBlockSize));
|
||||||
for (blockNb=0; blockNb<nbBlocks; blockNb++)
|
//ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, 0));
|
||||||
{
|
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||||
ZSTD_copyCCtx(ctx, refCtx);
|
ZSTD_copyCCtx(ctx, refCtx);
|
||||||
size_t rSize = ZSTD_compressContinue(ctx,
|
size_t rSize = ZSTD_compressContinue(ctx,
|
||||||
blockTable[blockNb].cPtr, blockTable[blockNb].cRoom,
|
blockTable[blockNb].cPtr, blockTable[blockNb].cRoom,
|
||||||
@@ -309,6 +308,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
blockTable[blockNb].cRoom - rSize);
|
blockTable[blockNb].cRoom - rSize);
|
||||||
if (ZSTD_isError(rSize)) EXM_THROW(2, "ZSTD_compressEnd() failed : %s", ZSTD_getErrorName(rSize));
|
if (ZSTD_isError(rSize)) EXM_THROW(2, "ZSTD_compressEnd() failed : %s", ZSTD_getErrorName(rSize));
|
||||||
blockTable[blockNb].cSize += rSize;
|
blockTable[blockNb].cSize += rSize;
|
||||||
|
|
||||||
|
if (blockNb==999999999)
|
||||||
|
printf("%4u : %6u => %6u bytes (%08X) \n",
|
||||||
|
blockNb, (U32)blockTable[blockNb].srcSize, (U32)blockTable[blockNb].cSize, XXH32(blockTable[blockNb].cPtr, blockTable[blockNb].cSize, 0));
|
||||||
}
|
}
|
||||||
nbLoops++;
|
nbLoops++;
|
||||||
}
|
}
|
||||||
@@ -340,7 +343,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
|
blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
|
||||||
|
|
||||||
if (ZSTD_isError(regenSize))
|
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;
|
blockTable[blockNb].resSize = regenSize;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
@@ -364,8 +368,11 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
}
|
}
|
||||||
pos = (U32)(u - bacc);
|
pos = (U32)(u - bacc);
|
||||||
bNb = pos / (128 KB);
|
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;
|
break;
|
||||||
|
}
|
||||||
|
if (u==srcSize-1) { /* should never happen */
|
||||||
|
printf("no difference detected\n");
|
||||||
} }
|
} }
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -375,7 +382,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
|
|||||||
if (crcOrig == crcCheck)
|
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.);
|
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
|
else
|
||||||
DISPLAY("\n");
|
DISPLAY("%2i-\n", cLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
|
|||||||
Reference in New Issue
Block a user