#define HASH_READ_SIZE 8
typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
-/* entropy tables always have same size */
-static size_t const hufCTable_size = HUF_CTABLE_SIZE(255);
-static size_t const litlengthCTable_size = FSE_CTABLE_SIZE(LLFSELog, MaxLL);
-static size_t const offcodeCTable_size = FSE_CTABLE_SIZE(OffFSELog, MaxOff);
-static size_t const matchlengthCTable_size = FSE_CTABLE_SIZE(MLFSELog, MaxML);
-static size_t const entropyScratchSpace_size = HUF_WORKSPACE_SIZE;
-
/*-*************************************
* Helper functions
U32* hashTable;
U32* hashTable3;
U32* chainTable;
- HUF_repeat hufCTable_repeatMode;
- HUF_CElt* hufCTable;
- U32 fseCTables_ready;
- FSE_CTable* offcodeCTable;
- FSE_CTable* matchlengthCTable;
- FSE_CTable* litlengthCTable;
- unsigned* entropyScratchSpace;
+ ZSTD_entropyCTables_t* entropy;
/* streaming */
char* inBuff;
cctx->workSpaceSize = workspaceSize - sizeof(ZSTD_CCtx);
/* entropy space (never moves) */
- /* note : this code should be shared with resetCCtx, rather than copy/pasted */
- { void* ptr = cctx->workSpace;
- cctx->hufCTable = (HUF_CElt*)ptr;
- ptr = (char*)cctx->hufCTable + hufCTable_size;
- cctx->offcodeCTable = (FSE_CTable*) ptr;
- ptr = (char*)ptr + offcodeCTable_size;
- cctx->matchlengthCTable = (FSE_CTable*) ptr;
- ptr = (char*)ptr + matchlengthCTable_size;
- cctx->litlengthCTable = (FSE_CTable*) ptr;
- ptr = (char*)ptr + litlengthCTable_size;
- assert(((size_t)ptr & 3) == 0); /* ensure correct alignment */
- cctx->entropyScratchSpace = (unsigned*) ptr;
- }
+ if (cctx->workSpaceSize < sizeof(ZSTD_entropyCTables_t)) return NULL;
+ assert(((size_t)cctx->workSpace & 7) == 0); /* ensure correct alignment */
+ cctx->entropy = (ZSTD_entropyCTables_t*)cctx->workSpace;
return cctx;
}
size_t const hSize = ((size_t)1) << cParams.hashLog;
U32 const hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
size_t const h3Size = ((size_t)1) << hashLog3;
- size_t const entropySpace = hufCTable_size + litlengthCTable_size
- + offcodeCTable_size + matchlengthCTable_size
- + entropyScratchSpace_size;
+ size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
size_t const optBudget = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
if (crp == ZSTDcrp_continue) {
if (ZSTD_equivalentParams(params.cParams, zc->appliedParams.cParams)) {
DEBUGLOG(5, "ZSTD_equivalentParams()==1");
- zc->fseCTables_ready = 0;
- zc->hufCTable_repeatMode = HUF_repeat_none;
+ zc->entropy->fseCTables_ready = 0;
+ zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
} }
void* ptr;
/* Check if workSpace is large enough, alloc a new one if needed */
- { size_t const entropySpace = hufCTable_size + litlengthCTable_size
- + offcodeCTable_size + matchlengthCTable_size
- + entropyScratchSpace_size;
+ { size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits)) * sizeof(U32)
+ (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
size_t const optSpace = ( (params.cParams.strategy == ZSTD_btopt)
ptr = zc->workSpace;
/* entropy space */
- zc->hufCTable = (HUF_CElt*)ptr;
- ptr = (char*)zc->hufCTable + hufCTable_size; /* note : HUF_CElt* is incomplete type, size is estimated via macro */
- zc->offcodeCTable = (FSE_CTable*) ptr;
- ptr = (char*)ptr + offcodeCTable_size;
- zc->matchlengthCTable = (FSE_CTable*) ptr;
- ptr = (char*)ptr + matchlengthCTable_size;
- zc->litlengthCTable = (FSE_CTable*) ptr;
- ptr = (char*)ptr + litlengthCTable_size;
- assert(((size_t)ptr & 3) == 0); /* ensure correct alignment */
- zc->entropyScratchSpace = (unsigned*) ptr;
+ assert(((size_t)zc->workSpace & 3) == 0); /* ensure correct alignment */
+ assert(zc->workSpaceSize >= sizeof(ZSTD_entropyCTables_t));
+ zc->entropy = (ZSTD_entropyCTables_t*)zc->workSpace;
} }
/* init params */
zc->stage = ZSTDcs_init;
zc->dictID = 0;
zc->loadedDictEnd = 0;
- zc->fseCTables_ready = 0;
- zc->hufCTable_repeatMode = HUF_repeat_none;
+ zc->entropy->fseCTables_ready = 0;
+ zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
zc->nextToUpdate = 1;
zc->nextSrc = NULL;
zc->base = NULL;
zc->hashLog3 = hashLog3;
zc->seqStore.litLengthSum = 0;
- /* ensure entropy tables are close together at the beginning */
- assert((void*)zc->hufCTable == zc->workSpace);
- assert((char*)zc->offcodeCTable == (char*)zc->hufCTable + hufCTable_size);
- assert((char*)zc->matchlengthCTable == (char*)zc->offcodeCTable + offcodeCTable_size);
- assert((char*)zc->litlengthCTable == (char*)zc->matchlengthCTable + matchlengthCTable_size);
- assert((char*)zc->entropyScratchSpace == (char*)zc->litlengthCTable + litlengthCTable_size);
- ptr = (char*)zc->entropyScratchSpace + entropyScratchSpace_size;
+ ptr = zc->entropy + 1;
/* opt parser space */
if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btultra)) {
dstCCtx->dictID = srcCCtx->dictID;
/* copy entropy tables */
- dstCCtx->fseCTables_ready = srcCCtx->fseCTables_ready;
- if (srcCCtx->fseCTables_ready) {
- memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, litlengthCTable_size);
- memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, matchlengthCTable_size);
- memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, offcodeCTable_size);
- }
- dstCCtx->hufCTable_repeatMode = srcCCtx->hufCTable_repeatMode;
- if (srcCCtx->hufCTable_repeatMode) {
- memcpy(dstCCtx->hufCTable, srcCCtx->hufCTable, hufCTable_size);
- }
+ memcpy(dstCCtx->entropy, srcCCtx->entropy, sizeof(ZSTD_entropyCTables_t));
return 0;
}
/* small ? don't even attempt compression (speed opt) */
# define LITERAL_NOENTROPY 63
- { size_t const minLitSize = zc->hufCTable_repeatMode == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
+ { size_t const minLitSize = zc->entropy->hufCTable_repeatMode == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
}
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
- { HUF_repeat repeat = zc->hufCTable_repeatMode;
+ { HUF_repeat repeat = zc->entropy->hufCTable_repeatMode;
int const preferRepeat = zc->appliedParams.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
- zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat)
+ zc->entropy->workspace, sizeof(zc->entropy->workspace), (HUF_CElt*)zc->entropy->hufCTable, &repeat, preferRepeat)
: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
- zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat);
+ zc->entropy->workspace, sizeof(zc->entropy->workspace), (HUF_CElt*)zc->entropy->hufCTable, &repeat, preferRepeat);
if (repeat != HUF_repeat_none) { hType = set_repeat; } /* reused the existing table */
- else { zc->hufCTable_repeatMode = HUF_repeat_check; } /* now have a table to reuse */
+ else { zc->entropy->hufCTable_repeatMode = HUF_repeat_check; } /* now have a table to reuse */
}
if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) {
- zc->hufCTable_repeatMode = HUF_repeat_none;
+ zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
}
if (cLitSize==1) {
- zc->hufCTable_repeatMode = HUF_repeat_none;
+ zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
}
const seqStore_t* seqStorePtr = &(zc->seqStore);
U32 count[MaxSeq+1];
S16 norm[MaxSeq+1];
- FSE_CTable* CTable_LitLength = zc->litlengthCTable;
- FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
- FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
+ FSE_CTable* CTable_LitLength = zc->entropy->litlengthCTable;
+ FSE_CTable* CTable_OffsetBits = zc->entropy->offcodeCTable;
+ FSE_CTable* CTable_MatchLength = zc->entropy->matchlengthCTable;
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
const seqDef* const sequences = seqStorePtr->sequencesStart;
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
/* CTable for Literal Lengths */
{ U32 max = MaxLL;
- size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->entropyScratchSpace);
+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->entropy->workspace);
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
*op++ = llCodeTable[0];
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
LLtype = set_rle;
- } else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+ } else if ((zc->entropy->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
LLtype = set_repeat;
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
/* CTable for Offsets */
{ U32 max = MaxOff;
- size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->entropyScratchSpace);
+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->entropy->workspace);
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
*op++ = ofCodeTable[0];
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
Offtype = set_rle;
- } else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+ } else if ((zc->entropy->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
Offtype = set_repeat;
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
/* CTable for MatchLengths */
{ U32 max = MaxML;
- size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->entropyScratchSpace);
+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->entropy->workspace);
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
*op++ = *mlCodeTable;
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
MLtype = set_rle;
- } else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+ } else if ((zc->entropy->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
MLtype = set_repeat;
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
} }
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
- zc->fseCTables_ready = 0;
+ zc->entropy->fseCTables_ready = 0;
/* Encoding Sequences */
{ BIT_CStream_t blockStream;
{ size_t const minGain = ZSTD_minGain(srcSize);
size_t const maxCSize = srcSize - minGain;
if ((size_t)(op-ostart) >= maxCSize) {
- zc->hufCTable_repeatMode = HUF_repeat_none;
+ zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
return 0;
} }
const BYTE* const dictEnd = dictPtr + dictSize;
short offcodeNCount[MaxOff+1];
unsigned offcodeMaxValue = MaxOff;
- BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
+
+ ZSTD_STATIC_ASSERT(sizeof(cctx->entropy->workspace) >= (1<<MAX(MLFSELog,LLFSELog)));
dictPtr += 4; /* skip magic number */
cctx->dictID = cctx->appliedParams.fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
dictPtr += 4;
- { size_t const hufHeaderSize = HUF_readCTable(cctx->hufCTable, 255, dictPtr, dictEnd-dictPtr);
+ { size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)cctx->entropy->hufCTable, 255, dictPtr, dictEnd-dictPtr);
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
dictPtr += hufHeaderSize;
}
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
- CHECK_E( FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)),
+ CHECK_E( FSE_buildCTable_wksp(cctx->entropy->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, cctx->entropy->workspace, sizeof(cctx->entropy->workspace)),
dictionary_corrupted);
dictPtr += offcodeHeaderSize;
}
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
/* Every match length code must have non-zero probability */
CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
- CHECK_E( FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)),
+ CHECK_E( FSE_buildCTable_wksp(cctx->entropy->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, cctx->entropy->workspace, sizeof(cctx->entropy->workspace)),
dictionary_corrupted);
dictPtr += matchlengthHeaderSize;
}
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
/* Every literal length code must have non-zero probability */
CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
- CHECK_E( FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)),
+ CHECK_E( FSE_buildCTable_wksp(cctx->entropy->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, cctx->entropy->workspace, sizeof(cctx->entropy->workspace)),
dictionary_corrupted);
dictPtr += litlengthHeaderSize;
}
if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
} }
- cctx->fseCTables_ready = 1;
- cctx->hufCTable_repeatMode = HUF_repeat_valid;
+ cctx->entropy->fseCTables_ready = 1;
+ cctx->entropy->hufCTable_repeatMode = HUF_repeat_valid;
return ZSTD_loadDictionaryContent(cctx, dictPtr, dictContentSize);
}
}