refactor HUF_compress_internal for clarity

changed workspace parameter convention
to always provide workspaceSize,
so that size can be explicitly checked.

Also, use more enum to make the meaning of some parameters more explicit.
This commit is contained in:
Yann Collet
2018-10-26 13:21:37 -07:00
parent e26126caca
commit 7b74405150
6 changed files with 87 additions and 65 deletions
+1 -1
View File
@@ -672,7 +672,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG; if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
/* Scan input and build symbol stats */ /* Scan input and build symbol stats */
{ CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) ); { CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, scratchBuffer, scratchBufferSize) );
if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */ if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
+19 -11
View File
@@ -73,6 +73,7 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
return largestCount; return largestCount;
} }
typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
/* HIST_count_parallel_wksp() : /* HIST_count_parallel_wksp() :
* store histogram into 4 intermediate tables, recombined at the end. * store histogram into 4 intermediate tables, recombined at the end.
@@ -85,8 +86,8 @@ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
static size_t HIST_count_parallel_wksp( static size_t HIST_count_parallel_wksp(
unsigned* count, unsigned* maxSymbolValuePtr, unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, const void* source, size_t sourceSize,
unsigned checkMax, HIST_checkInput_e check,
unsigned* const workSpace) U32* const workSpace)
{ {
const BYTE* ip = (const BYTE*)source; const BYTE* ip = (const BYTE*)source;
const BYTE* const iend = ip+sourceSize; const BYTE* const iend = ip+sourceSize;
@@ -137,7 +138,7 @@ static size_t HIST_count_parallel_wksp(
/* finish last symbols */ /* finish last symbols */
while (ip<iend) Counting1[*ip++]++; while (ip<iend) Counting1[*ip++]++;
if (checkMax) { /* verify stats will fit into destination table */ if (check) { /* verify stats will fit into destination table */
U32 s; for (s=255; s>maxSymbolValue; s--) { U32 s; for (s=255; s>maxSymbolValue; s--) {
Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s]; Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall); if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
@@ -157,14 +158,18 @@ static size_t HIST_count_parallel_wksp(
/* HIST_countFast_wksp() : /* HIST_countFast_wksp() :
* Same as HIST_countFast(), but using an externally provided scratch buffer. * Same as HIST_countFast(), but using an externally provided scratch buffer.
* `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ * `workSpace` is a writable buffer which must be 4-bytes aligned,
* `workSpaceSize` must be >= HIST_WKSP_SIZE
*/
size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, const void* source, size_t sourceSize,
unsigned* workSpace) void* workSpace, size_t workSpaceSize)
{ {
if (sourceSize < 1500) /* heuristic threshold */ if (sourceSize < 1500) /* heuristic threshold */
return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize);
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace); if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
} }
/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
@@ -172,24 +177,27 @@ size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize) const void* source, size_t sourceSize)
{ {
unsigned tmpCounters[HIST_WKSP_SIZE_U32]; unsigned tmpCounters[HIST_WKSP_SIZE_U32];
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters); return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
} }
/* HIST_count_wksp() : /* HIST_count_wksp() :
* Same as HIST_count(), but using an externally provided scratch buffer. * Same as HIST_count(), but using an externally provided scratch buffer.
* `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* source, size_t sourceSize, unsigned* workSpace) const void* source, size_t sourceSize,
void* workSpace, size_t workSpaceSize)
{ {
if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
if (*maxSymbolValuePtr < 255) if (*maxSymbolValuePtr < 255)
return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace); return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace);
*maxSymbolValuePtr = 255; *maxSymbolValuePtr = 255;
return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace); return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
} }
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize) const void* src, size_t srcSize)
{ {
unsigned tmpCounters[HIST_WKSP_SIZE_U32]; unsigned tmpCounters[HIST_WKSP_SIZE_U32];
return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters); return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));
} }
+11 -8
View File
@@ -41,11 +41,11 @@
/*! HIST_count(): /*! HIST_count():
* Provides the precise count of each byte within a table 'count'. * Provides the precise count of each byte within a table 'count'.
* 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
* Updates *maxSymbolValuePtr with actual largest symbol value detected. * Updates *maxSymbolValuePtr with actual largest symbol value detected.
* @return : count of the most frequent symbol (which isn't identified). * @return : count of the most frequent symbol (which isn't identified).
* or an error code, which can be tested using HIST_isError(). * or an error code, which can be tested using HIST_isError().
* note : if return == srcSize, there is only one symbol. * note : if return == srcSize, there is only one symbol.
*/ */
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize); const void* src, size_t srcSize);
@@ -56,14 +56,16 @@ unsigned HIST_isError(size_t code); /**< tells if a return value is an error co
/* --- advanced histogram functions --- */ /* --- advanced histogram functions --- */
#define HIST_WKSP_SIZE_U32 1024 #define HIST_WKSP_SIZE_U32 1024
#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned))
/** HIST_count_wksp() : /** HIST_count_wksp() :
* Same as HIST_count(), but using an externally provided scratch buffer. * Same as HIST_count(), but using an externally provided scratch buffer.
* Benefit is this function will use very little stack space. * Benefit is this function will use very little stack space.
* `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32 * `workSpace` is a writable buffer which must be 4-bytes aligned,
* `workSpaceSize` must be >= HIST_WKSP_SIZE
*/ */
size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize, const void* src, size_t srcSize,
unsigned* workSpace); void* workSpace, size_t workSpaceSize);
/** HIST_countFast() : /** HIST_countFast() :
* same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr. * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr.
@@ -74,11 +76,12 @@ size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
/** HIST_countFast_wksp() : /** HIST_countFast_wksp() :
* Same as HIST_countFast(), but using an externally provided scratch buffer. * Same as HIST_countFast(), but using an externally provided scratch buffer.
* `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32 * `workSpace` is a writable buffer which must be 4-bytes aligned,
* `workSpaceSize` must be >= HIST_WKSP_SIZE
*/ */
size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
const void* src, size_t srcSize, const void* src, size_t srcSize,
unsigned* workSpace); void* workSpace, size_t workSpaceSize);
/*! HIST_count_simple() : /*! HIST_count_simple() :
* Same as HIST_countFast(), this function is unsafe, * Same as HIST_countFast(), this function is unsafe,
+21 -20
View File
@@ -610,13 +610,14 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0); return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
} }
typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
static size_t HUF_compressCTable_internal( static size_t HUF_compressCTable_internal(
BYTE* const ostart, BYTE* op, BYTE* const oend, BYTE* const ostart, BYTE* op, BYTE* const oend,
const void* src, size_t srcSize, const void* src, size_t srcSize,
unsigned singleStream, const HUF_CElt* CTable, const int bmi2) HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int bmi2)
{ {
size_t const cSize = singleStream ? size_t const cSize = (nbStreams==HUF_singleStream) ?
HUF_compress1X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2) : HUF_compress1X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2) :
HUF_compress4X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2); HUF_compress4X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2);
if (HUF_isError(cSize)) { return cSize; } if (HUF_isError(cSize)) { return cSize; }
@@ -635,14 +636,14 @@ typedef struct {
/* HUF_compress_internal() : /* HUF_compress_internal() :
* `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ * `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
static size_t HUF_compress_internal ( static size_t
void* dst, size_t dstSize, HUF_compress_internal (void* dst, size_t dstSize,
const void* src, size_t srcSize, const void* src, size_t srcSize,
unsigned maxSymbolValue, unsigned huffLog, unsigned maxSymbolValue, unsigned huffLog,
unsigned singleStream, HUF_nbStreams_e nbStreams,
void* workSpace, size_t wkspSize, void* workSpace, size_t wkspSize,
HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat, HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
const int bmi2) const int bmi2)
{ {
HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace; HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;
BYTE* const ostart = (BYTE*)dst; BYTE* const ostart = (BYTE*)dst;
@@ -651,7 +652,7 @@ static size_t HUF_compress_internal (
/* checks & inits */ /* checks & inits */
if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall); if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
if (!srcSize) return 0; /* Uncompressed */ if (!srcSize) return 0; /* Uncompressed */
if (!dstSize) return 0; /* cannot fit anything within dst budget */ if (!dstSize) return 0; /* cannot fit anything within dst budget */
if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */ if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
@@ -664,11 +665,11 @@ static size_t HUF_compress_internal (
if (preferRepeat && repeat && *repeat == HUF_repeat_valid) { if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
return HUF_compressCTable_internal(ostart, op, oend, return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize, src, srcSize,
singleStream, oldHufTable, bmi2); nbStreams, oldHufTable, bmi2);
} }
/* Scan input and build symbol stats */ /* Scan input and build symbol stats */
{ CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->count) ); { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) );
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */ if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
} }
@@ -683,7 +684,7 @@ static size_t HUF_compress_internal (
if (preferRepeat && repeat && *repeat != HUF_repeat_none) { if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
return HUF_compressCTable_internal(ostart, op, oend, return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize, src, srcSize,
singleStream, oldHufTable, bmi2); nbStreams, oldHufTable, bmi2);
} }
/* Build Huffman Tree */ /* Build Huffman Tree */
@@ -706,7 +707,7 @@ static size_t HUF_compress_internal (
if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) { if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
return HUF_compressCTable_internal(ostart, op, oend, return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize, src, srcSize,
singleStream, oldHufTable, bmi2); nbStreams, oldHufTable, bmi2);
} } } }
/* Use the new huffman table */ /* Use the new huffman table */
@@ -718,7 +719,7 @@ static size_t HUF_compress_internal (
} }
return HUF_compressCTable_internal(ostart, op, oend, return HUF_compressCTable_internal(ostart, op, oend,
src, srcSize, src, srcSize,
singleStream, table->CTable, bmi2); nbStreams, table->CTable, bmi2);
} }
@@ -728,7 +729,7 @@ size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
void* workSpace, size_t wkspSize) void* workSpace, size_t wkspSize)
{ {
return HUF_compress_internal(dst, dstSize, src, srcSize, return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, 1 /*single stream*/, maxSymbolValue, huffLog, HUF_singleStream,
workSpace, wkspSize, workSpace, wkspSize,
NULL, NULL, 0, 0 /*bmi2*/); NULL, NULL, 0, 0 /*bmi2*/);
} }
@@ -740,7 +741,7 @@ size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2) HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)
{ {
return HUF_compress_internal(dst, dstSize, src, srcSize, return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, 1 /*single stream*/, maxSymbolValue, huffLog, HUF_singleStream,
workSpace, wkspSize, hufTable, workSpace, wkspSize, hufTable,
repeat, preferRepeat, bmi2); repeat, preferRepeat, bmi2);
} }
@@ -762,7 +763,7 @@ size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
void* workSpace, size_t wkspSize) void* workSpace, size_t wkspSize)
{ {
return HUF_compress_internal(dst, dstSize, src, srcSize, return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, 0 /*4 streams*/, maxSymbolValue, huffLog, HUF_fourStreams,
workSpace, wkspSize, workSpace, wkspSize,
NULL, NULL, 0, 0 /*bmi2*/); NULL, NULL, 0, 0 /*bmi2*/);
} }
@@ -777,7 +778,7 @@ size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2) HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)
{ {
return HUF_compress_internal(dst, dstSize, src, srcSize, return HUF_compress_internal(dst, dstSize, src, srcSize,
maxSymbolValue, huffLog, 0 /* 4 streams */, maxSymbolValue, huffLog, HUF_fourStreams,
workSpace, wkspSize, workSpace, wkspSize,
hufTable, repeat, preferRepeat, bmi2); hufTable, repeat, preferRepeat, bmi2);
} }
+31 -21
View File
@@ -1679,7 +1679,8 @@ static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
ZSTD_strategy strategy, int disableLiteralCompression, ZSTD_strategy strategy, int disableLiteralCompression,
void* dst, size_t dstCapacity, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, const void* src, size_t srcSize,
U32* workspace, const int bmi2) void* workspace, size_t wkspSize,
const int bmi2)
{ {
size_t const minGain = ZSTD_minGain(srcSize, strategy); size_t const minGain = ZSTD_minGain(srcSize, strategy);
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
@@ -1708,9 +1709,9 @@ static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0; int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2); workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
if (repeat != HUF_repeat_none) { if (repeat != HUF_repeat_none) {
/* reused the existing table */ /* reused the existing table */
hType = set_repeat; hType = set_repeat;
@@ -2186,11 +2187,13 @@ static size_t ZSTD_encodeSequences(
sequences, nbSeq, longOffsets); sequences, nbSeq, longOffsets);
} }
MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr, MEM_STATIC size_t
ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
ZSTD_entropyCTables_t const* prevEntropy, ZSTD_entropyCTables_t const* prevEntropy,
ZSTD_entropyCTables_t* nextEntropy, ZSTD_entropyCTables_t* nextEntropy,
ZSTD_CCtx_params const* cctxParams, ZSTD_CCtx_params const* cctxParams,
void* dst, size_t dstCapacity, U32* workspace, void* dst, size_t dstCapacity,
void* workspace, size_t wkspSize,
const int bmi2) const int bmi2)
{ {
const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
@@ -2222,7 +2225,8 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
cctxParams->cParams.strategy, disableLiteralCompression, cctxParams->cParams.strategy, disableLiteralCompression,
op, dstCapacity, op, dstCapacity,
literals, litSize, literals, litSize,
workspace, bmi2); workspace, wkspSize,
bmi2);
if (ZSTD_isError(cSize)) if (ZSTD_isError(cSize))
return cSize; return cSize;
assert(cSize <= dstCapacity); assert(cSize <= dstCapacity);
@@ -2250,7 +2254,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
ZSTD_seqToCodes(seqStorePtr); ZSTD_seqToCodes(seqStorePtr);
/* build CTable for Literal Lengths */ /* build CTable for Literal Lengths */
{ U32 max = MaxLL; { U32 max = MaxLL;
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); /* can't fail */ size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
DEBUGLOG(5, "Building LL table"); DEBUGLOG(5, "Building LL table");
nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode; nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy); LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy);
@@ -2259,7 +2263,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype, { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL, count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable), prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
workspace, HUF_WORKSPACE_SIZE); workspace, wkspSize);
if (ZSTD_isError(countSize)) return countSize; if (ZSTD_isError(countSize)) return countSize;
if (LLtype == set_compressed) if (LLtype == set_compressed)
lastNCount = op; lastNCount = op;
@@ -2267,7 +2271,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
} } } }
/* build CTable for Offsets */ /* build CTable for Offsets */
{ U32 max = MaxOff; { U32 max = MaxOff;
size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); /* can't fail */ size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */ /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed; ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
DEBUGLOG(5, "Building OF table"); DEBUGLOG(5, "Building OF table");
@@ -2277,7 +2281,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype, { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable), prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
workspace, HUF_WORKSPACE_SIZE); workspace, wkspSize);
if (ZSTD_isError(countSize)) return countSize; if (ZSTD_isError(countSize)) return countSize;
if (Offtype == set_compressed) if (Offtype == set_compressed)
lastNCount = op; lastNCount = op;
@@ -2285,7 +2289,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
} } } }
/* build CTable for MatchLengths */ /* build CTable for MatchLengths */
{ U32 max = MaxML; { U32 max = MaxML;
size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); /* can't fail */ size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
DEBUGLOG(5, "Building ML table"); DEBUGLOG(5, "Building ML table");
nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode; nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy); MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy);
@@ -2293,7 +2297,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype, { size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML, count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable), prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
workspace, HUF_WORKSPACE_SIZE); workspace, wkspSize);
if (ZSTD_isError(countSize)) return countSize; if (ZSTD_isError(countSize)) return countSize;
if (MLtype == set_compressed) if (MLtype == set_compressed)
lastNCount = op; lastNCount = op;
@@ -2331,16 +2335,20 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
return op - ostart; return op - ostart;
} }
MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr, MEM_STATIC size_t
const ZSTD_entropyCTables_t* prevEntropy, ZSTD_compressSequences(seqStore_t* seqStorePtr,
ZSTD_entropyCTables_t* nextEntropy, const ZSTD_entropyCTables_t* prevEntropy,
const ZSTD_CCtx_params* cctxParams, ZSTD_entropyCTables_t* nextEntropy,
void* dst, size_t dstCapacity, const ZSTD_CCtx_params* cctxParams,
size_t srcSize, U32* workspace, int bmi2) void* dst, size_t dstCapacity,
size_t srcSize,
void* workspace, size_t wkspSize,
int bmi2)
{ {
size_t const cSize = ZSTD_compressSequences_internal( size_t const cSize = ZSTD_compressSequences_internal(
seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity, seqStorePtr, prevEntropy, nextEntropy, cctxParams,
workspace, bmi2); dst, dstCapacity,
workspace, wkspSize, bmi2);
if (cSize == 0) return 0; if (cSize == 0) return 0;
/* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block. /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
* Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block. * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
@@ -2495,7 +2503,9 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
&zc->appliedParams, &zc->appliedParams,
dst, dstCapacity, dst, dstCapacity,
srcSize, zc->entropyWorkspace, zc->bmi2); srcSize,
zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
zc->bmi2);
out: out:
if (!ZSTD_isError(cSize) && cSize != 0) { if (!ZSTD_isError(cSize) && cSize != 0) {
+4 -4
View File
@@ -437,7 +437,7 @@ static size_t writeHufHeader(U32* seed, HUF_CElt* hufTable, void* dst, size_t ds
U32 count[HUF_SYMBOLVALUE_MAX+1]; U32 count[HUF_SYMBOLVALUE_MAX+1];
/* Scan input and build symbol stats */ /* Scan input and build symbol stats */
{ size_t const largest = HIST_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, WKSP); { size_t const largest = HIST_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, WKSP, sizeof(WKSP));
assert(!HIST_isError(largest)); assert(!HIST_isError(largest));
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 0; } /* single symbol, rle */ if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 0; } /* single symbol, rle */
if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */ if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
@@ -836,7 +836,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr,
/* CTable for Literal Lengths */ /* CTable for Literal Lengths */
{ U32 max = MaxLL; { U32 max = MaxLL;
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, WKSP); /* cannot fail */ size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, WKSP, sizeof(WKSP)); /* cannot fail */
assert(!HIST_isError(mostFrequent)); assert(!HIST_isError(mostFrequent));
if (mostFrequent == nbSeq) { if (mostFrequent == nbSeq) {
/* do RLE if we have the chance */ /* do RLE if we have the chance */
@@ -868,7 +868,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr,
/* CTable for Offsets */ /* CTable for Offsets */
/* see Literal Lengths for descriptions of mode choices */ /* see Literal Lengths for descriptions of mode choices */
{ U32 max = MaxOff; { U32 max = MaxOff;
size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, WKSP); /* cannot fail */ size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, WKSP, sizeof(WKSP)); /* cannot fail */
assert(!HIST_isError(mostFrequent)); assert(!HIST_isError(mostFrequent));
if (mostFrequent == nbSeq) { if (mostFrequent == nbSeq) {
*op++ = ofCodeTable[0]; *op++ = ofCodeTable[0];
@@ -896,7 +896,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr,
/* CTable for MatchLengths */ /* CTable for MatchLengths */
/* see Literal Lengths for descriptions of mode choices */ /* see Literal Lengths for descriptions of mode choices */
{ U32 max = MaxML; { U32 max = MaxML;
size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, WKSP); /* cannot fail */ size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, WKSP, sizeof(WKSP)); /* cannot fail */
assert(!HIST_isError(mostFrequent)); assert(!HIST_isError(mostFrequent));
if (mostFrequent == nbSeq) { if (mostFrequent == nbSeq) {
*op++ = *mlCodeTable; *op++ = *mlCodeTable;