From 699f11b4f726c258e4589a446eb16428550e7e8c Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 17 Aug 2017 17:33:46 -0700
Subject: [PATCH 001/248] Create opaque parameter structure
---
lib/common/zstd_internal.h | 4 +++
lib/compress/zstd_compress.c | 52 ++++++++++++++++++++++++++----------
lib/zstd.h | 2 ++
3 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 1621bca61..ddafc7874 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -221,6 +221,10 @@ typedef struct seqDef_s {
U16 matchLength;
} seqDef;
+typedef struct ZSTD_CCtx_params_s {
+ ZSTD_compressionParameters cParams;
+ ZSTD_frameParameters fParams;
+} ZSTD_CCtx_params;
typedef struct {
seqDef* sequencesStart;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 998fb3d49..3de173a62 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -84,8 +84,8 @@ struct ZSTD_CCtx_s {
ZSTD_compressionStage_e stage;
U32 dictID;
int compressionLevel;
- ZSTD_parameters requestedParams;
- ZSTD_parameters appliedParams;
+ ZSTD_CCtx_params requestedParams;
+ ZSTD_CCtx_params appliedParams;
void* workSpace;
size_t workSpaceSize;
size_t blockSize;
@@ -202,7 +202,28 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
/* private API call, for dictBuilder only */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
-static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) { return cctx->appliedParams; }
+// TODO: get rid of this function
+static ZSTD_parameters ZSTD_getParamsFromCCtxParams(const ZSTD_CCtx_params cctxParams)
+{
+ ZSTD_parameters params;
+ params.cParams = cctxParams.cParams;
+ params.fParams = cctxParams.fParams;
+ return params;
+}
+
+// TODO: get rid of this function too
+static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
+ ZSTD_CCtx_params cctxParams;
+ memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ return cctxParams;
+}
+
+
+static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
+ return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
+}
/* older variant; will be deprecated */
size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
@@ -582,7 +603,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 ple
{
U32 const end = (U32)(cctx->nextSrc - cctx->base);
DEBUGLOG(5, "continue mode");
- cctx->appliedParams = params;
+ cctx->appliedParams = ZSTD_makeCCtxParamsFromParams(params);
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
cctx->consumedSrcSize = 0;
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
@@ -670,7 +691,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
} }
/* init params */
- zc->appliedParams = params;
+ zc->appliedParams = ZSTD_makeCCtxParamsFromParams(params);
zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
zc->consumedSrcSize = 0;
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
@@ -766,7 +787,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
- { ZSTD_parameters params = srcCCtx->appliedParams;
+ { ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(srcCCtx->appliedParams);
params.fParams = fParams;
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
ZSTDcrp_noMemset, zbuff);
@@ -2952,8 +2973,10 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
if (frame && (cctx->stage==ZSTDcs_init)) {
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
- cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
+ fhSize = ZSTD_writeFrameHeader(
+ dst, dstCapacity,
+ ZSTD_getParamsFromCCtxParams(cctx->appliedParams),
+ cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
if (ZSTD_isError(fhSize)) return fhSize;
dstCapacity -= fhSize;
dst = (char*)dst + fhSize;
@@ -3269,7 +3292,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
/* special case : empty frame */
if (cctx->stage == ZSTDcs_init) {
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, ZSTD_getParamsFromCCtxParams(cctx->appliedParams), 0, 0);
if (ZSTD_isError(fhSize)) return fhSize;
dstCapacity -= fhSize;
op += fhSize;
@@ -3545,7 +3568,8 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
if (cdict==NULL) return ERROR(dictionary_wrong);
- { ZSTD_parameters params = cdict->refContext->appliedParams;
+ { ZSTD_parameters params =
+ ZSTD_getParamsFromCCtxParams(cdict->refContext->appliedParams);
params.fParams = fParams;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
return ZSTD_compressBegin_internal(cctx,
@@ -3653,7 +3677,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
{
- ZSTD_parameters params = zcs->requestedParams;
+ ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(zcs->requestedParams);
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
DEBUGLOG(5, "ZSTD_resetCStream");
if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
@@ -3696,7 +3720,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
zcs->cdict = cdict;
}
- zcs->requestedParams = params;
+ zcs->requestedParams = ZSTD_makeCCtxParamsFromParams(params);
zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
}
@@ -3729,7 +3753,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
CHECK_F( ZSTD_checkCParams(params.cParams) );
- zcs->requestedParams = params;
+ zcs->requestedParams = ZSTD_makeCCtxParamsFromParams(params);
zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, pledgedSrcSize);
}
@@ -3943,7 +3967,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
if (cctx->streamStage == zcss_init) {
const void* const prefix = cctx->prefix;
size_t const prefixSize = cctx->prefixSize;
- ZSTD_parameters params = cctx->requestedParams;
+ ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(cctx->requestedParams);
if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
params.cParams = ZSTD_getCParams(cctx->compressionLevel,
cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
diff --git a/lib/zstd.h b/lib/zstd.h
index a2a756dfc..4b2f4a3b3 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -425,6 +425,8 @@ typedef struct {
ZSTD_frameParameters fParams;
} ZSTD_parameters;
+typedef struct ZSTD_CCtx_params_s ZSTD_CCtx_params;
+
/*= Custom memory allocation functions */
typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
From ade95b8bed67c48b8bd91f0503904ea93af8dcd0 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 17 Aug 2017 18:13:08 -0700
Subject: [PATCH 002/248] Add opaque interfaces for static initialization
---
lib/compress/zstd_compress.c | 150 ++++++++++++++++++++++++-----------
lib/zstd.h | 9 +++
2 files changed, 111 insertions(+), 48 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 3de173a62..b5bdf680e 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -220,6 +220,16 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
return cctxParams;
}
+// TODO: get rid of this function too
+static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
+ ZSTD_compressionParameters cParams)
+{
+ ZSTD_CCtx_params cctxParams;
+ memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ cctxParams.cParams = cParams;
+ return cctxParams;
+}
+
static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
@@ -537,29 +547,40 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
}
+size_t ZSTD_estimateCCtxSize_advanced_opaque(ZSTD_CCtx_params* params)
+{
+ if (params == NULL) { return 0; }
+ { ZSTD_compressionParameters cParams = params->cParams;
+ size_t const blockSize =
+ MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
+ U32 const divider = (cParams.searchLength==3) ? 3 : 4;
+ size_t const maxNbSeq = blockSize / divider;
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
+ size_t const chainSize =
+ (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
+ 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 = sizeof(ZSTD_entropyCTables_t);
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
+
+ size_t const optBudget =
+ ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
- size_t const h3Size = ((size_t)1) << hashLog3;
- 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<cParams;
+ size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced(cParams);
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
+ size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
+ size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
+ size_t const streamingSize = inBuffSize + outBuffSize;
+
+ return CCtxSize + streamingSize;
+ }
+}
+
size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams)
{
- size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced(cParams);
- size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
- size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
- size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
- size_t const streamingSize = inBuffSize + outBuffSize;
-
- return CCtxSize + streamingSize;
+ ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
+ return ZSTD_estimateCStreamSize_advanced_opaque(¶ms);
}
size_t ZSTD_estimateCStreamSize(int compressionLevel) {
@@ -3390,14 +3421,24 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
/* ===== Dictionary API ===== */
+size_t ZSTD_estimateCDictSize_advanced_opaque(
+ size_t dictSize, ZSTD_CCtx_params* params, unsigned byReference)
+{
+ if (params == NULL) { return 0; }
+ DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
+ DEBUGLOG(5, "CCtx estimate : %u",
+ (U32)ZSTD_estimateCCtxSize_advanced_opaque(params));
+ return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced_opaque(params)
+ + (byReference ? 0 : dictSize);
+
+}
+
/*! ZSTD_estimateCDictSize_advanced() :
* Estimate amount of memory that will be needed to create a dictionary with following arguments */
size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
{
- DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
- DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize_advanced(cParams));
- return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced(cParams)
- + (byReference ? 0 : dictSize);
+ ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
+ return ZSTD_estimateCDictSize_advanced_opaque(dictSize, ¶ms, byReference);
}
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
@@ -3510,24 +3551,12 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
}
}
-/*! ZSTD_initStaticCDict_advanced() :
- * Generate a digested dictionary in provided memory area.
- * workspace: The memory area to emplace the dictionary into.
- * Provided pointer must 8-bytes aligned.
- * It must outlive dictionary usage.
- * workspaceSize: Use ZSTD_estimateCDictSize()
- * to determine how large workspace must be.
- * cParams : use ZSTD_getCParams() to transform a compression level
- * into its relevants cParams.
- * @return : pointer to ZSTD_CDict*, or NULL if error (size too small)
- * Note : there is no corresponding "free" function.
- * Since workspace was allocated externally, it must be freed externally.
- */
-ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
- const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
- ZSTD_compressionParameters cParams)
+ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
+ void *workspace, size_t workspaceSize, const void* dict,
+ size_t dictSize, unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_CCtx_params* params)
{
+ ZSTD_compressionParameters cParams = params->cParams;
size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams);
size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize)
+ cctxSize;
@@ -3557,6 +3586,31 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
return cdict;
}
+/*! ZSTD_initStaticCDict_advanced() :
+ * Generate a digested dictionary in provided memory area.
+ * workspace: The memory area to emplace the dictionary into.
+ * Provided pointer must 8-bytes aligned.
+ * It must outlive dictionary usage.
+ * workspaceSize: Use ZSTD_estimateCDictSize()
+ * to determine how large workspace must be.
+ * cParams : use ZSTD_getCParams() to transform a compression level
+ * into its relevants cParams.
+ * @return : pointer to ZSTD_CDict*, or NULL if error (size too small)
+ * Note : there is no corresponding "free" function.
+ * Since workspace was allocated externally, it must be freed externally.
+ */
+ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
+ const void* dict, size_t dictSize,
+ unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_compressionParameters cParams)
+{
+ ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
+ return ZSTD_initStaticCDict_advanced_opaque(
+ workspace, workspaceSize, dict, dictSize,
+ byReference, dictMode, ¶ms);
+}
+
+
ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
return ZSTD_getParamsFromCCtx(cdict->refContext);
}
diff --git a/lib/zstd.h b/lib/zstd.h
index 4b2f4a3b3..2111c9de0 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -501,6 +501,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
+ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_opaque(ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
/*! ZSTD_estimate?StreamSize() :
@@ -517,6 +518,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* In this case, get total size by adding ZSTD_estimate?DictSize */
ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
+ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_opaque(ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
@@ -526,6 +528,7 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
+ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, ZSTD_CCtx_params* params, unsigned byReference);
ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
@@ -602,6 +605,12 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams);
+ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
+ void* workspace, size_t workspaceSize,
+ const void* dict, size_t dictSize,
+ unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_CCtx_params* params);
+
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */
From 4169f49171a6fa98baf5e62c5ff6aeb74d675fd9 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 17 Aug 2017 18:45:04 -0700
Subject: [PATCH 003/248] Add initialization/allocation functions for opaque
params
---
lib/compress/zstd_compress.c | 38 ++++++++++++++++++++++++++++++++++++
lib/zstd.h | 6 ++++++
2 files changed, 44 insertions(+)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index b5bdf680e..509f8bedc 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -230,6 +230,44 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
return cctxParams;
}
+ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
+{
+ ZSTD_CCtx_params* params =
+ (ZSTD_CCtx_params*)ZSTD_calloc(sizeof(ZSTD_CCtx_params),
+ ZSTD_defaultCMem);
+ if (!params) { return NULL; }
+ // TODO
+// params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
+ return params;
+}
+
+size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params,
+ ZSTD_compressionParameters cParams)
+{
+ CHECK_F( params == NULL );
+ memset(params, 0, sizeof(ZSTD_CCtx_params));
+ params->cParams = cParams;
+ return 0;
+}
+
+ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(
+ int compressionLevel, unsigned long long estimatedSrcSize,
+ size_t dictSize)
+{
+ ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
+ if (params == NULL) { return NULL; }
+ ZSTD_initCCtxParams(params, ZSTD_getCParams(
+ compressionLevel, estimatedSrcSize, dictSize));
+ return params;
+}
+
+size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
+{
+ ZSTD_free(params, ZSTD_defaultCMem);
+ return 0;
+}
+
+
static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
diff --git a/lib/zstd.h b/lib/zstd.h
index 2111c9de0..b847d01f2 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -611,6 +611,12 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_CCtx_params* params);
+ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
+ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params, ZSTD_compressionParameters cParams);
+ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
+
+
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */
From c0221124d5344bcfe727c23fae22cdd506915da6 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 17 Aug 2017 19:30:22 -0700
Subject: [PATCH 004/248] Add function to set opaque parameters
---
lib/common/zstd_internal.h | 2 +
lib/compress/zstd_compress.c | 189 +++++++++++++++++++++++++++--------
lib/zstd.h | 4 +
3 files changed, 156 insertions(+), 39 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index ddafc7874..7c806b87c 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -224,6 +224,8 @@ typedef struct seqDef_s {
typedef struct ZSTD_CCtx_params_s {
ZSTD_compressionParameters cParams;
ZSTD_frameParameters fParams;
+ int compressionLevel;
+
} ZSTD_CCtx_params;
typedef struct {
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 509f8bedc..a48184153 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -230,45 +230,6 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
return cctxParams;
}
-ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
-{
- ZSTD_CCtx_params* params =
- (ZSTD_CCtx_params*)ZSTD_calloc(sizeof(ZSTD_CCtx_params),
- ZSTD_defaultCMem);
- if (!params) { return NULL; }
- // TODO
-// params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
- return params;
-}
-
-size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params,
- ZSTD_compressionParameters cParams)
-{
- CHECK_F( params == NULL );
- memset(params, 0, sizeof(ZSTD_CCtx_params));
- params->cParams = cParams;
- return 0;
-}
-
-ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(
- int compressionLevel, unsigned long long estimatedSrcSize,
- size_t dictSize)
-{
- ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
- if (params == NULL) { return NULL; }
- ZSTD_initCCtxParams(params, ZSTD_getCParams(
- compressionLevel, estimatedSrcSize, dictSize));
- return params;
-}
-
-size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
-{
- ZSTD_free(params, ZSTD_defaultCMem);
- return 0;
-}
-
-
-
static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
}
@@ -296,6 +257,55 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
cctx->compressionLevel = ZSTD_CLEVEL_CUSTOM;
}
+ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
+{
+ ZSTD_CCtx_params* params =
+ (ZSTD_CCtx_params*)ZSTD_calloc(sizeof(ZSTD_CCtx_params),
+ ZSTD_defaultCMem);
+ if (!params) { return NULL; }
+ params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
+ return params;
+}
+
+size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params,
+ ZSTD_compressionParameters cParams)
+{
+ memset(params, 0, sizeof(ZSTD_CCtx_params));
+ params->cParams = cParams;
+ params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ return 0;
+}
+
+ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(
+ int compressionLevel, unsigned long long estimatedSrcSize,
+ size_t dictSize)
+{
+ ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
+ if (params == NULL) { return NULL; }
+ ZSTD_initCCtxParams(params, ZSTD_getCParams(
+ compressionLevel, estimatedSrcSize, dictSize));
+ params->compressionLevel = compressionLevel;
+ return params;
+}
+
+size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
+{
+ if (params == NULL) { return 0; }
+ ZSTD_free(params, ZSTD_defaultCMem);
+ return 0;
+}
+
+
+
+static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
+{
+ if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
+ // TODO: src size, code duplication
+ params->cParams = ZSTD_getCParams(params->compressionLevel, 0, 0);
+ params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+
+}
+
#define CLAMPCHECK(val,min,max) { \
if (((val)<(min)) | ((val)>(max))) { \
return ERROR(parameter_outOfBound); \
@@ -443,6 +453,107 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
}
}
+size_t ZSTD_CCtxParam_setParameter(
+ ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value)
+{
+ switch(param)
+ {
+ case ZSTD_p_compressionLevel :
+ if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel();
+ if (value == 0) return 0;
+ params->compressionLevel = value;
+ return 0;
+
+ case ZSTD_p_windowLog :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.windowLog = value;
+ return 0;
+
+ case ZSTD_p_hashLog :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.hashLog = value;
+ return 0;
+
+ case ZSTD_p_chainLog :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.chainLog = value;
+ return 0;
+
+ case ZSTD_p_searchLog :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.searchLog = value;
+ return 0;
+
+ case ZSTD_p_minMatch :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.searchLength = value;
+ return 0;
+
+ case ZSTD_p_targetLength :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.targetLength = value;
+ return 0;
+
+ case ZSTD_p_compressionStrategy :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.strategy = (ZSTD_strategy)value;
+ return 0;
+
+ case ZSTD_p_contentSizeFlag :
+ params->fParams.contentSizeFlag = value > 0;
+ return 0;
+
+ case ZSTD_p_checksumFlag :
+ params->fParams.checksumFlag = value > 0;
+ return 0;
+
+ case ZSTD_p_dictIDFlag :
+ params->fParams.noDictIDFlag = (value == 0);
+ return 0;
+
+ case ZSTD_p_dictMode :
+ ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
+ if (value > (unsigned)ZSTD_dm_fullDict) {
+ return ERROR(parameter_outOfBound);
+ }
+// cctx->dictMode = (ZSTD_dictMode_e)value;
+ return 0;
+
+ case ZSTD_p_refDictContent :
+// cctx->dictContentByRef = value > 0;
+ return 0;
+
+ case ZSTD_p_forceMaxWindow :
+// cctx->forceWindow = value > 0;
+ return 0;
+
+ case ZSTD_p_nbThreads :
+ return 0;
+
+ case ZSTD_p_jobSize :
+ return 0;
+
+ case ZSTD_p_overlapSizeLog :
+ return 0;
+
+ default: return ERROR(parameter_unsupported);
+ }
+}
+
ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
{
DEBUGLOG(5, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize);
diff --git a/lib/zstd.h b/lib/zstd.h
index b847d01f2..e428319d4 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -616,6 +616,8 @@ ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(int compressionLevel,
ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params, ZSTD_compressionParameters cParams);
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
+ZSTDLIB_API
+
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
@@ -1009,6 +1011,8 @@ typedef enum {
* @result : 0, or an error code (which can be tested with ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
+ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
+
/*! ZSTD_CCtx_setPledgedSrcSize() :
* Total input data size to be compressed as a single frame.
* This value will be controlled at the end, and result in error if not respected.
From 97e27affcbe26f89b52f16b1a1a0b5e8f924419a Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 11:20:08 -0700
Subject: [PATCH 005/248] Move compression level to cctx params
---
lib/compress/zstd_compress.c | 97 +++++++++++++++++++++++-------------
lib/zstd.h | 2 +
2 files changed, 64 insertions(+), 35 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index a48184153..1ffeb5565 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -83,7 +83,7 @@ struct ZSTD_CCtx_s {
U32 forceWindow; /* force back-references to respect limit of 1<customMem = customMem;
- cctx->compressionLevel = ZSTD_CLEVEL_DEFAULT;
+ cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
ZSTD_STATIC_ASSERT(zcss_init==0);
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
return cctx;
@@ -230,6 +230,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
return cctxParams;
}
+// TODO: get rid of this function
static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
}
@@ -251,10 +252,11 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
#define ZSTD_CLEVEL_CUSTOM 999
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
{
- if (cctx->compressionLevel==ZSTD_CLEVEL_CUSTOM) return;
- cctx->requestedParams.cParams = ZSTD_getCParams(cctx->compressionLevel,
- cctx->pledgedSrcSizePlusOne-1, 0);
- cctx->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ if (cctx->requestedParams.compressionLevel==ZSTD_CLEVEL_CUSTOM) return;
+ cctx->requestedParams.cParams =
+ ZSTD_getCParams(cctx->requestedParams.compressionLevel,
+ cctx->pledgedSrcSizePlusOne-1, 0);
+ cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
}
ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
@@ -321,7 +323,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel(); /* cap max compression level */
if (value == 0) return 0; /* special value : 0 means "don't change anything" */
if (cctx->cdict) return ERROR(stage_wrong);
- cctx->compressionLevel = value;
+ cctx->requestedParams.compressionLevel = value;
return 0;
case ZSTD_p_windowLog :
@@ -554,6 +556,13 @@ size_t ZSTD_CCtxParam_setParameter(
}
}
+ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
+{
+ (void)cctx;
+ (void)params;
+ return 0;
+}
+
ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
{
DEBUGLOG(5, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize);
@@ -573,9 +582,9 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
cctx->cdict = NULL;
} else {
ZSTD_compressionParameters const cParams =
- cctx->compressionLevel == ZSTD_CLEVEL_CUSTOM ?
+ cctx->requestedParams.compressionLevel == ZSTD_CLEVEL_CUSTOM ?
cctx->requestedParams.cParams :
- ZSTD_getCParams(cctx->compressionLevel, 0, dictSize);
+ ZSTD_getCParams(cctx->requestedParams.compressionLevel, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
cctx->dictContentByRef, cctx->dictMode,
@@ -779,11 +788,11 @@ static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
/*! ZSTD_continueCCtx() :
* reuse CCtx without reset (note : requires no dictionary) */
-static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 pledgedSrcSize)
+static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
{
U32 const end = (U32)(cctx->nextSrc - cctx->base);
DEBUGLOG(5, "continue mode");
- cctx->appliedParams = ZSTD_makeCCtxParamsFromParams(params);
+ cctx->appliedParams = params;
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
cctx->consumedSrcSize = 0;
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
@@ -808,7 +817,7 @@ typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
/*! ZSTD_resetCCtx_internal() :
note : `params` are assumed fully validated at this stage */
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
- ZSTD_parameters params, U64 pledgedSrcSize,
+ ZSTD_CCtx_params params, U64 pledgedSrcSize,
ZSTD_compResetPolicy_e const crp,
ZSTD_buffered_policy_e const zbuff)
{
@@ -871,7 +880,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
} }
/* init params */
- zc->appliedParams = ZSTD_makeCCtxParamsFromParams(params);
+ zc->appliedParams = params;
zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
zc->consumedSrcSize = 0;
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
@@ -967,7 +976,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
- { ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(srcCCtx->appliedParams);
+ { ZSTD_CCtx_params params = srcCCtx->appliedParams;
params.fParams = fParams;
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
ZSTDcrp_noMemset, zbuff);
@@ -3100,7 +3109,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
- ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
+ ZSTD_CCtx_params params, U64 pledgedSrcSize, U32 dictID)
{ BYTE* const op = (BYTE*)dst;
U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
U32 const dictIDSizeCode = params.fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
@@ -3155,7 +3164,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (frame && (cctx->stage==ZSTDcs_init)) {
fhSize = ZSTD_writeFrameHeader(
dst, dstCapacity,
- ZSTD_getParamsFromCCtxParams(cctx->appliedParams),
+ cctx->appliedParams,
cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
if (ZSTD_isError(fhSize)) return fhSize;
dstCapacity -= fhSize;
@@ -3206,7 +3215,8 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
{
- U32 const cLevel = cctx->compressionLevel;
+ // TODO: Applied params compression level okay? Gets overwritten
+ U32 const cLevel = cctx->appliedParams.compressionLevel;
ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
cctx->appliedParams.cParams :
ZSTD_getCParams(cLevel, 0, 0);
@@ -3409,7 +3419,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_dictMode_e dictMode,
const ZSTD_CDict* cdict,
- ZSTD_parameters params, U64 pledgedSrcSize,
+ ZSTD_CCtx_params params, U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff)
{
DEBUGLOG(4, "ZSTD_compressBegin_internal");
@@ -3437,18 +3447,21 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
+
+ ZSTD_CCtx_params cctxParams = cctx->requestedParams;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
/* compression parameters verification and optimization */
CHECK_F(ZSTD_checkCParams(params.cParams));
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
- params, pledgedSrcSize, ZSTDb_not_buffered);
+ cctxParams, pledgedSrcSize, ZSTDb_not_buffered);
}
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
- params, 0, ZSTDb_not_buffered);
+ return ZSTD_compressBegin_advanced(cctx, dict, dictSize, params, 0);
}
@@ -3472,7 +3485,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
/* special case : empty frame */
if (cctx->stage == ZSTDcs_init) {
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, ZSTD_getParamsFromCCtxParams(cctx->appliedParams), 0, 0);
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
if (ZSTD_isError(fhSize)) return fhSize;
dstCapacity -= fhSize;
op += fhSize;
@@ -3528,8 +3541,12 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
const void* dict,size_t dictSize,
ZSTD_parameters params)
{
+ ZSTD_CCtx_params cctxParams = cctx->requestedParams;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+
CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
- params, srcSize, ZSTDb_not_buffered) );
+ cctxParams, srcSize, ZSTDb_not_buffered) );
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
@@ -3634,10 +3651,14 @@ static size_t ZSTD_initCDict_internal(
{ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
+ ZSTD_CCtx_params cctxParams =
+ ZSTD_makeCCtxParamsFromParams(params);
+ cctxParams.compressionLevel =
+ cdict->refContext->requestedParams.compressionLevel;
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
cdict->dictContent, dictSize, dictMode,
NULL,
- params, ZSTD_CONTENTSIZE_UNKNOWN,
+ cctxParams, ZSTD_CONTENTSIZE_UNKNOWN,
ZSTDb_not_buffered) );
}
@@ -3764,6 +3785,10 @@ ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
return ZSTD_getParamsFromCCtx(cdict->refContext);
}
+static ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict) {
+ return cdict->refContext->appliedParams;
+}
+
/* ZSTD_compressBegin_usingCDict_advanced() :
* cdict must be != NULL */
size_t ZSTD_compressBegin_usingCDict_advanced(
@@ -3771,8 +3796,8 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
if (cdict==NULL) return ERROR(dictionary_wrong);
- { ZSTD_parameters params =
- ZSTD_getParamsFromCCtxParams(cdict->refContext->appliedParams);
+ {
+ ZSTD_CCtx_params params = cdict->refContext->appliedParams;
params.fParams = fParams;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
return ZSTD_compressBegin_internal(cctx,
@@ -3858,6 +3883,8 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
const ZSTD_CDict* cdict,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
+ ZSTD_CCtx_params cctxParams = ZSTD_makeCCtxParamsFromParams(params);
+ cctxParams.compressionLevel = zcs->requestedParams.compressionLevel;
DEBUGLOG(4, "ZSTD_resetCStream_internal");
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
@@ -3866,7 +3893,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
CHECK_F( ZSTD_compressBegin_internal(zcs,
dict, dictSize, dictMode,
cdict,
- params, pledgedSrcSize,
+ cctxParams, pledgedSrcSize,
ZSTDb_buffered) );
zcs->inToCompress = 0;
@@ -3883,8 +3910,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(zcs->requestedParams);
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
DEBUGLOG(5, "ZSTD_resetCStream");
- if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
- params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
+ if (zcs->requestedParams.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
+ params.cParams = ZSTD_getCParams(zcs->requestedParams.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
}
return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
}
@@ -3915,7 +3942,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
if (cdict) {
- ZSTD_parameters const cdictParams = ZSTD_getParamsFromCDict(cdict);
+ ZSTD_CCtx_params const cdictParams = ZSTD_getCCtxParamsFromCDict(cdict);
params.cParams = cdictParams.cParams; /* cParams are enforced from cdict */
}
ZSTD_freeCDict(zcs->cdictLocal);
@@ -3924,7 +3951,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
}
zcs->requestedParams = ZSTD_makeCCtxParamsFromParams(params);
- zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ zcs->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
}
@@ -3957,14 +3984,14 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
{
CHECK_F( ZSTD_checkCParams(params.cParams) );
zcs->requestedParams = ZSTD_makeCCtxParamsFromParams(params);
- zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ zcs->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, pledgedSrcSize);
}
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- zcs->compressionLevel = compressionLevel;
+ zcs->requestedParams.compressionLevel = compressionLevel;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, 0);
}
@@ -4171,8 +4198,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
const void* const prefix = cctx->prefix;
size_t const prefixSize = cctx->prefixSize;
ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(cctx->requestedParams);
- if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
- params.cParams = ZSTD_getCParams(cctx->compressionLevel,
+ if (cctx->requestedParams.compressionLevel != ZSTD_CLEVEL_CUSTOM)
+ params.cParams = ZSTD_getCParams(cctx->requestedParams.compressionLevel,
cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
cctx->prefix = NULL; cctx->prefixSize = 0; /* single usage */
assert(prefix==NULL || cctx->cdict==NULL); /* only one can be set */
diff --git a/lib/zstd.h b/lib/zstd.h
index e428319d4..e5ff0a38e 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -1013,6 +1013,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param
ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
+ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params);
+
/*! ZSTD_CCtx_setPledgedSrcSize() :
* Total input data size to be compressed as a single frame.
* This value will be controlled at the end, and result in error if not respected.
From b6cb2ed8cb6eaf57f7f8a1c967e6f8590a998205 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 11:43:31 -0700
Subject: [PATCH 006/248] Move dictMode to cctxParams
---
lib/common/zstd_internal.h | 2 +
lib/compress/zstd_compress.c | 76 +++++++++++++++++++++---------------
lib/zstd.h | 2 +-
3 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 7c806b87c..b1cbd05a7 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -225,6 +225,8 @@ typedef struct ZSTD_CCtx_params_s {
ZSTD_compressionParameters cParams;
ZSTD_frameParameters fParams;
int compressionLevel;
+ U32 forceWindow;
+ ZSTD_dictMode_e dictMode;
} ZSTD_CCtx_params;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 1ffeb5565..ada9d4f57 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -80,7 +80,7 @@ struct ZSTD_CCtx_s {
U32 nextToUpdate3; /* index from which to continue dictionary update */
U32 hashLog3; /* dispatch table : larger == faster, more memory */
U32 loadedDictEnd; /* index of end of dictionary */
- U32 forceWindow; /* force back-references to respect limit of 1<forceWindow = value>0; cctx->loadedDictEnd = 0; return 0;
+ case ZSTD_p_forceWindow :
+ cctx->requestedParams.forceWindow = value>0;
+ cctx->loadedDictEnd = 0;
+ return 0;
ZSTD_STATIC_ASSERT(ZSTD_dm_auto==0);
ZSTD_STATIC_ASSERT(ZSTD_dm_rawContent==1);
- case ZSTD_p_forceRawDict : cctx->dictMode = (ZSTD_dictMode_e)(value>0); return 0;
+ case ZSTD_p_forceRawDict :
+ cctx->requestedParams.dictMode = (ZSTD_dictMode_e)(value>0);
+ return 0;
default: return ERROR(parameter_unsupported);
}
}
@@ -407,7 +412,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
if (value > (unsigned)ZSTD_dm_fullDict)
return ERROR(parameter_outOfBound);
- cctx->dictMode = (ZSTD_dictMode_e)value;
+ cctx->requestedParams.dictMode = (ZSTD_dictMode_e)value;
return 0;
case ZSTD_p_refDictContent :
@@ -419,7 +424,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize,
* even when referencing into Dictionary content
* default : 0 when using a CDict, 1 when using a Prefix */
- cctx->forceWindow = value>0;
+ cctx->requestedParams.forceWindow = value>0;
cctx->loadedDictEnd = 0;
return 0;
@@ -532,7 +537,7 @@ size_t ZSTD_CCtxParam_setParameter(
if (value > (unsigned)ZSTD_dm_fullDict) {
return ERROR(parameter_outOfBound);
}
-// cctx->dictMode = (ZSTD_dictMode_e)value;
+ params->dictMode = (ZSTD_dictMode_e)value;
return 0;
case ZSTD_p_refDictContent :
@@ -540,7 +545,7 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_forceMaxWindow :
-// cctx->forceWindow = value > 0;
+ params->forceWindow = value > 0;
return 0;
case ZSTD_p_nbThreads :
@@ -587,7 +592,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
ZSTD_getCParams(cctx->requestedParams.compressionLevel, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- cctx->dictContentByRef, cctx->dictMode,
+ cctx->dictContentByRef, cctx->requestedParams.dictMode,
cParams, cctx->customMem);
cctx->cdict = cctx->cdictLocal;
if (cctx->cdictLocal == NULL)
@@ -3244,7 +3249,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
zc->dictBase = zc->base;
zc->base += ip - zc->nextSrc;
zc->nextToUpdate = zc->dictLimit;
- zc->loadedDictEnd = zc->forceWindow ? 0 : (U32)(iend - zc->base);
+ zc->loadedDictEnd = zc->appliedParams.forceWindow ? 0 : (U32)(iend - zc->base);
zc->nextSrc = iend;
if (srcSize <= HASH_READ_SIZE) return 0;
@@ -3417,14 +3422,13 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
* @return : 0, or an error code */
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
- ZSTD_dictMode_e dictMode,
const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff)
{
DEBUGLOG(4, "ZSTD_compressBegin_internal");
DEBUGLOG(4, "dict ? %s", dict ? "dict" : (cdict ? "cdict" : "none"));
- DEBUGLOG(4, "dictMode : %u", (U32)dictMode);
+ DEBUGLOG(4, "dictMode : %u", (U32)(params.dictMode));
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
@@ -3437,7 +3441,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
ZSTDcrp_continue, zbuff) );
- return ZSTD_compress_insertDictionary(cctx, dict, dictSize, dictMode);
+ return ZSTD_compress_insertDictionary(cctx, dict, dictSize, params.dictMode);
}
@@ -3451,9 +3455,10 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
ZSTD_CCtx_params cctxParams = cctx->requestedParams;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
+ cctxParams.dictMode = ZSTD_dm_auto;
/* compression parameters verification and optimization */
CHECK_F(ZSTD_checkCParams(params.cParams));
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
cctxParams, pledgedSrcSize, ZSTDb_not_buffered);
}
@@ -3544,8 +3549,9 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
ZSTD_CCtx_params cctxParams = cctx->requestedParams;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
+ cctxParams.dictMode = ZSTD_dm_auto;
- CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
+ CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
cctxParams, srcSize, ZSTDb_not_buffered) );
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
@@ -3621,6 +3627,7 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
}
+#if 0
static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_frameParameters fParams)
{
ZSTD_parameters params;
@@ -3628,6 +3635,7 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_
params.fParams = fParams;
return params;
}
+#endif
static size_t ZSTD_initCDict_internal(
ZSTD_CDict* cdict,
@@ -3650,13 +3658,12 @@ static size_t ZSTD_initCDict_internal(
{ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
- ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
- ZSTD_CCtx_params cctxParams =
- ZSTD_makeCCtxParamsFromParams(params);
- cctxParams.compressionLevel =
- cdict->refContext->requestedParams.compressionLevel;
+ ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
+ cctxParams.cParams = cParams;
+ cctxParams.fParams = fParams;
+ cctxParams.dictMode = dictMode;
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
- cdict->dictContent, dictSize, dictMode,
+ cdict->dictContent, dictSize,
NULL,
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN,
ZSTDb_not_buffered) );
@@ -3723,7 +3730,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void *workspace, size_t workspaceSize, const void* dict,
- size_t dictSize, unsigned byReference, ZSTD_dictMode_e dictMode,
+ size_t dictSize, unsigned byReference,
ZSTD_CCtx_params* params)
{
ZSTD_compressionParameters cParams = params->cParams;
@@ -3749,7 +3756,7 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dict, dictSize,
- 1 /* byReference */, dictMode,
+ 1 /* byReference */, params->dictMode,
cParams) ))
return NULL;
@@ -3775,9 +3782,10 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
ZSTD_compressionParameters cParams)
{
ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
+ params.dictMode = dictMode;
return ZSTD_initStaticCDict_advanced_opaque(
workspace, workspaceSize, dict, dictSize,
- byReference, dictMode, ¶ms);
+ byReference, ¶ms);
}
@@ -3799,9 +3807,10 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
{
ZSTD_CCtx_params params = cdict->refContext->appliedParams;
params.fParams = fParams;
+ params.dictMode = ZSTD_dm_auto;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
return ZSTD_compressBegin_internal(cctx,
- NULL, 0, ZSTD_dm_auto,
+ NULL, 0,
cdict,
params, pledgedSrcSize,
ZSTDb_not_buffered);
@@ -3885,13 +3894,14 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
{
ZSTD_CCtx_params cctxParams = ZSTD_makeCCtxParamsFromParams(params);
cctxParams.compressionLevel = zcs->requestedParams.compressionLevel;
+ cctxParams.dictMode = dictMode;
DEBUGLOG(4, "ZSTD_resetCStream_internal");
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
CHECK_F( ZSTD_compressBegin_internal(zcs,
- dict, dictSize, dictMode,
+ dict, dictSize,
cdict,
cctxParams, pledgedSrcSize,
ZSTDb_buffered) );
@@ -3913,7 +3923,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
if (zcs->requestedParams.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
params.cParams = ZSTD_getCParams(zcs->requestedParams.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
}
- return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict, params, pledgedSrcSize);
}
/*! ZSTD_initCStream_internal() :
@@ -3936,7 +3946,8 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
}
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- zcs->dictContentByRef, zcs->dictMode,
+ zcs->dictContentByRef,
+ zcs->requestedParams.dictMode,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
@@ -3949,10 +3960,11 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
zcs->cdictLocal = NULL;
zcs->cdict = cdict;
}
-
- zcs->requestedParams = ZSTD_makeCCtxParamsFromParams(params);
+ zcs->requestedParams.cParams = params.cParams;
+ zcs->requestedParams.fParams = params.fParams;
zcs->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
- return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
+
+ return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict, params, pledgedSrcSize);
}
/* ZSTD_initCStream_usingCDict_advanced() :
@@ -4212,7 +4224,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
} else
#endif
{
- CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->requestedParams.dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
} }
/* compression stage */
diff --git a/lib/zstd.h b/lib/zstd.h
index e5ff0a38e..be3d7c4cc 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -608,7 +608,7 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ unsigned byReference,
ZSTD_CCtx_params* params);
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
From 2300c58a6f2fd98b9fbf602cfae4d868b38ab87a Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 12:03:16 -0700
Subject: [PATCH 007/248] Move dictContentByRef to cctx params
---
lib/common/zstd_internal.h | 5 +++++
lib/compress/zstd_compress.c | 33 ++++++++++++++++++++-------------
lib/zstd.h | 5 +++--
3 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index b1cbd05a7..f7359646e 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -224,9 +224,14 @@ typedef struct seqDef_s {
typedef struct ZSTD_CCtx_params_s {
ZSTD_compressionParameters cParams;
ZSTD_frameParameters fParams;
+
int compressionLevel;
U32 forceWindow;
+
+ /* Dictionary */
ZSTD_dictMode_e dictMode;
+ U32 dictContentByRef;
+
} ZSTD_CCtx_params;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index ada9d4f57..7802df507 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -117,7 +117,7 @@ struct ZSTD_CCtx_s {
/* Dictionary */
// ZSTD_dictMode_e dictMode; /* select restricting dictionary to "rawContent" or "fullDict" only */
- U32 dictContentByRef;
+// U32 dictContentByRef;
ZSTD_CDict* cdictLocal;
const ZSTD_CDict* cdict;
const void* prefix;
@@ -418,7 +418,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_refDictContent :
if (cctx->cdict) return ERROR(stage_wrong); /* must be set before loading */
/* dictionary content will be referenced, instead of copied */
- cctx->dictContentByRef = value>0;
+ cctx->requestedParams.dictContentByRef = value>0;
return 0;
case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize,
@@ -541,7 +541,7 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_refDictContent :
-// cctx->dictContentByRef = value > 0;
+ params->dictContentByRef = value > 0;
return 0;
case ZSTD_p_forceMaxWindow :
@@ -549,12 +549,15 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_nbThreads :
+ // TODO
return 0;
case ZSTD_p_jobSize :
+ // TODO
return 0;
case ZSTD_p_overlapSizeLog :
+ // TODO
return 0;
default: return ERROR(parameter_unsupported);
@@ -592,7 +595,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
ZSTD_getCParams(cctx->requestedParams.compressionLevel, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- cctx->dictContentByRef, cctx->requestedParams.dictMode,
+ cctx->requestedParams.dictContentByRef,
+ cctx->requestedParams.dictMode,
cParams, cctx->customMem);
cctx->cdict = cctx->cdictLocal;
if (cctx->cdictLocal == NULL)
@@ -3594,14 +3598,14 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
/* ===== Dictionary API ===== */
size_t ZSTD_estimateCDictSize_advanced_opaque(
- size_t dictSize, ZSTD_CCtx_params* params, unsigned byReference)
+ size_t dictSize, ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
DEBUGLOG(5, "CCtx estimate : %u",
(U32)ZSTD_estimateCCtxSize_advanced_opaque(params));
return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced_opaque(params)
- + (byReference ? 0 : dictSize);
+ + (params->dictContentByRef ? 0 : dictSize);
}
@@ -3610,7 +3614,8 @@ size_t ZSTD_estimateCDictSize_advanced_opaque(
size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
{
ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
- return ZSTD_estimateCDictSize_advanced_opaque(dictSize, ¶ms, byReference);
+ params.dictContentByRef = byReference;
+ return ZSTD_estimateCDictSize_advanced_opaque(dictSize, ¶ms);
}
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
@@ -3662,6 +3667,8 @@ static size_t ZSTD_initCDict_internal(
cctxParams.cParams = cParams;
cctxParams.fParams = fParams;
cctxParams.dictMode = dictMode;
+ cctxParams.dictContentByRef = byReference;
+
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
cdict->dictContent, dictSize,
NULL,
@@ -3730,12 +3737,12 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void *workspace, size_t workspaceSize, const void* dict,
- size_t dictSize, unsigned byReference,
+ size_t dictSize,
ZSTD_CCtx_params* params)
{
ZSTD_compressionParameters cParams = params->cParams;
size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams);
- size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize)
+ size_t const neededSize = sizeof(ZSTD_CDict) + (params->dictContentByRef ? 0 : dictSize)
+ cctxSize;
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
void* ptr;
@@ -3745,7 +3752,7 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
(U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
if (workspaceSize < neededSize) return NULL;
- if (!byReference) {
+ if (!params->dictContentByRef) {
memcpy(cdict+1, dict, dictSize);
dict = cdict+1;
ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
@@ -3783,12 +3790,12 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
{
ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
params.dictMode = dictMode;
+ params.dictContentByRef = byReference;
return ZSTD_initStaticCDict_advanced_opaque(
workspace, workspaceSize, dict, dictSize,
- byReference, ¶ms);
+ ¶ms);
}
-
ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
return ZSTD_getParamsFromCCtx(cdict->refContext);
}
@@ -3946,7 +3953,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
}
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- zcs->dictContentByRef,
+ zcs->requestedParams.dictContentByRef,
zcs->requestedParams.dictMode,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
diff --git a/lib/zstd.h b/lib/zstd.h
index be3d7c4cc..56316160a 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -528,7 +528,9 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
-ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, ZSTD_CCtx_params* params, unsigned byReference);
+
+// By reference
+ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
@@ -608,7 +610,6 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference,
ZSTD_CCtx_params* params);
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
From 81d89d82a69681567934d7f48c2dfb8a9ca409d8 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 12:08:57 -0700
Subject: [PATCH 008/248] Move nbThreads to cctx params
---
lib/common/zstd_internal.h | 2 ++
lib/compress/zstd_compress.c | 27 ++++++++++++++++-----------
2 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index f7359646e..7ea2ecc47 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -232,6 +232,8 @@ typedef struct ZSTD_CCtx_params_s {
ZSTD_dictMode_e dictMode;
U32 dictContentByRef;
+ /* Multithreading */
+ U32 nbThreads;
} ZSTD_CCtx_params;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 7802df507..e47ae9a1e 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -124,7 +124,7 @@ struct ZSTD_CCtx_s {
size_t prefixSize;
/* Multi-threading */
- U32 nbThreads;
+// U32 nbThreads;
ZSTDMT_CCtx* mtctx;
};
@@ -434,25 +434,25 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
#ifndef ZSTD_MULTITHREAD
if (value > 1) return ERROR(parameter_unsupported);
#endif
- if ((value>1) && (cctx->nbThreads != value)) {
+ if ((value>1) && (cctx->requestedParams.nbThreads != value)) {
if (cctx->staticSize) /* MT not compatible with static alloc */
return ERROR(parameter_unsupported);
ZSTDMT_freeCCtx(cctx->mtctx);
- cctx->nbThreads = 1;
+ cctx->requestedParams.nbThreads = 1;
cctx->mtctx = ZSTDMT_createCCtx_advanced(value, cctx->customMem);
if (cctx->mtctx == NULL) return ERROR(memory_allocation);
}
- cctx->nbThreads = value;
+ cctx->requestedParams.nbThreads = value;
return 0;
case ZSTD_p_jobSize:
- if (cctx->nbThreads <= 1) return ERROR(parameter_unsupported);
+ if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
assert(cctx->mtctx != NULL);
return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_sectionSize, value);
case ZSTD_p_overlapSizeLog:
- DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->nbThreads);
- if (cctx->nbThreads <= 1) return ERROR(parameter_unsupported);
+ DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->requestedParams.nbThreads);
+ if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
assert(cctx->mtctx != NULL);
return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
@@ -549,7 +549,12 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_nbThreads :
- // TODO
+ if (value == 0) { return 0; }
+#ifndef ZSTD_MULTITHREAD
+ if (value > 1) return ERROR(parameter_unsupported);
+#endif
+ // Do checks when applying parameters to cctx.
+ params->nbThreads = value;
return 0;
case ZSTD_p_jobSize :
@@ -4224,8 +4229,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
assert(prefix==NULL || cctx->cdict==NULL); /* only one can be set */
#ifdef ZSTD_MULTITHREAD
- if (cctx->nbThreads > 1) {
- DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", cctx->nbThreads);
+ if (cctx->requestedParams.nbThreads > 1) {
+ DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", cctx->requestedParams.nbThreads);
CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
cctx->streamStage = zcss_load;
} else
@@ -4236,7 +4241,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
/* compression stage */
#ifdef ZSTD_MULTITHREAD
- if (cctx->nbThreads > 1) {
+ if (cctx->requestedParams.nbThreads > 1) {
size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
DEBUGLOG(5, "ZSTDMT_compressStream_generic : %u", (U32)flushMin);
if ( ZSTD_isError(flushMin)
From 399ae013d4028bb197b14b183cb91b53742884f6 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 13:01:55 -0700
Subject: [PATCH 009/248] Add function to apply cctx params
---
lib/common/zstd_internal.h | 34 ++++++++++++++++++----------------
lib/compress/zstd_compress.c | 29 +++++++++++++++++++++++++----
2 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 7ea2ecc47..fa9f0c49c 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -221,22 +221,6 @@ typedef struct seqDef_s {
U16 matchLength;
} seqDef;
-typedef struct ZSTD_CCtx_params_s {
- ZSTD_compressionParameters cParams;
- ZSTD_frameParameters fParams;
-
- int compressionLevel;
- U32 forceWindow;
-
- /* Dictionary */
- ZSTD_dictMode_e dictMode;
- U32 dictContentByRef;
-
- /* Multithreading */
- U32 nbThreads;
-
-} ZSTD_CCtx_params;
-
typedef struct {
seqDef* sequencesStart;
seqDef* sequences;
@@ -251,6 +235,24 @@ typedef struct {
U32 repToConfirm[ZSTD_REP_NUM];
} seqStore_t;
+struct ZSTD_CCtx_params_s {
+ ZSTD_compressionParameters cParams;
+ ZSTD_frameParameters fParams;
+
+ int compressionLevel;
+
+ U32 forceWindow; /* force back-references to respect limit of 1<nbThreads <= 1) { return ERROR(parameter_unsupported); }
+ params->jobSize = value;
return 0;
case ZSTD_p_overlapSizeLog :
- // TODO
+ params->overlapSizeLog = value;
return 0;
default: return ERROR(parameter_unsupported);
}
}
+// This function should probably be updated whenever ZSTD_CCtx_params is updated.
ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
{
- (void)cctx;
- (void)params;
+ if (cctx->cdict) { return ERROR(stage_wrong); }
+
+ /* Assume the compression and frame parameters are validated */
+ cctx->requestedParams.cParams = params->cParams;
+ cctx->requestedParams.fParams = params->fParams;
+ cctx->requestedParams.compressionLevel = params->compressionLevel;
+
+ /* Assume dictionary parameters are validated */
+ cctx->requestedParams.dictMode = params->dictMode;
+ cctx->requestedParams.dictContentByRef = params->dictContentByRef;
+
+ /* Set force window explicitly since it sets cctx->loadedDictEnd */
+ CHECK_F( ZSTD_CCtx_setParameter(
+ cctx, ZSTD_p_forceMaxWindow, params->forceWindow) );
+
+ /* Set multithreading parameters explicitly */
+ CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbThreads, params->nbThreads) );
+ CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_jobSize, params->jobSize) );
+ CHECK_F( ZSTD_CCtx_setParameter(
+ cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
return 0;
}
From 63b8c985317b38e69b69fa69f4727e8d55ce2cb4 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 16:17:24 -0700
Subject: [PATCH 010/248] Pass cctx parameters to MTCtx
---
lib/compress/zstd_compress.c | 108 ++++++++++++++++++++++++---------
lib/compress/zstdmt_compress.c | 107 +++++++++++++++++++++++---------
lib/compress/zstdmt_compress.h | 9 +++
3 files changed, 165 insertions(+), 59 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 426636cfc..b63519d9a 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -213,7 +213,7 @@ static ZSTD_parameters ZSTD_getParamsFromCCtxParams(const ZSTD_CCtx_params cctxP
}
// TODO: get rid of this function too
-static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
+ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
ZSTD_CCtx_params cctxParams;
memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
cctxParams.cParams = params.cParams;
@@ -3474,6 +3474,17 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
return ZSTD_compress_insertDictionary(cctx, dict, dictSize, params.dictMode);
}
+size_t ZSTD_compressBegin_advanced_opaque(ZSTD_CCtx* cctx,
+ const void* dict, size_t dictSize,
+ ZSTD_CCtx_params params,
+ unsigned long long pledgedSrcSize)
+{
+ /* compression parameters verification and optimization */
+ CHECK_F( ZSTD_checkCParams(params.cParams) );
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
+ params, pledgedSrcSize,
+ ZSTDb_not_buffered);
+}
/*! ZSTD_compressBegin_advanced() :
* @return : 0, or an error code */
@@ -3481,15 +3492,13 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
-
ZSTD_CCtx_params cctxParams = cctx->requestedParams;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
cctxParams.dictMode = ZSTD_dm_auto;
- /* compression parameters verification and optimization */
- CHECK_F(ZSTD_checkCParams(params.cParams));
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
- cctxParams, pledgedSrcSize, ZSTDb_not_buffered);
+
+ return ZSTD_compressBegin_advanced_opaque(cctx, dict, dictSize, cctxParams,
+ pledgedSrcSize);
}
@@ -3580,10 +3589,11 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
cctxParams.dictMode = ZSTD_dm_auto;
-
- CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
- cctxParams, srcSize, ZSTDb_not_buffered) );
- return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
+ return ZSTD_compress_advanced_opaque(cctx,
+ dst, dstCapacity,
+ src, srcSize,
+ dict, dictSize,
+ cctxParams);
}
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
@@ -3596,6 +3606,18 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
}
+/* Internal */
+size_t ZSTD_compress_advanced_opaque(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_CCtx_params params)
+{
+ CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
+ params, srcSize, ZSTDb_not_buffered) );
+ return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
+}
+
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
const void* dict, size_t dictSize, int compressionLevel)
{
@@ -3920,14 +3942,13 @@ size_t ZSTD_CStreamOutSize(void)
return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
}
-static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
- const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
+static size_t ZSTD_resetCStream_internal_opaque(
+ ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params cctxParams = ZSTD_makeCCtxParamsFromParams(params);
- cctxParams.compressionLevel = zcs->requestedParams.compressionLevel;
- cctxParams.dictMode = dictMode;
+ params.dictMode = dictMode;
DEBUGLOG(4, "ZSTD_resetCStream_internal");
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
@@ -3936,7 +3957,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
CHECK_F( ZSTD_compressBegin_internal(zcs,
dict, dictSize,
cdict,
- cctxParams, pledgedSrcSize,
+ params, pledgedSrcSize,
ZSTDb_buffered) );
zcs->inToCompress = 0;
@@ -3948,6 +3969,19 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
return 0; /* ready to go */
}
+static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
+ const ZSTD_CDict* cdict,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ ZSTD_CCtx_params cctxParams = zcs->requestedParams;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ cctxParams.dictMode = dictMode;
+ return ZSTD_resetCStream_internal_opaque(zcs, dict, dictSize, dictMode,
+ cdict, cctxParams, pledgedSrcSize);
+}
+
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
{
ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(zcs->requestedParams);
@@ -3959,13 +3993,11 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict, params, pledgedSrcSize);
}
-/*! ZSTD_initCStream_internal() :
- * Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
- * Assumption 1 : params are valid
- * Assumption 2 : either dict, or cdict, is defined, not both */
-size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
+size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params,
+ unsigned long long pledgedSrcSize)
{
DEBUGLOG(5, "ZSTD_initCStream_internal");
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
@@ -3993,11 +4025,28 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
zcs->cdictLocal = NULL;
zcs->cdict = cdict;
}
- zcs->requestedParams.cParams = params.cParams;
- zcs->requestedParams.fParams = params.fParams;
- zcs->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ zcs->requestedParams = params;
- return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal_opaque(
+ zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict,
+ params, pledgedSrcSize);
+}
+
+
+/*! ZSTD_initCStream_internal() :
+ * Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
+ * Assumption 1 : params are valid
+ * Assumption 2 : either dict, or cdict, is defined, not both */
+size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ ZSTD_CCtx_params cctxParams = zcs->requestedParams;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, cdict,
+ cctxParams, pledgedSrcSize);
}
/* ZSTD_initCStream_usingCDict_advanced() :
@@ -4227,7 +4276,6 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
ZSTD_parameters params, unsigned long long pledgedSrcSize);
-
size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
ZSTD_outBuffer* output,
ZSTD_inBuffer* input,
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 234ced9de..2eb714e60 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -186,6 +186,14 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_free(buf.start, bufPool->cMem);
}
+static void ZSTDMT_zeroCCtxParams(ZSTD_CCtx_params* params)
+{
+ params->forceWindow = 0;
+ params->dictMode = (ZSTD_dictMode_e)(0);
+ params->nbThreads = 0;
+ params->jobSize = 0;
+ params->overlapSizeLog = 0;
+}
/* ===== CCtx Pool ===== */
/* a single CCtx Pool can be invoked from multiple threads in parallel */
@@ -292,7 +300,7 @@ typedef struct {
unsigned jobScanned;
pthread_mutex_t* jobCompleted_mutex;
pthread_cond_t* jobCompleted_cond;
- ZSTD_parameters params;
+ ZSTD_CCtx_params params;
const ZSTD_CDict* cdict;
ZSTDMT_CCtxPool* cctxPool;
ZSTDMT_bufferPool* bufPool;
@@ -330,7 +338,7 @@ void ZSTDMT_compressChunk(void* jobDescription)
} else { /* srcStart points at reloaded section */
if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
{ size_t const dictModeError = ZSTD_setCCtxParameter(cctx, ZSTD_p_forceRawDict, 1); /* Force loading dictionary in "content-only" mode (no header analysis) */
- size_t const initError = ZSTD_compressBegin_advanced(cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
+ size_t const initError = ZSTD_compressBegin_advanced_opaque(cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
if (ZSTD_isError(initError) || ZSTD_isError(dictModeError)) { job->cSize = initError; goto _endJob; }
ZSTD_setCCtxParameter(cctx, ZSTD_p_forceWindow, 1);
} }
@@ -382,7 +390,7 @@ struct ZSTDMT_CCtx_s {
size_t dictSize;
size_t targetDictSize;
inBuff_t inBuff;
- ZSTD_parameters params;
+ ZSTD_CCtx_params params;
XXH64_state_t xxhState;
unsigned nbThreads;
unsigned jobIDMask;
@@ -528,17 +536,17 @@ static unsigned computeNbChunks(size_t srcSize, unsigned windowLog, unsigned nbT
return (multiplier>1) ? nbChunksLarge : nbChunksSmall;
}
-
-size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const ZSTD_CDict* cdict,
- ZSTD_parameters const params,
- unsigned overlapLog)
+static size_t ZSTDMT_compress_advanced_opaque(
+ ZSTDMT_CCtx* mtctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params const cctxParams,
+ unsigned overlapLog)
{
unsigned const overlapRLog = (overlapLog>9) ? 0 : 9-overlapLog;
- size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (params.cParams.windowLog - overlapRLog);
- unsigned nbChunks = computeNbChunks(srcSize, params.cParams.windowLog, mtctx->nbThreads);
+ size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (cctxParams.cParams.windowLog - overlapRLog);
+ unsigned nbChunks = computeNbChunks(srcSize, cctxParams.cParams.windowLog, mtctx->nbThreads);
size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0x7FFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */
const char* const srcStart = (const char*)src;
@@ -546,12 +554,15 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */
size_t frameStartPos = 0, dstBufferPos = 0;
XXH64_state_t xxh64;
+ ZSTD_CCtx_params requestedParams = cctxParams;
+ ZSTDMT_zeroCCtxParams(&requestedParams);
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
- if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, params.fParams);
- return ZSTD_compress_advanced(cctx, dst, dstCapacity, src, srcSize, NULL, 0, params);
+
+ if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, cctxParams.fParams);
+ return ZSTD_compress_advanced_opaque(cctx, dst, dstCapacity, src, srcSize, NULL, 0, requestedParams);
}
assert(avgChunkSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), which is required for compressWithinDst */
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgChunkSize) );
@@ -580,7 +591,7 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
mtctx->jobs[u].srcSize = chunkSize;
mtctx->jobs[u].cdict = mtctx->nextJobID==0 ? cdict : NULL;
mtctx->jobs[u].fullFrameSize = srcSize;
- mtctx->jobs[u].params = params;
+ mtctx->jobs[u].params = requestedParams;
/* do not calculate checksum within sections, but write it in header for first section */
if (u!=0) mtctx->jobs[u].params.fParams.checksumFlag = 0;
mtctx->jobs[u].dstBuff = dstBuffer;
@@ -592,7 +603,7 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex;
mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond;
- if (params.fParams.checksumFlag) {
+ if (cctxParams.fParams.checksumFlag) {
XXH64_update(&xxh64, srcStart + frameStartPos, chunkSize);
}
@@ -636,7 +647,7 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
} /* for (chunkID=0; chunkID dstCapacity) {
error = ERROR(dstSize_tooSmall);
@@ -649,6 +660,23 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos);
return error ? error : dstPos;
}
+
+}
+
+size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_parameters const params,
+ unsigned overlapLog)
+{
+ ZSTD_CCtx_params cctxParams = mtctx->params;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ return ZSTDMT_compress_advanced_opaque(mtctx,
+ dst, dstCapacity,
+ src, srcSize,
+ cdict, cctxParams, overlapLog);
}
@@ -683,23 +711,28 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs)
}
}
-
-/** ZSTDMT_initCStream_internal() :
- * internal usage only */
-size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
- const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
+size_t ZSTDMT_initCStream_internal_opaque(
+ ZSTDMT_CCtx* zcs, const void* dict, size_t dictSize,
+ const ZSTD_CDict* cdict, ZSTD_CCtx_params cctxParams,
+ unsigned long long pledgedSrcSize)
{
+ ZSTD_parameters params;
+ params.cParams = cctxParams.cParams;
+ params.fParams = cctxParams.fParams;
+
DEBUGLOG(4, "ZSTDMT_initCStream_internal");
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
+ /* TODO: Set stuff to 0 to preserve old semantics. */
+ ZSTDMT_zeroCCtxParams(&cctxParams);
+
if (zcs->nbThreads==1) {
DEBUGLOG(4, "single thread mode");
- return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0],
- dict, dictSize, cdict,
- params, pledgedSrcSize);
+ return ZSTD_initCStream_internal_opaque(zcs->cctxPool->cctx[0],
+ dict, dictSize, cdict,
+ cctxParams, pledgedSrcSize);
}
if (zcs->allJobsCompleted == 0) { /* previous compression not correctly finished */
@@ -708,7 +741,7 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
zcs->allJobsCompleted = 1;
}
- zcs->params = params;
+ zcs->params = cctxParams;
zcs->frameContentSize = pledgedSrcSize;
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
@@ -742,6 +775,21 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
zcs->allJobsCompleted = 0;
if (params.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
return 0;
+
+}
+
+
+/** ZSTDMT_initCStream_internal() :
+ * internal usage only */
+size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
+ const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ ZSTD_CCtx_params cctxParams = zcs->params;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ return ZSTDMT_initCStream_internal_opaque(zcs, dict, dictSize, cdict,
+ cctxParams, pledgedSrcSize);
}
size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
@@ -772,7 +820,8 @@ size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize)
{
if (zcs->nbThreads==1)
return ZSTD_resetCStream(zcs->cctxPool->cctx[0], pledgedSrcSize);
- return ZSTDMT_initCStream_internal(zcs, NULL, 0, 0, zcs->params, pledgedSrcSize);
+ return ZSTDMT_initCStream_internal_opaque(zcs, NULL, 0, 0, zcs->params,
+ pledgedSrcSize);
}
size_t ZSTDMT_initCStream(ZSTDMT_CCtx* zcs, int compressionLevel) {
@@ -930,7 +979,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
&& (mtctx->inBuff.filled==0) /* nothing buffered */
&& (endOp==ZSTD_e_end) /* end order */
&& (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough room */
- size_t const cSize = ZSTDMT_compress_advanced(mtctx,
+ size_t const cSize = ZSTDMT_compress_advanced_opaque(mtctx,
(char*)output->dst + output->pos, output->size - output->pos,
(const char*)input->src + input->pos, input->size - input->pos,
mtctx->cdict, mtctx->params, mtctx->overlapLog);
diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
index 843a240aa..0b478b735 100644
--- a/lib/compress/zstdmt_compress.h
+++ b/lib/compress/zstdmt_compress.h
@@ -69,6 +69,15 @@ ZSTDLIB_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
const ZSTD_CDict* cdict,
ZSTD_parameters const params,
unsigned overlapLog);
+#if 0
+ZSTDLIB_API size_t ZSTDMT_compress_advanced_opaque(
+ ZSTDMT_CCtx* mtctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params* const params,
+ unsigned overlapLog);
+#endif
ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
const void* dict, size_t dictSize, /* dict can be released after init, a local copy is preserved within zcs */
From d77551929654d35bf46ebad1f0ebd6f0e31b6ccf Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 17:37:58 -0700
Subject: [PATCH 011/248] Add cctxParam versions of internal functions
---
lib/common/zstd_internal.h | 23 ++++-
lib/compress/zstd_compress.c | 169 +++++++++++++++++++--------------
lib/compress/zstdmt_compress.c | 8 +-
3 files changed, 122 insertions(+), 78 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index fa9f0c49c..0da950787 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -351,10 +351,11 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
* @return : 0, or an error code */
-size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize,
- const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize);
+size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params,
+ unsigned long long pledgedSrcSize);
/*! ZSTD_compressStream_generic() :
* Private use only. To be called from zstdmt_compress.c in single-thread mode. */
@@ -365,8 +366,20 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
/*! ZSTD_getParamsFromCDict() :
* as the name implies */
-ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict);
+ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict);
+/* INTERNAL */
+size_t ZSTD_compressBegin_advanced_opaque(ZSTD_CCtx* cctx,
+ const void* dict, size_t dictSize,
+ ZSTD_CCtx_params params,
+ unsigned long long pledgedSrcSize);
+
+/* INTERNAL */
+size_t ZSTD_compress_advanced_opaque(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_CCtx_params params);
typedef struct {
blockType_e blockType;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index b63519d9a..434f40562 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -203,6 +203,7 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
/* private API call, for dictBuilder only */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
+#if 0
// TODO: get rid of this function
static ZSTD_parameters ZSTD_getParamsFromCCtxParams(const ZSTD_CCtx_params cctxParams)
{
@@ -211,15 +212,18 @@ static ZSTD_parameters ZSTD_getParamsFromCCtxParams(const ZSTD_CCtx_params cctxP
params.fParams = cctxParams.fParams;
return params;
}
+#endif
+#if 0
// TODO: get rid of this function too
-ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
+static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
ZSTD_CCtx_params cctxParams;
memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
return cctxParams;
}
+#endif
// TODO: get rid of this function too
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
@@ -230,11 +234,12 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
cctxParams.cParams = cParams;
return cctxParams;
}
-
+#if 0
// TODO: get rid of this function
static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
}
+#endif
/* older variant; will be deprecated */
size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
@@ -292,7 +297,7 @@ ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(
if (params == NULL) { return NULL; }
ZSTD_initCCtxParams(params, ZSTD_getCParams(
compressionLevel, estimatedSrcSize, dictSize));
- params->compressionLevel = compressionLevel;
+ params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
return params;
}
@@ -786,10 +791,9 @@ size_t ZSTD_estimateCStreamSize_advanced_opaque(ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
{
- ZSTD_compressionParameters cParams = params->cParams;
- size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced(cParams);
- size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
- size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
+ size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
+ size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
size_t const streamingSize = inBuffSize + outBuffSize;
@@ -808,9 +812,8 @@ size_t ZSTD_estimateCStreamSize(int compressionLevel) {
return ZSTD_estimateCStreamSize_advanced(cParams);
}
-
-static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
- ZSTD_compressionParameters cParams2)
+static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
+ ZSTD_compressionParameters cParams2)
{
U32 bslog1 = MIN(cParams1.windowLog, ZSTD_BLOCKSIZELOG_MAX);
U32 bslog2 = MIN(cParams2.windowLog, ZSTD_BLOCKSIZELOG_MAX);
@@ -821,6 +824,13 @@ static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
& ((cParams1.searchLength==3) == (cParams2.searchLength==3)); /* hashlog3 space */
}
+/** Equivalence for resetCCtx purposes */
+static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
+ ZSTD_CCtx_params params2)
+{
+ return ZSTD_equivalentCParams(params1.cParams, params2.cParams);
+}
+
/*! ZSTD_continueCCtx() :
* reuse CCtx without reset (note : requires no dictionary) */
static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
@@ -859,8 +869,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
if (crp == ZSTDcrp_continue) {
- if (ZSTD_equivalentParams(params.cParams, zc->appliedParams.cParams)) {
- DEBUGLOG(5, "ZSTD_equivalentParams()==1");
+ if (ZSTD_equivalentParams(params, zc->appliedParams)) {
+ DEBUGLOG(5, "ZSTD_equivalentCParams()==1");
zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
zc->entropy->offcode_repeatMode = FSE_repeat_none;
zc->entropy->matchlength_repeatMode = FSE_repeat_none;
@@ -3255,6 +3265,7 @@ size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
cctx->appliedParams.cParams :
ZSTD_getCParams(cLevel, 0, 0);
+ DEBUGLOG(2, "ZSTD_getBlockSize: cLevel %u\n", cLevel);
return MIN (ZSTD_BLOCKSIZE_MAX, 1 << cParams.windowLog);
}
@@ -3490,7 +3501,8 @@ size_t ZSTD_compressBegin_advanced_opaque(ZSTD_CCtx* cctx,
* @return : 0, or an error code */
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
+ ZSTD_parameters params,
+ unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params cctxParams = cctx->requestedParams;
cctxParams.cParams = params.cParams;
@@ -3618,8 +3630,11 @@ size_t ZSTD_compress_advanced_opaque(ZSTD_CCtx* cctx,
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
-size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
- const void* dict, size_t dictSize, int compressionLevel)
+size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst,
+ size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict, size_t dictSize,
+ int compressionLevel)
{
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0);
params.fParams.contentSizeFlag = 1;
@@ -3690,14 +3705,12 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_
}
#endif
-static size_t ZSTD_initCDict_internal(
- ZSTD_CDict* cdict,
- const void* dictBuffer, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
- ZSTD_compressionParameters cParams)
+static size_t ZSTD_initCDict_internal_opaque(ZSTD_CDict* cdict,
+ const void* dictBuffer, size_t dictSize,
+ ZSTD_CCtx_params params)
{
- DEBUGLOG(5, "ZSTD_initCDict_internal, mode %u", (U32)dictMode);
- if ((byReference) || (!dictBuffer) || (!dictSize)) {
+ DEBUGLOG(5, "ZSTD_initCDict_internal_opaque, mode %u", (U32)params.dictMode);
+ if ((params.dictContentByRef) || (!dictBuffer) || (!dictSize)) {
cdict->dictBuffer = NULL;
cdict->dictContent = dictBuffer;
} else {
@@ -3709,21 +3722,30 @@ static size_t ZSTD_initCDict_internal(
}
cdict->dictContentSize = dictSize;
- { ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
+ /* Frame parameters should be zero? */
+ CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
+ cdict->dictContent, dictSize,
+ NULL,
+ params, ZSTD_CONTENTSIZE_UNKNOWN,
+ ZSTDb_not_buffered) );
+ return 0;
+}
+
+static size_t ZSTD_initCDict_internal(
+ ZSTD_CDict* cdict,
+ const void* dictBuffer, size_t dictSize,
+ unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_compressionParameters cParams)
+{
+ ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
+ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
- ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
- cctxParams.cParams = cParams;
- cctxParams.fParams = fParams;
- cctxParams.dictMode = dictMode;
- cctxParams.dictContentByRef = byReference;
-
- CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
- cdict->dictContent, dictSize,
- NULL,
- cctxParams, ZSTD_CONTENTSIZE_UNKNOWN,
- ZSTDb_not_buffered) );
- }
-
+ cctxParams.cParams = cParams;
+ cctxParams.fParams = fParams;
+ cctxParams.dictMode = dictMode;
+ cctxParams.dictContentByRef = byReference;
+ CHECK_F (ZSTD_initCDict_internal_opaque(
+ cdict, dictBuffer, dictSize, cctxParams) );
return 0;
}
@@ -3788,8 +3810,7 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
size_t dictSize,
ZSTD_CCtx_params* params)
{
- ZSTD_compressionParameters cParams = params->cParams;
- size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams);
+ size_t const cctxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
size_t const neededSize = sizeof(ZSTD_CDict) + (params->dictContentByRef ? 0 : dictSize)
+ cctxSize;
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
@@ -3808,11 +3829,9 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
ptr = cdict+1;
}
cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
+ params->dictContentByRef = 1;
- if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
- dict, dictSize,
- 1 /* byReference */, params->dictMode,
- cParams) ))
+ if (ZSTD_isError( ZSTD_initCDict_internal_opaque(cdict, dict, dictSize, *params) ))
return NULL;
return cdict;
@@ -3843,12 +3862,13 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
workspace, workspaceSize, dict, dictSize,
¶ms);
}
-
-ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
+#if 0
+static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
return ZSTD_getParamsFromCCtx(cdict->refContext);
-}
+}a
+#endif
-static ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict) {
+ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict) {
return cdict->refContext->appliedParams;
}
@@ -3969,6 +3989,7 @@ static size_t ZSTD_resetCStream_internal_opaque(
return 0; /* ready to go */
}
+#if 0
static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
const ZSTD_CDict* cdict,
@@ -3981,16 +4002,17 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
return ZSTD_resetCStream_internal_opaque(zcs, dict, dictSize, dictMode,
cdict, cctxParams, pledgedSrcSize);
}
+#endif
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
{
- ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(zcs->requestedParams);
+ ZSTD_CCtx_params params = zcs->requestedParams;
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
DEBUGLOG(5, "ZSTD_resetCStream");
- if (zcs->requestedParams.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
- params.cParams = ZSTD_getCParams(zcs->requestedParams.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
+ if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
+ params.cParams = ZSTD_getCParams(params.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
}
- return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal_opaque(zcs, NULL, 0, params.dictMode, zcs->cdict, params, pledgedSrcSize);
}
size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
@@ -4032,12 +4054,12 @@ size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
params, pledgedSrcSize);
}
-
+#if 0
/*! ZSTD_initCStream_internal() :
* Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
* Assumption 1 : params are valid
* Assumption 2 : either dict, or cdict, is defined, not both */
-size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
+static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
@@ -4048,6 +4070,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, cdict,
cctxParams, pledgedSrcSize);
}
+#endif
/* ZSTD_initCStream_usingCDict_advanced() :
* same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
@@ -4057,9 +4080,10 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
unsigned long long pledgedSrcSize)
{ /* cannot handle NULL cdict (does not know what to do) */
if (!cdict) return ERROR(dictionary_wrong);
- { ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
+ { ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
params.fParams = fParams;
- return ZSTD_initCStream_internal(zcs,
+ params.compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ return ZSTD_initCStream_internal_opaque(zcs,
NULL, 0, cdict,
params, pledgedSrcSize);
}
@@ -4076,30 +4100,34 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
+ ZSTD_CCtx_params cctxParams = zcs->requestedParams;
CHECK_F( ZSTD_checkCParams(params.cParams) );
- zcs->requestedParams = ZSTD_makeCCtxParamsFromParams(params);
+ zcs->requestedParams.cParams = params.cParams;
+ zcs->requestedParams.fParams = params.fParams;
zcs->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
- return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, pledgedSrcSize);
+ return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
}
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- zcs->requestedParams.compressionLevel = compressionLevel;
- return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, 0);
+ ZSTD_CCtx_params cctxParams = zcs->requestedParams;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ cctxParams.compressionLevel = compressionLevel;
+ return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, NULL, cctxParams, 0);
}
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
{
ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
params.fParams.contentSizeFlag = (pledgedSrcSize>0);
- return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, params, pledgedSrcSize);
+ return ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize);
}
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
{
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
- return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, params, 0);
+ return ZSTD_initCStream_srcSize(zcs, compressionLevel, 0);
}
/*====== Compression ======*/
@@ -4272,9 +4300,9 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
* @return : 0, or an error code */
-size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
+size_t ZSTDMT_initCStream_internal_opaque(ZSTDMT_CCtx* zcs,
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize);
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
ZSTD_outBuffer* output,
@@ -4290,22 +4318,23 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
if (cctx->streamStage == zcss_init) {
const void* const prefix = cctx->prefix;
size_t const prefixSize = cctx->prefixSize;
- ZSTD_parameters params = ZSTD_getParamsFromCCtxParams(cctx->requestedParams);
- if (cctx->requestedParams.compressionLevel != ZSTD_CLEVEL_CUSTOM)
- params.cParams = ZSTD_getCParams(cctx->requestedParams.compressionLevel,
+ ZSTD_CCtx_params params = cctx->requestedParams;
+
+ if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM)
+ params.cParams = ZSTD_getCParams(params.compressionLevel,
cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
cctx->prefix = NULL; cctx->prefixSize = 0; /* single usage */
assert(prefix==NULL || cctx->cdict==NULL); /* only one can be set */
#ifdef ZSTD_MULTITHREAD
- if (cctx->requestedParams.nbThreads > 1) {
- DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", cctx->requestedParams.nbThreads);
- CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ if (params.nbThreads > 1) {
+ DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
+ CHECK_F( ZSTDMT_initCStream_internal_opaque(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
cctx->streamStage = zcss_load;
} else
#endif
{
- CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->requestedParams.dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTD_resetCStream_internal_opaque(cctx, prefix, prefixSize, params.dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
} }
/* compression stage */
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 2eb714e60..ea5828f35 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -806,11 +806,13 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
+ ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
+ ZSTDMT_zeroCCtxParams(¶ms);
params.fParams = fParams;
- return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
- params, pledgedSrcSize);
+
+ return ZSTDMT_initCStream_internal_opaque(mtctx, NULL, 0 /*dictSize*/, cdict,
+ params, pledgedSrcSize);
}
From 6cee6e07e5a7e049527b9a32d5a1386d7debb66f Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 18 Aug 2017 22:48:31 -0700
Subject: [PATCH 012/248] Add internal createCDict function
---
lib/compress/zstd_compress.c | 43 ++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 434f40562..4f10aedf4 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3731,6 +3731,7 @@ static size_t ZSTD_initCDict_internal_opaque(ZSTD_CDict* cdict,
return 0;
}
+#if 0
static size_t ZSTD_initCDict_internal(
ZSTD_CDict* cdict,
const void* dictBuffer, size_t dictSize,
@@ -3748,11 +3749,52 @@ static size_t ZSTD_initCDict_internal(
cdict, dictBuffer, dictSize, cctxParams) );
return 0;
}
+#endif
+
+ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
+ const void* dictBuffer, size_t dictSize,
+ ZSTD_CCtx_params params, ZSTD_customMem customMem)
+{
+ DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
+ if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+
+ { ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
+ ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
+ /* Initialize to 0 to preserve semantics */
+ ZSTD_frameParameters const fParams = { 0, 0, 0 };
+ params.fParams = fParams;
+
+ if (!cdict || !cctx) {
+ ZSTD_free(cdict, customMem);
+ ZSTD_freeCCtx(cctx);
+ return NULL;
+ }
+ cdict->refContext = cctx;
+
+
+ if (ZSTD_isError( ZSTD_initCDict_internal_opaque(
+ cdict,
+ dictBuffer, dictSize,
+ params) )) {
+ ZSTD_freeCDict(cdict);
+ return NULL;
+ }
+ return cdict;
+ }
+}
+
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
{
+ ZSTD_CCtx_params cctxParams = ZSTD_makeCCtxParamsFromCParams(cParams);
+ ZSTD_frameParameters const fParams = { 0, 0, 0 };
+ cctxParams.fParams = fParams;
+ cctxParams.dictMode = dictMode;
+ cctxParams.dictContentByRef = byReference;
+ return ZSTD_createCDict_advanced_opaque(dictBuffer, dictSize, cctxParams, customMem);
+#if 0
DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
@@ -3776,6 +3818,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
return cdict;
}
+#endif
}
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
From 023b24e6d4491d9aa8ed6aba4ed43cff2ea61b34 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Sun, 20 Aug 2017 22:55:07 -0700
Subject: [PATCH 013/248] Add cctx param tests
---
lib/common/zstd_internal.h | 5 +-
lib/compress/zstd_compress.c | 230 ++++++++++--------------
lib/compress/zstdmt_compress.c | 4 +-
lib/zstd.h | 10 +-
programs/Makefile | 3 +-
programs/fileio.c | 5 +
programs/zstdcli.c | 1 +
tests/Makefile | 8 +-
tests/fullbench.c | 5 +
tests/roundTripCrashOpaque.c | 203 ++++++++++++++++++++++
tests/zstreamtest.c | 309 ++++++++++++++++++++++++++++++++-
11 files changed, 639 insertions(+), 144 deletions(-)
create mode 100644 tests/roundTripCrashOpaque.c
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 0da950787..1cccca286 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -246,11 +246,14 @@ struct ZSTD_CCtx_params_s {
/* Dictionary */
ZSTD_dictMode_e dictMode; /* select restricting dictionary to "rawContent" or "fullDict" only */
U32 dictContentByRef;
- U32 nbThreads;
/* Multithreading: used only to set mtctx parameters */
+ U32 nbThreads;
unsigned jobSize;
unsigned overlapSizeLog;
+
+ /* Test parameter */
+ U32 testParam;
};
typedef struct {
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 4f10aedf4..051a848a5 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -261,6 +261,7 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
#define ZSTD_CLEVEL_CUSTOM 999
+#if 0
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
{
if (cctx->requestedParams.compressionLevel==ZSTD_CLEVEL_CUSTOM) return;
@@ -269,6 +270,7 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
cctx->pledgedSrcSizePlusOne-1, 0);
cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
}
+#endif
ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
{
@@ -280,6 +282,14 @@ ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
return params;
}
+size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
+{
+ if (!params) { return ERROR(GENERIC); }
+ memset(params, 0, sizeof(ZSTD_CCtx_params));
+ params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
+ return 0;
+}
+
size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params,
ZSTD_compressionParameters cParams)
{
@@ -330,102 +340,27 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
switch(param)
{
- case ZSTD_p_compressionLevel :
- if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel(); /* cap max compression level */
+ case ZSTD_p_compressionLevel:
+ case ZSTD_p_windowLog:
+ case ZSTD_p_hashLog:
+ case ZSTD_p_chainLog:
+ case ZSTD_p_searchLog:
+ case ZSTD_p_minMatch:
+ case ZSTD_p_targetLength:
+ case ZSTD_p_compressionStrategy:
if (value == 0) return 0; /* special value : 0 means "don't change anything" */
if (cctx->cdict) return ERROR(stage_wrong);
- cctx->requestedParams.compressionLevel = value;
- return 0;
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
- case ZSTD_p_windowLog :
- DEBUGLOG(5, "setting ZSTD_p_windowLog = %u (cdict:%u)",
- value, (cctx->cdict!=NULL));
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.windowLog = value;
- return 0;
+ case ZSTD_p_contentSizeFlag:
+ case ZSTD_p_checksumFlag:
+ case ZSTD_p_dictIDFlag:
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
- case ZSTD_p_hashLog :
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.hashLog = value;
- return 0;
-
- case ZSTD_p_chainLog :
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.chainLog = value;
- return 0;
-
- case ZSTD_p_searchLog :
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.searchLog = value;
- return 0;
-
- case ZSTD_p_minMatch :
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.searchLength = value;
- return 0;
-
- case ZSTD_p_targetLength :
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.targetLength = value;
- return 0;
-
- case ZSTD_p_compressionStrategy :
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
- if (cctx->cdict) return ERROR(stage_wrong);
- CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
- ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.strategy = (ZSTD_strategy)value;
- return 0;
-
- case ZSTD_p_contentSizeFlag :
- DEBUGLOG(5, "set content size flag = %u", (value>0));
- /* Content size written in frame header _when known_ (default:1) */
- cctx->requestedParams.fParams.contentSizeFlag = value>0;
- return 0;
-
- case ZSTD_p_checksumFlag :
- /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
- cctx->requestedParams.fParams.checksumFlag = value>0;
- return 0;
-
- case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
- DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
- cctx->requestedParams.fParams.noDictIDFlag = (value==0);
- return 0;
-
- /* Dictionary parameters */
- case ZSTD_p_dictMode :
+ case ZSTD_p_dictMode:
+ case ZSTD_p_refDictContent:
if (cctx->cdict) return ERROR(stage_wrong); /* must be set before loading */
- /* restrict dictionary mode, to "rawContent" or "fullDict" only */
- ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
- if (value > (unsigned)ZSTD_dm_fullDict)
- return ERROR(parameter_outOfBound);
- cctx->requestedParams.dictMode = (ZSTD_dictMode_e)value;
- return 0;
-
- case ZSTD_p_refDictContent :
- if (cctx->cdict) return ERROR(stage_wrong); /* must be set before loading */
- /* dictionary content will be referenced, instead of copied */
- cctx->requestedParams.dictContentByRef = value>0;
- return 0;
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize,
* even when referencing into Dictionary content
@@ -462,6 +397,11 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
assert(cctx->mtctx != NULL);
return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
+ case ZSTD_p_test :
+ DEBUGLOG(2, "Setting test parameter = %u", value);
+ cctx->requestedParams.testParam = (value > 0);
+ return 0;
+
default: return ERROR(parameter_unsupported);
}
}
@@ -527,14 +467,18 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_contentSizeFlag :
+ /* Content size written in frame header _when known_ (default:1) */
+ DEBUGLOG(5, "set content size flag = %u", (value>0));
params->fParams.contentSizeFlag = value > 0;
return 0;
case ZSTD_p_checksumFlag :
+ /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
params->fParams.checksumFlag = value > 0;
return 0;
case ZSTD_p_dictIDFlag :
+ DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
params->fParams.noDictIDFlag = (value == 0);
return 0;
@@ -559,7 +503,7 @@ size_t ZSTD_CCtxParam_setParameter(
#ifndef ZSTD_MULTITHREAD
if (value > 1) return ERROR(parameter_unsupported);
#endif
- // Do checks when applying parameters to cctx.
+ /* Do checks when applying params to cctx */
params->nbThreads = value;
return 0;
@@ -569,18 +513,57 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_overlapSizeLog :
+ if (params->nbThreads <= 1) { return ERROR(parameter_unsupported); }
params->overlapSizeLog = value;
return 0;
+ case ZSTD_p_test :
+ DEBUGLOG(2, "setting opaque: ZSTD_p_test: %u", value);
+ params->testParam = (value > 0);
+ return 0;
+
default: return ERROR(parameter_unsupported);
}
}
+static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
+{
+ DEBUGLOG(2, "======CCtxParams======");
+ DEBUGLOG(2, "cParams: %u %u %u %u %u %u %u",
+ params->cParams.windowLog,
+ params->cParams.chainLog,
+ params->cParams.hashLog,
+ params->cParams.searchLog,
+ params->cParams.searchLength,
+ params->cParams.targetLength,
+ params->cParams.strategy);
+ DEBUGLOG(2, "fParams: %u %u %u",
+ params->fParams.contentSizeFlag,
+ params->fParams.checksumFlag,
+ params->fParams.noDictIDFlag);
+ DEBUGLOG(2, "cLevel, forceWindow: %u %u",
+ params->compressionLevel,
+ params->forceWindow);
+ DEBUGLOG(2, "dictionary: %u %u",
+ params->dictMode,
+ params->dictContentByRef);
+ DEBUGLOG(2, "multithreading: %u %u %u",
+ params->nbThreads,
+ params->jobSize,
+ params->overlapSizeLog);
+ DEBUGLOG(2, "testParam: %u",
+ params->testParam);
+}
+
// This function should probably be updated whenever ZSTD_CCtx_params is updated.
ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
{
+ if (params == NULL) { return ERROR(GENERIC); }
if (cctx->cdict) { return ERROR(stage_wrong); }
+ DEBUGLOG(2, "Applying cctx params\n");
+ ZSTD_debugPrintCCtxParams(params);
+
/* Assume the compression and frame parameters are validated */
cctx->requestedParams.cParams = params->cParams;
cctx->requestedParams.fParams = params->fParams;
@@ -596,9 +579,14 @@ ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params*
/* Set multithreading parameters explicitly */
CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_nbThreads, params->nbThreads) );
- CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_jobSize, params->jobSize) );
- CHECK_F( ZSTD_CCtx_setParameter(
+ if (params->nbThreads > 1) {
+ CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_jobSize, params->jobSize) );
+ CHECK_F( ZSTD_CCtx_setParameter(
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
+
+ }
+ /* Copy test parameter */
+ cctx->requestedParams.testParam = params->testParam;
return 0;
}
@@ -790,8 +778,7 @@ size_t ZSTD_estimateCCtxSize(int compressionLevel)
size_t ZSTD_estimateCStreamSize_advanced_opaque(ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
- {
- size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
+ { size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
@@ -3265,7 +3252,6 @@ size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
cctx->appliedParams.cParams :
ZSTD_getCParams(cLevel, 0, 0);
- DEBUGLOG(2, "ZSTD_getBlockSize: cLevel %u\n", cLevel);
return MIN (ZSTD_BLOCKSIZE_MAX, 1 << cParams.windowLog);
}
@@ -3485,7 +3471,8 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
return ZSTD_compress_insertDictionary(cctx, dict, dictSize, params.dictMode);
}
-size_t ZSTD_compressBegin_advanced_opaque(ZSTD_CCtx* cctx,
+size_t ZSTD_compressBegin_advanced_opaque(
+ ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize)
@@ -3619,11 +3606,12 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
}
/* Internal */
-size_t ZSTD_compress_advanced_opaque(ZSTD_CCtx* cctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const void* dict,size_t dictSize,
- ZSTD_CCtx_params params)
+size_t ZSTD_compress_advanced_opaque(
+ ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_CCtx_params params)
{
CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
params, srcSize, ZSTDb_not_buffered) );
@@ -3751,11 +3739,11 @@ static size_t ZSTD_initCDict_internal(
}
#endif
-ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
+static ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
const void* dictBuffer, size_t dictSize,
ZSTD_CCtx_params params, ZSTD_customMem customMem)
{
- DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
+ DEBUGLOG(5, "ZSTD_createCDict_advanced_opaque, mode %u", (U32)params.dictMode);
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
@@ -3794,31 +3782,6 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
cctxParams.dictMode = dictMode;
cctxParams.dictContentByRef = byReference;
return ZSTD_createCDict_advanced_opaque(dictBuffer, dictSize, cctxParams, customMem);
-#if 0
- DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
-
- { ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
- ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
-
- if (!cdict || !cctx) {
- ZSTD_free(cdict, customMem);
- ZSTD_freeCCtx(cctx);
- return NULL;
- }
- cdict->refContext = cctx;
-
- if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
- dictBuffer, dictSize,
- byReference, dictMode,
- cParams) )) {
- ZSTD_freeCDict(cdict);
- return NULL;
- }
-
- return cdict;
- }
-#endif
}
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
@@ -4064,7 +4027,6 @@ size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize)
{
- DEBUGLOG(5, "ZSTD_initCStream_internal");
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
@@ -4145,9 +4107,9 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
{
ZSTD_CCtx_params cctxParams = zcs->requestedParams;
CHECK_F( ZSTD_checkCParams(params.cParams) );
- zcs->requestedParams.cParams = params.cParams;
- zcs->requestedParams.fParams = params.fParams;
- zcs->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
}
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index ea5828f35..1296cd316 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -62,7 +62,7 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void)
DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
elapsedTime, #mutex); \
} } \
- } else pthread_mutex_lock(mutex); \
+ } else { pthread_mutex_lock(mutex); } \
}
#else
@@ -646,7 +646,7 @@ static size_t ZSTDMT_compress_advanced_opaque(
}
} /* for (chunkID=0; chunkID dstCapacity) {
diff --git a/lib/zstd.h b/lib/zstd.h
index 56316160a..eb2a857fe 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -498,6 +498,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ * TODO: ZSTD_estimateCCtxSize_advanced_opaque()
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
@@ -509,6 +510,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ * TODO: ZSTD_estimateCStreamSize_advanced_opaque
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.
* This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -525,11 +527,10 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
/*! ZSTD_estimate?DictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
* ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
+ * TODO: ZSTD_estimateCDictSize_advanced_opaque(), can set by reference
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
-
-// By reference
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
@@ -613,12 +614,11 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
ZSTD_CCtx_params* params);
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
+ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params, ZSTD_compressionParameters cParams);
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
-ZSTDLIB_API
-
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
@@ -647,6 +647,7 @@ ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
const void* dict,size_t dictSize,
ZSTD_parameters params);
+
/*! ZSTD_compress_usingCDict_advanced() :
* Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters */
ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
@@ -1002,6 +1003,7 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
+ ZSTD_p_test,
} ZSTD_cParameter;
diff --git a/programs/Makefile b/programs/Makefile
index 2460a091f..a192716a6 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -47,7 +47,8 @@ DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
-Wredundant-decls
-CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
+ZSTD_DEBUG_FLAGS = -g -DZSTD_DEBUG=2
+CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) $(ZSTD_DEBUG_FLAGS)
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
diff --git a/programs/fileio.c b/programs/fileio.c
index 1dd8008e8..b32dd83e0 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -213,6 +213,8 @@ void FIO_setOverlapLog(unsigned overlapLog){
DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n");
g_overlapLog = overlapLog;
}
+static U32 g_testParamFlag = 0;
+void FIO_setTestParamFlag(unsigned testParamFlag) { g_testParamFlag = testParamFlag; }
/*-*************************************
@@ -411,6 +413,9 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_nbThreads, g_nbThreads) );
/* dictionary */
CHECK( ZSTD_CCtx_loadDictionary(ress.cctx, dictBuffer, dictBuffSize) );
+
+ /* Test */
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_test, g_testParamFlag) );
}
#elif defined(ZSTD_MULTITHREAD)
{ ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index b1268c1f3..88d4e1524 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -430,6 +430,7 @@ int main(int argCount, const char* argv[])
if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(0); continue; }
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; }
if (!strcmp(argument, "--priority=rt")) { setRealTimePrio = 1; continue; }
+ if (!strcmp(argument, "--testParam")) { FIO_setTestParamFlag(1); continue; }
#ifdef ZSTD_GZCOMPRESS
if (!strcmp(argument, "--format=gzip")) { suffix = GZ_EXTENSION; FIO_setCompressionType(FIO_gzipCompression); continue; }
#endif
diff --git a/tests/Makefile b/tests/Makefile
index 3734f7737..55de2f58a 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -25,7 +25,7 @@ PRGDIR = ../programs
PYTHON ?= python3
TESTARTEFACT := versionsTest namespaceTest
-DEBUGLEVEL= 1
+DEBUGLEVEL= 2
DEBUGFLAGS= -g -DZSTD_DEBUG=$(DEBUGLEVEL)
CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
-I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR)
@@ -169,6 +169,12 @@ datagen : $(PRGDIR)/datagen.c datagencli.c
roundTripCrash : $(ZSTD_FILES) roundTripCrash.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
+OPAQUEFILES := $(ZSTD_FILES) $(ZDICT_FILES) roundTripCrashOpaque.c
+roundTripCrashOpaque : LDFLAGS += $(MULTITHREAD_CPP)
+roundTripCrashOpaque : LDFLAGS += $(MULTITHREAD_LD)
+roundTripCrashOpaque : $(OPAQUEFILES)
+ $(CC) $(FLAGS) $^ -o $@$(EXT)
+
longmatch : $(ZSTD_FILES) longmatch.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
diff --git a/tests/fullbench.c b/tests/fullbench.c
index 45ef2b6a3..0c41aa3d5 100644
--- a/tests/fullbench.c
+++ b/tests/fullbench.c
@@ -136,8 +136,10 @@ size_t local_ZSTD_compressStream(void* dst, size_t dstCapacity, void* buff2, con
buffIn.src = src;
buffIn.size = srcSize;
buffIn.pos = 0;
+
ZSTD_compressStream(g_cstream, &buffOut, &buffIn);
ZSTD_endStream(g_cstream, &buffOut);
+
return buffOut.pos;
}
@@ -383,11 +385,13 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
const BYTE* ip = dstBuff;
const BYTE* iend;
size_t frameHeaderSize, cBlockSize;
+
ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1); /* it would be better to use direct block compression here */
g_cSize = ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1);
frameHeaderSize = ZSTD_getFrameHeader(&zfp, dstBuff, ZSTD_frameHeaderSize_min);
if (frameHeaderSize==0) frameHeaderSize = ZSTD_frameHeaderSize_min;
ip += frameHeaderSize; /* Skip frame Header */
+
cBlockSize = ZSTD_getcBlockSize(ip, dstBuffSize, &bp); /* Get 1st block type */
if (bp.blockType != bt_compressed) {
DISPLAY("ZSTD_decodeSeqHeaders : impossible to test on this sample (not compressible)\n");
@@ -395,6 +399,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
}
iend = ip + ZSTD_blockHeaderSize + cBlockSize; /* End of first block */
ip += ZSTD_blockHeaderSize; /* skip block header */
+
ZSTD_decompressBegin(g_zdc);
ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, iend-ip); /* skip literal segment */
g_cSize = iend-ip;
diff --git a/tests/roundTripCrashOpaque.c b/tests/roundTripCrashOpaque.c
new file mode 100644
index 000000000..f9b6e7f83
--- /dev/null
+++ b/tests/roundTripCrashOpaque.c
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/*
+ This program takes a file in input,
+ performs a zstd round-trip test (compression - decompress)
+ compares the result with original
+ and generates a crash (double free) on corruption detection.
+*/
+
+/*===========================================
+* Dependencies
+*==========================================*/
+#include /* size_t */
+#include /* malloc, free, exit */
+#include /* fprintf */
+#include /* stat */
+#include /* stat */
+#include "xxhash.h"
+
+#define ZSTD_STATIC_LINKING_ONLY
+#include "zstd.h"
+
+/*===========================================
+* Macros
+*==========================================*/
+#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
+
+#define CHECK_Z(f) { \
+ size_t const err = f; \
+ if (ZSTD_isError(err)) { \
+ fprintf(stderr, \
+ "Error=> %s: %s", \
+ #f, ZSTD_getErrorName(err)); \
+ exit(1); \
+} }
+
+
+/** roundTripTest() :
+* Compresses `srcBuff` into `compressedBuff`,
+* then decompresses `compressedBuff` into `resultBuff`.
+* @return : result of decompression, which should be == `srcSize`
+* or an error code if either compression or decompression fails.
+* Note : `compressedBuffCapacity` should be `>= ZSTD_compressBound(srcSize)`
+* for compression to be guaranteed to work */
+static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity,
+ void* compressedBuff, size_t compressedBuffCapacity,
+ const void* srcBuff, size_t srcBuffSize)
+{
+ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
+ ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams();
+ ZSTD_inBuffer inBuffer = { srcBuff, srcBuffSize, 0 };
+ ZSTD_outBuffer outBuffer = {compressedBuff, compressedBuffCapacity, 0 };
+
+ ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, 1);
+ ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_test, 1);
+
+ ZSTD_CCtx_applyCCtxParams(cctx, cctxParams);
+
+ CHECK_Z (ZSTD_compress_generic(cctx, &outBuffer, &inBuffer, ZSTD_e_end) );
+
+ ZSTD_freeCCtxParams(cctxParams);
+ ZSTD_freeCCtx(cctx);
+
+ return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, outBuffer.pos);
+}
+
+
+static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize)
+{
+ const char* ip1 = (const char*)buff1;
+ const char* ip2 = (const char*)buff2;
+ size_t pos;
+
+ for (pos=0; pos= `fileSize` */
+static void loadFile(void* buffer, const char* fileName, size_t fileSize)
+{
+ FILE* const f = fopen(fileName, "rb");
+ if (isDirectory(fileName)) {
+ fprintf(stderr, "Ignoring %s directory \n", fileName);
+ exit(2);
+ }
+ if (f==NULL) {
+ fprintf(stderr, "Impossible to open %s \n", fileName);
+ exit(3);
+ }
+ { size_t const readSize = fread(buffer, 1, fileSize, f);
+ if (readSize != fileSize) {
+ fprintf(stderr, "Error reading %s \n", fileName);
+ exit(5);
+ } }
+ fclose(f);
+}
+
+
+static void fileCheck(const char* fileName)
+{
+ size_t const fileSize = getFileSize(fileName);
+ void* buffer = malloc(fileSize);
+ if (!buffer) {
+ fprintf(stderr, "not enough memory \n");
+ exit(4);
+ }
+ loadFile(buffer, fileName, fileSize);
+ roundTripCheck(buffer, fileSize);
+ free (buffer);
+}
+
+int main(int argCount, const char** argv) {
+ if (argCount < 2) {
+ fprintf(stderr, "Error : no argument : need input file \n");
+ exit(9);
+ }
+ fileCheck(argv[1]);
+ fprintf(stderr, "no pb detected\n");
+ return 0;
+}
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 3e551e331..0281a406d 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1494,6 +1494,309 @@ _output_error:
goto _cleanup;
}
+static int fuzzerTests_newAPI_opaque(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)
+{
+ U32 const maxSrcLog = bigTests ? 24 : 22;
+ static const U32 maxSampleLog = 19;
+ size_t const srcBufferSize = (size_t)1<= testNb) { DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); }
+ else { DISPLAYUPDATE(2, "\r%6u ", testNb); }
+ FUZ_rand(&coreSeed);
+ lseed = coreSeed ^ prime32;
+
+ /* states full reset (deliberately not synchronized) */
+ /* some issues can only happen when reusing states */
+ if ((FUZ_rand(&lseed) & 0xFF) == 131) {
+ DISPLAYLEVEL(5, "Creating new context \n");
+ ZSTD_freeCCtx(zc);
+ zc = ZSTD_createCCtx();
+ CHECK(zc==NULL, "ZSTD_createCCtx allocation error");
+ resetAllowed=0;
+ }
+ if ((FUZ_rand(&lseed) & 0xFF) == 132) {
+ ZSTD_freeDStream(zd);
+ zd = ZSTD_createDStream();
+ CHECK(zd==NULL, "ZSTD_createDStream allocation error");
+ ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */
+ }
+
+ /* srcBuffer selection [0-4] */
+ { U32 buffNb = FUZ_rand(&lseed) & 0x7F;
+ if (buffNb & 7) buffNb=2; /* most common : compressible (P) */
+ else {
+ buffNb >>= 3;
+ if (buffNb & 7) {
+ const U32 tnb[2] = { 1, 3 }; /* barely/highly compressible */
+ buffNb = tnb[buffNb >> 3];
+ } else {
+ const U32 tnb[2] = { 0, 4 }; /* not compressible / sparse */
+ buffNb = tnb[buffNb >> 3];
+ } }
+ srcBuffer = cNoiseBuffer[buffNb];
+ }
+
+ /* compression init */
+ CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) ); /* cancel previous dict /*/
+ if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */
+ && oldTestLog /* at least one test happened */ && resetAllowed) {
+ maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
+ if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1;
+ { int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1;
+ CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, compressionLevel));
+ }
+ } else {
+ U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
+ U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog;
+ U32 const cLevelCandidate = (FUZ_rand(&lseed) %
+ (ZSTD_maxCLevel() -
+ (MAX(testLog, dictLog) / 3))) +
+ 1;
+ U32 const cLevel = MIN(cLevelCandidate, cLevelMax);
+ maxTestSize = FUZ_rLogLength(&lseed, testLog);
+ oldTestLog = testLog;
+ /* random dictionary selection */
+ dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0;
+ { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
+ dict = srcBuffer + dictStart;
+ if (!dictSize) dict=NULL;
+ }
+ { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize;
+ ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, pledgedSrcSize, dictSize);
+
+ /* mess with compression parameters */
+ cParams.windowLog += (FUZ_rand(&lseed) & 3) - 1;
+ cParams.hashLog += (FUZ_rand(&lseed) & 3) - 1;
+ cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1;
+ cParams.searchLog += (FUZ_rand(&lseed) & 3) - 1;
+ cParams.searchLength += (FUZ_rand(&lseed) & 3) - 1;
+ cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((double)(FUZ_rand(&lseed) & 127) / 128)));
+ cParams = ZSTD_adjustCParams(cParams, 0, 0);
+
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_windowLog, cParams.windowLog) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_hashLog, cParams.hashLog) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_chainLog, cParams.chainLog) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_searchLog, cParams.searchLog) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_minMatch, cParams.searchLength) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_targetLength, cParams.targetLength) );
+
+ /* unconditionally set, to be sync with decoder */
+ /* mess with frame parameters */
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
+ DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize);
+
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1) );
+ /* multi-threading parameters */
+ { U32 const nbThreadsCandidate = (FUZ_rand(&lseed) & 4) + 1;
+ U32 const nbThreads = MIN(nbThreadsCandidate, nbThreadsMax);
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbThreads, nbThreads) );
+ if (nbThreads > 1) {
+ U32 const jobLog = FUZ_rand(&lseed) % (testLog+1);
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10) );
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_jobSize, (U32)FUZ_rLogLength(&lseed, jobLog)) );
+ }
+ }
+
+ if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_forceMaxWindow, FUZ_rand(&lseed) & 1) );
+
+ if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_test, FUZ_rand(&lseed) & 1) );
+
+
+ /* Apply parameters */
+
+ CHECK_Z (ZSTD_CCtx_applyCCtxParams(zc, cctxParams) );
+
+ if (FUZ_rand(&lseed) & 1) {
+ CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
+ if (dict && dictSize) {
+ /* test that compression parameters are rejected (correctly) after loading a non-NULL dictionary */
+ size_t const setError = ZSTD_CCtx_applyCCtxParams(zc, cctxParams);
+ CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_applyCCtxParams should have failed");
+ } } else {
+ CHECK_Z( ZSTD_CCtx_refPrefix(zc, dict, dictSize) );
+ }
+ } }
+
+ /* multi-segments compression test */
+ XXH64_reset(&xxhState, 0);
+ { ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ;
+ for (cSize=0, totalTestSize=0 ; (totalTestSize < maxTestSize) ; ) {
+ /* compress random chunks into randomly sized dst buffers */
+ size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
+ size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize);
+ size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize);
+ size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1);
+ size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
+ ZSTD_EndDirective const flush = (FUZ_rand(&lseed) & 15) ? ZSTD_e_continue : ZSTD_e_flush;
+ ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 };
+ outBuff.size = outBuff.pos + dstBuffSize;
+
+ CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, flush) );
+ DISPLAYLEVEL(5, "compress consumed %u bytes (total : %u) \n",
+ (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos));
+
+ XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos);
+ memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos);
+ totalTestSize += inBuff.pos;
+ }
+
+ /* final frame epilogue */
+ { size_t remainingToFlush = (size_t)(-1);
+ while (remainingToFlush) {
+ ZSTD_inBuffer inBuff = { NULL, 0, 0 };
+ size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1);
+ size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
+ outBuff.size = outBuff.pos + adjustedDstSize;
+ DISPLAYLEVEL(5, "End-flush into dst buffer of size %u \n", (U32)adjustedDstSize);
+ remainingToFlush = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end);
+ CHECK(ZSTD_isError(remainingToFlush),
+ "ZSTD_compress_generic w/ ZSTD_e_end error : %s",
+ ZSTD_getErrorName(remainingToFlush) );
+ } }
+ crcOrig = XXH64_digest(&xxhState);
+ cSize = outBuff.pos;
+ DISPLAYLEVEL(5, "Frame completed : %u bytes \n", (U32)cSize);
+ }
+
+ /* multi - fragments decompression test */
+ if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
+ DISPLAYLEVEL(5, "resetting DCtx (dict:%08X) \n", (U32)(size_t)dict);
+ CHECK_Z( ZSTD_resetDStream(zd) );
+ } else {
+ DISPLAYLEVEL(5, "using dict of size %u \n", (U32)dictSize);
+ CHECK_Z( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
+ }
+ { size_t decompressionResult = 1;
+ ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 };
+ ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
+ for (totalGenSize = 0 ; decompressionResult ; ) {
+ size_t const readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
+ size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
+ size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
+ inBuff.size = inBuff.pos + readCSrcSize;
+ outBuff.size = inBuff.pos + dstBuffSize;
+ DISPLAYLEVEL(5, "ZSTD_decompressStream input %u bytes (pos:%u/%u)\n",
+ (U32)readCSrcSize, (U32)inBuff.pos, (U32)cSize);
+ decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);
+ CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult));
+ DISPLAYLEVEL(5, "inBuff.pos = %u \n", (U32)readCSrcSize);
+ }
+ CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (U32)outBuff.pos, (U32)totalTestSize);
+ CHECK (inBuff.pos != cSize, "compressed data should be fully read (%u != %u)", (U32)inBuff.pos, (U32)cSize);
+ { U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
+ if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
+ CHECK (crcDest!=crcOrig, "decompressed data corrupted");
+ } }
+
+ /*===== noisy/erroneous src decompression test =====*/
+
+ /* add some noise */
+ { U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2;
+ U32 nn; for (nn=0; nn
Date: Mon, 21 Aug 2017 01:59:08 -0700
Subject: [PATCH 014/248] Disable tests and refactor
---
lib/common/zstd_internal.h | 18 ++-
lib/compress/zstd_compress.c | 148 ++++++++----------
lib/compress/zstdmt_compress.c | 5 +-
lib/compress/zstdmt_compress.h | 9 --
lib/zstd.h | 14 +-
programs/Makefile | 3 +-
programs/fileio.c | 6 +-
programs/fileio.h | 3 +
programs/zstdcli.c | 2 +
tests/Makefile | 9 +-
...TripCrashOpaque.c => cctxParamRoundTrip.c} | 5 +-
tests/fullbench.c | 5 -
tests/zstreamtest.c | 4 +-
13 files changed, 102 insertions(+), 129 deletions(-)
rename tests/{roundTripCrashOpaque.c => cctxParamRoundTrip.c} (98%)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 1cccca286..8b8419a4c 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -221,6 +221,7 @@ typedef struct seqDef_s {
U16 matchLength;
} seqDef;
+
typedef struct {
seqDef* sequencesStart;
seqDef* sequences;
@@ -240,7 +241,6 @@ struct ZSTD_CCtx_params_s {
ZSTD_frameParameters fParams;
int compressionLevel;
-
U32 forceWindow; /* force back-references to respect limit of 1<seqStore); }
-#if 0
-// TODO: get rid of this function
-static ZSTD_parameters ZSTD_getParamsFromCCtxParams(const ZSTD_CCtx_params cctxParams)
-{
- ZSTD_parameters params;
- params.cParams = cctxParams.cParams;
- params.fParams = cctxParams.fParams;
- return params;
-}
-#endif
-#if 0
-// TODO: get rid of this function too
-static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromParams(ZSTD_parameters params) {
- ZSTD_CCtx_params cctxParams;
- memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- return cctxParams;
-}
-#endif
-
-// TODO: get rid of this function too
+/* TODO: get rid of this function if possible*/
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
ZSTD_compressionParameters cParams)
{
@@ -234,12 +220,6 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
cctxParams.cParams = cParams;
return cctxParams;
}
-#if 0
-// TODO: get rid of this function
-static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) {
- return ZSTD_getParamsFromCCtxParams(cctx->appliedParams);
-}
-#endif
/* older variant; will be deprecated */
size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
@@ -261,7 +241,6 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
#define ZSTD_CLEVEL_CUSTOM 999
-#if 0
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
{
if (cctx->requestedParams.compressionLevel==ZSTD_CLEVEL_CUSTOM) return;
@@ -270,7 +249,6 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
cctx->pledgedSrcSizePlusOne-1, 0);
cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
}
-#endif
ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
{
@@ -290,27 +268,15 @@ size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
return 0;
}
-size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params,
- ZSTD_compressionParameters cParams)
+size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
{
- memset(params, 0, sizeof(ZSTD_CCtx_params));
- params->cParams = cParams;
- params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ memset(cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ cctxParams->cParams = params.cParams;
+ cctxParams->fParams = params.fParams;
+ cctxParams->compressionLevel = ZSTD_CLEVEL_CUSTOM;
return 0;
}
-ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(
- int compressionLevel, unsigned long long estimatedSrcSize,
- size_t dictSize)
-{
- ZSTD_CCtx_params* params = ZSTD_createCCtxParams();
- if (params == NULL) { return NULL; }
- ZSTD_initCCtxParams(params, ZSTD_getCParams(
- compressionLevel, estimatedSrcSize, dictSize));
- params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
- return params;
-}
-
size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
@@ -318,8 +284,6 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
return 0;
}
-
-
static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
{
if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
@@ -341,6 +305,10 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
switch(param)
{
case ZSTD_p_compressionLevel:
+ if (value == 0) return 0;
+ if (cctx->cdict) return ERROR(stage_wrong);
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+
case ZSTD_p_windowLog:
case ZSTD_p_hashLog:
case ZSTD_p_chainLog:
@@ -350,6 +318,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_compressionStrategy:
if (value == 0) return 0; /* special value : 0 means "don't change anything" */
if (cctx->cdict) return ERROR(stage_wrong);
+ ZSTD_cLevelToCParams(cctx);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_contentSizeFlag:
@@ -396,11 +365,12 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
assert(cctx->mtctx != NULL);
return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
-
+#if 0
case ZSTD_p_test :
DEBUGLOG(2, "Setting test parameter = %u", value);
cctx->requestedParams.testParam = (value > 0);
return 0;
+#endif
default: return ERROR(parameter_unsupported);
}
@@ -477,12 +447,13 @@ size_t ZSTD_CCtxParam_setParameter(
params->fParams.checksumFlag = value > 0;
return 0;
- case ZSTD_p_dictIDFlag :
+ case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
params->fParams.noDictIDFlag = (value == 0);
return 0;
case ZSTD_p_dictMode :
+ /* restrict dictionary mode to "rawContent" or "fullDict" only */
ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
if (value > (unsigned)ZSTD_dm_fullDict) {
return ERROR(parameter_outOfBound);
@@ -491,6 +462,7 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_refDictContent :
+ /* dictionary content will be referenced, instead of copied */
params->dictContentByRef = value > 0;
return 0;
@@ -516,16 +488,18 @@ size_t ZSTD_CCtxParam_setParameter(
if (params->nbThreads <= 1) { return ERROR(parameter_unsupported); }
params->overlapSizeLog = value;
return 0;
-
+#if 0
case ZSTD_p_test :
DEBUGLOG(2, "setting opaque: ZSTD_p_test: %u", value);
params->testParam = (value > 0);
return 0;
+#endif
default: return ERROR(parameter_unsupported);
}
}
+#if 0
static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
{
DEBUGLOG(2, "======CCtxParams======");
@@ -551,19 +525,24 @@ static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
params->nbThreads,
params->jobSize,
params->overlapSizeLog);
+#if 0
DEBUGLOG(2, "testParam: %u",
params->testParam);
+#endif
}
+#endif
-// This function should probably be updated whenever ZSTD_CCtx_params is updated.
-ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
+/**
+ * This function should be updated whenever ZSTD_CCtx_params is updated.
+ * Parameters are copied manually before the dictionary is loaded.
+ * The multithreading parameters jobSize and overlapSizeLog are set only if
+ * nbThreads >= 1.
+ */
+size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
{
if (params == NULL) { return ERROR(GENERIC); }
if (cctx->cdict) { return ERROR(stage_wrong); }
- DEBUGLOG(2, "Applying cctx params\n");
- ZSTD_debugPrintCCtxParams(params);
-
/* Assume the compression and frame parameters are validated */
cctx->requestedParams.cParams = params->cParams;
cctx->requestedParams.fParams = params->fParams;
@@ -585,8 +564,10 @@ ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params*
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
}
- /* Copy test parameter */
+#if 0
+ /* Copy test parameter */
cctx->requestedParams.testParam = params->testParam;
+#endif
return 0;
}
@@ -3247,7 +3228,6 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
{
- // TODO: Applied params compression level okay? Gets overwritten
U32 const cLevel = cctx->appliedParams.compressionLevel;
ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
cctx->appliedParams.cParams :
@@ -3710,7 +3690,8 @@ static size_t ZSTD_initCDict_internal_opaque(ZSTD_CDict* cdict,
}
cdict->dictContentSize = dictSize;
- /* Frame parameters should be zero? */
+ /* TODO: do the frame parameters need to be zero?
+ * does nbThreads need to be zero? */
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
cdict->dictContent, dictSize,
NULL,
@@ -3748,9 +3729,6 @@ static ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
- /* Initialize to 0 to preserve semantics */
- ZSTD_frameParameters const fParams = { 0, 0, 0 };
- params.fParams = fParams;
if (!cdict || !cctx) {
ZSTD_free(cdict, customMem);
@@ -3759,7 +3737,6 @@ static ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
}
cdict->refContext = cctx;
-
if (ZSTD_isError( ZSTD_initCDict_internal_opaque(
cdict,
dictBuffer, dictSize,
@@ -3777,8 +3754,6 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
{
ZSTD_CCtx_params cctxParams = ZSTD_makeCCtxParamsFromCParams(cParams);
- ZSTD_frameParameters const fParams = { 0, 0, 0 };
- cctxParams.fParams = fParams;
cctxParams.dictMode = dictMode;
cctxParams.dictContentByRef = byReference;
return ZSTD_createCDict_advanced_opaque(dictBuffer, dictSize, cctxParams, customMem);
@@ -3837,6 +3812,7 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
params->dictContentByRef = 1;
+ /* What if nbThreads > 1? */
if (ZSTD_isError( ZSTD_initCDict_internal_opaque(cdict, dict, dictSize, *params) ))
return NULL;
@@ -3970,11 +3946,10 @@ size_t ZSTD_CStreamOutSize(void)
static size_t ZSTD_resetCStream_internal_opaque(
ZSTD_CStream* zcs,
- const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
+ const void* dict, size_t dictSize,
const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
- params.dictMode = dictMode;
DEBUGLOG(4, "ZSTD_resetCStream_internal");
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
@@ -4004,8 +3979,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
ZSTD_CCtx_params cctxParams = zcs->requestedParams;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
- cctxParams.dictMode = dictMode;
- return ZSTD_resetCStream_internal_opaque(zcs, dict, dictSize, dictMode,
+ return ZSTD_resetCStream_internal_opaque(zcs, dict, dictSize,
cdict, cctxParams, pledgedSrcSize);
}
#endif
@@ -4018,14 +3992,15 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
params.cParams = ZSTD_getCParams(params.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
}
- return ZSTD_resetCStream_internal_opaque(zcs, NULL, 0, params.dictMode, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal_opaque(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
}
-size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params,
- unsigned long long pledgedSrcSize)
+size_t ZSTD_initCStream_internal_opaque(
+ ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params,
+ unsigned long long pledgedSrcSize)
{
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
@@ -4038,8 +4013,8 @@ size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
}
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- zcs->requestedParams.dictContentByRef,
- zcs->requestedParams.dictMode,
+ params.dictContentByRef,
+ params.dictMode,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
@@ -4055,8 +4030,7 @@ size_t ZSTD_initCStream_internal_opaque(ZSTD_CStream* zcs,
zcs->requestedParams = params;
return ZSTD_resetCStream_internal_opaque(
- zcs, NULL, 0, zcs->requestedParams.dictMode, zcs->cdict,
- params, pledgedSrcSize);
+ zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
}
#if 0
@@ -4339,7 +4313,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
} else
#endif
{
- CHECK_F( ZSTD_resetCStream_internal_opaque(cctx, prefix, prefixSize, params.dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTD_resetCStream_internal_opaque(cctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
} }
/* compression stage */
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 1296cd316..76a062f04 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -186,6 +186,10 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_free(buf.start, bufPool->cMem);
}
+/**
+ * TODO
+ * Resets parameters to zero for jobs?
+ */
static void ZSTDMT_zeroCCtxParams(ZSTD_CCtx_params* params)
{
params->forceWindow = 0;
@@ -778,7 +782,6 @@ size_t ZSTDMT_initCStream_internal_opaque(
}
-
/** ZSTDMT_initCStream_internal() :
* internal usage only */
size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
index 0b478b735..843a240aa 100644
--- a/lib/compress/zstdmt_compress.h
+++ b/lib/compress/zstdmt_compress.h
@@ -69,15 +69,6 @@ ZSTDLIB_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
const ZSTD_CDict* cdict,
ZSTD_parameters const params,
unsigned overlapLog);
-#if 0
-ZSTDLIB_API size_t ZSTDMT_compress_advanced_opaque(
- ZSTDMT_CCtx* mtctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params* const params,
- unsigned overlapLog);
-#endif
ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
const void* dict, size_t dictSize, /* dict can be released after init, a local copy is preserved within zcs */
diff --git a/lib/zstd.h b/lib/zstd.h
index eb2a857fe..f02f28c82 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -510,7 +510,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * TODO: ZSTD_estimateCStreamSize_advanced_opaque
+ * TODO: ZSTD_estimateCStreamSize_advanced_opaque()
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.
* This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -527,7 +527,7 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
/*! ZSTD_estimate?DictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
* ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
- * TODO: ZSTD_estimateCDictSize_advanced_opaque(), can set by reference
+ * TODO: ZSTD_estimateCDictSize_advanced_opaque()
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
@@ -615,11 +615,9 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
-ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createAndInitCCtxParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
-ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* params, ZSTD_compressionParameters cParams);
+ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
-
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */
@@ -647,7 +645,6 @@ ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
const void* dict,size_t dictSize,
ZSTD_parameters params);
-
/*! ZSTD_compress_usingCDict_advanced() :
* Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters */
ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
@@ -1003,7 +1000,9 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
+#if 0
ZSTD_p_test,
+#endif
} ZSTD_cParameter;
@@ -1014,8 +1013,9 @@ typedef enum {
* @result : 0, or an error code (which can be tested with ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
+/* TODO */
ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
-
+/* TODO */
ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params);
/*! ZSTD_CCtx_setPledgedSrcSize() :
diff --git a/programs/Makefile b/programs/Makefile
index a192716a6..2460a091f 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -47,8 +47,7 @@ DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
-Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
-Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
-Wredundant-decls
-ZSTD_DEBUG_FLAGS = -g -DZSTD_DEBUG=2
-CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) $(ZSTD_DEBUG_FLAGS)
+CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
diff --git a/programs/fileio.c b/programs/fileio.c
index b32dd83e0..1fb249d6b 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -213,9 +213,10 @@ void FIO_setOverlapLog(unsigned overlapLog){
DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n");
g_overlapLog = overlapLog;
}
+#if 0
static U32 g_testParamFlag = 0;
void FIO_setTestParamFlag(unsigned testParamFlag) { g_testParamFlag = testParamFlag; }
-
+#endif
/*-*************************************
* Functions
@@ -413,9 +414,10 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_nbThreads, g_nbThreads) );
/* dictionary */
CHECK( ZSTD_CCtx_loadDictionary(ress.cctx, dictBuffer, dictBuffSize) );
-
+#if 0
/* Test */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_test, g_testParamFlag) );
+#endif
}
#elif defined(ZSTD_MULTITHREAD)
{ ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
diff --git a/programs/fileio.h b/programs/fileio.h
index 9d9167df9..497e122e1 100644
--- a/programs/fileio.h
+++ b/programs/fileio.h
@@ -56,6 +56,9 @@ void FIO_setMemLimit(unsigned memLimit);
void FIO_setNbThreads(unsigned nbThreads);
void FIO_setBlockSize(unsigned blockSize);
void FIO_setOverlapLog(unsigned overlapLog);
+#if 0
+void FIO_setTestParamFlag(unsigned testParamFlag);
+#endif
/*-*************************************
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index 88d4e1524..5e95e4268 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -430,7 +430,9 @@ int main(int argCount, const char* argv[])
if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(0); continue; }
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; }
if (!strcmp(argument, "--priority=rt")) { setRealTimePrio = 1; continue; }
+#if 0
if (!strcmp(argument, "--testParam")) { FIO_setTestParamFlag(1); continue; }
+#endif
#ifdef ZSTD_GZCOMPRESS
if (!strcmp(argument, "--format=gzip")) { suffix = GZ_EXTENSION; FIO_setCompressionType(FIO_gzipCompression); continue; }
#endif
diff --git a/tests/Makefile b/tests/Makefile
index 55de2f58a..e815f5850 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -25,7 +25,7 @@ PRGDIR = ../programs
PYTHON ?= python3
TESTARTEFACT := versionsTest namespaceTest
-DEBUGLEVEL= 2
+DEBUGLEVEL= 1
DEBUGFLAGS= -g -DZSTD_DEBUG=$(DEBUGLEVEL)
CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
-I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR)
@@ -169,10 +169,9 @@ datagen : $(PRGDIR)/datagen.c datagencli.c
roundTripCrash : $(ZSTD_FILES) roundTripCrash.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
-OPAQUEFILES := $(ZSTD_FILES) $(ZDICT_FILES) roundTripCrashOpaque.c
-roundTripCrashOpaque : LDFLAGS += $(MULTITHREAD_CPP)
-roundTripCrashOpaque : LDFLAGS += $(MULTITHREAD_LD)
-roundTripCrashOpaque : $(OPAQUEFILES)
+cctxParamRoundTrip : LDFLAGS += $(MULTITHREAD_CPP)
+cctxParamRoundTrip : LDFLAGS += $(MULTITHREAD_LD)
+cctxParamRoundTrip : $(ZSTD_FILES) cctxParamRoundTrip.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
longmatch : $(ZSTD_FILES) longmatch.c
diff --git a/tests/roundTripCrashOpaque.c b/tests/cctxParamRoundTrip.c
similarity index 98%
rename from tests/roundTripCrashOpaque.c
rename to tests/cctxParamRoundTrip.c
index f9b6e7f83..45a57a151 100644
--- a/tests/roundTripCrashOpaque.c
+++ b/tests/cctxParamRoundTrip.c
@@ -38,13 +38,16 @@
fprintf(stderr, \
"Error=> %s: %s", \
#f, ZSTD_getErrorName(err)); \
- exit(1); \
+ crash(1); \
} }
/** roundTripTest() :
* Compresses `srcBuff` into `compressedBuff`,
* then decompresses `compressedBuff` into `resultBuff`.
+*
+* Parameters are currently set manually.
+*
* @return : result of decompression, which should be == `srcSize`
* or an error code if either compression or decompression fails.
* Note : `compressedBuffCapacity` should be `>= ZSTD_compressBound(srcSize)`
diff --git a/tests/fullbench.c b/tests/fullbench.c
index 0c41aa3d5..45ef2b6a3 100644
--- a/tests/fullbench.c
+++ b/tests/fullbench.c
@@ -136,10 +136,8 @@ size_t local_ZSTD_compressStream(void* dst, size_t dstCapacity, void* buff2, con
buffIn.src = src;
buffIn.size = srcSize;
buffIn.pos = 0;
-
ZSTD_compressStream(g_cstream, &buffOut, &buffIn);
ZSTD_endStream(g_cstream, &buffOut);
-
return buffOut.pos;
}
@@ -385,13 +383,11 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
const BYTE* ip = dstBuff;
const BYTE* iend;
size_t frameHeaderSize, cBlockSize;
-
ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1); /* it would be better to use direct block compression here */
g_cSize = ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1);
frameHeaderSize = ZSTD_getFrameHeader(&zfp, dstBuff, ZSTD_frameHeaderSize_min);
if (frameHeaderSize==0) frameHeaderSize = ZSTD_frameHeaderSize_min;
ip += frameHeaderSize; /* Skip frame Header */
-
cBlockSize = ZSTD_getcBlockSize(ip, dstBuffSize, &bp); /* Get 1st block type */
if (bp.blockType != bt_compressed) {
DISPLAY("ZSTD_decodeSeqHeaders : impossible to test on this sample (not compressible)\n");
@@ -399,7 +395,6 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
}
iend = ip + ZSTD_blockHeaderSize + cBlockSize; /* End of first block */
ip += ZSTD_blockHeaderSize; /* skip block header */
-
ZSTD_decompressBegin(g_zdc);
ip += ZSTD_decodeLiteralsBlock(g_zdc, ip, iend-ip); /* skip literal segment */
g_cSize = iend-ip;
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 0281a406d..ce50925a1 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1655,9 +1655,9 @@ static int fuzzerTests_newAPI_opaque(U32 seed, U32 nbTests, unsigned startTest,
}
if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_forceMaxWindow, FUZ_rand(&lseed) & 1) );
-
+#if 0
if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_test, FUZ_rand(&lseed) & 1) );
-
+#endif
/* Apply parameters */
From 91b30dbe847d8cad72b81de33e99dab650cb0f29 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 10:09:06 -0700
Subject: [PATCH 015/248] Remove test parameter
---
lib/common/zstd_internal.h | 40 ++++++------
lib/compress/zstd_compress.c | 108 ++++++++++++++-------------------
lib/compress/zstdmt_compress.c | 12 ++--
lib/zstd.h | 26 +++++---
programs/fileio.c | 8 ---
programs/fileio.h | 3 -
programs/zstdcli.c | 3 -
tests/Makefile | 2 +-
tests/cctxParamRoundTrip.c | 25 ++++----
tests/zstreamtest.c | 7 ---
10 files changed, 98 insertions(+), 136 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 8b8419a4c..ee3164183 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -236,27 +236,6 @@ typedef struct {
U32 repToConfirm[ZSTD_REP_NUM];
} seqStore_t;
-struct ZSTD_CCtx_params_s {
- ZSTD_compressionParameters cParams;
- ZSTD_frameParameters fParams;
-
- int compressionLevel;
- U32 forceWindow; /* force back-references to respect limit of 1<seqStore); }
-
-/* TODO: get rid of this function if possible*/
-static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
- ZSTD_compressionParameters cParams)
-{
- ZSTD_CCtx_params cctxParams;
- memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
- cctxParams.cParams = cParams;
- return cctxParams;
-}
-
/* older variant; will be deprecated */
size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
{
@@ -239,7 +228,6 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
}
}
-
#define ZSTD_CLEVEL_CUSTOM 999
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
{
@@ -250,6 +238,16 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
}
+static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
+ ZSTD_compressionParameters cParams)
+{
+ ZSTD_CCtx_params cctxParams;
+ memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ cctxParams.cParams = cParams;
+ cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ return cctxParams;
+}
+
ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
{
ZSTD_CCtx_params* params =
@@ -287,10 +285,8 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
{
if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
- // TODO: src size, code duplication
params->cParams = ZSTD_getCParams(params->compressionLevel, 0, 0);
params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
-
}
#define CLAMPCHECK(val,min,max) { \
@@ -305,7 +301,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
switch(param)
{
case ZSTD_p_compressionLevel:
- if (value == 0) return 0;
+ if (value == 0) return 0; /* special value : 0 means "don't change anything" */
if (cctx->cdict) return ERROR(stage_wrong);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
@@ -316,9 +312,9 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_minMatch:
case ZSTD_p_targetLength:
case ZSTD_p_compressionStrategy:
- if (value == 0) return 0; /* special value : 0 means "don't change anything" */
+ if (value == 0) return 0;
if (cctx->cdict) return ERROR(stage_wrong);
- ZSTD_cLevelToCParams(cctx);
+ ZSTD_cLevelToCParams(cctx); /* Can optimize if srcSize is known */
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_contentSizeFlag:
@@ -365,12 +361,6 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
assert(cctx->mtctx != NULL);
return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
-#if 0
- case ZSTD_p_test :
- DEBUGLOG(2, "Setting test parameter = %u", value);
- cctx->requestedParams.testParam = (value > 0);
- return 0;
-#endif
default: return ERROR(parameter_unsupported);
}
@@ -488,12 +478,6 @@ size_t ZSTD_CCtxParam_setParameter(
if (params->nbThreads <= 1) { return ERROR(parameter_unsupported); }
params->overlapSizeLog = value;
return 0;
-#if 0
- case ZSTD_p_test :
- DEBUGLOG(2, "setting opaque: ZSTD_p_test: %u", value);
- params->testParam = (value > 0);
- return 0;
-#endif
default: return ERROR(parameter_unsupported);
}
@@ -525,10 +509,6 @@ static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
params->nbThreads,
params->jobSize,
params->overlapSizeLog);
-#if 0
- DEBUGLOG(2, "testParam: %u",
- params->testParam);
-#endif
}
#endif
@@ -537,6 +517,8 @@ static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
* Parameters are copied manually before the dictionary is loaded.
* The multithreading parameters jobSize and overlapSizeLog are set only if
* nbThreads >= 1.
+ *
+ * Pledged srcSize is treated as unknown.
*/
size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
{
@@ -564,10 +546,6 @@ size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
}
-#if 0
- /* Copy test parameter */
- cctx->requestedParams.testParam = params->testParam;
-#endif
return 0;
}
@@ -3748,7 +3726,6 @@ static ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
}
}
-
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
@@ -3791,32 +3768,36 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
size_t dictSize,
ZSTD_CCtx_params* params)
{
- size_t const cctxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
- size_t const neededSize = sizeof(ZSTD_CDict) + (params->dictContentByRef ? 0 : dictSize)
- + cctxSize;
- ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
- void* ptr;
- DEBUGLOG(5, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
- if ((size_t)workspace & 7) return NULL; /* 8-aligned */
- DEBUGLOG(5, "(workspaceSize < neededSize) : (%u < %u) => %u",
- (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
- if (workspaceSize < neededSize) return NULL;
+ if (params == NULL) { return NULL; }
+ { ZSTD_CCtx_params cctxParams = *params;
+ size_t const cctxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
+ size_t const neededSize = sizeof(ZSTD_CDict)
+ + (cctxParams.dictContentByRef ? 0 : dictSize)
+ + cctxSize;
+ ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
+ void* ptr;
+ DEBUGLOG(5, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
+ if ((size_t)workspace & 7) return NULL; /* 8-aligned */
+ DEBUGLOG(5, "(workspaceSize < neededSize) : (%u < %u) => %u",
+ (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
+ if (workspaceSize < neededSize) return NULL;
- if (!params->dictContentByRef) {
- memcpy(cdict+1, dict, dictSize);
- dict = cdict+1;
- ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
- } else {
- ptr = cdict+1;
+ if (!cctxParams.dictContentByRef) {
+ memcpy(cdict+1, dict, dictSize);
+ dict = cdict+1;
+ ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
+ } else {
+ ptr = cdict+1;
+ }
+ cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
+ cctxParams.dictContentByRef = 1;
+
+ /* What if nbThreads > 1? */
+ if (ZSTD_isError( ZSTD_initCDict_internal_opaque(cdict, dict, dictSize, cctxParams) ))
+ return NULL;
+
+ return cdict;
}
- cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
- params->dictContentByRef = 1;
-
- /* What if nbThreads > 1? */
- if (ZSTD_isError( ZSTD_initCDict_internal_opaque(cdict, dict, dictSize, *params) ))
- return NULL;
-
- return cdict;
}
/*! ZSTD_initStaticCDict_advanced() :
@@ -3861,8 +3842,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
if (cdict==NULL) return ERROR(dictionary_wrong);
- {
- ZSTD_CCtx_params params = cdict->refContext->appliedParams;
+ { ZSTD_CCtx_params params = cdict->refContext->appliedParams;
params.fParams = fParams;
params.dictMode = ZSTD_dm_auto;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 76a062f04..84f42220c 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -188,7 +188,8 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
/**
* TODO
- * Resets parameters to zero for jobs?
+ *
+ * Sets parameters to zero for jobs. Notably, nbThreads should be zero?
*/
static void ZSTDMT_zeroCCtxParams(ZSTD_CCtx_params* params)
{
@@ -564,7 +565,6 @@ static size_t ZSTDMT_compress_advanced_opaque(
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
-
if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, cctxParams.fParams);
return ZSTD_compress_advanced_opaque(cctx, dst, dstCapacity, src, srcSize, NULL, 0, requestedParams);
}
@@ -664,7 +664,6 @@ static size_t ZSTDMT_compress_advanced_opaque(
if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos);
return error ? error : dstPos;
}
-
}
size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
@@ -750,6 +749,7 @@ size_t ZSTDMT_initCStream_internal_opaque(
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
+ /* TODO: This will need a cctxParam version? */
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
params.cParams, zcs->cMem);
@@ -779,12 +779,10 @@ size_t ZSTDMT_initCStream_internal_opaque(
zcs->allJobsCompleted = 0;
if (params.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
return 0;
-
}
-/** ZSTDMT_initCStream_internal() :
- * internal usage only */
-size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
+/** ZSTDMT_initCStream_internal() */
+static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
diff --git a/lib/zstd.h b/lib/zstd.h
index f02f28c82..bbecd5ea2 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -498,7 +498,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * TODO: ZSTD_estimateCCtxSize_advanced_opaque()
+ * ZSTD_estimateCCtxSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter().
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
@@ -510,7 +510,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * TODO: ZSTD_estimateCStreamSize_advanced_opaque()
+ * ZSTD_estimateCStreamSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter().
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.
* This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -527,7 +527,7 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
/*! ZSTD_estimate?DictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
* ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
- * TODO: ZSTD_estimateCDictSize_advanced_opaque()
+ * ZSTD_estimateCDictSize_advanced_opaque() allows further compression parameters. ByReference can be set with ZSTD_CCtxParam_setParameter.
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
@@ -613,7 +613,10 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
const void* dict, size_t dictSize,
ZSTD_CCtx_params* params);
+/* TODO */
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
+/*! ZSTD_resetCCtxParams() :
+ * Reset params to default, with the default compression level. */
ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
@@ -1000,9 +1003,6 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
-#if 0
- ZSTD_p_test,
-#endif
} ZSTD_cParameter;
@@ -1013,9 +1013,19 @@ typedef enum {
* @result : 0, or an error code (which can be tested with ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
-/* TODO */
+/*! ZSTD_CCtxParam_setParameter() :
+ * Similar to ZSTD_CCtx_setParameter.
+ * Set one compression parameter, selected by enum ZSTD_cParameter.
+ * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_applyCCtxParams().
+ * Note : when `value` is an enum, cast it to unsigned for proper type checking.
+ * @result : 0, or an error code (which can be tested with ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
-/* TODO */
+
+/*! ZSTD_CCtx_applyCCtxParams() :
+ * Apply a set of ZSTD_CCtx_params to the compression context.
+ * This must be done before the dictionary is loaded.
+ * The pledgedSrcSize is treated as unknown.
+ * Multithreading parameters are applied only if nbThreads > 1. */
ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params);
/*! ZSTD_CCtx_setPledgedSrcSize() :
diff --git a/programs/fileio.c b/programs/fileio.c
index 1fb249d6b..669052d8b 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -213,10 +213,6 @@ void FIO_setOverlapLog(unsigned overlapLog){
DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n");
g_overlapLog = overlapLog;
}
-#if 0
-static U32 g_testParamFlag = 0;
-void FIO_setTestParamFlag(unsigned testParamFlag) { g_testParamFlag = testParamFlag; }
-#endif
/*-*************************************
* Functions
@@ -414,10 +410,6 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_nbThreads, g_nbThreads) );
/* dictionary */
CHECK( ZSTD_CCtx_loadDictionary(ress.cctx, dictBuffer, dictBuffSize) );
-#if 0
- /* Test */
- CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_test, g_testParamFlag) );
-#endif
}
#elif defined(ZSTD_MULTITHREAD)
{ ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
diff --git a/programs/fileio.h b/programs/fileio.h
index 497e122e1..9d9167df9 100644
--- a/programs/fileio.h
+++ b/programs/fileio.h
@@ -56,9 +56,6 @@ void FIO_setMemLimit(unsigned memLimit);
void FIO_setNbThreads(unsigned nbThreads);
void FIO_setBlockSize(unsigned blockSize);
void FIO_setOverlapLog(unsigned overlapLog);
-#if 0
-void FIO_setTestParamFlag(unsigned testParamFlag);
-#endif
/*-*************************************
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index 5e95e4268..b1268c1f3 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -430,9 +430,6 @@ int main(int argCount, const char* argv[])
if (!strcmp(argument, "--keep")) { FIO_setRemoveSrcFile(0); continue; }
if (!strcmp(argument, "--rm")) { FIO_setRemoveSrcFile(1); continue; }
if (!strcmp(argument, "--priority=rt")) { setRealTimePrio = 1; continue; }
-#if 0
- if (!strcmp(argument, "--testParam")) { FIO_setTestParamFlag(1); continue; }
-#endif
#ifdef ZSTD_GZCOMPRESS
if (!strcmp(argument, "--format=gzip")) { suffix = GZ_EXTENSION; FIO_setCompressionType(FIO_gzipCompression); continue; }
#endif
diff --git a/tests/Makefile b/tests/Makefile
index e815f5850..228f4cdd2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -217,7 +217,7 @@ clean:
fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
fuzzer-dll$(EXT) zstreamtest-dll$(EXT) zbufftest-dll$(EXT)\
zstreamtest$(EXT) zstreamtest32$(EXT) \
- datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \
+ datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) cctxParamRoundTrip$(EXT) longmatch$(EXT) \
symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) poolTests$(EXT) \
decodecorpus$(EXT)
@echo Cleaning completed
diff --git a/tests/cctxParamRoundTrip.c b/tests/cctxParamRoundTrip.c
index 45a57a151..906ad9cec 100644
--- a/tests/cctxParamRoundTrip.c
+++ b/tests/cctxParamRoundTrip.c
@@ -32,6 +32,15 @@
*==========================================*/
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
+static void crash(int errorCode){
+ /* abort if AFL/libfuzzer, exit otherwise */
+ #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */
+ abort();
+ #else
+ exit(errorCode);
+ #endif
+}
+
#define CHECK_Z(f) { \
size_t const err = f; \
if (ZSTD_isError(err)) { \
@@ -41,7 +50,6 @@
crash(1); \
} }
-
/** roundTripTest() :
* Compresses `srcBuff` into `compressedBuff`,
* then decompresses `compressedBuff` into `resultBuff`.
@@ -61,10 +69,8 @@ static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity,
ZSTD_inBuffer inBuffer = { srcBuff, srcBuffSize, 0 };
ZSTD_outBuffer outBuffer = {compressedBuff, compressedBuffCapacity, 0 };
- ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, 1);
- ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_test, 1);
-
- ZSTD_CCtx_applyCCtxParams(cctx, cctxParams);
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, 1) );
+ CHECK_Z( ZSTD_CCtx_applyCCtxParams(cctx, cctxParams) );
CHECK_Z (ZSTD_compress_generic(cctx, &outBuffer, &inBuffer, ZSTD_e_end) );
@@ -88,15 +94,6 @@ static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize
return pos;
}
-static void crash(int errorCode){
- /* abort if AFL/libfuzzer, exit otherwise */
- #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */
- abort();
- #else
- exit(errorCode);
- #endif
-}
-
static void roundTripCheck(const void* srcBuff, size_t srcBuffSize)
{
size_t const cBuffSize = ZSTD_compressBound(srcBuffSize);
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index ce50925a1..ced9c57ff 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1655,12 +1655,8 @@ static int fuzzerTests_newAPI_opaque(U32 seed, U32 nbTests, unsigned startTest,
}
if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_forceMaxWindow, FUZ_rand(&lseed) & 1) );
-#if 0
- if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_test, FUZ_rand(&lseed) & 1) );
-#endif
/* Apply parameters */
-
CHECK_Z (ZSTD_CCtx_applyCCtxParams(zc, cctxParams) );
if (FUZ_rand(&lseed) & 1) {
@@ -1795,9 +1791,6 @@ _output_error:
goto _cleanup;
}
-
-
-
/*-*******************************************************
* Command line
*********************************************************/
From 502031ca10f07be4981f07cb6a7b87d8d1211806 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 11:00:44 -0700
Subject: [PATCH 016/248] Use cctxParam version of createCDict internally
---
lib/common/zstd_internal.h | 5 +++++
lib/compress/zstd_compress.c | 12 +++++++-----
lib/compress/zstdmt_compress.c | 18 ++++++++----------
3 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index ee3164183..65719f541 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -360,6 +360,11 @@ size_t ZSTD_initCStream_internal_opaque(
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize);
+/* INTERNAL */
+ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
+ const void* dictBuffer, size_t dictSize,
+ ZSTD_CCtx_params params, ZSTD_customMem customMem);
+
/*! ZSTD_compressStream_generic() :
* Private use only. To be called from zstdmt_compress.c in single-thread mode. */
size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index ee0365ca3..265be326f 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3698,7 +3698,8 @@ static size_t ZSTD_initCDict_internal(
}
#endif
-static ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
+/* Internal only */
+ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
const void* dictBuffer, size_t dictSize,
ZSTD_CCtx_params params, ZSTD_customMem customMem)
{
@@ -3715,6 +3716,7 @@ static ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
}
cdict->refContext = cctx;
+ /* TODO: What should be zero? */
if (ZSTD_isError( ZSTD_initCDict_internal_opaque(
cdict,
dictBuffer, dictSize,
@@ -3992,10 +3994,10 @@ size_t ZSTD_initCStream_internal_opaque(
return ERROR(memory_allocation);
}
ZSTD_freeCDict(zcs->cdictLocal);
- zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- params.dictContentByRef,
- params.dictMode,
- params.cParams, zcs->customMem);
+ /* TODO opaque version: what needs to be zero? */
+ zcs->cdictLocal = ZSTD_createCDict_advanced_opaque(
+ dict, dictSize,
+ params, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 84f42220c..e7a05f4b1 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -195,6 +195,7 @@ static void ZSTDMT_zeroCCtxParams(ZSTD_CCtx_params* params)
{
params->forceWindow = 0;
params->dictMode = (ZSTD_dictMode_e)(0);
+ params->dictContentByRef = 0;
params->nbThreads = 0;
params->jobSize = 0;
params->overlapSizeLog = 0;
@@ -719,13 +720,9 @@ size_t ZSTDMT_initCStream_internal_opaque(
const ZSTD_CDict* cdict, ZSTD_CCtx_params cctxParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_parameters params;
- params.cParams = cctxParams.cParams;
- params.fParams = cctxParams.fParams;
-
DEBUGLOG(4, "ZSTDMT_initCStream_internal");
/* params are supposed to be fully validated at this point */
- assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
+ assert(!ZSTD_isError(ZSTD_checkCParams(cctxParams.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
/* TODO: Set stuff to 0 to preserve old semantics. */
@@ -749,10 +746,11 @@ size_t ZSTDMT_initCStream_internal_opaque(
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
- /* TODO: This will need a cctxParam version? */
- zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- 0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
- params.cParams, zcs->cMem);
+ /* TODO: cctxParam version? Is this correct?
+ * by reference should be zero, mode should be ZSTD_dm_auto */
+ zcs->cdictLocal = ZSTD_createCDict_advanced_opaque(
+ dict, dictSize,
+ cctxParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
@@ -777,7 +775,7 @@ size_t ZSTDMT_initCStream_internal_opaque(
zcs->nextJobID = 0;
zcs->frameEnded = 0;
zcs->allJobsCompleted = 0;
- if (params.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
+ if (cctxParams.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
return 0;
}
From f306d400c0d986dc246d74ea7916211c2bb45632 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 21 Aug 2017 11:12:11 -0700
Subject: [PATCH 017/248] [cover] Fix divide by zero
---
lib/dictBuilder/cover.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
index 3d445ae8b..cc4b13376 100644
--- a/lib/dictBuilder/cover.c
+++ b/lib/dictBuilder/cover.c
@@ -479,11 +479,16 @@ static COVER_segment_t COVER_selectSegment(const COVER_ctx_t *ctx, U32 *freqs,
* Check the validity of the parameters.
* Returns non-zero if the parameters are valid and 0 otherwise.
*/
-static int COVER_checkParameters(ZDICT_cover_params_t parameters) {
+static int COVER_checkParameters(ZDICT_cover_params_t parameters,
+ size_t maxDictSize) {
/* k and d are required parameters */
if (parameters.d == 0 || parameters.k == 0) {
return 0;
}
+ /* k <= maxDictSize */
+ if (parameters.k > maxDictSize) {
+ return 0;
+ }
/* d <= k */
if (parameters.d > parameters.k) {
return 0;
@@ -648,7 +653,7 @@ ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover(
COVER_ctx_t ctx;
COVER_map_t activeDmers;
/* Checks */
- if (!COVER_checkParameters(parameters)) {
+ if (!COVER_checkParameters(parameters, dictBufferCapacity)) {
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
return ERROR(GENERIC);
}
@@ -995,7 +1000,7 @@ ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
data->parameters.d = d;
data->parameters.steps = kSteps;
/* Check the parameters */
- if (!COVER_checkParameters(data->parameters)) {
+ if (!COVER_checkParameters(data->parameters, dictBufferCapacity)) {
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
free(data);
continue;
From 3587556873ff75ce4a5bed09d2d436ad3901c714 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 21 Aug 2017 11:16:47 -0700
Subject: [PATCH 018/248] [cover] Test small maxdict
---
tests/playTests.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/playTests.sh b/tests/playTests.sh
index bc8584e7a..706cef2da 100755
--- a/tests/playTests.sh
+++ b/tests/playTests.sh
@@ -291,8 +291,10 @@ $ECHO "- Create dictionary with wrong dictID parameter order (must fail)"
$ZSTD --train *.c ../programs/*.c --dictID -o 1 tmpDict1 && die "wrong order : --dictID must be followed by argument "
$ECHO "- Create dictionary with size limit"
$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict=4K -v
+$ECHO "- Create dictionary with small size limit"
+$ZSTD --train *.c ../programs/*.c -o tmpDict3 --maxdict=1K -v
$ECHO "- Create dictionary with wrong parameter order (must fail)"
-$ZSTD --train *.c ../programs/*.c -o tmpDict2 --maxdict -v 4K && die "wrong order : --maxdict must be followed by argument "
+$ZSTD --train *.c ../programs/*.c -o tmpDict3 --maxdict -v 4K && die "wrong order : --maxdict must be followed by argument "
$ECHO "- Compress without dictID"
$ZSTD -f tmp -D tmpDict1 --no-dictID
$ZSTD -d tmp.zst -D tmpDict -fo result
From 232d62b6371e18678300e5569f507f3eb8f29ee8 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Mon, 21 Aug 2017 11:24:32 -0700
Subject: [PATCH 019/248] fixed a few headers that were too hastily copy/pasted
during last license change
---
examples/dictionary_compression.c | 9 ++++-----
examples/dictionary_decompression.c | 9 ++++-----
examples/multiple_streaming_compression.c | 9 ++++-----
examples/simple_compression.c | 9 ++++-----
examples/simple_decompression.c | 9 ++++-----
examples/streaming_compression.c | 9 ++++-----
examples/streaming_decompression.c | 9 ++++-----
lib/compress/zstd_opt.h | 2 +-
programs/platform.h | 2 +-
programs/util.h | 2 +-
zlibWrapper/examples/zwrapbench.c | 3 +--
zlibWrapper/gzcompatibility.h | 2 +-
zlibWrapper/zstd_zlibwrapper.c | 2 +-
zlibWrapper/zstd_zlibwrapper.h | 2 +-
14 files changed, 35 insertions(+), 43 deletions(-)
diff --git a/examples/dictionary_compression.c b/examples/dictionary_compression.c
index 17acec98d..adcc3b4d5 100644
--- a/examples/dictionary_compression.c
+++ b/examples/dictionary_compression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
diff --git a/examples/dictionary_decompression.c b/examples/dictionary_decompression.c
index 345c968c3..ef739c189 100644
--- a/examples/dictionary_decompression.c
+++ b/examples/dictionary_decompression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
diff --git a/examples/multiple_streaming_compression.c b/examples/multiple_streaming_compression.c
index 7bfa133ee..61699104c 100644
--- a/examples/multiple_streaming_compression.c
+++ b/examples/multiple_streaming_compression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
diff --git a/examples/simple_compression.c b/examples/simple_compression.c
index 95853faa6..ab1131475 100644
--- a/examples/simple_compression.c
+++ b/examples/simple_compression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
diff --git a/examples/simple_decompression.c b/examples/simple_decompression.c
index 9e9fcc9ed..4b7ea59e5 100644
--- a/examples/simple_decompression.c
+++ b/examples/simple_decompression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
#include // malloc, exit
diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c
index ac7ee7687..24ad15bd6 100644
--- a/examples/streaming_compression.c
+++ b/examples/streaming_compression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
diff --git a/examples/streaming_decompression.c b/examples/streaming_decompression.c
index 76dd85169..bb2d80987 100644
--- a/examples/streaming_decompression.c
+++ b/examples/streaming_decompression.c
@@ -1,10 +1,9 @@
-/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/**
+ * Copyright 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
+ * This source code is licensed under the license found in the
+ * LICENSE-examples file in the root directory of this source tree.
*/
diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h
index ae24732c7..4d938c80d 100644
--- a/lib/compress/zstd_opt.h
+++ b/lib/compress/zstd_opt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/programs/platform.h b/programs/platform.h
index fb2e9b173..e9629a0fa 100644
--- a/programs/platform.h
+++ b/programs/platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/programs/util.h b/programs/util.h
index 7b553661c..d6e1dfc20 100644
--- a/programs/util.h
+++ b/programs/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c
index 050c9db63..82ec47b70 100644
--- a/zlibWrapper/examples/zwrapbench.c
+++ b/zlibWrapper/examples/zwrapbench.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -36,7 +36,6 @@
#endif
-
/*-************************************
* Constants
**************************************/
diff --git a/zlibWrapper/gzcompatibility.h b/zlibWrapper/gzcompatibility.h
index ac9020acc..98ddf1f11 100644
--- a/zlibWrapper/gzcompatibility.h
+++ b/zlibWrapper/gzcompatibility.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c
index 272369a28..836587f2b 100644
--- a/zlibWrapper/zstd_zlibwrapper.c
+++ b/zlibWrapper/zstd_zlibwrapper.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
diff --git a/zlibWrapper/zstd_zlibwrapper.h b/zlibWrapper/zstd_zlibwrapper.h
index f8f368009..9c923cb18 100644
--- a/zlibWrapper/zstd_zlibwrapper.h
+++ b/zlibWrapper/zstd_zlibwrapper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
From 25be09c6b47dc4cff63bfe447a1b3499e00d66e6 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 11:34:53 -0700
Subject: [PATCH 020/248] Set some parameters to zero before initializing cdict
---
lib/compress/zstd_compress.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 265be326f..530611dd5 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3708,15 +3708,12 @@ ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
-
if (!cdict || !cctx) {
ZSTD_free(cdict, customMem);
ZSTD_freeCCtx(cctx);
return NULL;
}
cdict->refContext = cctx;
-
- /* TODO: What should be zero? */
if (ZSTD_isError( ZSTD_initCDict_internal_opaque(
cdict,
dictBuffer, dictSize,
@@ -4256,7 +4253,7 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
return ZSTD_compressStream_generic(zcs, output, input, ZSTD_e_continue);
}
-/*! ZSTDMT_initCStream_internal() :
+/*! ZSTDMT_initCStream_internal_opaque() :
* Private use only. Init streaming operation.
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
From 560b34f6d2c305fc91cf08838c807f13497a261c Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 11:44:58 -0700
Subject: [PATCH 021/248] Return error code when initializing NULL cctxParams
---
lib/compress/zstd_compress.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 530611dd5..69e977890 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -268,6 +268,7 @@ size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
{
+ if (!cctxParams) { return ERROR(GENERIC); }
memset(cctxParams, 0, sizeof(ZSTD_CCtx_params));
cctxParams->cParams = params.cParams;
cctxParams->fParams = params.fParams;
From 73c73bf16a0e9aafe0776144469b1bbf9f26b193 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 12:41:19 -0700
Subject: [PATCH 022/248] Reduce code duplication in zstreamtest
---
lib/zstd.h | 2 +-
tests/zstreamtest.c | 73 +++++++++++++++++++++++++++++----------------
2 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/lib/zstd.h b/lib/zstd.h
index bbecd5ea2..a88382e5c 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -1002,7 +1002,7 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
- * even when referencing into Dictionary content (default:0) */
+ * even when referencing into Dictionary content (default:0) */
} ZSTD_cParameter;
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index ced9c57ff..8f974b461 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1206,6 +1206,7 @@ _output_error:
/* Tests for ZSTD_compress_generic() API */
+#if 0
static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)
{
U32 const maxSrcLog = bigTests ? 24 : 22;
@@ -1493,8 +1494,22 @@ _output_error:
result = 1;
goto _cleanup;
}
+#endif
-static int fuzzerTests_newAPI_opaque(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)
+/** If useOpaqueAPI, sets param in cctxParams.
+ * Otherwise, sets the param in zc. */
+static size_t setCCtxParameter(ZSTD_CCtx* zc, ZSTD_CCtx_params* cctxParams,
+ ZSTD_cParameter param, unsigned value,
+ U32 useOpaqueAPI)
+{
+ if (useOpaqueAPI) {
+ return ZSTD_CCtxParam_setParameter(cctxParams, param, value);
+ } else {
+ return ZSTD_CCtx_setParameter(zc, param, value);
+ }
+}
+
+static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests, U32 const useOpaqueAPI)
{
U32 const maxSrcLog = bigTests ? 24 : 22;
static const U32 maxSampleLog = 19;
@@ -1597,7 +1612,7 @@ static int fuzzerTests_newAPI_opaque(U32 seed, U32 nbTests, unsigned startTest,
maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1;
{ int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1;
- CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, compressionLevel));
+ CHECK_Z (setCCtxParameter(zc, cctxParams, ZSTD_p_compressionLevel, compressionLevel, useOpaqueAPI) );
}
} else {
U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
@@ -1627,45 +1642,53 @@ static int fuzzerTests_newAPI_opaque(U32 seed, U32 nbTests, unsigned startTest,
cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((double)(FUZ_rand(&lseed) & 127) / 128)));
cParams = ZSTD_adjustCParams(cParams, 0, 0);
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_windowLog, cParams.windowLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_hashLog, cParams.hashLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_chainLog, cParams.chainLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_searchLog, cParams.searchLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_minMatch, cParams.searchLength) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_targetLength, cParams.targetLength) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_windowLog, cParams.windowLog, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_hashLog, cParams.hashLog, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_chainLog, cParams.chainLog, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_searchLog, cParams.searchLog, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_minMatch, cParams.searchLength, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize);
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
/* multi-threading parameters */
{ U32 const nbThreadsCandidate = (FUZ_rand(&lseed) & 4) + 1;
U32 const nbThreads = MIN(nbThreadsCandidate, nbThreadsMax);
- CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbThreads, nbThreads) );
+ CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_nbThreads, nbThreads, useOpaqueAPI) );
if (nbThreads > 1) {
U32 const jobLog = FUZ_rand(&lseed) % (testLog+1);
- CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10) );
- CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_jobSize, (U32)FUZ_rLogLength(&lseed, jobLog)) );
+ CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10, useOpaqueAPI) );
+ CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_jobSize, (U32)FUZ_rLogLength(&lseed, jobLog), useOpaqueAPI) );
}
}
- if (FUZ_rand(&lseed) & 1) CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_forceMaxWindow, FUZ_rand(&lseed) & 1) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z (setCCtxParameter(zc, cctxParams, ZSTD_p_forceMaxWindow, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
/* Apply parameters */
- CHECK_Z (ZSTD_CCtx_applyCCtxParams(zc, cctxParams) );
+ if (useOpaqueAPI) {
+ CHECK_Z (ZSTD_CCtx_applyCCtxParams(zc, cctxParams) );
+ }
if (FUZ_rand(&lseed) & 1) {
CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
if (dict && dictSize) {
/* test that compression parameters are rejected (correctly) after loading a non-NULL dictionary */
- size_t const setError = ZSTD_CCtx_applyCCtxParams(zc, cctxParams);
- CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_applyCCtxParams should have failed");
- } } else {
+ if (useOpaqueAPI) {
+ size_t const setError = ZSTD_CCtx_applyCCtxParams(zc, cctxParams);
+ CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_applyCCtxParams should have failed");
+ } else {
+ size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1);
+ CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed");
+ }
+ }
+ } else {
CHECK_Z( ZSTD_CCtx_refPrefix(zc, dict, dictSize) );
}
} }
@@ -1810,7 +1833,7 @@ int FUZ_usage(const char* programName)
return 0;
}
-typedef enum { simple_api, mt_api, advanced_api, advanced_api_opaque } e_api;
+typedef enum { simple_api, mt_api, advanced_api } e_api;
int main(int argc, const char** argv)
{
@@ -1826,6 +1849,7 @@ int main(int argc, const char** argv)
e_api selected_api = simple_api;
const char* const programName = argv[0];
ZSTD_customMem const customNULL = ZSTD_defaultCMem;
+ U32 useOpaqueAPI = 0;
/* Check command line */
for(argNb=1; argNb
Date: Mon, 21 Aug 2017 12:57:18 -0700
Subject: [PATCH 023/248] Pass ZSTD_CCtx_params as const ptr when possible
---
lib/compress/zstd_compress.c | 18 +++++++++---------
lib/zstd.h | 10 +++++-----
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 69e977890..b6774e947 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -521,7 +521,7 @@ static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
*
* Pledged srcSize is treated as unknown.
*/
-size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params)
+size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
{
if (params == NULL) { return ERROR(GENERIC); }
if (cctx->cdict) { return ERROR(stage_wrong); }
@@ -693,10 +693,10 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
}
-size_t ZSTD_estimateCCtxSize_advanced_opaque(ZSTD_CCtx_params* params)
+size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
- { ZSTD_compressionParameters cParams = params->cParams;
+ { ZSTD_compressionParameters const cParams = params->cParams;
size_t const blockSize =
MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
U32 const divider = (cParams.searchLength==3) ? 3 : 4;
@@ -725,7 +725,7 @@ size_t ZSTD_estimateCCtxSize_advanced_opaque(ZSTD_CCtx_params* params)
size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams)
{
- ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
+ ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
return ZSTD_estimateCCtxSize_advanced_opaque(¶ms);
}
@@ -735,7 +735,7 @@ size_t ZSTD_estimateCCtxSize(int compressionLevel)
return ZSTD_estimateCCtxSize_advanced(cParams);
}
-size_t ZSTD_estimateCStreamSize_advanced_opaque(ZSTD_CCtx_params* params)
+size_t ZSTD_estimateCStreamSize_advanced_opaque(const ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
{ size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
@@ -750,7 +750,7 @@ size_t ZSTD_estimateCStreamSize_advanced_opaque(ZSTD_CCtx_params* params)
size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams)
{
- ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
+ ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
return ZSTD_estimateCStreamSize_advanced_opaque(¶ms);
}
@@ -3608,7 +3608,7 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
/* ===== Dictionary API ===== */
size_t ZSTD_estimateCDictSize_advanced_opaque(
- size_t dictSize, ZSTD_CCtx_params* params)
+ size_t dictSize, const ZSTD_CCtx_params* params)
{
if (params == NULL) { return 0; }
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
@@ -3766,7 +3766,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void *workspace, size_t workspaceSize, const void* dict,
size_t dictSize,
- ZSTD_CCtx_params* params)
+ const ZSTD_CCtx_params* params)
{
if (params == NULL) { return NULL; }
{ ZSTD_CCtx_params cctxParams = *params;
@@ -3928,7 +3928,7 @@ static size_t ZSTD_resetCStream_internal_opaque(
ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
+ const ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_resetCStream_internal");
/* params are supposed to be fully validated at this point */
diff --git a/lib/zstd.h b/lib/zstd.h
index a88382e5c..0fd97cd6f 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -502,7 +502,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
-ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_opaque(ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
/*! ZSTD_estimate?StreamSize() :
@@ -520,7 +520,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* In this case, get total size by adding ZSTD_estimate?DictSize */
ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
-ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_opaque(ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_opaque(const ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
@@ -531,7 +531,7 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
-ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, const ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
@@ -611,7 +611,7 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- ZSTD_CCtx_params* params);
+ const ZSTD_CCtx_params* params);
/* TODO */
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
@@ -1026,7 +1026,7 @@ ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cP
* This must be done before the dictionary is loaded.
* The pledgedSrcSize is treated as unknown.
* Multithreading parameters are applied only if nbThreads > 1. */
-ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
/*! ZSTD_CCtx_setPledgedSrcSize() :
* Total input data size to be compressed as a single frame.
From d49eb40c03845d0961f2819f502c51a11bd7cbe5 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 21 Aug 2017 13:10:03 -0700
Subject: [PATCH 024/248] [cover] Stop when segmentSize is less than d
---
lib/dictBuilder/cover.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
index 3d445ae8b..501b5b490 100644
--- a/lib/dictBuilder/cover.c
+++ b/lib/dictBuilder/cover.c
@@ -622,9 +622,9 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
/* Select a segment */
COVER_segment_t segment = COVER_selectSegment(
ctx, freqs, activeDmers, epochBegin, epochEnd, parameters);
- /* Trim the segment if necessary and if it is empty then we are done */
+ /* Trim the segment if necessary and if it is too small then we are done */
segmentSize = MIN(segment.end - segment.begin + parameters.d - 1, tail);
- if (segmentSize == 0) {
+ if (segmentSize < parameters.d) {
break;
}
/* We fill the dictionary from the back to allow the best segments to be
From 1c0dbe81b17addc1f48be895326124158ea5a2c3 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 13:18:00 -0700
Subject: [PATCH 025/248] Add documentation for CCtx_params
---
lib/compress/zstd_compress.c | 8 +++--
lib/zstd.h | 60 +++++++++++++++++++++++-------------
2 files changed, 44 insertions(+), 24 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index b6774e947..c37b2ad49 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -471,12 +471,12 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_jobSize :
- if (params->nbThreads <= 1) { return ERROR(parameter_unsupported); }
+ if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
params->jobSize = value;
return 0;
case ZSTD_p_overlapSizeLog :
- if (params->nbThreads <= 1) { return ERROR(parameter_unsupported); }
+ if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
params->overlapSizeLog = value;
return 0;
@@ -526,6 +526,10 @@ size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params
if (params == NULL) { return ERROR(GENERIC); }
if (cctx->cdict) { return ERROR(stage_wrong); }
+ /* TODO: some parameters can be set even if cctx->cdict.
+ * They can be set directly using ZSTD_CCtx_setParameter?
+ */
+
/* Assume the compression and frame parameters are validated */
cctx->requestedParams.cParams = params->cParams;
cctx->requestedParams.fParams = params->fParams;
diff --git a/lib/zstd.h b/lib/zstd.h
index 0fd97cd6f..09b89911f 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -613,13 +613,7 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
const void* dict, size_t dictSize,
const ZSTD_CCtx_params* params);
-/* TODO */
-ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
-/*! ZSTD_resetCCtxParams() :
- * Reset params to default, with the default compression level. */
-ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
-ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
-ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
+
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
@@ -1013,21 +1007,6 @@ typedef enum {
* @result : 0, or an error code (which can be tested with ZSTD_isError()). */
ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
-/*! ZSTD_CCtxParam_setParameter() :
- * Similar to ZSTD_CCtx_setParameter.
- * Set one compression parameter, selected by enum ZSTD_cParameter.
- * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_applyCCtxParams().
- * Note : when `value` is an enum, cast it to unsigned for proper type checking.
- * @result : 0, or an error code (which can be tested with ZSTD_isError()). */
-ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
-
-/*! ZSTD_CCtx_applyCCtxParams() :
- * Apply a set of ZSTD_CCtx_params to the compression context.
- * This must be done before the dictionary is loaded.
- * The pledgedSrcSize is treated as unknown.
- * Multithreading parameters are applied only if nbThreads > 1. */
-ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
-
/*! ZSTD_CCtx_setPledgedSrcSize() :
* Total input data size to be compressed as a single frame.
* This value will be controlled at the end, and result in error if not respected.
@@ -1131,7 +1110,44 @@ size_t ZSTD_compress_generic_simpleArgs (
const void* src, size_t srcSize, size_t* srcPos,
ZSTD_EndDirective endOp);
+/** ZSTD_CCtx_params :
+ *
+ * - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
+ * - ZSTD_CCtxParam_setParameter() : Push parameters one by one into an
+ * existing ZSTD_CCtx_params structure. This is similar to
+ * ZSTD_CCtx_setParameter().
+ * - ZSTD_CCtx_applyCCtxParams() : Apply parameters to an existing CCtx. These
+ * parameters will be applied to all subsequent compression jobs.
+ * - ZSTD_compress_generic() : Do compression using the CCtx.
+ * - ZSTD_freeCCtxParams() : Free the memory. */
+ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
+
+/*! ZSTD_resetCCtxParams() :
+ * Reset params to default, with the default compression level. */
+ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
+
+/*! ZSTD_initCCtxParams() :
+ * Set the compression and frame parameters of cctxParams according to params.
+ * All other parameters are reset to their default values. */
+ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
+
+ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
+
+/*! ZSTD_CCtxParam_setParameter() :
+ * Similar to ZSTD_CCtx_setParameter.
+ * Set one compression parameter, selected by enum ZSTD_cParameter.
+ * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_applyCCtxParams().
+ * Note : when `value` is an enum, cast it to unsigned for proper type checking.
+ * @result : 0, or an error code (which can be tested with ZSTD_isError()). */
+ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
+
+/*! ZSTD_CCtx_applyCCtxParams() :
+ * Apply a set of ZSTD_CCtx_params to the compression context.
+ * This must be done before the dictionary is loaded.
+ * The pledgedSrcSize is treated as unknown.
+ * Multithreading parameters are applied only if nbThreads > 1. */
+ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
/**
Block functions
From fd8a25786efe8f6696e8c964dc8b6f247c759203 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 13:23:35 -0700
Subject: [PATCH 026/248] Check parameters are valid in initCCtxParams
---
lib/compress/zstd_compress.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index c37b2ad49..a85683059 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -266,9 +266,10 @@ size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
return 0;
}
-size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
+size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters const params)
{
if (!cctxParams) { return ERROR(GENERIC); }
+ CHECK_F( ZSTD_checkCParams(params.cParams) );
memset(cctxParams, 0, sizeof(ZSTD_CCtx_params));
cctxParams->cParams = params.cParams;
cctxParams->fParams = params.fParams;
From 9a54a315aa28a6659b935bd6ce95cb962715ebbc Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 21 Aug 2017 13:30:07 -0700
Subject: [PATCH 027/248] [cover] Convert score to U32 and check for zero
---
lib/dictBuilder/cover.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
index 501b5b490..07fedc2d1 100644
--- a/lib/dictBuilder/cover.c
+++ b/lib/dictBuilder/cover.c
@@ -382,7 +382,7 @@ static void COVER_group(COVER_ctx_t *ctx, const void *group,
typedef struct {
U32 begin;
U32 end;
- double score;
+ U32 score;
} COVER_segment_t;
/**
@@ -622,6 +622,10 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
/* Select a segment */
COVER_segment_t segment = COVER_selectSegment(
ctx, freqs, activeDmers, epochBegin, epochEnd, parameters);
+ /* If the segment covers no dmers, then we are out of content */
+ if (segment.score == 0) {
+ break;
+ }
/* Trim the segment if necessary and if it is too small then we are done */
segmentSize = MIN(segment.end - segment.begin + parameters.d - 1, tail);
if (segmentSize < parameters.d) {
From 98de3f6847052019bb0a35a50f294d0d87a137ad Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 21 Aug 2017 14:23:17 -0700
Subject: [PATCH 028/248] [cover] Add dictionary size to compressed size
---
lib/dictBuilder/cover.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
index 07fedc2d1..3770c2cac 100644
--- a/lib/dictBuilder/cover.c
+++ b/lib/dictBuilder/cover.c
@@ -888,7 +888,7 @@ static void COVER_tryParameters(void *opaque) {
goto _compressCleanup;
}
/* Compress each sample and sum their sizes (or error) */
- totalCompressedSize = 0;
+ totalCompressedSize = dictBufferCapacity;
for (i = 0; i < ctx->nbSamples; ++i) {
const size_t size = ZSTD_compress_usingCDict(
cctx, dst, dstCapacity, ctx->samples + ctx->offsets[i],
From 29c2d9a4d05213adac3bdb8b5855d80079112799 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 21 Aug 2017 14:28:31 -0700
Subject: [PATCH 029/248] [cover] Turn down notification for ZDICT subroutines
---
lib/dictBuilder/cover.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
index 3770c2cac..64f23f23c 100644
--- a/lib/dictBuilder/cover.c
+++ b/lib/dictBuilder/cover.c
@@ -998,6 +998,7 @@ ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
data->parameters.k = k;
data->parameters.d = d;
data->parameters.steps = kSteps;
+ data->parameters.zParams.notificationLevel = g_displayLevel;
/* Check the parameters */
if (!COVER_checkParameters(data->parameters)) {
DISPLAYLEVEL(1, "Cover parameters incorrect\n");
From 5b956f4753c87905e8ae69ae3458e5ef56e44f07 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 14:49:16 -0700
Subject: [PATCH 030/248] Comment out CCtx_param versions of CDict functions
---
lib/common/zstd_internal.h | 5 --
lib/compress/zstd_compress.c | 119 +++++++++++++++++++++++++--------
lib/compress/zstdmt_compress.c | 9 ++-
lib/zstd.h | 9 ---
4 files changed, 96 insertions(+), 46 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 65719f541..ee3164183 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -360,11 +360,6 @@ size_t ZSTD_initCStream_internal_opaque(
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize);
-/* INTERNAL */
-ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
- const void* dictBuffer, size_t dictSize,
- ZSTD_CCtx_params params, ZSTD_customMem customMem);
-
/*! ZSTD_compressStream_generic() :
* Private use only. To be called from zstdmt_compress.c in single-thread mode. */
size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index a85683059..649cf8780 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3611,7 +3611,7 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
/* ===== Dictionary API ===== */
-
+#if 0
size_t ZSTD_estimateCDictSize_advanced_opaque(
size_t dictSize, const ZSTD_CCtx_params* params)
{
@@ -3623,14 +3623,17 @@ size_t ZSTD_estimateCDictSize_advanced_opaque(
+ (params->dictContentByRef ? 0 : dictSize);
}
+#endif
/*! ZSTD_estimateCDictSize_advanced() :
* Estimate amount of memory that will be needed to create a dictionary with following arguments */
size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
{
- ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
- params.dictContentByRef = byReference;
- return ZSTD_estimateCDictSize_advanced_opaque(dictSize, ¶ms);
+ DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
+ DEBUGLOG(5, "CCtx estimate : %u",
+ (U32)ZSTD_estimateCCtxSize_advanced(cParams));
+ return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced(cParams)
+ + (byReference ? 0 : dictSize);
}
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
@@ -3657,6 +3660,7 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_
}
#endif
+#if 0
static size_t ZSTD_initCDict_internal_opaque(ZSTD_CDict* cdict,
const void* dictBuffer, size_t dictSize,
ZSTD_CCtx_params params)
@@ -3683,27 +3687,44 @@ static size_t ZSTD_initCDict_internal_opaque(ZSTD_CDict* cdict,
ZSTDb_not_buffered) );
return 0;
}
+#endif
-#if 0
static size_t ZSTD_initCDict_internal(
ZSTD_CDict* cdict,
const void* dictBuffer, size_t dictSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams)
{
- ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
- ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
+ DEBUGLOG(5, "ZSTD_initCDict_internal, mode %u", (U32)dictMode);
+ if ((byReference) || (!dictBuffer) || (!dictSize)) {
+ cdict->dictBuffer = NULL;
+ cdict->dictContent = dictBuffer;
+ } else {
+ void* const internalBuffer = ZSTD_malloc(dictSize, cdict->refContext->customMem);
+ cdict->dictBuffer = internalBuffer;
+ cdict->dictContent = internalBuffer;
+ if (!internalBuffer) return ERROR(memory_allocation);
+ memcpy(internalBuffer, dictBuffer, dictSize);
+ }
+ cdict->dictContentSize = dictSize;
+
+ { ZSTD_frameParameters const fParams = { 0 /*contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
- cctxParams.cParams = cParams;
- cctxParams.fParams = fParams;
- cctxParams.dictMode = dictMode;
- cctxParams.dictContentByRef = byReference;
- CHECK_F (ZSTD_initCDict_internal_opaque(
- cdict, dictBuffer, dictSize, cctxParams) );
+ ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
+ cctxParams.fParams = fParams;
+ cctxParams.cParams = cParams;
+ cctxParams.dictContentByRef = byReference;
+ cctxParams.dictMode = dictMode;
+ CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
+ cdict->dictContent, dictSize,
+ NULL,
+ cctxParams, ZSTD_CONTENTSIZE_UNKNOWN,
+ ZSTDb_not_buffered) );
+ }
return 0;
}
-#endif
+#if 0
/* Internal only */
ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
const void* dictBuffer, size_t dictSize,
@@ -3730,15 +3751,33 @@ ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
return cdict;
}
}
+#endif
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
{
- ZSTD_CCtx_params cctxParams = ZSTD_makeCCtxParamsFromCParams(cParams);
- cctxParams.dictMode = dictMode;
- cctxParams.dictContentByRef = byReference;
- return ZSTD_createCDict_advanced_opaque(dictBuffer, dictSize, cctxParams, customMem);
+ DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", dictMode);
+ if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+
+ { ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
+ ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
+ if (!cdict || !cctx) {
+ ZSTD_free(cdict, customMem);
+ ZSTD_freeCCtx(cctx);
+ return NULL;
+ }
+ cdict->refContext = cctx;
+ if (ZSTD_isError( ZSTD_initCDict_internal(
+ cdict,
+ dictBuffer, dictSize,
+ byReference, dictMode,
+ cParams) )) {
+ ZSTD_freeCDict(cdict);
+ return NULL;
+ }
+ return cdict;
+ }
}
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
@@ -3768,6 +3807,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
}
}
+#if 0
ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
void *workspace, size_t workspaceSize, const void* dict,
size_t dictSize,
@@ -3804,6 +3844,7 @@ ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
return cdict;
}
}
+#endif
/*! ZSTD_initStaticCDict_advanced() :
* Generate a digested dictionary in provided memory area.
@@ -3823,13 +3864,35 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams)
{
- ZSTD_CCtx_params params = ZSTD_makeCCtxParamsFromCParams(cParams);
- params.dictMode = dictMode;
- params.dictContentByRef = byReference;
- return ZSTD_initStaticCDict_advanced_opaque(
- workspace, workspaceSize, dict, dictSize,
- ¶ms);
+ size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams);
+ size_t const neededSize = sizeof(ZSTD_CDict)
+ + (byReference ? 0 : dictSize)
+ + cctxSize;
+ ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
+ void* ptr;
+ DEBUGLOG(5, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
+ if ((size_t)workspace & 7) return NULL; /* 8-aligned */
+ DEBUGLOG(5, "(workspaceSize < neededSize) : (%u < %u) => %u",
+ (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
+ if (workspaceSize < neededSize) return NULL;
+
+ if (!byReference) {
+ memcpy(cdict+1, dict, dictSize);
+ dict = cdict+1;
+ ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
+ } else {
+ ptr = cdict+1;
+ }
+ cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
+
+ if (ZSTD_isError( ZSTD_initCDict_internal(cdict, dict, dictSize,
+ 1 /* byReference */,
+ dictMode, cParams) ))
+ return NULL;
+
+ return cdict;
}
+
#if 0
static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
return ZSTD_getParamsFromCCtx(cdict->refContext);
@@ -3997,10 +4060,12 @@ size_t ZSTD_initCStream_internal_opaque(
return ERROR(memory_allocation);
}
ZSTD_freeCDict(zcs->cdictLocal);
- /* TODO opaque version: what needs to be zero? */
- zcs->cdictLocal = ZSTD_createCDict_advanced_opaque(
+
+ /* Is a CCtx_params version needed? */
+ zcs->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- params, zcs->customMem);
+ params.dictContentByRef, params.dictMode,
+ params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index e7a05f4b1..02dad6c0b 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -746,11 +746,10 @@ size_t ZSTDMT_initCStream_internal_opaque(
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
- /* TODO: cctxParam version? Is this correct?
- * by reference should be zero, mode should be ZSTD_dm_auto */
- zcs->cdictLocal = ZSTD_createCDict_advanced_opaque(
- dict, dictSize,
- cctxParams, zcs->cMem);
+ /* TODO: cctxParam version? Is this correct? */
+ zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
+ 0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
+ cctxParams.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
diff --git a/lib/zstd.h b/lib/zstd.h
index 09b89911f..3e7574c78 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -527,11 +527,9 @@ ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t sr
/*! ZSTD_estimate?DictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
* ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
- * ZSTD_estimateCDictSize_advanced_opaque() allows further compression parameters. ByReference can be set with ZSTD_CCtxParam_setParameter.
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
-ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced_opaque(size_t dictSize, const ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
@@ -608,13 +606,6 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams);
-ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
- void* workspace, size_t workspaceSize,
- const void* dict, size_t dictSize,
- const ZSTD_CCtx_params* params);
-
-
-
/*! ZSTD_getCParams() :
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
* `estimatedSrcSize` value is optional, select 0 if not known */
From 60e1bc617cd9cb2b254967b419d9f5dc194582c9 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 15:39:37 -0700
Subject: [PATCH 031/248] Explicitly create a job cctxParam for multithreading
---
lib/compress/zstdmt_compress.c | 42 +++++++++++++++-------------------
1 file changed, 18 insertions(+), 24 deletions(-)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 02dad6c0b..cf362a756 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -186,19 +186,17 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_free(buf.start, bufPool->cMem);
}
-/**
- * TODO
- *
- * Sets parameters to zero for jobs. Notably, nbThreads should be zero?
- */
-static void ZSTDMT_zeroCCtxParams(ZSTD_CCtx_params* params)
+/* TODO: Set relevant job parameters, initialize others to default.
+ * Notably, nbThreads should be zero. */
+static ZSTD_CCtx_params ZSTDMT_makeJobCCtxParams(ZSTD_CCtx_params const params)
{
- params->forceWindow = 0;
- params->dictMode = (ZSTD_dictMode_e)(0);
- params->dictContentByRef = 0;
- params->nbThreads = 0;
- params->jobSize = 0;
- params->overlapSizeLog = 0;
+ ZSTD_CCtx_params jobParams;
+ memset(&jobParams, 0, sizeof(jobParams));
+
+ jobParams.cParams = params.cParams;
+ jobParams.fParams = params.fParams;
+ jobParams.compressionLevel = params.compressionLevel;
+ return jobParams;
}
/* ===== CCtx Pool ===== */
@@ -560,8 +558,7 @@ static size_t ZSTDMT_compress_advanced_opaque(
unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */
size_t frameStartPos = 0, dstBufferPos = 0;
XXH64_state_t xxh64;
- ZSTD_CCtx_params requestedParams = cctxParams;
- ZSTDMT_zeroCCtxParams(&requestedParams);
+ ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
@@ -720,19 +717,17 @@ size_t ZSTDMT_initCStream_internal_opaque(
const ZSTD_CDict* cdict, ZSTD_CCtx_params cctxParams,
unsigned long long pledgedSrcSize)
{
+ ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
DEBUGLOG(4, "ZSTDMT_initCStream_internal");
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(cctxParams.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
- /* TODO: Set stuff to 0 to preserve old semantics. */
- ZSTDMT_zeroCCtxParams(&cctxParams);
-
if (zcs->nbThreads==1) {
DEBUGLOG(4, "single thread mode");
return ZSTD_initCStream_internal_opaque(zcs->cctxPool->cctx[0],
dict, dictSize, cdict,
- cctxParams, pledgedSrcSize);
+ requestedParams, pledgedSrcSize);
}
if (zcs->allJobsCompleted == 0) { /* previous compression not correctly finished */
@@ -749,7 +744,7 @@ size_t ZSTDMT_initCStream_internal_opaque(
/* TODO: cctxParam version? Is this correct? */
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
- cctxParams.cParams, zcs->cMem);
+ requestedParams.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
@@ -804,13 +799,12 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
+ ZSTD_CCtx_params requestedParams =
+ ZSTDMT_makeJobCCtxParams(ZSTD_getCCtxParamsFromCDict(cdict));
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
- ZSTDMT_zeroCCtxParams(¶ms);
- params.fParams = fParams;
-
+ requestedParams.fParams = fParams;
return ZSTDMT_initCStream_internal_opaque(mtctx, NULL, 0 /*dictSize*/, cdict,
- params, pledgedSrcSize);
+ requestedParams, pledgedSrcSize);
}
From e50ed1fa3ac5857b6be914ec818a71c914789d4f Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 22 Aug 2017 11:55:42 -0700
Subject: [PATCH 032/248] Fix undefined behavior when srcSize==1
---
lib/common/bitstream.h | 33 ++++++++++++++++++---------------
lib/common/zstd_internal.h | 31 +++++++++++++++++--------------
lib/compress/zstd_compress.c | 3 ++-
3 files changed, 37 insertions(+), 30 deletions(-)
diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h
index 06121f21c..c6f001248 100644
--- a/lib/common/bitstream.h
+++ b/lib/common/bitstream.h
@@ -169,25 +169,28 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
****************************************************************/
MEM_STATIC unsigned BIT_highbit32 (register U32 val)
{
+ assert(val != 0);
+ {
# if defined(_MSC_VER) /* Visual */
- unsigned long r=0;
- _BitScanReverse ( &r, val );
- return (unsigned) r;
+ unsigned long r=0;
+ _BitScanReverse ( &r, val );
+ return (unsigned) r;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
- return 31 - __builtin_clz (val);
+ return 31 - __builtin_clz (val);
# else /* Software version */
- static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
- 11, 14, 16, 18, 22, 25, 3, 30,
- 8, 12, 20, 28, 15, 17, 24, 7,
- 19, 27, 23, 6, 26, 5, 4, 31 };
- U32 v = val;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
+ static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
+ 11, 14, 16, 18, 22, 25, 3, 30,
+ 8, 12, 20, 28, 15, 17, 24, 7,
+ 19, 27, 23, 6, 26, 5, 4, 31 };
+ U32 v = val;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
# endif
+ }
}
/*===== Local Constants =====*/
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 261052860..ac1f39896 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -268,24 +268,27 @@ void ZSTD_free(void* ptr, ZSTD_customMem customMem);
MEM_STATIC U32 ZSTD_highbit32(U32 val)
{
+ assert(val != 0);
+ {
# if defined(_MSC_VER) /* Visual */
- unsigned long r=0;
- _BitScanReverse(&r, val);
- return (unsigned)r;
+ unsigned long r=0;
+ _BitScanReverse(&r, val);
+ return (unsigned)r;
# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
- return 31 - __builtin_clz(val);
+ return 31 - __builtin_clz(val);
# else /* Software version */
- static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
- U32 v = val;
- int r;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
- return r;
+ static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
+ U32 v = val;
+ int r;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
+ return r;
# endif
+ }
}
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 0322c03eb..31e941596 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -497,7 +497,8 @@ ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameter
{ U32 const minSrcSize = (srcSize==0) ? 500 : 0;
U64 const rSize = srcSize + dictSize + minSrcSize;
if (rSize < ((U64)1< srcLog) cPar.windowLog = srcLog;
} }
if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
From 6b2b6a9bd5676f15df702c1861990972a4d67141 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Tue, 22 Aug 2017 12:08:39 -0700
Subject: [PATCH 033/248] fixed extraordinary scenario where all fields use
maximum possible nb of bits simultaneously
can only happen if windowLog>=27 (level 22 --ultra)
---
lib/compress/zstd_compress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 0322c03eb..66641e3d9 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -1131,7 +1131,7 @@ MEM_STATIC size_t ZSTD_encodeSequences(void* dst, size_t dstCapacity,
BIT_addBits(&blockStream, sequences[n].litLength, llBits);
if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
- if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
+ if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
if (longOffsets) {
int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
if (extraBits) {
From 8fd16367761528cd1f49bcd0ab58f73e70a2e29a Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 21 Aug 2017 18:10:44 -0700
Subject: [PATCH 034/248] Remove unused functions
---
lib/common/zstd_internal.h | 4 +-
lib/compress/zstd_compress.c | 200 +++------------------------------
lib/compress/zstdmt_compress.c | 12 +-
tests/cctxParamRoundTrip.c | 2 +
4 files changed, 25 insertions(+), 193 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index ee3164183..4e56f6a92 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -348,12 +348,12 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val)
void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
-/*! ZSTD_initCStream_internal_opaque() :
+/*! ZSTD_initCStream_internal() :
* Private use only. Init streaming operation.
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
* @return : 0, or an error code */
-size_t ZSTD_initCStream_internal_opaque(
+size_t ZSTD_initCStream_internal(
ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
const ZSTD_CDict* cdict,
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 649cf8780..cfefe5c20 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -80,14 +80,8 @@ struct ZSTD_CCtx_s {
U32 nextToUpdate3; /* index from which to continue dictionary update */
U32 hashLog3; /* dispatch table : larger == faster, more memory */
U32 loadedDictEnd; /* index of end of dictionary */
-#if 0
- U32 forceWindow; /* force back-references to respect limit of 1<cdict) { return ERROR(stage_wrong); }
- /* TODO: some parameters can be set even if cctx->cdict.
- * They can be set directly using ZSTD_CCtx_setParameter?
- */
-
/* Assume the compression and frame parameters are validated */
cctx->requestedParams.cParams = params->cParams;
cctx->requestedParams.fParams = params->fParams;
@@ -3611,19 +3594,6 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
/* ===== Dictionary API ===== */
-#if 0
-size_t ZSTD_estimateCDictSize_advanced_opaque(
- size_t dictSize, const ZSTD_CCtx_params* params)
-{
- if (params == NULL) { return 0; }
- DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
- DEBUGLOG(5, "CCtx estimate : %u",
- (U32)ZSTD_estimateCCtxSize_advanced_opaque(params));
- return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced_opaque(params)
- + (params->dictContentByRef ? 0 : dictSize);
-
-}
-#endif
/*! ZSTD_estimateCDictSize_advanced() :
* Estimate amount of memory that will be needed to create a dictionary with following arguments */
@@ -3650,45 +3620,6 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
}
-#if 0
-static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_frameParameters fParams)
-{
- ZSTD_parameters params;
- params.cParams = cParams;
- params.fParams = fParams;
- return params;
-}
-#endif
-
-#if 0
-static size_t ZSTD_initCDict_internal_opaque(ZSTD_CDict* cdict,
- const void* dictBuffer, size_t dictSize,
- ZSTD_CCtx_params params)
-{
- DEBUGLOG(5, "ZSTD_initCDict_internal_opaque, mode %u", (U32)params.dictMode);
- if ((params.dictContentByRef) || (!dictBuffer) || (!dictSize)) {
- cdict->dictBuffer = NULL;
- cdict->dictContent = dictBuffer;
- } else {
- void* const internalBuffer = ZSTD_malloc(dictSize, cdict->refContext->customMem);
- cdict->dictBuffer = internalBuffer;
- cdict->dictContent = internalBuffer;
- if (!internalBuffer) return ERROR(memory_allocation);
- memcpy(internalBuffer, dictBuffer, dictSize);
- }
- cdict->dictContentSize = dictSize;
-
- /* TODO: do the frame parameters need to be zero?
- * does nbThreads need to be zero? */
- CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
- cdict->dictContent, dictSize,
- NULL,
- params, ZSTD_CONTENTSIZE_UNKNOWN,
- ZSTDb_not_buffered) );
- return 0;
-}
-#endif
-
static size_t ZSTD_initCDict_internal(
ZSTD_CDict* cdict,
const void* dictBuffer, size_t dictSize,
@@ -3710,6 +3641,7 @@ static size_t ZSTD_initCDict_internal(
{ ZSTD_frameParameters const fParams = { 0 /*contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
+ /* TODO: correct? */
ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
cctxParams.fParams = fParams;
cctxParams.cParams = cParams;
@@ -3724,35 +3656,6 @@ static size_t ZSTD_initCDict_internal(
return 0;
}
-#if 0
-/* Internal only */
-ZSTD_CDict* ZSTD_createCDict_advanced_opaque(
- const void* dictBuffer, size_t dictSize,
- ZSTD_CCtx_params params, ZSTD_customMem customMem)
-{
- DEBUGLOG(5, "ZSTD_createCDict_advanced_opaque, mode %u", (U32)params.dictMode);
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
-
- { ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
- ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
- if (!cdict || !cctx) {
- ZSTD_free(cdict, customMem);
- ZSTD_freeCCtx(cctx);
- return NULL;
- }
- cdict->refContext = cctx;
- if (ZSTD_isError( ZSTD_initCDict_internal_opaque(
- cdict,
- dictBuffer, dictSize,
- params) )) {
- ZSTD_freeCDict(cdict);
- return NULL;
- }
- return cdict;
- }
-}
-#endif
-
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
@@ -3807,45 +3710,6 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
}
}
-#if 0
-ZSTD_CDict* ZSTD_initStaticCDict_advanced_opaque(
- void *workspace, size_t workspaceSize, const void* dict,
- size_t dictSize,
- const ZSTD_CCtx_params* params)
-{
- if (params == NULL) { return NULL; }
- { ZSTD_CCtx_params cctxParams = *params;
- size_t const cctxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
- size_t const neededSize = sizeof(ZSTD_CDict)
- + (cctxParams.dictContentByRef ? 0 : dictSize)
- + cctxSize;
- ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
- void* ptr;
- DEBUGLOG(5, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
- if ((size_t)workspace & 7) return NULL; /* 8-aligned */
- DEBUGLOG(5, "(workspaceSize < neededSize) : (%u < %u) => %u",
- (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
- if (workspaceSize < neededSize) return NULL;
-
- if (!cctxParams.dictContentByRef) {
- memcpy(cdict+1, dict, dictSize);
- dict = cdict+1;
- ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
- } else {
- ptr = cdict+1;
- }
- cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
- cctxParams.dictContentByRef = 1;
-
- /* What if nbThreads > 1? */
- if (ZSTD_isError( ZSTD_initCDict_internal_opaque(cdict, dict, dictSize, cctxParams) ))
- return NULL;
-
- return cdict;
- }
-}
-#endif
-
/*! ZSTD_initStaticCDict_advanced() :
* Generate a digested dictionary in provided memory area.
* workspace: The memory area to emplace the dictionary into.
@@ -3893,12 +3757,6 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
return cdict;
}
-#if 0
-static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
- return ZSTD_getParamsFromCCtx(cdict->refContext);
-}a
-#endif
-
ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict) {
return cdict->refContext->appliedParams;
}
@@ -3910,7 +3768,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
if (cdict==NULL) return ERROR(dictionary_wrong);
- { ZSTD_CCtx_params params = cdict->refContext->appliedParams;
+ { ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
params.fParams = fParams;
params.dictMode = ZSTD_dm_auto;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
@@ -3992,7 +3850,7 @@ size_t ZSTD_CStreamOutSize(void)
return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
}
-static size_t ZSTD_resetCStream_internal_opaque(
+static size_t ZSTD_resetCStream_internal(
ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
const ZSTD_CDict* cdict,
@@ -4018,20 +3876,6 @@ static size_t ZSTD_resetCStream_internal_opaque(
return 0; /* ready to go */
}
-#if 0
-static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
- const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
-{
- ZSTD_CCtx_params cctxParams = zcs->requestedParams;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- return ZSTD_resetCStream_internal_opaque(zcs, dict, dictSize,
- cdict, cctxParams, pledgedSrcSize);
-}
-#endif
-
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params params = zcs->requestedParams;
@@ -4040,10 +3884,14 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
params.cParams = ZSTD_getCParams(params.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
}
- return ZSTD_resetCStream_internal_opaque(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
}
-size_t ZSTD_initCStream_internal_opaque(
+/*! ZSTD_initCStream_internal() :
+ * Note : not static (but hidden) (not exposed). Used by zstdmt_compress.c
+ * Assumption 1 : params are valid
+ * Assumption 2 : either dict, or cdict, is defined, not both */
+size_t ZSTD_initCStream_internal(
ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
const ZSTD_CDict* cdict,
@@ -4079,28 +3927,10 @@ size_t ZSTD_initCStream_internal_opaque(
}
zcs->requestedParams = params;
- return ZSTD_resetCStream_internal_opaque(
+ return ZSTD_resetCStream_internal(
zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
}
-#if 0
-/*! ZSTD_initCStream_internal() :
- * Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
- * Assumption 1 : params are valid
- * Assumption 2 : either dict, or cdict, is defined, not both */
-static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
-{
- ZSTD_CCtx_params cctxParams = zcs->requestedParams;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
- return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, cdict,
- cctxParams, pledgedSrcSize);
-}
-#endif
-
/* ZSTD_initCStream_usingCDict_advanced() :
* same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
@@ -4112,7 +3942,7 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
{ ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
params.fParams = fParams;
params.compressionLevel = ZSTD_CLEVEL_CUSTOM;
- return ZSTD_initCStream_internal_opaque(zcs,
+ return ZSTD_initCStream_internal(zcs,
NULL, 0, cdict,
params, pledgedSrcSize);
}
@@ -4134,7 +3964,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
- return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
+ return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
}
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
@@ -4144,7 +3974,7 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
cctxParams.compressionLevel = compressionLevel;
- return ZSTD_initCStream_internal_opaque(zcs, dict, dictSize, NULL, cctxParams, 0);
+ return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, 0);
}
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
@@ -4363,7 +4193,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
} else
#endif
{
- CHECK_F( ZSTD_resetCStream_internal_opaque(cctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
} }
/* compression stage */
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index cf362a756..ebedec904 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -186,12 +186,12 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_free(buf.start, bufPool->cMem);
}
-/* TODO: Set relevant job parameters, initialize others to default.
- * Notably, nbThreads should be zero. */
+/* Sets parameterse relevant to the compression job, initializing others to
+ * default values. Notably, nbThreads should probably be zero. */
static ZSTD_CCtx_params ZSTDMT_makeJobCCtxParams(ZSTD_CCtx_params const params)
{
ZSTD_CCtx_params jobParams;
- memset(&jobParams, 0, sizeof(jobParams));
+ memset(&jobParams, 0, sizeof(ZSTD_CCtx_params));
jobParams.cParams = params.cParams;
jobParams.fParams = params.fParams;
@@ -725,9 +725,9 @@ size_t ZSTDMT_initCStream_internal_opaque(
if (zcs->nbThreads==1) {
DEBUGLOG(4, "single thread mode");
- return ZSTD_initCStream_internal_opaque(zcs->cctxPool->cctx[0],
- dict, dictSize, cdict,
- requestedParams, pledgedSrcSize);
+ return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0],
+ dict, dictSize, cdict,
+ requestedParams, pledgedSrcSize);
}
if (zcs->allJobsCompleted == 0) { /* previous compression not correctly finished */
diff --git a/tests/cctxParamRoundTrip.c b/tests/cctxParamRoundTrip.c
index 906ad9cec..5ce47d4d1 100644
--- a/tests/cctxParamRoundTrip.c
+++ b/tests/cctxParamRoundTrip.c
@@ -70,6 +70,8 @@ static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity,
ZSTD_outBuffer outBuffer = {compressedBuff, compressedBuffCapacity, 0 };
CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, 1) );
+ CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbThreads, 3) );
+ CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionStrategy, ZSTD_lazy) );
CHECK_Z( ZSTD_CCtx_applyCCtxParams(cctx, cctxParams) );
CHECK_Z (ZSTD_compress_generic(cctx, &outBuffer, &inBuffer, ZSTD_e_end) );
From 23fc0e41fac27cca8ff41a283238f29d190e5462 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 22 Aug 2017 14:24:47 -0700
Subject: [PATCH 035/248] Remove 'opaque' naming from internal functions
---
lib/common/zstd_internal.h | 12 ++++----
lib/compress/zstd_compress.c | 26 ++++++++---------
lib/compress/zstdmt_compress.c | 52 +++++++++++++++-------------------
3 files changed, 42 insertions(+), 48 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 4e56f6a92..a68c7cbce 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -372,17 +372,17 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict);
/* INTERNAL */
-size_t ZSTD_compressBegin_advanced_opaque(ZSTD_CCtx* cctx,
+size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize);
/* INTERNAL */
-size_t ZSTD_compress_advanced_opaque(ZSTD_CCtx* cctx,
- void* dst, size_t dstCapacity,
- const void* src, size_t srcSize,
- const void* dict,size_t dictSize,
- ZSTD_CCtx_params params);
+size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_CCtx_params params);
typedef struct {
blockType_e blockType;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index cfefe5c20..65081b239 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3418,7 +3418,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
return ZSTD_compress_insertDictionary(cctx, dict, dictSize, params.dictMode);
}
-size_t ZSTD_compressBegin_advanced_opaque(
+size_t ZSTD_compressBegin_advanced_internal(
ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_CCtx_params params,
@@ -3443,8 +3443,8 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
cctxParams.fParams = params.fParams;
cctxParams.dictMode = ZSTD_dm_auto;
- return ZSTD_compressBegin_advanced_opaque(cctx, dict, dictSize, cctxParams,
- pledgedSrcSize);
+ return ZSTD_compressBegin_advanced_internal(cctx, dict, dictSize, cctxParams,
+ pledgedSrcSize);
}
@@ -3535,11 +3535,11 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
cctxParams.dictMode = ZSTD_dm_auto;
- return ZSTD_compress_advanced_opaque(cctx,
- dst, dstCapacity,
- src, srcSize,
- dict, dictSize,
- cctxParams);
+ return ZSTD_compress_advanced_internal(cctx,
+ dst, dstCapacity,
+ src, srcSize,
+ dict, dictSize,
+ cctxParams);
}
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
@@ -3553,7 +3553,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
}
/* Internal */
-size_t ZSTD_compress_advanced_opaque(
+size_t ZSTD_compress_advanced_internal(
ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
@@ -3888,7 +3888,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
}
/*! ZSTD_initCStream_internal() :
- * Note : not static (but hidden) (not exposed). Used by zstdmt_compress.c
+ * Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
* Assumption 1 : params are valid
* Assumption 2 : either dict, or cdict, is defined, not both */
size_t ZSTD_initCStream_internal(
@@ -4154,12 +4154,12 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
return ZSTD_compressStream_generic(zcs, output, input, ZSTD_e_continue);
}
-/*! ZSTDMT_initCStream_internal_opaque() :
+/*! ZSTDMT_initCStream_internal() :
* Private use only. Init streaming operation.
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
* @return : 0, or an error code */
-size_t ZSTDMT_initCStream_internal_opaque(ZSTDMT_CCtx* zcs,
+size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
@@ -4188,7 +4188,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
#ifdef ZSTD_MULTITHREAD
if (params.nbThreads > 1) {
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
- CHECK_F( ZSTDMT_initCStream_internal_opaque(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
cctx->streamStage = zcss_load;
} else
#endif
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index ebedec904..4b8360933 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -342,7 +342,7 @@ void ZSTDMT_compressChunk(void* jobDescription)
} else { /* srcStart points at reloaded section */
if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
{ size_t const dictModeError = ZSTD_setCCtxParameter(cctx, ZSTD_p_forceRawDict, 1); /* Force loading dictionary in "content-only" mode (no header analysis) */
- size_t const initError = ZSTD_compressBegin_advanced_opaque(cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
+ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
if (ZSTD_isError(initError) || ZSTD_isError(dictModeError)) { job->cSize = initError; goto _endJob; }
ZSTD_setCCtxParameter(cctx, ZSTD_p_forceWindow, 1);
} }
@@ -540,7 +540,7 @@ static unsigned computeNbChunks(size_t srcSize, unsigned windowLog, unsigned nbT
return (multiplier>1) ? nbChunksLarge : nbChunksSmall;
}
-static size_t ZSTDMT_compress_advanced_opaque(
+static size_t ZSTDMT_compress_advanced_internal(
ZSTDMT_CCtx* mtctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
@@ -564,7 +564,7 @@ static size_t ZSTDMT_compress_advanced_opaque(
if (nbChunks==1) { /* fallback to single-thread mode */
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, cctxParams.fParams);
- return ZSTD_compress_advanced_opaque(cctx, dst, dstCapacity, src, srcSize, NULL, 0, requestedParams);
+ return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, requestedParams);
}
assert(avgChunkSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), which is required for compressWithinDst */
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgChunkSize) );
@@ -674,10 +674,10 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
ZSTD_CCtx_params cctxParams = mtctx->params;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
- return ZSTDMT_compress_advanced_opaque(mtctx,
- dst, dstCapacity,
- src, srcSize,
- cdict, cctxParams, overlapLog);
+ return ZSTDMT_compress_advanced_internal(mtctx,
+ dst, dstCapacity,
+ src, srcSize,
+ cdict, cctxParams, overlapLog);
}
@@ -712,7 +712,7 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs)
}
}
-size_t ZSTDMT_initCStream_internal_opaque(
+size_t ZSTDMT_initCStream_internal(
ZSTDMT_CCtx* zcs, const void* dict, size_t dictSize,
const ZSTD_CDict* cdict, ZSTD_CCtx_params cctxParams,
unsigned long long pledgedSrcSize)
@@ -773,25 +773,17 @@ size_t ZSTDMT_initCStream_internal_opaque(
return 0;
}
-/** ZSTDMT_initCStream_internal() */
-static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
- const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
-{
- ZSTD_CCtx_params cctxParams = zcs->params;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
- return ZSTDMT_initCStream_internal_opaque(zcs, dict, dictSize, cdict,
- cctxParams, pledgedSrcSize);
-}
-
size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
const void* dict, size_t dictSize,
ZSTD_parameters params,
unsigned long long pledgedSrcSize)
{
+ ZSTD_CCtx_params cctxParams = mtctx->params;
DEBUGLOG(5, "ZSTDMT_initCStream_advanced");
- return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, NULL, params, pledgedSrcSize);
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, NULL,
+ cctxParams, pledgedSrcSize);
}
size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
@@ -799,12 +791,11 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params requestedParams =
- ZSTDMT_makeJobCCtxParams(ZSTD_getCCtxParamsFromCDict(cdict));
+ ZSTD_CCtx_params requestedParams = ZSTD_getCCtxParamsFromCDict(cdict);
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
requestedParams.fParams = fParams;
- return ZSTDMT_initCStream_internal_opaque(mtctx, NULL, 0 /*dictSize*/, cdict,
- requestedParams, pledgedSrcSize);
+ return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
+ requestedParams, pledgedSrcSize);
}
@@ -814,13 +805,16 @@ size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize)
{
if (zcs->nbThreads==1)
return ZSTD_resetCStream(zcs->cctxPool->cctx[0], pledgedSrcSize);
- return ZSTDMT_initCStream_internal_opaque(zcs, NULL, 0, 0, zcs->params,
- pledgedSrcSize);
+ return ZSTDMT_initCStream_internal(zcs, NULL, 0, 0, zcs->params,
+ pledgedSrcSize);
}
size_t ZSTDMT_initCStream(ZSTDMT_CCtx* zcs, int compressionLevel) {
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
- return ZSTDMT_initCStream_internal(zcs, NULL, 0, NULL, params, 0);
+ ZSTD_CCtx_params cctxParams = zcs->params;
+ cctxParams.cParams = params.cParams;
+ cctxParams.fParams = params.fParams;
+ return ZSTDMT_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, 0);
}
@@ -973,7 +967,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
&& (mtctx->inBuff.filled==0) /* nothing buffered */
&& (endOp==ZSTD_e_end) /* end order */
&& (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough room */
- size_t const cSize = ZSTDMT_compress_advanced_opaque(mtctx,
+ size_t const cSize = ZSTDMT_compress_advanced_internal(mtctx,
(char*)output->dst + output->pos, output->size - output->pos,
(const char*)input->src + input->pos, input->size - input->pos,
mtctx->cdict, mtctx->params, mtctx->overlapLog);
From 11303778d0fbc2559e7bf3e6b4f6b25b8748451a Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 22 Aug 2017 14:53:13 -0700
Subject: [PATCH 036/248] Add function to make cctxParams from ZSTD_parameters
---
lib/compress/zstd_compress.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 65081b239..d6f50e60c 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -271,6 +271,15 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
return 0;
}
+static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
+ ZSTD_CCtx_params cctxParams, ZSTD_parameters params)
+{
+ ZSTD_CCtx_params ret = cctxParams;
+ ret.cParams = params.cParams;
+ ret.fParams = params.fParams;
+ return ret;
+}
+
static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
{
if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
@@ -3438,11 +3447,9 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
ZSTD_parameters params,
unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params cctxParams = cctx->requestedParams;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
+ ZSTD_CCtx_params cctxParams =
+ ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
cctxParams.dictMode = ZSTD_dm_auto;
-
return ZSTD_compressBegin_advanced_internal(cctx, dict, dictSize, cctxParams,
pledgedSrcSize);
}
@@ -3531,9 +3538,8 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
const void* dict,size_t dictSize,
ZSTD_parameters params)
{
- ZSTD_CCtx_params cctxParams = cctx->requestedParams;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
+ ZSTD_CCtx_params cctxParams =
+ ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
cctxParams.dictMode = ZSTD_dm_auto;
return ZSTD_compress_advanced_internal(cctx,
dst, dstCapacity,
@@ -3959,10 +3965,9 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params cctxParams = zcs->requestedParams;
+ ZSTD_CCtx_params cctxParams =
+ ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
CHECK_F( ZSTD_checkCParams(params.cParams) );
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
}
@@ -3970,9 +3975,8 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- ZSTD_CCtx_params cctxParams = zcs->requestedParams;
- cctxParams.cParams = params.cParams;
- cctxParams.fParams = params.fParams;
+ ZSTD_CCtx_params cctxParams =
+ ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
cctxParams.compressionLevel = compressionLevel;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, 0);
}
From 20f715d70971e77c892feeaaf8868ea06da9bd42 Mon Sep 17 00:00:00 2001
From: Dmitriy Titarenko
Date: Wed, 23 Aug 2017 15:56:15 +0500
Subject: [PATCH 037/248] Fix displayLevel overflow
---
lib/dictBuilder/cover.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
index 117acbf7b..61497846b 100644
--- a/lib/dictBuilder/cover.c
+++ b/lib/dictBuilder/cover.c
@@ -969,7 +969,7 @@ ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
/* Initialization */
COVER_best_init(&best);
/* Turn down global display level to clean up display at level 2 and below */
- g_displayLevel = parameters->zParams.notificationLevel - 1;
+ g_displayLevel = displayLevel == 0 ? 0 : displayLevel - 1;
/* Loop through d first because each new value needs a new context */
LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
kIterations);
From 6f1a21c7e9a41adbecba62b3f9e7eb6741f0eaef Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 23 Aug 2017 10:24:19 -0700
Subject: [PATCH 038/248] Remove formatting-only changes
---
lib/common/zstd_internal.h | 1 -
lib/compress/zstd_compress.c | 53 +++---
lib/compress/zstdmt_compress.c | 4 +-
lib/zstd.h | 3 +-
programs/fileio.c | 1 +
tests/zstreamtest.c | 293 +--------------------------------
6 files changed, 28 insertions(+), 327 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index a68c7cbce..53631b936 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -304,7 +304,6 @@ struct ZSTD_CCtx_params_s {
unsigned overlapSizeLog;
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
-
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index d6f50e60c..d1d321011 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -215,6 +215,7 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
}
}
+
#define ZSTD_CLEVEL_CUSTOM 999
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
{
@@ -3151,10 +3152,8 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
if (frame && (cctx->stage==ZSTDcs_init)) {
- fhSize = ZSTD_writeFrameHeader(
- dst, dstCapacity,
- cctx->appliedParams,
- cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity,cctx->appliedParams,
+ cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
if (ZSTD_isError(fhSize)) return fhSize;
dstCapacity -= fhSize;
dst = (char*)dst + fhSize;
@@ -3444,8 +3443,7 @@ size_t ZSTD_compressBegin_advanced_internal(
* @return : 0, or an error code */
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
- ZSTD_parameters params,
- unsigned long long pledgedSrcSize)
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
@@ -3571,11 +3569,8 @@ size_t ZSTD_compress_advanced_internal(
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
-size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst,
- size_t dstCapacity,
- const void* src, size_t srcSize,
- const void* dict, size_t dictSize,
- int compressionLevel)
+size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
+ const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0);
params.fParams.contentSizeFlag = 1;
@@ -3606,8 +3601,7 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
{
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
- DEBUGLOG(5, "CCtx estimate : %u",
- (U32)ZSTD_estimateCCtxSize_advanced(cParams));
+ DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize_advanced(cParams));
return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced(cParams)
+ (byReference ? 0 : dictSize);
}
@@ -3645,7 +3639,7 @@ static size_t ZSTD_initCDict_internal(
}
cdict->dictContentSize = dictSize;
- { ZSTD_frameParameters const fParams = { 0 /*contentSizeFlag */,
+ { ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
/* TODO: correct? */
ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
@@ -3666,7 +3660,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
{
- DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", dictMode);
+ DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
@@ -3677,8 +3671,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
return NULL;
}
cdict->refContext = cctx;
- if (ZSTD_isError( ZSTD_initCDict_internal(
- cdict,
+ if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dictBuffer, dictSize,
byReference, dictMode,
cParams) )) {
@@ -3735,8 +3728,7 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
ZSTD_compressionParameters cParams)
{
size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams);
- size_t const neededSize = sizeof(ZSTD_CDict)
- + (byReference ? 0 : dictSize)
+ size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize)
+ cctxSize;
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
void* ptr;
@@ -3755,9 +3747,10 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
}
cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
- if (ZSTD_isError( ZSTD_initCDict_internal(cdict, dict, dictSize,
- 1 /* byReference */,
- dictMode, cParams) ))
+ if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
+ dict, dictSize,
+ 1 /* byReference */, dictMode,
+ cParams) ))
return NULL;
return cdict;
@@ -3897,12 +3890,10 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
* Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
* Assumption 1 : params are valid
* Assumption 2 : either dict, or cdict, is defined, not both */
-size_t ZSTD_initCStream_internal(
- ZSTD_CStream* zcs,
- const void* dict, size_t dictSize,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params,
- unsigned long long pledgedSrcSize)
+size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
@@ -3931,10 +3922,10 @@ size_t ZSTD_initCStream_internal(
zcs->cdictLocal = NULL;
zcs->cdict = cdict;
}
+
zcs->requestedParams = params;
- return ZSTD_resetCStream_internal(
- zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
}
/* ZSTD_initCStream_usingCDict_advanced() :
@@ -4167,6 +4158,7 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
+
size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
ZSTD_outBuffer* output,
ZSTD_inBuffer* input,
@@ -4182,7 +4174,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
const void* const prefix = cctx->prefix;
size_t const prefixSize = cctx->prefixSize;
ZSTD_CCtx_params params = cctx->requestedParams;
-
if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM)
params.cParams = ZSTD_getCParams(params.compressionLevel,
cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 4b8360933..a52cb8aa0 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -62,7 +62,7 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void)
DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
elapsedTime, #mutex); \
} } \
- } else { pthread_mutex_lock(mutex); } \
+ } else pthread_mutex_lock(mutex); \
}
#else
@@ -743,7 +743,7 @@ size_t ZSTDMT_initCStream_internal(
ZSTD_freeCDict(zcs->cdictLocal);
/* TODO: cctxParam version? Is this correct? */
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- 0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
+ 0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
requestedParams.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
diff --git a/lib/zstd.h b/lib/zstd.h
index 3e7574c78..e207e46bf 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -987,7 +987,7 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
- * even when referencing into Dictionary content (default:0) */
+ * even when referencing into Dictionary content (default:0) */
} ZSTD_cParameter;
@@ -1101,6 +1101,7 @@ size_t ZSTD_compress_generic_simpleArgs (
const void* src, size_t srcSize, size_t* srcPos,
ZSTD_EndDirective endOp);
+
/** ZSTD_CCtx_params :
*
* - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
diff --git a/programs/fileio.c b/programs/fileio.c
index 669052d8b..1dd8008e8 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -214,6 +214,7 @@ void FIO_setOverlapLog(unsigned overlapLog){
g_overlapLog = overlapLog;
}
+
/*-*************************************
* Functions
***************************************/
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 8f974b461..98e121949 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1204,298 +1204,6 @@ _output_error:
goto _cleanup;
}
-
-/* Tests for ZSTD_compress_generic() API */
-#if 0
-static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)
-{
- U32 const maxSrcLog = bigTests ? 24 : 22;
- static const U32 maxSampleLog = 19;
- size_t const srcBufferSize = (size_t)1<= testNb) { DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); }
- else { DISPLAYUPDATE(2, "\r%6u ", testNb); }
- FUZ_rand(&coreSeed);
- lseed = coreSeed ^ prime32;
-
- /* states full reset (deliberately not synchronized) */
- /* some issues can only happen when reusing states */
- if ((FUZ_rand(&lseed) & 0xFF) == 131) {
- DISPLAYLEVEL(5, "Creating new context \n");
- ZSTD_freeCCtx(zc);
- zc = ZSTD_createCCtx();
- CHECK(zc==NULL, "ZSTD_createCCtx allocation error");
- resetAllowed=0;
- }
- if ((FUZ_rand(&lseed) & 0xFF) == 132) {
- ZSTD_freeDStream(zd);
- zd = ZSTD_createDStream();
- CHECK(zd==NULL, "ZSTD_createDStream allocation error");
- ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */
- }
-
- /* srcBuffer selection [0-4] */
- { U32 buffNb = FUZ_rand(&lseed) & 0x7F;
- if (buffNb & 7) buffNb=2; /* most common : compressible (P) */
- else {
- buffNb >>= 3;
- if (buffNb & 7) {
- const U32 tnb[2] = { 1, 3 }; /* barely/highly compressible */
- buffNb = tnb[buffNb >> 3];
- } else {
- const U32 tnb[2] = { 0, 4 }; /* not compressible / sparse */
- buffNb = tnb[buffNb >> 3];
- } }
- srcBuffer = cNoiseBuffer[buffNb];
- }
-
- /* compression init */
- CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) ); /* cancel previous dict /*/
- if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */
- && oldTestLog /* at least one test happened */ && resetAllowed) {
- maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
- if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1;
- { int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1;
- CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_compressionLevel, compressionLevel) );
- }
- } else {
- U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
- U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog;
- U32 const cLevelCandidate = (FUZ_rand(&lseed) %
- (ZSTD_maxCLevel() -
- (MAX(testLog, dictLog) / 3))) +
- 1;
- U32 const cLevel = MIN(cLevelCandidate, cLevelMax);
- maxTestSize = FUZ_rLogLength(&lseed, testLog);
- oldTestLog = testLog;
- /* random dictionary selection */
- dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0;
- { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize);
- dict = srcBuffer + dictStart;
- if (!dictSize) dict=NULL;
- }
- { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize;
- ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, pledgedSrcSize, dictSize);
-
- /* mess with compression parameters */
- cParams.windowLog += (FUZ_rand(&lseed) & 3) - 1;
- cParams.hashLog += (FUZ_rand(&lseed) & 3) - 1;
- cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1;
- cParams.searchLog += (FUZ_rand(&lseed) & 3) - 1;
- cParams.searchLength += (FUZ_rand(&lseed) & 3) - 1;
- cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((double)(FUZ_rand(&lseed) & 127) / 128)));
- cParams = ZSTD_adjustCParams(cParams, 0, 0);
-
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_hashLog, cParams.hashLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_chainLog, cParams.chainLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_searchLog, cParams.searchLog) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_minMatch, cParams.searchLength) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) );
-
- /* unconditionally set, to be sync with decoder */
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1) );
- if (FUZ_rand(&lseed) & 1) {
- CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
- if (dict && dictSize) {
- /* test that compression parameters are rejected (correctly) after loading a non-NULL dictionary */
- size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1) ;
- CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed");
- } } else {
- CHECK_Z( ZSTD_CCtx_refPrefix(zc, dict, dictSize) );
- }
-
- /* mess with frame parameters */
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
- DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize);
-
- /* multi-threading parameters */
- { U32 const nbThreadsCandidate = (FUZ_rand(&lseed) & 4) + 1;
- U32 const nbThreads = MIN(nbThreadsCandidate, nbThreadsMax);
- CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_nbThreads, nbThreads) );
- if (nbThreads > 1) {
- U32 const jobLog = FUZ_rand(&lseed) % (testLog+1);
- CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10) );
- CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_jobSize, (U32)FUZ_rLogLength(&lseed, jobLog)) );
- } } } }
-
- /* multi-segments compression test */
- XXH64_reset(&xxhState, 0);
- { ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ;
- for (cSize=0, totalTestSize=0 ; (totalTestSize < maxTestSize) ; ) {
- /* compress random chunks into randomly sized dst buffers */
- size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
- size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize);
- size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize);
- size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1);
- size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize);
- ZSTD_EndDirective const flush = (FUZ_rand(&lseed) & 15) ? ZSTD_e_continue : ZSTD_e_flush;
- ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 };
- outBuff.size = outBuff.pos + dstBuffSize;
-
- CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, flush) );
- DISPLAYLEVEL(5, "compress consumed %u bytes (total : %u) \n",
- (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos));
-
- XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos);
- memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos);
- totalTestSize += inBuff.pos;
- }
-
- /* final frame epilogue */
- { size_t remainingToFlush = (size_t)(-1);
- while (remainingToFlush) {
- ZSTD_inBuffer inBuff = { NULL, 0, 0 };
- size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog+1);
- size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
- outBuff.size = outBuff.pos + adjustedDstSize;
- DISPLAYLEVEL(5, "End-flush into dst buffer of size %u \n", (U32)adjustedDstSize);
- remainingToFlush = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end);
- CHECK(ZSTD_isError(remainingToFlush),
- "ZSTD_compress_generic w/ ZSTD_e_end error : %s",
- ZSTD_getErrorName(remainingToFlush) );
- } }
- crcOrig = XXH64_digest(&xxhState);
- cSize = outBuff.pos;
- DISPLAYLEVEL(5, "Frame completed : %u bytes \n", (U32)cSize);
- }
-
- /* multi - fragments decompression test */
- if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
- DISPLAYLEVEL(5, "resetting DCtx (dict:%08X) \n", (U32)(size_t)dict);
- CHECK_Z( ZSTD_resetDStream(zd) );
- } else {
- DISPLAYLEVEL(5, "using dict of size %u \n", (U32)dictSize);
- CHECK_Z( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
- }
- { size_t decompressionResult = 1;
- ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 };
- ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
- for (totalGenSize = 0 ; decompressionResult ; ) {
- size_t const readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog);
- size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
- size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
- inBuff.size = inBuff.pos + readCSrcSize;
- outBuff.size = inBuff.pos + dstBuffSize;
- DISPLAYLEVEL(5, "ZSTD_decompressStream input %u bytes (pos:%u/%u)\n",
- (U32)readCSrcSize, (U32)inBuff.pos, (U32)cSize);
- decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);
- CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult));
- DISPLAYLEVEL(5, "inBuff.pos = %u \n", (U32)readCSrcSize);
- }
- CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (U32)outBuff.pos, (U32)totalTestSize);
- CHECK (inBuff.pos != cSize, "compressed data should be fully read (%u != %u)", (U32)inBuff.pos, (U32)cSize);
- { U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0);
- if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize);
- CHECK (crcDest!=crcOrig, "decompressed data corrupted");
- } }
-
- /*===== noisy/erroneous src decompression test =====*/
-
- /* add some noise */
- { U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2;
- U32 nn; for (nn=0; nn
Date: Wed, 23 Aug 2017 12:03:30 -0700
Subject: [PATCH 039/248] Add prototype support for customMem with cctxParams
---
lib/common/zstd_internal.h | 4 ++
lib/compress/zstd_compress.c | 123 ++++++++++++++++++-----------------
lib/zstd.h | 4 +-
3 files changed, 71 insertions(+), 60 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 53631b936..4e2403bee 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -302,6 +302,10 @@ struct ZSTD_CCtx_params_s {
U32 nbThreads;
unsigned jobSize;
unsigned overlapSizeLog;
+
+ /* For use with createCCtxParams() and freeCCtxParams() only */
+ ZSTD_customMem customMem;
+
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index d1d321011..b375d369a 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -217,13 +217,22 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
#define ZSTD_CLEVEL_CUSTOM 999
+static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* params, size_t srcSize)
+{
+ if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
+ params->cParams = ZSTD_getCParams(params->compressionLevel, srcSize, 0);
+ params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
+}
+
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
{
- if (cctx->requestedParams.compressionLevel==ZSTD_CLEVEL_CUSTOM) return;
- cctx->requestedParams.cParams =
- ZSTD_getCParams(cctx->requestedParams.compressionLevel,
- cctx->pledgedSrcSizePlusOne-1, 0);
- cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
+ ZSTD_cLevelToCCtxParams_srcSize(
+ &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1);
+}
+
+static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
+{
+ ZSTD_cLevelToCCtxParams_srcSize(params, 0);
}
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
@@ -236,16 +245,31 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
return cctxParams;
}
-ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
+static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced(
+ ZSTD_customMem customMem)
{
- ZSTD_CCtx_params* params =
- (ZSTD_CCtx_params*)ZSTD_calloc(sizeof(ZSTD_CCtx_params),
- ZSTD_defaultCMem);
+ ZSTD_CCtx_params* params;
+ if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
+ params = (ZSTD_CCtx_params*)ZSTD_calloc(
+ sizeof(ZSTD_CCtx_params), customMem);
if (!params) { return NULL; }
+ params->customMem = customMem;
params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
return params;
}
+ZSTD_CCtx_params* ZSTD_createCCtxParams(void)
+{
+ return ZSTD_createCCtxParams_advanced(ZSTD_defaultCMem);
+}
+
+size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
+{
+ if (params == NULL) { return 0; }
+ ZSTD_free(params, params->customMem);
+ return 0;
+}
+
size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
{
if (!params) { return ERROR(GENERIC); }
@@ -265,13 +289,6 @@ size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
return 0;
}
-size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
-{
- if (params == NULL) { return 0; }
- ZSTD_free(params, ZSTD_defaultCMem);
- return 0;
-}
-
static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
ZSTD_CCtx_params cctxParams, ZSTD_parameters params)
{
@@ -281,13 +298,6 @@ static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
return ret;
}
-static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* params)
-{
- if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
- params->cParams = ZSTD_getCParams(params->compressionLevel, 0, 0);
- params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
-}
-
#define CLAMPCHECK(val,min,max) { \
if (((val)<(min)) | ((val)>(max))) { \
return ERROR(parameter_outOfBound); \
@@ -311,7 +321,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_minMatch:
case ZSTD_p_targetLength:
case ZSTD_p_compressionStrategy:
- if (value == 0) return 0;
+ if (value == 0) return 0; /* special value : 0 means "don't change anything" */
if (cctx->cdict) return ERROR(stage_wrong);
ZSTD_cLevelToCParams(cctx); /* Can optimize if srcSize is known */
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
@@ -329,9 +339,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize,
* even when referencing into Dictionary content
* default : 0 when using a CDict, 1 when using a Prefix */
- cctx->requestedParams.forceWindow = value>0;
cctx->loadedDictEnd = 0;
- return 0;
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_nbThreads:
if (value==0) return 0;
@@ -521,7 +530,6 @@ static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
*/
size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
{
- if (params == NULL) { return ERROR(GENERIC); }
if (cctx->cdict) { return ERROR(stage_wrong); }
/* Assume the compression and frame parameters are validated */
@@ -545,6 +553,8 @@ size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
}
+
+ /* customMem is used only for create/free params and can be ignored */
return 0;
}
@@ -693,32 +703,29 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params)
{
- if (params == NULL) { return 0; }
- { ZSTD_compressionParameters const cParams = params->cParams;
- size_t const blockSize =
- MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
- U32 const divider = (cParams.searchLength==3) ? 3 : 4;
- size_t const maxNbSeq = blockSize / divider;
- size_t const tokenSpace = blockSize + 11*maxNbSeq;
- size_t const chainSize =
- (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
- 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 = sizeof(ZSTD_entropyCTables_t);
- size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
+ ZSTD_compressionParameters const cParams = params->cParams;
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
+ U32 const divider = (cParams.searchLength==3) ? 3 : 4;
+ size_t const maxNbSeq = blockSize / divider;
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
+ size_t const chainSize =
+ (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
+ 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 = sizeof(ZSTD_entropyCTables_t);
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
- size_t const optBudget =
- ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<cParams.windowLog);
- size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
- size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
- size_t const streamingSize = inBuffSize + outBuffSize;
+ size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
+ size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
+ size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
+ size_t const streamingSize = inBuffSize + outBuffSize;
- return CCtxSize + streamingSize;
- }
+ return CCtxSize + streamingSize;
}
size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams)
diff --git a/lib/zstd.h b/lib/zstd.h
index e207e46bf..4cff6974b 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -1111,7 +1111,9 @@ size_t ZSTD_compress_generic_simpleArgs (
* - ZSTD_CCtx_applyCCtxParams() : Apply parameters to an existing CCtx. These
* parameters will be applied to all subsequent compression jobs.
* - ZSTD_compress_generic() : Do compression using the CCtx.
- * - ZSTD_freeCCtxParams() : Free the memory. */
+ * - ZSTD_freeCCtxParams() : Free the memory.
+ *
+ * This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation. */
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
From 64ce49426bf4fb7873027f040a7a3fa1fd666563 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 23 Aug 2017 12:30:47 -0700
Subject: [PATCH 040/248] Fix cstream compression level
---
lib/compress/zstd_compress.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index b375d369a..bfe021949 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3457,14 +3457,16 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
pledgedSrcSize);
}
-
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- return ZSTD_compressBegin_advanced(cctx, dict, dictSize, params, 0);
+ ZSTD_CCtx_params cctxParams =
+ ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
+ cctxParams.dictMode = ZSTD_dm_auto;
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
+ cctxParams, 0, ZSTDb_not_buffered);
}
-
size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
{
return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel);
@@ -3928,6 +3930,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
zcs->cdict = cdict;
}
+ params.compressionLevel = ZSTD_CLEVEL_CUSTOM;
zcs->requestedParams = params;
return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
@@ -3943,7 +3946,6 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
if (!cdict) return ERROR(dictionary_wrong);
{ ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
params.fParams = fParams;
- params.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_initCStream_internal(zcs,
NULL, 0, cdict,
params, pledgedSrcSize);
@@ -3964,7 +3966,6 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
ZSTD_CCtx_params cctxParams =
ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
CHECK_F( ZSTD_checkCParams(params.cParams) );
- cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
}
@@ -3973,15 +3974,16 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
ZSTD_CCtx_params cctxParams =
ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
- cctxParams.compressionLevel = compressionLevel;
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, 0);
}
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
{
+ ZSTD_CCtx_params cctxParams;
ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
params.fParams.contentSizeFlag = (pledgedSrcSize>0);
- return ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize);
+ cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
+ return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, pledgedSrcSize);
}
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
From 1c81f725ff7d8caa9136154fb2fdd19488f23083 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 23 Aug 2017 15:47:15 -0700
Subject: [PATCH 041/248] Remove duplicated testing code
---
lib/compress/zstd_compress.c | 2 +-
tests/Makefile | 7 +-
tests/cctxParamRoundTrip.c | 205 -----------------------------------
tests/roundTripCrash.c | 79 +++++++++++---
4 files changed, 67 insertions(+), 226 deletions(-)
delete mode 100644 tests/cctxParamRoundTrip.c
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index bfe021949..40b6625fc 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -217,7 +217,7 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
#define ZSTD_CLEVEL_CUSTOM 999
-static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* params, size_t srcSize)
+static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* params, U64 srcSize)
{
if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
params->cParams = ZSTD_getCParams(params->compressionLevel, srcSize, 0);
diff --git a/tests/Makefile b/tests/Makefile
index 228f4cdd2..3734f7737 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -169,11 +169,6 @@ datagen : $(PRGDIR)/datagen.c datagencli.c
roundTripCrash : $(ZSTD_FILES) roundTripCrash.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
-cctxParamRoundTrip : LDFLAGS += $(MULTITHREAD_CPP)
-cctxParamRoundTrip : LDFLAGS += $(MULTITHREAD_LD)
-cctxParamRoundTrip : $(ZSTD_FILES) cctxParamRoundTrip.c
- $(CC) $(FLAGS) $^ -o $@$(EXT)
-
longmatch : $(ZSTD_FILES) longmatch.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
@@ -217,7 +212,7 @@ clean:
fuzzer$(EXT) fuzzer32$(EXT) zbufftest$(EXT) zbufftest32$(EXT) \
fuzzer-dll$(EXT) zstreamtest-dll$(EXT) zbufftest-dll$(EXT)\
zstreamtest$(EXT) zstreamtest32$(EXT) \
- datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) cctxParamRoundTrip$(EXT) longmatch$(EXT) \
+ datagen$(EXT) paramgrill$(EXT) roundTripCrash$(EXT) longmatch$(EXT) \
symbols$(EXT) invalidDictionaries$(EXT) legacy$(EXT) poolTests$(EXT) \
decodecorpus$(EXT)
@echo Cleaning completed
diff --git a/tests/cctxParamRoundTrip.c b/tests/cctxParamRoundTrip.c
deleted file mode 100644
index 5ce47d4d1..000000000
--- a/tests/cctxParamRoundTrip.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
-
-/*
- This program takes a file in input,
- performs a zstd round-trip test (compression - decompress)
- compares the result with original
- and generates a crash (double free) on corruption detection.
-*/
-
-/*===========================================
-* Dependencies
-*==========================================*/
-#include /* size_t */
-#include /* malloc, free, exit */
-#include /* fprintf */
-#include /* stat */
-#include /* stat */
-#include "xxhash.h"
-
-#define ZSTD_STATIC_LINKING_ONLY
-#include "zstd.h"
-
-/*===========================================
-* Macros
-*==========================================*/
-#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
-
-static void crash(int errorCode){
- /* abort if AFL/libfuzzer, exit otherwise */
- #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */
- abort();
- #else
- exit(errorCode);
- #endif
-}
-
-#define CHECK_Z(f) { \
- size_t const err = f; \
- if (ZSTD_isError(err)) { \
- fprintf(stderr, \
- "Error=> %s: %s", \
- #f, ZSTD_getErrorName(err)); \
- crash(1); \
-} }
-
-/** roundTripTest() :
-* Compresses `srcBuff` into `compressedBuff`,
-* then decompresses `compressedBuff` into `resultBuff`.
-*
-* Parameters are currently set manually.
-*
-* @return : result of decompression, which should be == `srcSize`
-* or an error code if either compression or decompression fails.
-* Note : `compressedBuffCapacity` should be `>= ZSTD_compressBound(srcSize)`
-* for compression to be guaranteed to work */
-static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity,
- void* compressedBuff, size_t compressedBuffCapacity,
- const void* srcBuff, size_t srcBuffSize)
-{
- ZSTD_CCtx* const cctx = ZSTD_createCCtx();
- ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams();
- ZSTD_inBuffer inBuffer = { srcBuff, srcBuffSize, 0 };
- ZSTD_outBuffer outBuffer = {compressedBuff, compressedBuffCapacity, 0 };
-
- CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, 1) );
- CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbThreads, 3) );
- CHECK_Z (ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionStrategy, ZSTD_lazy) );
- CHECK_Z( ZSTD_CCtx_applyCCtxParams(cctx, cctxParams) );
-
- CHECK_Z (ZSTD_compress_generic(cctx, &outBuffer, &inBuffer, ZSTD_e_end) );
-
- ZSTD_freeCCtxParams(cctxParams);
- ZSTD_freeCCtx(cctx);
-
- return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, outBuffer.pos);
-}
-
-
-static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize)
-{
- const char* ip1 = (const char*)buff1;
- const char* ip2 = (const char*)buff2;
- size_t pos;
-
- for (pos=0; pos= `fileSize` */
-static void loadFile(void* buffer, const char* fileName, size_t fileSize)
-{
- FILE* const f = fopen(fileName, "rb");
- if (isDirectory(fileName)) {
- fprintf(stderr, "Ignoring %s directory \n", fileName);
- exit(2);
- }
- if (f==NULL) {
- fprintf(stderr, "Impossible to open %s \n", fileName);
- exit(3);
- }
- { size_t const readSize = fread(buffer, 1, fileSize, f);
- if (readSize != fileSize) {
- fprintf(stderr, "Error reading %s \n", fileName);
- exit(5);
- } }
- fclose(f);
-}
-
-
-static void fileCheck(const char* fileName)
-{
- size_t const fileSize = getFileSize(fileName);
- void* buffer = malloc(fileSize);
- if (!buffer) {
- fprintf(stderr, "not enough memory \n");
- exit(4);
- }
- loadFile(buffer, fileName, fileSize);
- roundTripCheck(buffer, fileSize);
- free (buffer);
-}
-
-int main(int argCount, const char** argv) {
- if (argCount < 2) {
- fprintf(stderr, "Error : no argument : need input file \n");
- exit(9);
- }
- fileCheck(argv[1]);
- fprintf(stderr, "no pb detected\n");
- return 0;
-}
diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c
index 77c6737ee..fb14fa87b 100644
--- a/tests/roundTripCrash.c
+++ b/tests/roundTripCrash.c
@@ -20,9 +20,12 @@
#include /* size_t */
#include /* malloc, free, exit */
#include /* fprintf */
+#include /* strcmp */
#include /* stat */
#include /* stat */
#include "xxhash.h"
+
+#define ZSTD_STATIC_LINKING_ONLY
#include "zstd.h"
/*===========================================
@@ -30,6 +33,24 @@
*==========================================*/
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
+static void crash(int errorCode){
+ /* abort if AFL/libfuzzer, exit otherwise */
+ #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */
+ abort();
+ #else
+ exit(errorCode);
+ #endif
+}
+
+#define CHECK_Z(f) { \
+ size_t const err = f; \
+ if (ZSTD_isError(err)) { \
+ fprintf(stderr, \
+ "Error=> %s: %s", \
+ #f, ZSTD_getErrorName(err)); \
+ crash(1); \
+} }
+
/** roundTripTest() :
* Compresses `srcBuff` into `compressedBuff`,
* then decompresses `compressedBuff` into `resultBuff`.
@@ -54,6 +75,35 @@ static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity,
return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, cSize);
}
+/** cctxParamRoundTripTest() :
+ * Same as roundTripTest() except allows experimenting with ZSTD_CCtx_params. */
+static size_t cctxParamRoundTripTest(void* resultBuff, size_t resultBuffCapacity,
+ void* compressedBuff, size_t compressedBuffCapacity,
+ const void* srcBuff, size_t srcBuffSize)
+{
+ ZSTD_CCtx* const cctx = ZSTD_createCCtx();
+ ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams();
+ ZSTD_inBuffer inBuffer = { srcBuff, srcBuffSize, 0 };
+ ZSTD_outBuffer outBuffer = {compressedBuff, compressedBuffCapacity, 0 };
+
+ static const int maxClevel = 19;
+ size_t const hashLength = MIN(128, srcBuffSize);
+ unsigned const h32 = XXH32(srcBuff, hashLength, 0);
+ int const cLevel = h32 % maxClevel;
+
+ /* Set parameters */
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, cLevel) );
+
+ /* Apply parameters */
+ CHECK_Z( ZSTD_CCtx_applyCCtxParams(cctx, cctxParams) );
+
+ CHECK_Z (ZSTD_compress_generic(cctx, &outBuffer, &inBuffer, ZSTD_e_end) );
+
+ ZSTD_freeCCtxParams(cctxParams);
+ ZSTD_freeCCtx(cctx);
+
+ return ZSTD_decompress(resultBuff, resultBuffCapacity, compressedBuff, outBuffer.pos);
+}
static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize)
{
@@ -68,16 +118,7 @@ static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize
return pos;
}
-static void crash(int errorCode){
- /* abort if AFL/libfuzzer, exit otherwise */
- #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */
- abort();
- #else
- exit(errorCode);
- #endif
-}
-
-static void roundTripCheck(const void* srcBuff, size_t srcBuffSize)
+static void roundTripCheck(const void* srcBuff, size_t srcBuffSize, int testCCtxParams)
{
size_t const cBuffSize = ZSTD_compressBound(srcBuffSize);
void* cBuff = malloc(cBuffSize);
@@ -88,7 +129,9 @@ static void roundTripCheck(const void* srcBuff, size_t srcBuffSize)
exit (1);
}
- { size_t const result = roundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize);
+ { size_t const result = testCCtxParams ?
+ cctxParamRoundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize)
+ : roundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize);
if (ZSTD_isError(result)) {
fprintf(stderr, "roundTripTest error : %s \n", ZSTD_getErrorName(result));
crash(1);
@@ -162,7 +205,7 @@ static void loadFile(void* buffer, const char* fileName, size_t fileSize)
}
-static void fileCheck(const char* fileName)
+static void fileCheck(const char* fileName, int testCCtxParams)
{
size_t const fileSize = getFileSize(fileName);
void* buffer = malloc(fileSize);
@@ -171,16 +214,24 @@ static void fileCheck(const char* fileName)
exit(4);
}
loadFile(buffer, fileName, fileSize);
- roundTripCheck(buffer, fileSize);
+ roundTripCheck(buffer, fileSize, testCCtxParams);
free (buffer);
}
int main(int argCount, const char** argv) {
+ int argNb = 1;
+ int testCCtxParams = 0;
if (argCount < 2) {
fprintf(stderr, "Error : no argument : need input file \n");
exit(9);
}
- fileCheck(argv[1]);
+
+ if (!strcmp(argv[argNb], "--cctxParams")) {
+ testCCtxParams = 1;
+ argNb++;
+ }
+
+ fileCheck(argv[argNb], testCCtxParams);
fprintf(stderr, "no pb detected\n");
return 0;
}
From bf3108fb50e0039a0fd15b3386366d40f0fd5a58 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 23 Aug 2017 17:03:31 -0700
Subject: [PATCH 042/248] Ensure zstdmt uses 'job version' of cctx parameters
---
lib/compress/zstd_compress.c | 2 --
lib/compress/zstdmt_compress.c | 20 ++++++++++----------
2 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 40b6625fc..8bf01c905 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -3648,11 +3648,9 @@ static size_t ZSTD_initCDict_internal(
{ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
- /* TODO: correct? */
ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
cctxParams.fParams = fParams;
cctxParams.cParams = cParams;
- cctxParams.dictContentByRef = byReference;
cctxParams.dictMode = dictMode;
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
cdict->dictContent, dictSize,
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index a52cb8aa0..927fff472 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -548,9 +548,10 @@ static size_t ZSTDMT_compress_advanced_internal(
ZSTD_CCtx_params const cctxParams,
unsigned overlapLog)
{
+ ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
unsigned const overlapRLog = (overlapLog>9) ? 0 : 9-overlapLog;
- size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (cctxParams.cParams.windowLog - overlapRLog);
- unsigned nbChunks = computeNbChunks(srcSize, cctxParams.cParams.windowLog, mtctx->nbThreads);
+ size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (requestedParams.cParams.windowLog - overlapRLog);
+ unsigned nbChunks = computeNbChunks(srcSize, requestedParams.cParams.windowLog, mtctx->nbThreads);
size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0x7FFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */
const char* const srcStart = (const char*)src;
@@ -558,12 +559,11 @@ static size_t ZSTDMT_compress_advanced_internal(
unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */
size_t frameStartPos = 0, dstBufferPos = 0;
XXH64_state_t xxh64;
- ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
- if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, cctxParams.fParams);
+ if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, requestedParams.fParams);
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, requestedParams);
}
assert(avgChunkSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), which is required for compressWithinDst */
@@ -605,7 +605,7 @@ static size_t ZSTDMT_compress_advanced_internal(
mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex;
mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond;
- if (cctxParams.fParams.checksumFlag) {
+ if (requestedParams.fParams.checksumFlag) {
XXH64_update(&xxh64, srcStart + frameStartPos, chunkSize);
}
@@ -648,8 +648,8 @@ static size_t ZSTDMT_compress_advanced_internal(
}
} /* for (chunkID=0; chunkID dstCapacity) {
error = ERROR(dstSize_tooSmall);
@@ -720,7 +720,7 @@ size_t ZSTDMT_initCStream_internal(
ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
DEBUGLOG(4, "ZSTDMT_initCStream_internal");
/* params are supposed to be fully validated at this point */
- assert(!ZSTD_isError(ZSTD_checkCParams(cctxParams.cParams)));
+ assert(!ZSTD_isError(ZSTD_checkCParams(requestedParams.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
if (zcs->nbThreads==1) {
@@ -736,7 +736,7 @@ size_t ZSTDMT_initCStream_internal(
zcs->allJobsCompleted = 1;
}
- zcs->params = cctxParams;
+ zcs->params = requestedParams;
zcs->frameContentSize = pledgedSrcSize;
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
@@ -769,7 +769,7 @@ size_t ZSTDMT_initCStream_internal(
zcs->nextJobID = 0;
zcs->frameEnded = 0;
zcs->allJobsCompleted = 0;
- if (cctxParams.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
+ if (requestedParams.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
return 0;
}
From fd9bf425160fbfd58ecac5da1058b28fcb88641a Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 23 Aug 2017 19:11:05 -0700
Subject: [PATCH 043/248] Fix forceWindow and dictMode setting for zstdmt jobs
---
lib/compress/zstdmt_compress.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 927fff472..6661e0a73 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -341,10 +341,21 @@ void ZSTDMT_compressChunk(void* jobDescription)
if (ZSTD_isError(initError)) { job->cSize = initError; goto _endJob; }
} else { /* srcStart points at reloaded section */
if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
- { size_t const dictModeError = ZSTD_setCCtxParameter(cctx, ZSTD_p_forceRawDict, 1); /* Force loading dictionary in "content-only" mode (no header analysis) */
- size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
- if (ZSTD_isError(initError) || ZSTD_isError(dictModeError)) { job->cSize = initError; goto _endJob; }
- ZSTD_setCCtxParameter(cctx, ZSTD_p_forceWindow, 1);
+ { ZSTD_CCtx_params jobParams = job->params;
+ /* Force loading dictionary in "content-only" mode (no header analysis) */
+ size_t const dictModeError =
+ ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_dictMode, 1);
+ size_t const forceWindowError =
+ ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstChunk);
+ /* TODO: new/old api do not interact well here (or with
+ * ZSTD_setCCtxParameter).
+ * ZSTD_compressBegin_advanced copies params directly to
+ * appliedParams. ZSTD_CCtx_setParameter sets params in requested
+ * parameters. They should not be mixed -- parameters should be passed
+ * directly */
+ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, jobParams, job->fullFrameSize);
+ if (ZSTD_isError(initError) || ZSTD_isError(dictModeError) ||
+ ZSTD_isError(forceWindowError)) { job->cSize = initError; goto _endJob; }
} }
if (!job->firstChunk) { /* flush and overwrite frame header when it's not first segment */
size_t const hSize = ZSTD_compressContinue(cctx, dstBuff.start, dstBuff.size, src, 0);
From 2fbf0285b2a1ac16e18007889b9422d88dfbdffc Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 24 Aug 2017 11:25:41 -0700
Subject: [PATCH 044/248] Fix interaction with ZSTD_setCCtxParameter() and
cleanup
---
lib/compress/zstd_compress.c | 35 ++++------------------------------
lib/compress/zstdmt_compress.c | 12 ++++--------
2 files changed, 8 insertions(+), 39 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 8bf01c905..f3f602230 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -198,18 +198,22 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
/* older variant; will be deprecated */
+/* Both requested and applied params need to be set as this function can be
+ * called before/after ZSTD_parameters have been applied. */
size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
{
switch(param)
{
case ZSTD_p_forceWindow :
cctx->requestedParams.forceWindow = value>0;
+ cctx->appliedParams.forceWindow = value>0;
cctx->loadedDictEnd = 0;
return 0;
ZSTD_STATIC_ASSERT(ZSTD_dm_auto==0);
ZSTD_STATIC_ASSERT(ZSTD_dm_rawContent==1);
case ZSTD_p_forceRawDict :
cctx->requestedParams.dictMode = (ZSTD_dictMode_e)(value>0);
+ cctx->appliedParams.dictMode = (ZSTD_dictMode_e)(value>0);
return 0;
default: return ERROR(parameter_unsupported);
}
@@ -491,35 +495,6 @@ size_t ZSTD_CCtxParam_setParameter(
}
}
-#if 0
-static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
-{
- DEBUGLOG(2, "======CCtxParams======");
- DEBUGLOG(2, "cParams: %u %u %u %u %u %u %u",
- params->cParams.windowLog,
- params->cParams.chainLog,
- params->cParams.hashLog,
- params->cParams.searchLog,
- params->cParams.searchLength,
- params->cParams.targetLength,
- params->cParams.strategy);
- DEBUGLOG(2, "fParams: %u %u %u",
- params->fParams.contentSizeFlag,
- params->fParams.checksumFlag,
- params->fParams.noDictIDFlag);
- DEBUGLOG(2, "cLevel, forceWindow: %u %u",
- params->compressionLevel,
- params->forceWindow);
- DEBUGLOG(2, "dictionary: %u %u",
- params->dictMode,
- params->dictContentByRef);
- DEBUGLOG(2, "multithreading: %u %u %u",
- params->nbThreads,
- params->jobSize,
- params->overlapSizeLog);
-}
-#endif
-
/**
* This function should be updated whenever ZSTD_CCtx_params is updated.
* Parameters are copied manually before the dictionary is loaded.
@@ -3910,8 +3885,6 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
return ERROR(memory_allocation);
}
ZSTD_freeCDict(zcs->cdictLocal);
-
- /* Is a CCtx_params version needed? */
zcs->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
params.dictContentByRef, params.dictMode,
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 6661e0a73..f7f02cfbb 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -186,7 +186,7 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
ZSTD_free(buf.start, bufPool->cMem);
}
-/* Sets parameterse relevant to the compression job, initializing others to
+/* Sets parameters relevant to the compression job, initializing others to
* default values. Notably, nbThreads should probably be zero. */
static ZSTD_CCtx_params ZSTDMT_makeJobCCtxParams(ZSTD_CCtx_params const params)
{
@@ -347,12 +347,9 @@ void ZSTDMT_compressChunk(void* jobDescription)
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_dictMode, 1);
size_t const forceWindowError =
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstChunk);
- /* TODO: new/old api do not interact well here (or with
- * ZSTD_setCCtxParameter).
- * ZSTD_compressBegin_advanced copies params directly to
- * appliedParams. ZSTD_CCtx_setParameter sets params in requested
- * parameters. They should not be mixed -- parameters should be passed
- * directly */
+ /* Note: ZSTD_setCCtxParameter() should not be used here.
+ * ZSTD_compressBegin_advanced_internal() copies the ZSTD_CCtx_params
+ * directly to appliedParams. */
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, jobParams, job->fullFrameSize);
if (ZSTD_isError(initError) || ZSTD_isError(dictModeError) ||
ZSTD_isError(forceWindowError)) { job->cSize = initError; goto _endJob; }
@@ -752,7 +749,6 @@ size_t ZSTDMT_initCStream_internal(
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
- /* TODO: cctxParam version? Is this correct? */
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
requestedParams.cParams, zcs->cMem);
From 376f4359142d296cc78435ca72335bf25bc7854e Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Thu, 24 Aug 2017 14:45:06 -0700
Subject: [PATCH 045/248] [dictBuilder] Set default compression level to 3
---
lib/dictBuilder/zdict.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c
index c2871c2cc..8e6aa9c1c 100644
--- a/lib/dictBuilder/zdict.c
+++ b/lib/dictBuilder/zdict.c
@@ -60,7 +60,7 @@
#define NOISELENGTH 32
-static const int g_compressionLevel_default = 6;
+static const int g_compressionLevel_default = 3;
static const U32 g_selectivity_default = 9;
@@ -703,7 +703,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
memset(repOffset, 0, sizeof(repOffset));
repOffset[1] = repOffset[4] = repOffset[8] = 1;
memset(bestRepOffset, 0, sizeof(bestRepOffset));
- if (compressionLevel==0) compressionLevel = g_compressionLevel_default;
+ if (compressionLevel<=0) compressionLevel = g_compressionLevel_default;
params = ZSTD_getParams(compressionLevel, averageSampleSize, dictBufferSize);
{ size_t const beginResult = ZSTD_compressBegin_advanced(esr.ref, dictBuffer, dictBufferSize, params, 0);
if (ZSTD_isError(beginResult)) {
@@ -1056,6 +1056,8 @@ size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
memset(¶ms, 0, sizeof(params));
params.d = 8;
params.steps = 4;
+ /* Default to level 6 since no compression level information is avaialble */
+ params.zParams.compressionLevel = 6;
return ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, dictBufferCapacity,
samplesBuffer, samplesSizes,
nbSamples, ¶ms);
From 15fdeb9e41306e8bb8d6a909a7be643768d75e6b Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 24 Aug 2017 16:28:49 -0700
Subject: [PATCH 046/248] Enforce nbThreads<=1 for estimateCCtxSize
---
lib/compress/zstd_compress.c | 63 ++++++++++++++++++++----------------
lib/zstd.h | 7 ++--
tests/Makefile | 1 +
3 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index f3f602230..4513d9831 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -678,29 +678,34 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params)
{
- ZSTD_compressionParameters const cParams = params->cParams;
- size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
- U32 const divider = (cParams.searchLength==3) ? 3 : 4;
- size_t const maxNbSeq = blockSize / divider;
- size_t const tokenSpace = blockSize + 11*maxNbSeq;
- size_t const chainSize =
- (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
- 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 = sizeof(ZSTD_entropyCTables_t);
- size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
+ /* Estimate CCtx size is supported for single-threaded compression only. */
+ if (params->nbThreads > 1) {
+ return 0;
+ }
+ { ZSTD_compressionParameters const cParams = params->cParams;
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
+ U32 const divider = (cParams.searchLength==3) ? 3 : 4;
+ size_t const maxNbSeq = blockSize / divider;
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
+ size_t const chainSize =
+ (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
+ 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 = sizeof(ZSTD_entropyCTables_t);
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
- size_t const optBudget =
- ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<cParams.windowLog);
- size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
- size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
- size_t const streamingSize = inBuffSize + outBuffSize;
+ if (params->nbThreads > 1) {
+ return 0;
+ }
+ { size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
+ size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
+ size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
+ size_t const streamingSize = inBuffSize + outBuffSize;
- return CCtxSize + streamingSize;
+ return CCtxSize + streamingSize;
+ }
}
size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams)
diff --git a/lib/zstd.h b/lib/zstd.h
index 4cff6974b..03994f9a8 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -498,7 +498,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCCtxSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter().
+ * ZSTD_estimateCCtxSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
@@ -510,7 +510,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
* ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCStreamSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter().
+ * ZSTD_estimateCStreamSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.
* This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -1113,7 +1113,8 @@ size_t ZSTD_compress_generic_simpleArgs (
* - ZSTD_compress_generic() : Do compression using the CCtx.
* - ZSTD_freeCCtxParams() : Free the memory.
*
- * This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation. */
+ * This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation
+ * for single-threaded compression. */
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
diff --git a/tests/Makefile b/tests/Makefile
index 3734f7737..006059b72 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -323,6 +323,7 @@ test-zstream: zstreamtest
$(QEMU_SYS) ./zstreamtest $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
$(QEMU_SYS) ./zstreamtest --mt $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
$(QEMU_SYS) ./zstreamtest --newapi $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
+ $(QEMU_SYS) ./zstreamtest --opaqueapi $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
test-zstream32: zstreamtest32
$(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS)
From 89dc856caee4a9c10740b6ee8b20aaa74f1a2b7b Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Thu, 24 Aug 2017 16:48:32 -0700
Subject: [PATCH 047/248] [pool] Fix formatting
---
lib/common/pool.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/lib/common/pool.c b/lib/common/pool.c
index a227044f7..0f848901a 100644
--- a/lib/common/pool.c
+++ b/lib/common/pool.c
@@ -25,8 +25,8 @@
/* A job is a function and an opaque argument */
typedef struct POOL_job_s {
- POOL_function function;
- void *opaque;
+ POOL_function function;
+ void *opaque;
} POOL_job;
struct POOL_ctx_s {
@@ -214,13 +214,13 @@ void POOL_add(void* ctxVoid, POOL_function function, void *opaque) {
/* We don't need any data, but if it is empty malloc() might return NULL. */
struct POOL_ctx_s {
- int data;
+ int data;
};
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
- (void)numThreads;
- (void)queueSize;
- return (POOL_ctx*)malloc(sizeof(POOL_ctx));
+ (void)numThreads;
+ (void)queueSize;
+ return (POOL_ctx*)malloc(sizeof(POOL_ctx));
}
void POOL_free(POOL_ctx* ctx) {
@@ -228,8 +228,8 @@ void POOL_free(POOL_ctx* ctx) {
}
void POOL_add(void* ctx, POOL_function function, void* opaque) {
- (void)ctx;
- function(opaque);
+ (void)ctx;
+ function(opaque);
}
size_t POOL_sizeof(POOL_ctx* ctx) {
From 26dc040a7b0b527a65da93020a8f4c15652e17ee Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Thu, 24 Aug 2017 17:01:41 -0700
Subject: [PATCH 048/248] [pool] Accept custom allocators
---
lib/common/pool.c | 32 ++++++++++++++++++++++----------
lib/common/pool.h | 3 +++
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/lib/common/pool.c b/lib/common/pool.c
index 0f848901a..ada9b1696 100644
--- a/lib/common/pool.c
+++ b/lib/common/pool.c
@@ -30,6 +30,7 @@ typedef struct POOL_job_s {
} POOL_job;
struct POOL_ctx_s {
+ ZSTD_customMem customMem;
/* Keep track of the threads */
pthread_t *threads;
size_t numThreads;
@@ -98,11 +99,15 @@ static void* POOL_thread(void* opaque) {
}
POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
+ return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
+}
+
+POOL_ctx *POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
POOL_ctx *ctx;
/* Check the parameters */
if (!numThreads) { return NULL; }
/* Allocate the context and zero initialize */
- ctx = (POOL_ctx *)calloc(1, sizeof(POOL_ctx));
+ ctx = (POOL_ctx *)ZSTD_calloc(sizeof(POOL_ctx), customMem);
if (!ctx) { return NULL; }
/* Initialize the job queue.
* It needs one extra space since one space is wasted to differentiate empty
@@ -119,8 +124,9 @@ POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
(void)pthread_cond_init(&ctx->queuePopCond, NULL);
ctx->shutdown = 0;
/* Allocate space for the thread handles */
- ctx->threads = (pthread_t*)malloc(numThreads * sizeof(pthread_t));
+ ctx->threads = (pthread_t*)ZSTD_malloc(numThreads * sizeof(pthread_t), customMem);
ctx->numThreads = 0;
+ ctx->customMem = customMem;
/* Check for errors */
if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
/* Initialize the threads */
@@ -160,9 +166,9 @@ void POOL_free(POOL_ctx *ctx) {
pthread_mutex_destroy(&ctx->queueMutex);
pthread_cond_destroy(&ctx->queuePushCond);
pthread_cond_destroy(&ctx->queuePopCond);
- if (ctx->queue) free(ctx->queue);
- if (ctx->threads) free(ctx->threads);
- free(ctx);
+ ZSTD_free(ctx->queue, ctx->customMem);
+ ZSTD_free(ctx->threads, ctx->customMem);
+ ZSTD_free(ctx, ctx->customMem);
}
size_t POOL_sizeof(POOL_ctx *ctx) {
@@ -213,18 +219,23 @@ void POOL_add(void* ctxVoid, POOL_function function, void *opaque) {
/* No multi-threading support */
/* We don't need any data, but if it is empty malloc() might return NULL. */
-struct POOL_ctx_s {
- int data;
-};
+struct POOL_ctx_s {};
+static POOL_ctx g_ctx;
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
+ return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
+}
+
+POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {
(void)numThreads;
(void)queueSize;
- return (POOL_ctx*)malloc(sizeof(POOL_ctx));
+ (void)customMem;
+ return &g_ctx;
}
void POOL_free(POOL_ctx* ctx) {
- free(ctx);
+ assert(ctx == &g_ctx);
+ (void)ctx;
}
void POOL_add(void* ctx, POOL_function function, void* opaque) {
@@ -234,6 +245,7 @@ void POOL_add(void* ctx, POOL_function function, void* opaque) {
size_t POOL_sizeof(POOL_ctx* ctx) {
if (ctx==NULL) return 0; /* supports sizeof NULL */
+ assert(ctx == &g_ctx);
return sizeof(*ctx);
}
diff --git a/lib/common/pool.h b/lib/common/pool.h
index 264c5c9ca..411b73e11 100644
--- a/lib/common/pool.h
+++ b/lib/common/pool.h
@@ -16,6 +16,7 @@ extern "C" {
#include /* size_t */
+#include "zstd_internal.h" /* ZSTD_customMem */
typedef struct POOL_ctx_s POOL_ctx;
@@ -27,6 +28,8 @@ typedef struct POOL_ctx_s POOL_ctx;
*/
POOL_ctx *POOL_create(size_t numThreads, size_t queueSize);
+POOL_ctx *POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem);
+
/*! POOL_free() :
Free a thread pool returned by POOL_create().
*/
From de6c6bce859193ac7dc50a96b01c6de4ae9e328b Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Thu, 24 Aug 2017 18:09:50 -0700
Subject: [PATCH 049/248] Fix zstd_internal.h for C++ mode
---
lib/common/zstd_common.c | 3 +--
lib/common/zstd_internal.h | 8 ++++++++
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c
index 08384cabf..1155c60c4 100644
--- a/lib/common/zstd_common.c
+++ b/lib/common/zstd_common.c
@@ -15,8 +15,7 @@
#include /* malloc, calloc, free */
#include /* memset */
#include "error_private.h"
-#define ZSTD_STATIC_LINKING_ONLY
-#include "zstd.h"
+#include "zstd_internal.h"
/*-****************************************
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index ac1f39896..fce75723a 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -29,6 +29,11 @@
#include "xxhash.h" /* XXH_reset, update, digest */
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
/*-*************************************
* Debug
***************************************/
@@ -334,5 +339,8 @@ typedef struct {
size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
blockProperties_t* bpPtr);
+#if defined (__cplusplus)
+}
+#endif
#endif /* ZSTD_CCOMMON_H_MODULE */
From db3f5372dfc636c848f8ad5b74c392272b48b326 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Thu, 24 Aug 2017 18:12:28 -0700
Subject: [PATCH 050/248] [zstdmt] Use POOL_create_advanced()
---
lib/compress/zstdmt_compress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 8564bc439..84a568890 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -426,7 +426,7 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
mtctx->allJobsCompleted = 1;
mtctx->sectionSize = 0;
mtctx->overlapLog = ZSTDMT_OVERLAPLOG_DEFAULT;
- mtctx->factory = POOL_create(nbThreads, 0);
+ mtctx->factory = POOL_create_advanced(nbThreads, 0, cMem);
mtctx->jobs = ZSTDMT_allocJobsTable(&nbJobs, cMem);
mtctx->jobIDMask = nbJobs - 1;
mtctx->bufPool = ZSTDMT_createBufferPool(nbThreads, cMem);
From eb7bbab36a1a5b81be860234cd6ec602184d4fc7 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 10:48:07 -0700
Subject: [PATCH 051/248] Remove ZSTD_p_refDictContent and dictContentByRef
---
lib/common/zstd_internal.h | 1 -
lib/compress/zstd_compress.c | 26 ++++++++++++++++----------
lib/compress/zstdmt_compress.c | 2 +-
lib/zstd.h | 13 +++++++++----
tests/zstreamtest.c | 7 +++++--
5 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 4e2403bee..393a17247 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -294,7 +294,6 @@ struct ZSTD_CCtx_params_s {
U32 forceWindow; /* force back-references to respect limit of
* 1<requestedParams, param, value);
case ZSTD_p_dictMode:
- case ZSTD_p_refDictContent:
if (cctx->cdict) return ERROR(stage_wrong); /* must be set before loading */
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
@@ -463,11 +462,6 @@ size_t ZSTD_CCtxParam_setParameter(
params->dictMode = (ZSTD_dictMode_e)value;
return 0;
- case ZSTD_p_refDictContent :
- /* dictionary content will be referenced, instead of copied */
- params->dictContentByRef = value > 0;
- return 0;
-
case ZSTD_p_forceMaxWindow :
params->forceWindow = value > 0;
return 0;
@@ -514,7 +508,6 @@ size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params
/* Assume dictionary parameters are validated */
cctx->requestedParams.dictMode = params->dictMode;
- cctx->requestedParams.dictContentByRef = params->dictContentByRef;
/* Set force window explicitly since it sets cctx->loadedDictEnd */
CHECK_F( ZSTD_CCtx_setParameter(
@@ -541,7 +534,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
return 0;
}
-ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
+size_t ZSTD_CCtx_loadDictionary_internal(
+ ZSTD_CCtx* cctx, const void* dict, size_t dictSize, unsigned byReference)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
if (cctx->staticSize) return ERROR(memory_allocation); /* no malloc for static CCtx */
@@ -557,7 +551,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
ZSTD_getCParams(cctx->requestedParams.compressionLevel, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- cctx->requestedParams.dictContentByRef,
+ byReference,
cctx->requestedParams.dictMode,
cParams, cctx->customMem);
cctx->cdict = cctx->cdictLocal;
@@ -567,6 +561,18 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
return 0;
}
+ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
+ ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
+{
+ return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, 1);
+}
+
+ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
+{
+ return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, 0);
+}
+
+
size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
@@ -3896,7 +3902,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- params.dictContentByRef, params.dictMode,
+ 0 /* byReference */, params.dictMode,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index f7f02cfbb..fae17e656 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -344,7 +344,7 @@ void ZSTDMT_compressChunk(void* jobDescription)
{ ZSTD_CCtx_params jobParams = job->params;
/* Force loading dictionary in "content-only" mode (no header analysis) */
size_t const dictModeError =
- ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_dictMode, 1);
+ ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_dictMode, (U32)ZSTD_dm_rawContent);
size_t const forceWindowError =
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstChunk);
/* Note: ZSTD_setCCtxParameter() should not be used here.
diff --git a/lib/zstd.h b/lib/zstd.h
index 03994f9a8..01fbb18cd 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -970,8 +970,6 @@ typedef enum {
/* dictionary parameters (must be set before ZSTD_CCtx_loadDictionary) */
ZSTD_p_dictMode=300, /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e.
* default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
- ZSTD_p_refDictContent, /* Dictionary content will be referenced, instead of copied (default:0==byCopy).
- * It requires that dictionary buffer outlives its users */
/* multi-threading parameters */
ZSTD_p_nbThreads=400, /* Select how many threads a compression job can spawn (default:1)
@@ -1015,8 +1013,9 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
* @result : 0, or an error code (which can be tested with ZSTD_isError()).
* Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
* meaning "return to no-dictionary mode".
- * Note 1 : `dict` content will be copied internally,
- * except if ZSTD_p_refDictContent is set before loading.
+ * Note 1 : `dict` content will be copied internally. Use
+ * ZSTD_CCtx_loadDictionary_byReference() to reference dictionary
+ * content instead.
* Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
* For this reason, compression parameters cannot be changed anymore after loading a dictionary.
* It's also a CPU-heavy operation, with non-negligible impact on latency.
@@ -1024,6 +1023,12 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
* To return to "no-dictionary" situation, load a NULL dictionary */
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+/*! ZSTD_CCtx_loadDictionary_byReference() :
+ * Same as ZSTD_CCtx_loadDictionary() except dictionary content will be
+ * referenced, instead of copied. The dictionary buffer must outlive its users.
+ */
+ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+
/*! ZSTD_CCtx_refCDict() :
* Reference a prepared dictionary, to be used for all next compression jobs.
* Note that compression parameters are enforced from within CDict,
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 98e121949..0373676d0 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1366,7 +1366,6 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) );
DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize);
- if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
/* multi-threading parameters */
{ U32 const nbThreadsCandidate = (FUZ_rand(&lseed) & 4) + 1;
U32 const nbThreads = MIN(nbThreadsCandidate, nbThreadsMax);
@@ -1386,7 +1385,11 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
}
if (FUZ_rand(&lseed) & 1) {
- CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
+ if (FUZ_rand(&lseed) & 1) {
+ CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
+ } else {
+ CHECK_Z( ZSTD_CCtx_loadDictionary_byReference(zc, dict, dictSize) );
+ }
if (dict && dictSize) {
/* test that compression parameters are rejected (correctly) after loading a non-NULL dictionary */
if (useOpaqueAPI) {
From de5193422d458be51531cd429d1d9b5cd5d78a92 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 11:36:17 -0700
Subject: [PATCH 052/248] Distinguish between jobParams and cctxParams in
zstdmt
---
lib/compress/zstdmt_compress.c | 36 +++++++++++++++++-----------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index fae17e656..cf21177e0 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -556,10 +556,10 @@ static size_t ZSTDMT_compress_advanced_internal(
ZSTD_CCtx_params const cctxParams,
unsigned overlapLog)
{
- ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
+ ZSTD_CCtx_params const jobParams = ZSTDMT_makeJobCCtxParams(cctxParams);
unsigned const overlapRLog = (overlapLog>9) ? 0 : 9-overlapLog;
- size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (requestedParams.cParams.windowLog - overlapRLog);
- unsigned nbChunks = computeNbChunks(srcSize, requestedParams.cParams.windowLog, mtctx->nbThreads);
+ size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (cctxParams.cParams.windowLog - overlapRLog);
+ unsigned nbChunks = computeNbChunks(srcSize, cctxParams.cParams.windowLog, mtctx->nbThreads);
size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0x7FFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */
const char* const srcStart = (const char*)src;
@@ -571,8 +571,8 @@ static size_t ZSTDMT_compress_advanced_internal(
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
- if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, requestedParams.fParams);
- return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, requestedParams);
+ if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, jobParams.fParams);
+ return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, jobParams);
}
assert(avgChunkSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), which is required for compressWithinDst */
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgChunkSize) );
@@ -601,7 +601,7 @@ static size_t ZSTDMT_compress_advanced_internal(
mtctx->jobs[u].srcSize = chunkSize;
mtctx->jobs[u].cdict = mtctx->nextJobID==0 ? cdict : NULL;
mtctx->jobs[u].fullFrameSize = srcSize;
- mtctx->jobs[u].params = requestedParams;
+ mtctx->jobs[u].params = jobParams;
/* do not calculate checksum within sections, but write it in header for first section */
if (u!=0) mtctx->jobs[u].params.fParams.checksumFlag = 0;
mtctx->jobs[u].dstBuff = dstBuffer;
@@ -613,7 +613,7 @@ static size_t ZSTDMT_compress_advanced_internal(
mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex;
mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond;
- if (requestedParams.fParams.checksumFlag) {
+ if (cctxParams.fParams.checksumFlag) {
XXH64_update(&xxh64, srcStart + frameStartPos, chunkSize);
}
@@ -656,8 +656,8 @@ static size_t ZSTDMT_compress_advanced_internal(
}
} /* for (chunkID=0; chunkID dstCapacity) {
error = ERROR(dstSize_tooSmall);
@@ -725,17 +725,17 @@ size_t ZSTDMT_initCStream_internal(
const ZSTD_CDict* cdict, ZSTD_CCtx_params cctxParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params const requestedParams = ZSTDMT_makeJobCCtxParams(cctxParams);
DEBUGLOG(4, "ZSTDMT_initCStream_internal");
/* params are supposed to be fully validated at this point */
- assert(!ZSTD_isError(ZSTD_checkCParams(requestedParams.cParams)));
+ assert(!ZSTD_isError(ZSTD_checkCParams(cctxParams.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
if (zcs->nbThreads==1) {
+ ZSTD_CCtx_params const jobParams = ZSTDMT_makeJobCCtxParams(cctxParams);
DEBUGLOG(4, "single thread mode");
return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0],
dict, dictSize, cdict,
- requestedParams, pledgedSrcSize);
+ jobParams, pledgedSrcSize);
}
if (zcs->allJobsCompleted == 0) { /* previous compression not correctly finished */
@@ -744,14 +744,14 @@ size_t ZSTDMT_initCStream_internal(
zcs->allJobsCompleted = 1;
}
- zcs->params = requestedParams;
+ zcs->params = cctxParams;
zcs->frameContentSize = pledgedSrcSize;
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
- requestedParams.cParams, zcs->cMem);
+ cctxParams.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
@@ -776,7 +776,7 @@ size_t ZSTDMT_initCStream_internal(
zcs->nextJobID = 0;
zcs->frameEnded = 0;
zcs->allJobsCompleted = 0;
- if (requestedParams.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
+ if (cctxParams.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
return 0;
}
@@ -798,11 +798,11 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params requestedParams = ZSTD_getCCtxParamsFromCDict(cdict);
+ ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
- requestedParams.fParams = fParams;
+ params.fParams = fParams;
return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
- requestedParams, pledgedSrcSize);
+ params, pledgedSrcSize);
}
From 991115372341f7c7d28d81304b0dbae6c30d2ba9 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 13:14:51 -0700
Subject: [PATCH 053/248] Move jobSize and overlapLog in zstdmt to cctxParams
---
lib/compress/zstd_compress.c | 23 ++++----
lib/compress/zstdmt_compress.c | 100 ++++++++++++++++++++-------------
tests/Makefile | 2 +-
tests/roundTripCrash.c | 3 +
4 files changed, 77 insertions(+), 51 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 5c7a724cc..c87037196 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -307,6 +307,10 @@ static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
return ERROR(parameter_outOfBound); \
} }
+size_t ZSTDMT_CCtxParam_setMTCtxParameter(
+ ZSTD_CCtx_params* params, ZSDTMT_parameter parameter, unsigned value);
+size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThreads);
+
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
@@ -359,19 +363,20 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
cctx->mtctx = ZSTDMT_createCCtx_advanced(value, cctx->customMem);
if (cctx->mtctx == NULL) return ERROR(memory_allocation);
}
- cctx->requestedParams.nbThreads = value;
- return 0;
+
+ /* Need to initialize overlapSizeLog */
+ return ZSTDMT_initializeCCtxParameters(&cctx->requestedParams, value);
case ZSTD_p_jobSize:
if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
assert(cctx->mtctx != NULL);
- return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_sectionSize, value);
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_overlapSizeLog:
DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->requestedParams.nbThreads);
if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
assert(cctx->mtctx != NULL);
- return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
default: return ERROR(parameter_unsupported);
}
@@ -471,19 +476,15 @@ size_t ZSTD_CCtxParam_setParameter(
#ifndef ZSTD_MULTITHREAD
if (value > 1) return ERROR(parameter_unsupported);
#endif
- /* Do checks when applying params to cctx */
- params->nbThreads = value;
- return 0;
+ return ZSTDMT_initializeCCtxParameters(params, value);
case ZSTD_p_jobSize :
if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
- params->jobSize = value;
- return 0;
+ return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_sectionSize, value);
case ZSTD_p_overlapSizeLog :
if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
- params->overlapSizeLog = value;
- return 0;
+ return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_overlapSectionLog, value);
default: return ERROR(parameter_unsupported);
}
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index cf21177e0..7c3bd0198 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -404,15 +404,12 @@ struct ZSTDMT_CCtx_s {
inBuff_t inBuff;
ZSTD_CCtx_params params;
XXH64_state_t xxhState;
- unsigned nbThreads;
unsigned jobIDMask;
unsigned doneJobID;
unsigned nextJobID;
unsigned frameEnded;
unsigned allJobsCompleted;
- unsigned overlapLog;
unsigned long long frameContentSize;
- size_t sectionSize;
ZSTD_customMem cMem;
ZSTD_CDict* cdictLocal;
const ZSTD_CDict* cdict;
@@ -427,6 +424,15 @@ static ZSTDMT_jobDescription* ZSTDMT_allocJobsTable(U32* nbJobsPtr, ZSTD_customM
nbJobs * sizeof(ZSTDMT_jobDescription), cMem);
}
+/* Internal only */
+size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThreads)
+{
+ params->nbThreads = nbThreads;
+ params->overlapSizeLog = ZSTDMT_OVERLAPLOG_DEFAULT;
+ params->jobSize = 0;
+ return 0;
+}
+
ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
{
ZSTDMT_CCtx* mtctx;
@@ -441,11 +447,9 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
mtctx = (ZSTDMT_CCtx*) ZSTD_calloc(sizeof(ZSTDMT_CCtx), cMem);
if (!mtctx) return NULL;
+ ZSTDMT_initializeCCtxParameters(&mtctx->params, nbThreads);
mtctx->cMem = cMem;
- mtctx->nbThreads = nbThreads;
mtctx->allJobsCompleted = 1;
- mtctx->sectionSize = 0;
- mtctx->overlapLog = ZSTDMT_OVERLAPLOG_DEFAULT;
mtctx->factory = POOL_create(nbThreads, 1);
mtctx->jobs = ZSTDMT_allocJobsTable(&nbJobs, cMem);
mtctx->jobIDMask = nbJobs - 1;
@@ -516,22 +520,35 @@ size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)
+ ZSTD_sizeof_CDict(mtctx->cdictLocal);
}
-size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value)
-{
+/* Internal only */
+size_t ZSTDMT_CCtxParam_setMTCtxParameter(
+ ZSTD_CCtx_params* params, ZSDTMT_parameter parameter, unsigned value) {
switch(parameter)
{
case ZSTDMT_p_sectionSize :
- mtctx->sectionSize = value;
+ params->jobSize = value;
return 0;
case ZSTDMT_p_overlapSectionLog :
DEBUGLOG(5, "ZSTDMT_p_overlapSectionLog : %u", value);
- mtctx->overlapLog = (value >= 9) ? 9 : value;
+ params->overlapSizeLog = (value >= 9) ? 9 : value;
return 0;
default :
return ERROR(parameter_unsupported);
}
}
+size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value)
+{
+ switch(parameter)
+ {
+ case ZSTDMT_p_sectionSize :
+ return ZSTDMT_CCtxParam_setMTCtxParameter(&mtctx->params, parameter, value);
+ case ZSTDMT_p_overlapSectionLog :
+ return ZSTDMT_CCtxParam_setMTCtxParameter(&mtctx->params, parameter, value);
+ default :
+ return ERROR(parameter_unsupported);
+ }
+}
/* ------------------------------------------ */
/* ===== Multi-threaded compression ===== */
@@ -553,13 +570,12 @@ static size_t ZSTDMT_compress_advanced_internal(
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
const ZSTD_CDict* cdict,
- ZSTD_CCtx_params const cctxParams,
- unsigned overlapLog)
+ ZSTD_CCtx_params const params)
{
- ZSTD_CCtx_params const jobParams = ZSTDMT_makeJobCCtxParams(cctxParams);
- unsigned const overlapRLog = (overlapLog>9) ? 0 : 9-overlapLog;
- size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (cctxParams.cParams.windowLog - overlapRLog);
- unsigned nbChunks = computeNbChunks(srcSize, cctxParams.cParams.windowLog, mtctx->nbThreads);
+ ZSTD_CCtx_params const jobParams = ZSTDMT_makeJobCCtxParams(params);
+ unsigned const overlapRLog = (params.overlapSizeLog>9) ? 0 : 9-params.overlapSizeLog;
+ size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (params.cParams.windowLog - overlapRLog);
+ unsigned nbChunks = computeNbChunks(srcSize, params.cParams.windowLog, params.nbThreads);
size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0x7FFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */
const char* const srcStart = (const char*)src;
@@ -567,6 +583,8 @@ static size_t ZSTDMT_compress_advanced_internal(
unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */
size_t frameStartPos = 0, dstBufferPos = 0;
XXH64_state_t xxh64;
+ assert(jobParams.nbThreads == 0);
+ assert(mtctx->cctxPool.totalCCtx == params.nbThreads);
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
@@ -613,7 +631,7 @@ static size_t ZSTDMT_compress_advanced_internal(
mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex;
mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond;
- if (cctxParams.fParams.checksumFlag) {
+ if (params.fParams.checksumFlag) {
XXH64_update(&xxh64, srcStart + frameStartPos, chunkSize);
}
@@ -656,8 +674,8 @@ static size_t ZSTDMT_compress_advanced_internal(
}
} /* for (chunkID=0; chunkID dstCapacity) {
error = ERROR(dstSize_tooSmall);
@@ -682,10 +700,11 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,
ZSTD_CCtx_params cctxParams = mtctx->params;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
+ cctxParams.overlapSizeLog = overlapLog;
return ZSTDMT_compress_advanced_internal(mtctx,
dst, dstCapacity,
src, srcSize,
- cdict, cctxParams, overlapLog);
+ cdict, cctxParams);
}
@@ -722,20 +741,22 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs)
size_t ZSTDMT_initCStream_internal(
ZSTDMT_CCtx* zcs, const void* dict, size_t dictSize,
- const ZSTD_CDict* cdict, ZSTD_CCtx_params cctxParams,
+ const ZSTD_CDict* cdict, ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTDMT_initCStream_internal");
/* params are supposed to be fully validated at this point */
- assert(!ZSTD_isError(ZSTD_checkCParams(cctxParams.cParams)));
+ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
+ assert(mtctx->cctxPool.totalCCtx == params.nbThreads);
- if (zcs->nbThreads==1) {
- ZSTD_CCtx_params const jobParams = ZSTDMT_makeJobCCtxParams(cctxParams);
+ if (params.nbThreads==1) {
+ ZSTD_CCtx_params const singleThreadParams = ZSTDMT_makeJobCCtxParams(params);
DEBUGLOG(4, "single thread mode");
+ assert(singleThreadParams.nbThreads == 0);
return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0],
dict, dictSize, cdict,
- jobParams, pledgedSrcSize);
+ singleThreadParams, pledgedSrcSize);
}
if (zcs->allJobsCompleted == 0) { /* previous compression not correctly finished */
@@ -744,14 +765,14 @@ size_t ZSTDMT_initCStream_internal(
zcs->allJobsCompleted = 1;
}
- zcs->params = cctxParams;
+ zcs->params = params;
zcs->frameContentSize = pledgedSrcSize;
if (dict) {
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
- cctxParams.cParams, zcs->cMem);
+ params.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
@@ -761,10 +782,10 @@ size_t ZSTDMT_initCStream_internal(
zcs->cdict = cdict;
}
- zcs->targetDictSize = (zcs->overlapLog==0) ? 0 : (size_t)1 << (zcs->params.cParams.windowLog - (9 - zcs->overlapLog));
- DEBUGLOG(4, "overlapLog : %u ", zcs->overlapLog);
+ zcs->targetDictSize = (params.overlapSizeLog==0) ? 0 : (size_t)1 << (params.cParams.windowLog - (9 - params.overlapSizeLog));
+ DEBUGLOG(4, "overlapLog : %u ", params.overlapSizeLog);
DEBUGLOG(4, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10));
- zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2);
+ zcs->targetSectionSize = params.jobSize ? params.jobSize : (size_t)1 << (params.cParams.windowLog + 2);
zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize);
zcs->targetSectionSize = MAX(zcs->targetDictSize, zcs->targetSectionSize);
DEBUGLOG(4, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10));
@@ -776,7 +797,7 @@ size_t ZSTDMT_initCStream_internal(
zcs->nextJobID = 0;
zcs->frameEnded = 0;
zcs->allJobsCompleted = 0;
- if (cctxParams.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
+ if (params.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
return 0;
}
@@ -798,11 +819,12 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
ZSTD_frameParameters fParams,
unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
+ ZSTD_CCtx_params cctxParams = mtctx->params;
+ cctxParams.cParams = ZSTD_getCCtxParamsFromCDict(cdict).cParams;
+ cctxParams.fParams = fParams;
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
- params.fParams = fParams;
return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
- params, pledgedSrcSize);
+ cctxParams, pledgedSrcSize);
}
@@ -810,7 +832,7 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
* pledgedSrcSize is optional and can be zero == unknown */
size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize)
{
- if (zcs->nbThreads==1)
+ if (zcs->params.nbThreads==1)
return ZSTD_resetCStream(zcs->cctxPool->cctx[0], pledgedSrcSize);
return ZSTDMT_initCStream_internal(zcs, NULL, 0, 0, zcs->params,
pledgedSrcSize);
@@ -965,7 +987,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
/* current frame being ended. Only flush/end are allowed. Or start new frame with init */
return ERROR(stage_wrong);
}
- if (mtctx->nbThreads==1) { /* delegate to single-thread (synchronous) */
+ if (mtctx->params.nbThreads==1) { /* delegate to single-thread (synchronous) */
return ZSTD_compressStream_generic(mtctx->cctxPool->cctx[0], output, input, endOp);
}
@@ -977,7 +999,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
size_t const cSize = ZSTDMT_compress_advanced_internal(mtctx,
(char*)output->dst + output->pos, output->size - output->pos,
(const char*)input->src + input->pos, input->size - input->pos,
- mtctx->cdict, mtctx->params, mtctx->overlapLog);
+ mtctx->cdict, mtctx->params);
if (ZSTD_isError(cSize)) return cSize;
input->pos = input->size;
output->pos += cSize;
@@ -1052,7 +1074,7 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp
size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
{
DEBUGLOG(5, "ZSTDMT_flushStream");
- if (zcs->nbThreads==1)
+ if (zcs->params.nbThreads==1)
return ZSTD_flushStream(zcs->cctxPool->cctx[0], output);
return ZSTDMT_flushStream_internal(zcs, output, 0 /* endFrame */);
}
@@ -1060,7 +1082,7 @@ size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
{
DEBUGLOG(4, "ZSTDMT_endStream");
- if (zcs->nbThreads==1)
+ if (zcs->params.nbThreads==1)
return ZSTD_endStream(zcs->cctxPool->cctx[0], output);
return ZSTDMT_flushStream_internal(zcs, output, 1 /* endFrame */);
}
diff --git a/tests/Makefile b/tests/Makefile
index 006059b72..f6389bd91 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -167,7 +167,7 @@ datagen : $(PRGDIR)/datagen.c datagencli.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
roundTripCrash : $(ZSTD_FILES) roundTripCrash.c
- $(CC) $(FLAGS) $^ -o $@$(EXT)
+ $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT)
longmatch : $(ZSTD_FILES) longmatch.c
$(CC) $(FLAGS) $^ -o $@$(EXT)
diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c
index fb14fa87b..cb0221c58 100644
--- a/tests/roundTripCrash.c
+++ b/tests/roundTripCrash.c
@@ -93,6 +93,9 @@ static size_t cctxParamRoundTripTest(void* resultBuff, size_t resultBuffCapacity
/* Set parameters */
CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_compressionLevel, cLevel) );
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_nbThreads, 2) );
+ CHECK_Z( ZSTD_CCtxParam_setParameter(cctxParams, ZSTD_p_overlapSizeLog, 5) );
+
/* Apply parameters */
CHECK_Z( ZSTD_CCtx_applyCCtxParams(cctx, cctxParams) );
From 0744592d385df6718f46b7e7d8201609e0459a40 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 13:23:16 -0700
Subject: [PATCH 054/248] Add function initializing cctxParams from clevel
---
lib/compress/zstd_compress.c | 7 ++++++-
lib/compress/zstdmt_compress.c | 4 ++--
lib/zstd.h | 11 ++++++++---
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index c87037196..c8cfd6c94 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -282,7 +282,12 @@ size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
return 0;
}
-size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
+size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
+ return ZSTD_initCCtxParams_advanced(cctxParams, params);
+}
+
+size_t ZSTD_initCCtxParams_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
{
if (!cctxParams) { return ERROR(GENERIC); }
CHECK_F( ZSTD_checkCParams(params.cParams) );
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 7c3bd0198..c93d784da 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -584,7 +584,7 @@ static size_t ZSTDMT_compress_advanced_internal(
size_t frameStartPos = 0, dstBufferPos = 0;
XXH64_state_t xxh64;
assert(jobParams.nbThreads == 0);
- assert(mtctx->cctxPool.totalCCtx == params.nbThreads);
+ assert(mtctx->cctxPool->totalCCtx == params.nbThreads);
DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
if (nbChunks==1) { /* fallback to single-thread mode */
@@ -748,7 +748,7 @@ size_t ZSTDMT_initCStream_internal(
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
- assert(mtctx->cctxPool.totalCCtx == params.nbThreads);
+ assert(zcs->cctxPool->totalCCtx == params.nbThreads);
if (params.nbThreads==1) {
ZSTD_CCtx_params const singleThreadParams = ZSTDMT_makeJobCCtxParams(params);
diff --git a/lib/zstd.h b/lib/zstd.h
index 01fbb18cd..bfbe82849 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -1128,9 +1128,14 @@ ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
/*! ZSTD_initCCtxParams() :
- * Set the compression and frame parameters of cctxParams according to params.
- * All other parameters are reset to their default values. */
-ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
+ * Initializes the compression parameters of cctxParams according to
+ * compression level. All other parameters are reset to their default values. */
+ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, int compressionLevel);
+
+/*! ZSTD_initCCtxParams_advanced() :
+ * Initializes the compression and frame parameters of cctxParams according to
+ * params. All other parameters are reset to their default values. */
+ZSTDLIB_API size_t ZSTD_initCCtxParams_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
From 18224608ffa214221b16e55db8759f5486985568 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 13:58:41 -0700
Subject: [PATCH 055/248] Remove ZSTD_setCCtxParameter()
---
lib/compress/zstd_compress.c | 22 ----------------------
lib/compress/zstdmt_compress.c | 3 ---
lib/zstd.h | 30 ++++++++++++------------------
tests/fuzzer.c | 1 -
4 files changed, 12 insertions(+), 44 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index c8cfd6c94..74cbe53b0 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -197,28 +197,6 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
/* private API call, for dictBuilder only */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
-/* older variant; will be deprecated */
-/* Both requested and applied params need to be set as this function can be
- * called before/after ZSTD_parameters have been applied. */
-size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
-{
- switch(param)
- {
- case ZSTD_p_forceWindow :
- cctx->requestedParams.forceWindow = value>0;
- cctx->appliedParams.forceWindow = value>0;
- cctx->loadedDictEnd = 0;
- return 0;
- ZSTD_STATIC_ASSERT(ZSTD_dm_auto==0);
- ZSTD_STATIC_ASSERT(ZSTD_dm_rawContent==1);
- case ZSTD_p_forceRawDict :
- cctx->requestedParams.dictMode = (ZSTD_dictMode_e)(value>0);
- cctx->appliedParams.dictMode = (ZSTD_dictMode_e)(value>0);
- return 0;
- default: return ERROR(parameter_unsupported);
- }
-}
-
#define ZSTD_CLEVEL_CUSTOM 999
static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* params, U64 srcSize)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index c93d784da..5f0f254c2 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -347,9 +347,6 @@ void ZSTDMT_compressChunk(void* jobDescription)
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_dictMode, (U32)ZSTD_dm_rawContent);
size_t const forceWindowError =
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstChunk);
- /* Note: ZSTD_setCCtxParameter() should not be used here.
- * ZSTD_compressBegin_advanced_internal() copies the ZSTD_CCtx_params
- * directly to appliedParams. */
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, jobParams, job->fullFrameSize);
if (ZSTD_isError(initError) || ZSTD_isError(dictModeError) ||
ZSTD_isError(forceWindowError)) { job->cSize = initError; goto _endJob; }
diff --git a/lib/zstd.h b/lib/zstd.h
index bfbe82849..0c970f3f9 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -558,17 +558,6 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
-/* !!! To be deprecated !!! */
-typedef enum {
- ZSTD_p_forceWindow, /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
- ZSTD_p_forceRawDict /* Force loading dictionary in "content-only" mode (no header analysis) */
-} ZSTD_CCtxParameter;
-/*! ZSTD_setCCtxParameter() :
- * Set advanced parameters, selected through enum ZSTD_CCtxParameter
- * @result : 0, or an error code (which can be tested with ZSTD_isError()) */
-ZSTDLIB_API size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value);
-
-
/*! ZSTD_createCDict_byReference() :
* Create a digested dictionary for compression
* Dictionary content is simply referenced, and therefore stays in dictBuffer.
@@ -1119,22 +1108,25 @@ size_t ZSTD_compress_generic_simpleArgs (
* - ZSTD_freeCCtxParams() : Free the memory.
*
* This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation
- * for single-threaded compression. */
-
+ * for single-threaded compression.
+ */
ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
/*! ZSTD_resetCCtxParams() :
- * Reset params to default, with the default compression level. */
+ * Reset params to default, with the default compression level.
+ */
ZSTDLIB_API size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
/*! ZSTD_initCCtxParams() :
* Initializes the compression parameters of cctxParams according to
- * compression level. All other parameters are reset to their default values. */
+ * compression level. All other parameters are reset to their default values.
+ */
ZSTDLIB_API size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, int compressionLevel);
/*! ZSTD_initCCtxParams_advanced() :
* Initializes the compression and frame parameters of cctxParams according to
- * params. All other parameters are reset to their default values. */
+ * params. All other parameters are reset to their default values.
+ */
ZSTDLIB_API size_t ZSTD_initCCtxParams_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
@@ -1144,14 +1136,16 @@ ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
* Set one compression parameter, selected by enum ZSTD_cParameter.
* Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_applyCCtxParams().
* Note : when `value` is an enum, cast it to unsigned for proper type checking.
- * @result : 0, or an error code (which can be tested with ZSTD_isError()). */
+ * @result : 0, or an error code (which can be tested with ZSTD_isError()).
+ */
ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
/*! ZSTD_CCtx_applyCCtxParams() :
* Apply a set of ZSTD_CCtx_params to the compression context.
* This must be done before the dictionary is loaded.
* The pledgedSrcSize is treated as unknown.
- * Multithreading parameters are applied only if nbThreads > 1. */
+ * Multithreading parameters are applied only if nbThreads > 1.
+ */
ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
/**
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 046c67ea8..3f7595e99 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -1334,7 +1334,6 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
}
CHECK_Z( ZSTD_copyCCtx(ctx, refCtx, 0) );
}
- ZSTD_setCCtxParameter(ctx, ZSTD_p_forceWindow, FUZ_rand(&lseed) & 1);
{ U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2;
U32 n;
From 2adde898c800e30ec43afef5eec5f5caf7ffc950 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 16:13:40 -0700
Subject: [PATCH 056/248] Fix typo with ZSTDMT_parameter
---
lib/common/zstd_internal.h | 2 +-
lib/compress/zstd_compress.c | 2 +-
lib/compress/zstdmt_compress.c | 4 ++--
lib/compress/zstdmt_compress.h | 6 +++---
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 393a17247..53de69739 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -297,7 +297,7 @@ struct ZSTD_CCtx_params_s {
ZSTD_dictMode_e dictMode; /* select restricting dictionary to "rawContent"
* or "fullDict" only */
- /* Multithreading: used only to set mtctx parameters */
+ /* Multithreading: used to pass parameters to mtctx */
U32 nbThreads;
unsigned jobSize;
unsigned overlapSizeLog;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 74cbe53b0..6f4121c75 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -291,7 +291,7 @@ static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
} }
size_t ZSTDMT_CCtxParam_setMTCtxParameter(
- ZSTD_CCtx_params* params, ZSDTMT_parameter parameter, unsigned value);
+ ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, unsigned value);
size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThreads);
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 5f0f254c2..8687ea3c0 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -519,7 +519,7 @@ size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)
/* Internal only */
size_t ZSTDMT_CCtxParam_setMTCtxParameter(
- ZSTD_CCtx_params* params, ZSDTMT_parameter parameter, unsigned value) {
+ ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, unsigned value) {
switch(parameter)
{
case ZSTDMT_p_sectionSize :
@@ -534,7 +534,7 @@ size_t ZSTDMT_CCtxParam_setMTCtxParameter(
}
}
-size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value)
+size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, unsigned value)
{
switch(parameter)
{
diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
index 843a240aa..4381af363 100644
--- a/lib/compress/zstdmt_compress.h
+++ b/lib/compress/zstdmt_compress.h
@@ -80,19 +80,19 @@ ZSTDLIB_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
ZSTD_frameParameters fparams,
unsigned long long pledgedSrcSize); /* note : zero means empty */
-/* ZSDTMT_parameter :
+/* ZSTDMT_parameter :
* List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
typedef enum {
ZSTDMT_p_sectionSize, /* size of input "section". Each section is compressed in parallel. 0 means default, which is dynamically determined within compression functions */
ZSTDMT_p_overlapSectionLog /* Log of overlapped section; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window */
-} ZSDTMT_parameter;
+} ZSTDMT_parameter;
/* ZSTDMT_setMTCtxParameter() :
* allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.
* The function must be called typically after ZSTD_createCCtx().
* Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.
* @return : 0, or an error code (which can be tested using ZSTD_isError()) */
-ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value);
+ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, unsigned value);
/*! ZSTDMT_compressStream_generic() :
From 024098a47dba898d60e578cbc93bdc9fca6d8016 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 25 Aug 2017 17:58:28 -0700
Subject: [PATCH 057/248] Fix parameter retrieval from cdict
---
lib/common/zstd_internal.h | 4 ++--
lib/compress/zstd_compress.c | 15 ++++++++-------
lib/compress/zstdmt_compress.c | 2 +-
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 53de69739..bfec42fad 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -369,9 +369,9 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
ZSTD_inBuffer* input,
ZSTD_EndDirective const flushMode);
-/*! ZSTD_getParamsFromCDict() :
+/*! ZSTD_getCParamsFromCDict() :
* as the name implies */
-ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict);
+ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);
/* INTERNAL */
size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 6f4121c75..1f570a92a 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -477,7 +477,7 @@ size_t ZSTD_CCtxParam_setParameter(
* This function should be updated whenever ZSTD_CCtx_params is updated.
* Parameters are copied manually before the dictionary is loaded.
* The multithreading parameters jobSize and overlapSizeLog are set only if
- * nbThreads >= 1.
+ * nbThreads > 1.
*
* Pledged srcSize is treated as unknown.
*/
@@ -3735,8 +3735,8 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
return cdict;
}
-ZSTD_CCtx_params ZSTD_getCCtxParamsFromCDict(const ZSTD_CDict* cdict) {
- return cdict->refContext->appliedParams;
+ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) {
+ return cdict->refContext->appliedParams.cParams;
}
/* ZSTD_compressBegin_usingCDict_advanced() :
@@ -3746,7 +3746,8 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
{
if (cdict==NULL) return ERROR(dictionary_wrong);
- { ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
+ { ZSTD_CCtx_params params = cctx->requestedParams;
+ params.cParams = ZSTD_getCParamsFromCDict(cdict);
params.fParams = fParams;
params.dictMode = ZSTD_dm_auto;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
@@ -3892,8 +3893,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
} else {
if (cdict) {
- ZSTD_CCtx_params const cdictParams = ZSTD_getCCtxParamsFromCDict(cdict);
- params.cParams = cdictParams.cParams; /* cParams are enforced from cdict */
+ params.cParams = ZSTD_getCParamsFromCDict(cdict); /* cParams are enforced from cdict */
}
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = NULL;
@@ -3914,7 +3914,8 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
unsigned long long pledgedSrcSize)
{ /* cannot handle NULL cdict (does not know what to do) */
if (!cdict) return ERROR(dictionary_wrong);
- { ZSTD_CCtx_params params = ZSTD_getCCtxParamsFromCDict(cdict);
+ { ZSTD_CCtx_params params = zcs->requestedParams;
+ params.cParams = ZSTD_getCParamsFromCDict(cdict);
params.fParams = fParams;
return ZSTD_initCStream_internal(zcs,
NULL, 0, cdict,
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 8687ea3c0..b1a681e74 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -817,7 +817,7 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params cctxParams = mtctx->params;
- cctxParams.cParams = ZSTD_getCCtxParamsFromCDict(cdict).cParams;
+ cctxParams.cParams = ZSTD_getCParamsFromCDict(cdict);
cctxParams.fParams = fParams;
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
From cf689b84f9ffc1eed65a16520b96185845fe0644 Mon Sep 17 00:00:00 2001
From: "Bernhard M. Wiedemann"
Date: Sat, 26 Aug 2017 17:08:00 +0200
Subject: [PATCH 058/248] Sort input file list
in order to make builds reproducible
in spite of indeterministic filesystem readdir order.
See https://reproducible-builds.org/ for why this is good.
---
lib/Makefile | 2 +-
programs/Makefile | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Makefile b/lib/Makefile
index 5845cf170..e31ce0438 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -31,7 +31,7 @@ CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS)
FLAGS = $(CPPFLAGS) $(CFLAGS)
-ZSTD_FILES := $(wildcard common/*.c compress/*.c decompress/*.c dictBuilder/*.c deprecated/*.c)
+ZSTD_FILES := $(sort $(wildcard common/*.c compress/*.c decompress/*.c dictBuilder/*.c deprecated/*.c))
ZSTD_LEGACY_SUPPORT ?= 4
diff --git a/programs/Makefile b/programs/Makefile
index c5469cfc4..5fd3703d4 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -68,7 +68,7 @@ endif
else
endif
-ZSTDLIB_FILES := $(wildcard $(ZSTD_FILES)) $(wildcard $(ZSTDLEGACY_FILES)) $(wildcard $(ZDICT_FILES))
+ZSTDLIB_FILES := $(sort $(wildcard $(ZSTD_FILES)) $(wildcard $(ZSTDLEGACY_FILES)) $(wildcard $(ZDICT_FILES)))
ZSTDLIB_OBJ := $(patsubst %.c,%.o,$(ZSTDLIB_FILES))
# Define *.exe as extension for Windows systems
From 7c365eb02c2eda99fde29a9e0894b667611556b2 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Fri, 25 Aug 2017 17:44:32 -0700
Subject: [PATCH 059/248] [threading] Fix ERROR macro after including windows.h
---
lib/common/error_private.h | 3 ++-
lib/common/threading.h | 8 ++++++++
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/lib/common/error_private.h b/lib/common/error_private.h
index 9dd9a87cf..f8e68016a 100644
--- a/lib/common/error_private.h
+++ b/lib/common/error_private.h
@@ -51,7 +51,8 @@ typedef ZSTD_ErrorCode ERR_enum;
#ifdef ERROR
# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
#endif
-#define ERROR(name) ((size_t)-PREFIX(name))
+#define ERROR(name) ZSTD_ERROR(name)
+#define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
diff --git a/lib/common/threading.h b/lib/common/threading.h
index ab09977a8..0a9fcf857 100644
--- a/lib/common/threading.h
+++ b/lib/common/threading.h
@@ -37,7 +37,15 @@ extern "C" {
# define WIN32_LEAN_AND_MEAN
#endif
+#ifdef ERROR
+# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
+#endif
#include
+#ifdef ERROR
+# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
+#endif
+#define ERROR(name) ZSTD_ERROR(name)
+
/* mutex */
#define pthread_mutex_t CRITICAL_SECTION
From 02033be08c581ec59d4ef26d46defc0687d15f81 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 28 Aug 2017 17:19:01 -0700
Subject: [PATCH 060/248] [pool] Visual Studios disallows empty structs
---
lib/common/pool.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/common/pool.c b/lib/common/pool.c
index ada9b1696..9567d112f 100644
--- a/lib/common/pool.c
+++ b/lib/common/pool.c
@@ -219,7 +219,9 @@ void POOL_add(void* ctxVoid, POOL_function function, void *opaque) {
/* No multi-threading support */
/* We don't need any data, but if it is empty malloc() might return NULL. */
-struct POOL_ctx_s {};
+struct POOL_ctx_s {
+ int dummy;
+};
static POOL_ctx g_ctx;
POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
From 0e56a84a1ea5c22530eeafe8938d8f56e45cce4b Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Mon, 28 Aug 2017 19:25:17 -0700
Subject: [PATCH 061/248] Fix getting cParams from CCtxParams
---
lib/compress/zstd_compress.c | 47 ++++++++++++++++++------------------
1 file changed, 24 insertions(+), 23 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 1f570a92a..4a8e9c8bd 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -197,12 +197,19 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
/* private API call, for dictBuilder only */
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
-
#define ZSTD_CLEVEL_CUSTOM 999
+
+static ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
+ ZSTD_CCtx_params params, U64 srcSizeHint, size_t dictSize)
+{
+ return (params.compressionLevel == ZSTD_CLEVEL_CUSTOM ?
+ params.cParams :
+ ZSTD_getCParams(params.compressionLevel, srcSizeHint, dictSize));
+}
+
static void ZSTD_cLevelToCCtxParams_srcSize(ZSTD_CCtx_params* params, U64 srcSize)
{
- if (params->compressionLevel == ZSTD_CLEVEL_CUSTOM) return;
- params->cParams = ZSTD_getCParams(params->compressionLevel, srcSize, 0);
+ params->cParams = ZSTD_getCParamsFromCCtxParams(*params, srcSize, 0);
params->compressionLevel = ZSTD_CLEVEL_CUSTOM;
}
@@ -254,15 +261,14 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
{
- if (!params) { return ERROR(GENERIC); }
- memset(params, 0, sizeof(ZSTD_CCtx_params));
- params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
- return 0;
+ return ZSTD_initCCtxParams(params, ZSTD_CLEVEL_DEFAULT);
}
size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
- return ZSTD_initCCtxParams_advanced(cctxParams, params);
+ if (!cctxParams) { return ERROR(GENERIC); }
+ memset(cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ cctxParams->compressionLevel = compressionLevel;
+ return 0;
}
size_t ZSTD_initCCtxParams_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
@@ -530,9 +536,7 @@ size_t ZSTD_CCtx_loadDictionary_internal(
cctx->cdict = NULL;
} else {
ZSTD_compressionParameters const cParams =
- cctx->requestedParams.compressionLevel == ZSTD_CLEVEL_CUSTOM ?
- cctx->requestedParams.cParams :
- ZSTD_getCParams(cctx->requestedParams.compressionLevel, 0, dictSize);
+ ZSTD_getCParamsFromCCtxParams(cctx->requestedParams, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
byReference,
@@ -672,7 +676,8 @@ size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params)
if (params->nbThreads > 1) {
return 0;
}
- { ZSTD_compressionParameters const cParams = params->cParams;
+ { ZSTD_compressionParameters const cParams =
+ ZSTD_getCParamsFromCCtxParams(*params, 0, 0);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
U32 const divider = (cParams.searchLength==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider;
@@ -3182,10 +3187,8 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
{
- U32 const cLevel = cctx->appliedParams.compressionLevel;
- ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
- cctx->appliedParams.cParams :
- ZSTD_getCParams(cLevel, 0, 0);
+ ZSTD_compressionParameters cParams =
+ ZSTD_getCParamsFromCCtxParams(cctx->appliedParams, 0, 0);
return MIN (ZSTD_BLOCKSIZE_MAX, 1 << cParams.windowLog);
}
@@ -3859,10 +3862,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params params = zcs->requestedParams;
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
+ params.cParams = ZSTD_getCParamsFromCCtxParams(params, pledgedSrcSize, 0);
DEBUGLOG(5, "ZSTD_resetCStream");
- if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM) {
- params.cParams = ZSTD_getCParams(params.compressionLevel, pledgedSrcSize, 0 /* dictSize */);
- }
return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
}
@@ -4152,9 +4153,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
const void* const prefix = cctx->prefix;
size_t const prefixSize = cctx->prefixSize;
ZSTD_CCtx_params params = cctx->requestedParams;
- if (params.compressionLevel != ZSTD_CLEVEL_CUSTOM)
- params.cParams = ZSTD_getCParams(params.compressionLevel,
- cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
+ params.cParams = ZSTD_getCParamsFromCCtxParams(
+ cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
cctx->prefix = NULL; cctx->prefixSize = 0; /* single usage */
assert(prefix==NULL || cctx->cdict==NULL); /* only one can be set */
@@ -4382,6 +4382,7 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
{ ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel];
return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); }
+
}
/*! ZSTD_getParams() :
From 394bdd7db9c13c9fadad704e7535b3588c650d97 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Tue, 29 Aug 2017 09:24:11 -0700
Subject: [PATCH 062/248] changed license for examples
intentionnally this time
---
LICENSE-examples | 11 -----------
.../seekable_format/examples/parallel_compression.c | 9 +++++----
.../seekable_format/examples/parallel_processing.c | 9 +++++----
.../seekable_format/examples/seekable_compression.c | 9 +++++----
.../seekable_format/examples/seekable_decompression.c | 9 +++++----
examples/dictionary_compression.c | 9 +++++----
examples/dictionary_decompression.c | 9 +++++----
examples/multiple_streaming_compression.c | 9 +++++----
examples/simple_compression.c | 9 +++++----
examples/simple_decompression.c | 9 +++++----
examples/streaming_compression.c | 9 +++++----
examples/streaming_decompression.c | 9 +++++----
12 files changed, 55 insertions(+), 55 deletions(-)
delete mode 100644 LICENSE-examples
diff --git a/LICENSE-examples b/LICENSE-examples
deleted file mode 100644
index 1de781305..000000000
--- a/LICENSE-examples
+++ /dev/null
@@ -1,11 +0,0 @@
-Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
-
-The examples provided by Facebook are for non-commercial testing and evaluation
-purposes only. Facebook reserves all rights not expressly granted.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/contrib/seekable_format/examples/parallel_compression.c b/contrib/seekable_format/examples/parallel_compression.c
index 89a13185f..69644d2b3 100644
--- a/contrib/seekable_format/examples/parallel_compression.c
+++ b/contrib/seekable_format/examples/parallel_compression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2017-present, Facebook, Inc.
+/*
+ * Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include // malloc, free, exit, atoi
diff --git a/contrib/seekable_format/examples/parallel_processing.c b/contrib/seekable_format/examples/parallel_processing.c
index cea4d5364..da3477632 100644
--- a/contrib/seekable_format/examples/parallel_processing.c
+++ b/contrib/seekable_format/examples/parallel_processing.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2017-present, Facebook, Inc.
+/*
+ * Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/*
diff --git a/contrib/seekable_format/examples/seekable_compression.c b/contrib/seekable_format/examples/seekable_compression.c
index a33952d93..9485bf26f 100644
--- a/contrib/seekable_format/examples/seekable_compression.c
+++ b/contrib/seekable_format/examples/seekable_compression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2017-present, Facebook, Inc.
+/*
+ * Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include // malloc, free, exit, atoi
diff --git a/contrib/seekable_format/examples/seekable_decompression.c b/contrib/seekable_format/examples/seekable_decompression.c
index b765a7591..9cd232922 100644
--- a/contrib/seekable_format/examples/seekable_decompression.c
+++ b/contrib/seekable_format/examples/seekable_decompression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/examples/dictionary_compression.c b/examples/dictionary_compression.c
index adcc3b4d5..17acec98d 100644
--- a/examples/dictionary_compression.c
+++ b/examples/dictionary_compression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/examples/dictionary_decompression.c b/examples/dictionary_decompression.c
index ef739c189..345c968c3 100644
--- a/examples/dictionary_decompression.c
+++ b/examples/dictionary_decompression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/examples/multiple_streaming_compression.c b/examples/multiple_streaming_compression.c
index 61699104c..7bfa133ee 100644
--- a/examples/multiple_streaming_compression.c
+++ b/examples/multiple_streaming_compression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/examples/simple_compression.c b/examples/simple_compression.c
index ab1131475..95853faa6 100644
--- a/examples/simple_compression.c
+++ b/examples/simple_compression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/examples/simple_decompression.c b/examples/simple_decompression.c
index 4b7ea59e5..9e9fcc9ed 100644
--- a/examples/simple_decompression.c
+++ b/examples/simple_decompression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include // malloc, exit
diff --git a/examples/streaming_compression.c b/examples/streaming_compression.c
index 24ad15bd6..ac7ee7687 100644
--- a/examples/streaming_compression.c
+++ b/examples/streaming_compression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/examples/streaming_decompression.c b/examples/streaming_decompression.c
index bb2d80987..76dd85169 100644
--- a/examples/streaming_decompression.c
+++ b/examples/streaming_decompression.c
@@ -1,9 +1,10 @@
-/**
- * Copyright 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the license found in the
- * LICENSE-examples file in the root directory of this source tree.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
From b5b9275e6780107aaf54212a038b3daeba247400 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 10:49:29 -0700
Subject: [PATCH 063/248] Rename estimateCCtxSize_advanced() and
estimateCStreamSize_advanced()
---
lib/compress/zstd_compress.c | 25 +++++++++++++------------
lib/zstd.h | 26 +++++++++++++-------------
tests/paramgrill.c | 4 ++--
tests/zstreamtest.c | 2 +-
4 files changed, 29 insertions(+), 28 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 4a8e9c8bd..26de0efd8 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -670,7 +670,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
}
-size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params)
+size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params)
{
/* Estimate CCtx size is supported for single-threaded compression only. */
if (params->nbThreads > 1) {
@@ -703,24 +703,24 @@ size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params)
}
}
-size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams)
+size_t ZSTD_estimateCCtxSize_advanced_usingCParams(ZSTD_compressionParameters cParams)
{
ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
- return ZSTD_estimateCCtxSize_advanced_opaque(¶ms);
+ return ZSTD_estimateCCtxSize_advanced_usingCCtxParams(¶ms);
}
size_t ZSTD_estimateCCtxSize(int compressionLevel)
{
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
- return ZSTD_estimateCCtxSize_advanced(cParams);
+ return ZSTD_estimateCCtxSize_advanced_usingCParams(cParams);
}
-size_t ZSTD_estimateCStreamSize_advanced_opaque(const ZSTD_CCtx_params* params)
+size_t ZSTD_estimateCStreamSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params)
{
if (params->nbThreads > 1) {
return 0;
}
- { size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_opaque(params);
+ { size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_usingCCtxParams(params);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
@@ -730,15 +730,15 @@ size_t ZSTD_estimateCStreamSize_advanced_opaque(const ZSTD_CCtx_params* params)
}
}
-size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams)
+size_t ZSTD_estimateCStreamSize_advanced_usingCParams(ZSTD_compressionParameters cParams)
{
ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);
- return ZSTD_estimateCStreamSize_advanced_opaque(¶ms);
+ return ZSTD_estimateCStreamSize_advanced_usingCCtxParams(¶ms);
}
size_t ZSTD_estimateCStreamSize(int compressionLevel) {
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
- return ZSTD_estimateCStreamSize_advanced(cParams);
+ return ZSTD_estimateCStreamSize_advanced_usingCParams(cParams);
}
static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
@@ -3585,8 +3585,9 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
{
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
- DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize_advanced(cParams));
- return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced(cParams)
+ DEBUGLOG(5, "CCtx estimate : %u",
+ (U32)ZSTD_estimateCCtxSize_advanced_usingCParams(cParams));
+ return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced_usingCParams(cParams)
+ (byReference ? 0 : dictSize);
}
@@ -3709,7 +3710,7 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
unsigned byReference, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams)
{
- size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams);
+ size_t const cctxSize = ZSTD_estimateCCtxSize_advanced_usingCParams(cParams);
size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize)
+ cctxSize;
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
diff --git a/lib/zstd.h b/lib/zstd.h
index 0c970f3f9..6d91e92a4 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -496,21 +496,21 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* of a future {D,C}Ctx, before its creation.
* ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one.
* It will also consider src size to be arbitrarily "large", which is worst case.
- * If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
- * ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCCtxSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
+ * If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced_usingCParams() can provide a tighter estimation.
+ * ZSTD_estimateCCtxSize_advanced_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ * ZSTD_estimateCCtxSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
-ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
-ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_opaque(const ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_usingCParams(ZSTD_compressionParameters cParams);
+ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
-/*! ZSTD_estimate?StreamSize() :
+/*! ZSTD_estimateCStreamSize() :
* ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one.
* It will also consider src size to be arbitrarily "large", which is worst case.
- * If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
- * ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCStreamSize_advanced_opaque() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
+ * If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced_usingCParams() can provide a tighter estimation.
+ * ZSTD_estimateCStreamSize_advanced_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ * ZSTD_estimateCStreamSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.
* This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -519,14 +519,14 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* an internal ?Dict will be created, which additional size is not estimated here.
* In this case, get total size by adding ZSTD_estimate?DictSize */
ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
-ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
-ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_opaque(const ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_usingCParams(ZSTD_compressionParameters cParams);
+ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
-/*! ZSTD_estimate?DictSize() :
+/*! ZSTD_estimateCDictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
- * ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
+ * ZSTD_estimateCStreamSize_advanced_usingCParams() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
* Note : dictionary created "byReference" are smaller */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
diff --git a/tests/paramgrill.c b/tests/paramgrill.c
index da06ccb52..1818e5121 100644
--- a/tests/paramgrill.c
+++ b/tests/paramgrill.c
@@ -390,8 +390,8 @@ static int BMK_seed(winnerInfo_t* winners, const ZSTD_compressionParameters para
double W_DMemUsed_note = W_ratioNote * ( 40 + 9*cLevel) - log((double)W_DMemUsed);
double O_DMemUsed_note = O_ratioNote * ( 40 + 9*cLevel) - log((double)O_DMemUsed);
- size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize_advanced(params);
- size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize_advanced(winners[cLevel].params);
+ size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize_advanced_usingCParams(params);
+ size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize_advanced_usingCParams(winners[cLevel].params);
double W_CMemUsed_note = W_ratioNote * ( 50 + 13*cLevel) - log((double)W_CMemUsed);
double O_CMemUsed_note = O_ratioNote * ( 50 + 13*cLevel) - log((double)O_CMemUsed);
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 0373676d0..0bf833c51 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -197,7 +197,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
/* context size functions */
DISPLAYLEVEL(3, "test%3i : estimate CStream size : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictSize);
- size_t const s = ZSTD_estimateCStreamSize_advanced(cParams)
+ size_t const s = ZSTD_estimateCStreamSize_advanced_usingCParams(cParams)
/* uses ZSTD_initCStream_usingDict() */
+ ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
if (ZSTD_isError(s)) goto _output_error;
From 9822f97721e472d711f8e28c7304dac379ccdfb6 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Tue, 29 Aug 2017 11:54:38 -0700
Subject: [PATCH 064/248] [error] Don't guard undef X with ifdef X
---
lib/common/error_private.h | 4 +---
lib/common/threading.h | 8 ++------
2 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/lib/common/error_private.h b/lib/common/error_private.h
index f8e68016a..a55bce847 100644
--- a/lib/common/error_private.h
+++ b/lib/common/error_private.h
@@ -48,9 +48,7 @@ typedef ZSTD_ErrorCode ERR_enum;
/*-****************************************
* Error codes handling
******************************************/
-#ifdef ERROR
-# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
-#endif
+#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
#define ERROR(name) ZSTD_ERROR(name)
#define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
diff --git a/lib/common/threading.h b/lib/common/threading.h
index 0a9fcf857..bd4b654c2 100644
--- a/lib/common/threading.h
+++ b/lib/common/threading.h
@@ -37,13 +37,9 @@ extern "C" {
# define WIN32_LEAN_AND_MEAN
#endif
-#ifdef ERROR
-# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
-#endif
+#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
#include
-#ifdef ERROR
-# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
-#endif
+#undef ERROR
#define ERROR(name) ZSTD_ERROR(name)
From c88fb9267f6bad0d0477960d535a553ee33b7840 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 11:55:02 -0700
Subject: [PATCH 065/248] Replace 'byReference' with enum
---
lib/compress/zstd_compress.c | 40 ++++++++++++++++++-------------
lib/compress/zstdmt_compress.c | 2 +-
lib/decompress/zstd_decompress.c | 27 +++++++++++----------
lib/zstd.h | 28 ++++++++++++++--------
programs/bench.c | 2 +-
tests/fuzzer.c | 18 +++++++-------
tests/zstreamtest.c | 6 ++---
zlibWrapper/examples/zwrapbench.c | 2 +-
8 files changed, 70 insertions(+), 55 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 26de0efd8..511d1c3a0 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -525,7 +525,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
}
size_t ZSTD_CCtx_loadDictionary_internal(
- ZSTD_CCtx* cctx, const void* dict, size_t dictSize, unsigned byReference)
+ ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
+ ZSTD_dictLoadMethod_e dictLoadMethod)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
if (cctx->staticSize) return ERROR(memory_allocation); /* no malloc for static CCtx */
@@ -539,7 +540,7 @@ size_t ZSTD_CCtx_loadDictionary_internal(
ZSTD_getCParamsFromCCtxParams(cctx->requestedParams, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- byReference,
+ dictLoadMethod,
cctx->requestedParams.dictMode,
cParams, cctx->customMem);
cctx->cdict = cctx->cdictLocal;
@@ -552,12 +553,12 @@ size_t ZSTD_CCtx_loadDictionary_internal(
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
{
- return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, 1);
+ return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, ZSTD_dlm_byRef);
}
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
{
- return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, 0);
+ return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, ZSTD_dlm_byCopy);
}
@@ -3582,13 +3583,15 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
/*! ZSTD_estimateCDictSize_advanced() :
* Estimate amount of memory that will be needed to create a dictionary with following arguments */
-size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
+size_t ZSTD_estimateCDictSize_advanced(
+ size_t dictSize, ZSTD_compressionParameters cParams,
+ ZSTD_dictLoadMethod_e dictLoadMethod)
{
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
DEBUGLOG(5, "CCtx estimate : %u",
(U32)ZSTD_estimateCCtxSize_advanced_usingCParams(cParams));
return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced_usingCParams(cParams)
- + (byReference ? 0 : dictSize);
+ + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
}
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
@@ -3608,11 +3611,12 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
static size_t ZSTD_initCDict_internal(
ZSTD_CDict* cdict,
const void* dictBuffer, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams)
{
DEBUGLOG(5, "ZSTD_initCDict_internal, mode %u", (U32)dictMode);
- if ((byReference) || (!dictBuffer) || (!dictSize)) {
+ if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
cdict->dictBuffer = NULL;
cdict->dictContent = dictBuffer;
} else {
@@ -3640,7 +3644,8 @@ static size_t ZSTD_initCDict_internal(
}
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
{
DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
@@ -3656,7 +3661,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
cdict->refContext = cctx;
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dictBuffer, dictSize,
- byReference, dictMode,
+ dictLoadMethod, dictMode,
cParams) )) {
ZSTD_freeCDict(cdict);
return NULL;
@@ -3669,7 +3674,7 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL
{
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
return ZSTD_createCDict_advanced(dict, dictSize,
- 0 /* byReference */, ZSTD_dm_auto,
+ ZSTD_dlm_byCopy, ZSTD_dm_auto,
cParams, ZSTD_defaultCMem);
}
@@ -3677,7 +3682,7 @@ ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int
{
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
return ZSTD_createCDict_advanced(dict, dictSize,
- 1 /* byReference */, ZSTD_dm_auto,
+ ZSTD_dlm_byRef, ZSTD_dm_auto,
cParams, ZSTD_defaultCMem);
}
@@ -3707,11 +3712,12 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
*/
ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams)
{
size_t const cctxSize = ZSTD_estimateCCtxSize_advanced_usingCParams(cParams);
- size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize)
+ size_t const neededSize = sizeof(ZSTD_CDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize)
+ cctxSize;
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
void* ptr;
@@ -3721,7 +3727,7 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
(U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
if (workspaceSize < neededSize) return NULL;
- if (!byReference) {
+ if (dictLoadMethod == ZSTD_dlm_byCopy) {
memcpy(cdict+1, dict, dictSize);
dict = cdict+1;
ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
@@ -3732,7 +3738,7 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
dict, dictSize,
- 1 /* byReference */, dictMode,
+ ZSTD_dlm_byRef, dictMode,
cParams) ))
return NULL;
@@ -3889,7 +3895,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- 0 /* byReference */, params.dictMode,
+ ZSTD_dlm_byCopy, params.dictMode,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index b1a681e74..e64a1f694 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -768,7 +768,7 @@ size_t ZSTDMT_initCStream_internal(
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- 0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
+ ZSTD_dlm_byCopy, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
params.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
index 92e80c1ac..6f4e72391 100644
--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1993,9 +1993,9 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
}
-static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, unsigned byReference)
+static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
{
- if ((byReference) || (!dict) || (!dictSize)) {
+ if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
ddict->dictBuffer = NULL;
ddict->dictContent = dict;
} else {
@@ -2014,7 +2014,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_
return 0;
}
-ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
+ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_customMem customMem)
{
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
@@ -2022,7 +2022,7 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
if (!ddict) return NULL;
ddict->cMem = customMem;
- if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, byReference) )) {
+ if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, dictLoadMethod) )) {
ZSTD_freeDDict(ddict);
return NULL;
}
@@ -2038,7 +2038,7 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
{
ZSTD_customMem const allocator = { NULL, NULL, NULL };
- return ZSTD_createDDict_advanced(dict, dictSize, 0, allocator);
+ return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, allocator);
}
/*! ZSTD_createDDict_byReference() :
@@ -2048,25 +2048,26 @@ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
{
ZSTD_customMem const allocator = { NULL, NULL, NULL };
- return ZSTD_createDDict_advanced(dictBuffer, dictSize, 1, allocator);
+ return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, allocator);
}
ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference)
+ ZSTD_dictLoadMethod_e dictLoadMethod)
{
- size_t const neededSpace = sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize);
+ size_t const neededSpace =
+ sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace;
assert(workspace != NULL);
assert(dict != NULL);
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
if (workspaceSize < neededSpace) return NULL;
- if (!byReference) {
+ if (dictLoadMethod == ZSTD_dlm_byCopy) {
memcpy(ddict+1, dict, dictSize); /* local copy */
dict = ddict+1;
}
- if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, 1 /* byRef */) ))
+ if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, ZSTD_dlm_byRef) ))
return NULL;
return ddict;
}
@@ -2084,10 +2085,10 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
/*! ZSTD_estimateDDictSize() :
* Estimate amount of memory that will be needed to create a dictionary for decompression.
- * Note : dictionary created "byReference" are smaller */
-size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference)
+ * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */
+size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
{
- return sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize);
+ return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
}
size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
diff --git a/lib/zstd.h b/lib/zstd.h
index 6d91e92a4..9ff8ad99f 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -524,13 +524,19 @@ ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced_usingCCtxParams(const ZSTD_
ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
-/*! ZSTD_estimateCDictSize() :
+typedef enum {
+ ZSTD_dlm_byCopy = 0, /* Copy dictionary content internally. */
+ ZSTD_dlm_byRef, /* Reference dictionary content -- the dictionary buffer must outlives its users. */
+} ZSTD_dictLoadMethod_e;
+
+/*! ZSTD_estimate?DictSize() :
* ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
* ZSTD_estimateCStreamSize_advanced_usingCParams() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
- * Note : dictionary created "byReference" are smaller */
+ * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller
+ */
ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
-ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
-ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
+ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);
+ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);
/***************************************
@@ -564,7 +570,6 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize
* It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict */
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
-
typedef enum { ZSTD_dm_auto=0, /* dictionary is "full" if it starts with ZSTD_MAGIC_DICTIONARY, otherwise it is "rawContent" */
ZSTD_dm_rawContent, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */
ZSTD_dm_fullDict /* refuses to load a dictionary if it does not respect Zstandard's specification */
@@ -572,7 +577,8 @@ typedef enum { ZSTD_dm_auto=0, /* dictionary is "full" if it starts with
/*! ZSTD_createCDict_advanced() :
* Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams,
ZSTD_customMem customMem);
@@ -592,7 +598,7 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS
ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams);
/*! ZSTD_getCParams() :
@@ -670,7 +676,8 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, siz
/*! ZSTD_createDDict_advanced() :
* Create a ZSTD_DDict using external alloc and free, optionally by reference */
ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_customMem customMem);
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_customMem customMem);
/*! ZSTD_initStaticDDict() :
* Generate a digested dictionary in provided memory area.
@@ -685,7 +692,7 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictS
*/
ZSTDLIB_API ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference);
+ ZSTD_dictLoadMethod_e dictLoadMethod);
/*! ZSTD_getDictID_fromDict() :
* Provides the dictID stored within dictionary.
@@ -1018,6 +1025,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
*/
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+
/*! ZSTD_CCtx_refCDict() :
* Reference a prepared dictionary, to be used for all next compression jobs.
* Note that compression parameters are enforced from within CDict,
@@ -1096,7 +1104,7 @@ size_t ZSTD_compress_generic_simpleArgs (
ZSTD_EndDirective endOp);
-/** ZSTD_CCtx_params :
+/** ZSTD_CCtx_params
*
* - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
* - ZSTD_CCtxParam_setParameter() : Push parameters one by one into an
diff --git a/programs/bench.c b/programs/bench.c
index f9493e3b0..7731d079e 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -284,7 +284,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
if (comprParams->searchLength) zparams.cParams.searchLength = comprParams->searchLength;
if (comprParams->targetLength) zparams.cParams.targetLength = comprParams->targetLength;
if (comprParams->strategy) zparams.cParams.strategy = comprParams->strategy;
- cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1 /*byRef*/, ZSTD_dm_auto, zparams.cParams, cmem);
+ cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, ZSTD_dlm_byRef, ZSTD_dm_auto, zparams.cParams, cmem);
if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure");
#endif
do {
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 3f7595e99..9f661175a 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -598,10 +598,10 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(4, "test%3i : decompress with static DDict : ", testNb++);
- { size_t const ddictBufferSize = ZSTD_estimateDDictSize(dictSize, 0);
+ { size_t const ddictBufferSize = ZSTD_estimateDDictSize(dictSize, ZSTD_dlm_byCopy);
void* ddictBuffer = malloc(ddictBufferSize);
if (ddictBuffer == NULL) goto _output_error;
- { ZSTD_DDict* const ddict = ZSTD_initStaticDDict(ddictBuffer, ddictBufferSize, CNBuffer, dictSize, 0);
+ { ZSTD_DDict* const ddict = ZSTD_initStaticDDict(ddictBuffer, ddictBufferSize, CNBuffer, dictSize, ZSTD_dlm_byCopy);
size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict);
if (r != CNBuffSize - dictSize) goto _output_error;
}
@@ -687,14 +687,14 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : estimate CDict size : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
- size_t const estimatedSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, 1 /*byReference*/);
+ size_t const estimatedSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byRef);
DISPLAYLEVEL(4, "OK : %u \n", (U32)estimatedSize);
}
DISPLAYLEVEL(4, "test%3i : compress with CDict ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize,
- 1 /* byReference */, ZSTD_dm_auto,
+ ZSTD_dlm_byRef, ZSTD_dm_auto,
cParams, ZSTD_defaultCMem);
DISPLAYLEVEL(4, "(size : %u) : ", (U32)ZSTD_sizeof_CDict(cdict));
cSize = ZSTD_compress_usingCDict(cctx, compressedBuffer, compressedBufferSize,
@@ -720,12 +720,12 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : compress with static CDict : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
- size_t const cdictSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
+ size_t const cdictSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
void* const cdictBuffer = malloc(cdictSize);
if (cdictBuffer==NULL) goto _output_error;
{ ZSTD_CDict* const cdict = ZSTD_initStaticCDict(cdictBuffer, cdictSize,
dictBuffer, dictSize,
- 0 /* by Reference */, ZSTD_dm_auto,
+ ZSTD_dlm_byCopy, ZSTD_dm_auto,
cParams);
if (cdict == NULL) {
DISPLAY("ZSTD_initStaticCDict failed ");
@@ -745,7 +745,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : ZSTD_compress_usingCDict_advanced, no contentSize, no dictID : ", testNb++);
{ ZSTD_frameParameters const fParams = { 0 /* frameSize */, 1 /* checksum */, 1 /* noDictID*/ };
ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
- ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1 /*byRef*/, ZSTD_dm_auto, cParams, ZSTD_defaultCMem);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dm_auto, cParams, ZSTD_defaultCMem);
cSize = ZSTD_compress_usingCDict_advanced(cctx, compressedBuffer, compressedBufferSize,
CNBuffer, CNBuffSize, cdict, fParams);
ZSTD_freeCDict(cdict);
@@ -796,7 +796,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a good dictionary : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
- ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1 /*byRef*/, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem);
if (cdict==NULL) goto _output_error;
ZSTD_freeCDict(cdict);
}
@@ -804,7 +804,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a rawContent (must fail) : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
- ZSTD_CDict* const cdict = ZSTD_createCDict_advanced((const char*)dictBuffer+1, dictSize-1, 1 /*byRef*/, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced((const char*)dictBuffer+1, dictSize-1, ZSTD_dlm_byRef, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem);
if (cdict!=NULL) goto _output_error;
ZSTD_freeCDict(cdict);
}
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 0bf833c51..5d6ef4168 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -199,7 +199,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictSize);
size_t const s = ZSTD_estimateCStreamSize_advanced_usingCParams(cParams)
/* uses ZSTD_initCStream_usingDict() */
- + ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
+ + ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
if (ZSTD_isError(s)) goto _output_error;
DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
}
@@ -275,7 +275,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
DISPLAYLEVEL(5, " (windowSize : %u) ", (U32)fhi.windowSize);
{ size_t const s = ZSTD_estimateDStreamSize(fhi.windowSize)
/* uses ZSTD_initDStream_usingDict() */
- + ZSTD_estimateDDictSize(dictSize, 0);
+ + ZSTD_estimateDDictSize(dictSize, ZSTD_dlm_byCopy);
if (ZSTD_isError(s)) goto _output_error;
DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
} }
@@ -477,7 +477,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
DISPLAYLEVEL(3, "test%3i : ZSTD_initCStream_usingCDict_advanced with masked dictID : ", testNb++);
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictionary.filled);
ZSTD_frameParameters const fParams = { 1 /* contentSize */, 1 /* checksum */, 1 /* noDictID */};
- ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, 1 /* byReference */, ZSTD_dm_auto, cParams, customMem);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, ZSTD_dlm_byRef, ZSTD_dm_auto, cParams, customMem);
size_t const initError = ZSTD_initCStream_usingCDict_advanced(zc, cdict, fParams, CNBufferSize);
if (ZSTD_isError(initError)) goto _output_error;
cSize = 0;
diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c
index 1fc2117f6..d99424a7e 100644
--- a/zlibWrapper/examples/zwrapbench.c
+++ b/zlibWrapper/examples/zwrapbench.c
@@ -236,7 +236,7 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
if (compressor == BMK_ZSTD) {
ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize);
ZSTD_customMem const cmem = { NULL, NULL, NULL };
- ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1 /*byRef*/, ZSTD_dm_auto, zparams.cParams, cmem);
+ ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, ZSTD_dlm_byRef, ZSTD_dm_auto, zparams.cParams, cmem);
if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure");
do {
From c7a18b7c219b10c1ca8b33cd0d3f2614cae7ff54 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 15:10:42 -0700
Subject: [PATCH 066/248] Localize 'dictMode' from cctx to function param
---
lib/common/zstd_internal.h | 4 +-
lib/compress/zstd_compress.c | 104 ++++++++++++++++-----------------
lib/compress/zstdmt_compress.c | 10 ++--
lib/zstd.h | 23 ++++----
4 files changed, 69 insertions(+), 72 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index bfec42fad..6097f8e6f 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -293,9 +293,6 @@ struct ZSTD_CCtx_params_s {
int compressionLevel;
U32 forceWindow; /* force back-references to respect limit of
* 1<requestedParams, param, value);
- case ZSTD_p_dictMode:
- if (cctx->cdict) return ERROR(stage_wrong); /* must be set before loading */
- return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
-
case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize,
* even when referencing into Dictionary content
* default : 0 when using a CDict, 1 when using a Prefix */
@@ -447,15 +448,6 @@ size_t ZSTD_CCtxParam_setParameter(
params->fParams.noDictIDFlag = (value == 0);
return 0;
- case ZSTD_p_dictMode :
- /* restrict dictionary mode to "rawContent" or "fullDict" only */
- ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
- if (value > (unsigned)ZSTD_dm_fullDict) {
- return ERROR(parameter_outOfBound);
- }
- params->dictMode = (ZSTD_dictMode_e)value;
- return 0;
-
case ZSTD_p_forceMaxWindow :
params->forceWindow = value > 0;
return 0;
@@ -496,9 +488,6 @@ size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params
cctx->requestedParams.fParams = params->fParams;
cctx->requestedParams.compressionLevel = params->compressionLevel;
- /* Assume dictionary parameters are validated */
- cctx->requestedParams.dictMode = params->dictMode;
-
/* Set force window explicitly since it sets cctx->loadedDictEnd */
CHECK_F( ZSTD_CCtx_setParameter(
cctx, ZSTD_p_forceMaxWindow, params->forceWindow) );
@@ -524,9 +513,9 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
return 0;
}
-size_t ZSTD_CCtx_loadDictionary_internal(
- ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
- ZSTD_dictLoadMethod_e dictLoadMethod)
+size_t ZSTD_CCtx_loadDictionary_advanced(
+ ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
+ ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
if (cctx->staticSize) return ERROR(memory_allocation); /* no malloc for static CCtx */
@@ -541,7 +530,7 @@ size_t ZSTD_CCtx_loadDictionary_internal(
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
dictLoadMethod,
- cctx->requestedParams.dictMode,
+ dictMode,
cParams, cctx->customMem);
cctx->cdict = cctx->cdictLocal;
if (cctx->cdictLocal == NULL)
@@ -553,12 +542,14 @@ size_t ZSTD_CCtx_loadDictionary_internal(
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
{
- return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, ZSTD_dlm_byRef);
+ return ZSTD_CCtx_loadDictionary_advanced(
+ cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dm_auto);
}
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
{
- return ZSTD_CCtx_loadDictionary_internal(cctx, dict, dictSize, ZSTD_dlm_byCopy);
+ return ZSTD_CCtx_loadDictionary_advanced(
+ cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dm_auto);
}
@@ -566,20 +557,27 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
cctx->cdict = cdict;
- cctx->prefix = NULL; /* exclusive */
- cctx->prefixSize = 0;
+ memset(&cctx->prefixDict, 0, sizeof(ZSTD_prefixDict)); /* exclusive */
return 0;
}
size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
+{
+ return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dm_rawContent);
+}
+
+size_t ZSTD_CCtx_refPrefix_advanced(
+ ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictMode_e dictMode)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
cctx->cdict = NULL; /* prefix discards any prior cdict */
- cctx->prefix = prefix;
- cctx->prefixSize = prefixSize;
+ cctx->prefixDict.dict = prefix;
+ cctx->prefixDict.dictSize = prefixSize;
+ cctx->prefixDict.dictMode = dictMode;
return 0;
}
+
static void ZSTD_startNewCompression(ZSTD_CCtx* cctx)
{
cctx->streamStage = zcss_init;
@@ -3387,13 +3385,14 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
* @return : 0, or an error code */
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
+ ZSTD_dictMode_e dictMode,
const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, U64 pledgedSrcSize,
ZSTD_buffered_policy_e zbuff)
{
DEBUGLOG(4, "ZSTD_compressBegin_internal");
DEBUGLOG(4, "dict ? %s", dict ? "dict" : (cdict ? "cdict" : "none"));
- DEBUGLOG(4, "dictMode : %u", (U32)(params.dictMode));
+ DEBUGLOG(4, "dictMode : %u", (U32)dictMode);
/* params are supposed to be fully validated at this point */
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
@@ -3406,18 +3405,19 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
ZSTDcrp_continue, zbuff) );
- return ZSTD_compress_insertDictionary(cctx, dict, dictSize, params.dictMode);
+ return ZSTD_compress_insertDictionary(cctx, dict, dictSize, dictMode);
}
size_t ZSTD_compressBegin_advanced_internal(
ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
+ ZSTD_dictMode_e dictMode,
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize)
{
/* compression parameters verification and optimization */
CHECK_F( ZSTD_checkCParams(params.cParams) );
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, dictMode, NULL,
params, pledgedSrcSize,
ZSTDb_not_buffered);
}
@@ -3430,8 +3430,8 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
{
ZSTD_CCtx_params cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
- cctxParams.dictMode = ZSTD_dm_auto;
- return ZSTD_compressBegin_advanced_internal(cctx, dict, dictSize, cctxParams,
+ return ZSTD_compressBegin_advanced_internal(cctx, dict, dictSize, ZSTD_dm_auto,
+ cctxParams,
pledgedSrcSize);
}
@@ -3440,8 +3440,7 @@ size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t di
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
ZSTD_CCtx_params cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
- cctxParams.dictMode = ZSTD_dm_auto;
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
cctxParams, 0, ZSTDb_not_buffered);
}
@@ -3523,7 +3522,6 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
{
ZSTD_CCtx_params cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
- cctxParams.dictMode = ZSTD_dm_auto;
return ZSTD_compress_advanced_internal(cctx,
dst, dstCapacity,
src, srcSize,
@@ -3549,7 +3547,7 @@ size_t ZSTD_compress_advanced_internal(
const void* dict,size_t dictSize,
ZSTD_CCtx_params params)
{
- CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
+ CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
params, srcSize, ZSTDb_not_buffered) );
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
}
@@ -3633,9 +3631,8 @@ static size_t ZSTD_initCDict_internal(
ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
cctxParams.fParams = fParams;
cctxParams.cParams = cParams;
- cctxParams.dictMode = dictMode;
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
- cdict->dictContent, dictSize,
+ cdict->dictContent, dictSize, dictMode,
NULL,
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN,
ZSTDb_not_buffered) );
@@ -3759,10 +3756,9 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
{ ZSTD_CCtx_params params = cctx->requestedParams;
params.cParams = ZSTD_getCParamsFromCDict(cdict);
params.fParams = fParams;
- params.dictMode = ZSTD_dm_auto;
DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
return ZSTD_compressBegin_internal(cctx,
- NULL, 0,
+ NULL, 0, ZSTD_dm_auto,
cdict,
params, pledgedSrcSize,
ZSTDb_not_buffered);
@@ -3841,7 +3837,7 @@ size_t ZSTD_CStreamOutSize(void)
static size_t ZSTD_resetCStream_internal(
ZSTD_CStream* zcs,
- const void* dict, size_t dictSize,
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
const ZSTD_CDict* cdict,
const ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
@@ -3851,7 +3847,7 @@ static size_t ZSTD_resetCStream_internal(
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
CHECK_F( ZSTD_compressBegin_internal(zcs,
- dict, dictSize,
+ dict, dictSize, dictMode,
cdict,
params, pledgedSrcSize,
ZSTDb_buffered) );
@@ -3871,7 +3867,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
params.cParams = ZSTD_getCParamsFromCCtxParams(params, pledgedSrcSize, 0);
DEBUGLOG(5, "ZSTD_resetCStream");
- return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, zcs->cdict, params, pledgedSrcSize);
}
/*! ZSTD_initCStream_internal() :
@@ -3895,7 +3891,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- ZSTD_dlm_byCopy, params.dictMode,
+ ZSTD_dlm_byCopy, ZSTD_dm_auto,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
@@ -3911,7 +3907,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
params.compressionLevel = ZSTD_CLEVEL_CUSTOM;
zcs->requestedParams = params;
- return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
+ return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, zcs->cdict, params, pledgedSrcSize);
}
/* ZSTD_initCStream_usingCDict_advanced() :
@@ -4157,23 +4153,27 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
/* transparent initialization stage */
if (cctx->streamStage == zcss_init) {
- const void* const prefix = cctx->prefix;
- size_t const prefixSize = cctx->prefixSize;
+ ZSTD_prefixDict const prefixDict = cctx->prefixDict;
ZSTD_CCtx_params params = cctx->requestedParams;
params.cParams = ZSTD_getCParamsFromCCtxParams(
cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
- cctx->prefix = NULL; cctx->prefixSize = 0; /* single usage */
- assert(prefix==NULL || cctx->cdict==NULL); /* only one can be set */
+ memset(&cctx->prefixDict, 0, sizeof(ZSTD_prefixDict)); /* single usage */
+ assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
#ifdef ZSTD_MULTITHREAD
if (params.nbThreads > 1) {
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
- CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTDMT_initCStream_internal(
+ cctx->mtctx, prefixDict.dict, prefixDict.dictSize,
+ cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
cctx->streamStage = zcss_load;
} else
#endif
{
- CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
+ CHECK_F( ZSTD_resetCStream_internal(
+ cctx, prefixDict.dict, prefixDict.dictSize,
+ prefixDict.dictMode, cctx->cdict, params,
+ cctx->pledgedSrcSizePlusOne-1) );
} }
/* compression stage */
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index e64a1f694..41278677f 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -343,13 +343,13 @@ void ZSTDMT_compressChunk(void* jobDescription)
if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
{ ZSTD_CCtx_params jobParams = job->params;
/* Force loading dictionary in "content-only" mode (no header analysis) */
- size_t const dictModeError =
- ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_dictMode, (U32)ZSTD_dm_rawContent);
size_t const forceWindowError =
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstChunk);
- size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, jobParams, job->fullFrameSize);
- if (ZSTD_isError(initError) || ZSTD_isError(dictModeError) ||
- ZSTD_isError(forceWindowError)) { job->cSize = initError; goto _endJob; }
+ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, ZSTD_dm_rawContent, jobParams, job->fullFrameSize);
+ if (ZSTD_isError(initError) || ZSTD_isError(forceWindowError)) {
+ job->cSize = initError;
+ goto _endJob;
+ }
} }
if (!job->firstChunk) { /* flush and overwrite frame header when it's not first segment */
size_t const hSize = ZSTD_compressContinue(cctx, dstBuff.start, dstBuff.size, src, 0);
diff --git a/lib/zstd.h b/lib/zstd.h
index 9ff8ad99f..8ac564884 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -963,10 +963,6 @@ typedef enum {
ZSTD_p_checksumFlag, /* A 32-bits checksum of content is written at end of frame (default:0) */
ZSTD_p_dictIDFlag, /* When applicable, dictID of dictionary is provided in frame header (default:1) */
- /* dictionary parameters (must be set before ZSTD_CCtx_loadDictionary) */
- ZSTD_p_dictMode=300, /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e.
- * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
-
/* multi-threading parameters */
ZSTD_p_nbThreads=400, /* Select how many threads a compression job can spawn (default:1)
* More threads improve speed, but also increase memory usage.
@@ -1011,19 +1007,19 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
* meaning "return to no-dictionary mode".
* Note 1 : `dict` content will be copied internally. Use
* ZSTD_CCtx_loadDictionary_byReference() to reference dictionary
- * content instead.
+ * content instead. The dictionary buffer must then outlive its
+ * users.
* Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
* For this reason, compression parameters cannot be changed anymore after loading a dictionary.
* It's also a CPU-heavy operation, with non-negligible impact on latency.
* Note 3 : Dictionary will be used for all future compression jobs.
- * To return to "no-dictionary" situation, load a NULL dictionary */
-ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
-
-/*! ZSTD_CCtx_loadDictionary_byReference() :
- * Same as ZSTD_CCtx_loadDictionary() except dictionary content will be
- * referenced, instead of copied. The dictionary buffer must outlive its users.
+ * To return to "no-dictionary" situation, load a NULL dictionary
+ * Note 5 : Use ZSTD_CCtx_loadDictionary_advanced() to select how dictionary
+ * content will be interpreted.
*/
+ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode);
/*! ZSTD_CCtx_refCDict() :
@@ -1050,8 +1046,11 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
* Note 1 : Prefix buffer is referenced. It must outlive compression job.
* Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
* It's a CPU-heavy operation, with non-negligible impact on latency.
- * Note 3 : it's possible to alter ZSTD_p_dictMode using ZSTD_CCtx_setParameter() */
+ * Note 3 : By default, the prefix is treated as raw content
+ * (ZSTD_dm_rawContent). Use ZSTD_CCtx_refPrefix_advanced() to alter
+ * dictMode. */
ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);
+ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictMode_e dictMode);
From 4e835720bf17a3c4cb448804a701e605d7889f5f Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 16:18:21 -0700
Subject: [PATCH 067/248] Delay creation of ZSTDMT_CCtx
---
lib/compress/zstd_compress.c | 39 +++++++++++++++-------------------
lib/compress/zstdmt_compress.c | 2 +-
2 files changed, 18 insertions(+), 23 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 990f3aa6b..4251bbb01 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -122,7 +122,7 @@ struct ZSTD_CCtx_s {
/* Dictionary */
ZSTD_CDict* cdictLocal;
const ZSTD_CDict* cdict;
- ZSTD_prefixDict prefixDict;
+ ZSTD_prefixDict prefixDict; /* single-usage dictionary */
/* Multi-threading */
ZSTDMT_CCtx* mtctx;
@@ -342,30 +342,16 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
case ZSTD_p_nbThreads:
if (value==0) return 0;
DEBUGLOG(5, " setting nbThreads : %u", value);
-#ifndef ZSTD_MULTITHREAD
- if (value > 1) return ERROR(parameter_unsupported);
-#endif
- if ((value>1) && (cctx->requestedParams.nbThreads != value)) {
- if (cctx->staticSize) /* MT not compatible with static alloc */
- return ERROR(parameter_unsupported);
- ZSTDMT_freeCCtx(cctx->mtctx);
- cctx->requestedParams.nbThreads = 1;
- cctx->mtctx = ZSTDMT_createCCtx_advanced(value, cctx->customMem);
- if (cctx->mtctx == NULL) return ERROR(memory_allocation);
+ if (value > 1 && cctx->staticSize) {
+ return ERROR(parameter_unsupported); /* MT not compatible with static alloc */
}
-
- /* Need to initialize overlapSizeLog */
- return ZSTDMT_initializeCCtxParameters(&cctx->requestedParams, value);
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_jobSize:
- if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
- assert(cctx->mtctx != NULL);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_overlapSizeLog:
DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->requestedParams.nbThreads);
- if (cctx->requestedParams.nbThreads <= 1) return ERROR(parameter_unsupported);
- assert(cctx->mtctx != NULL);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
default: return ERROR(parameter_unsupported);
@@ -453,7 +439,7 @@ size_t ZSTD_CCtxParam_setParameter(
return 0;
case ZSTD_p_nbThreads :
- if (value == 0) { return 0; }
+ if (value == 0) return 0;
#ifndef ZSTD_MULTITHREAD
if (value > 1) return ERROR(parameter_unsupported);
#endif
@@ -481,7 +467,8 @@ size_t ZSTD_CCtxParam_setParameter(
*/
size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
{
- if (cctx->cdict) { return ERROR(stage_wrong); }
+ if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
+ if (cctx->cdict) return ERROR(stage_wrong);
/* Assume the compression and frame parameters are validated */
cctx->requestedParams.cParams = params->cParams;
@@ -498,7 +485,6 @@ size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params
CHECK_F( ZSTD_CCtx_setParameter(cctx, ZSTD_p_jobSize, params->jobSize) );
CHECK_F( ZSTD_CCtx_setParameter(
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
-
}
/* customMem is used only for create/free params and can be ignored */
@@ -4162,11 +4148,19 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
#ifdef ZSTD_MULTITHREAD
if (params.nbThreads > 1) {
+ if (cctx->mtctx == NULL || cctx->appliedParams.nbThreads != params.nbThreads) {
+ ZSTDMT_freeCCtx(cctx->mtctx);
+ cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbThreads, cctx->customMem);
+ if (cctx->mtctx == NULL) return ERROR(memory_allocation);
+ }
+
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
+
CHECK_F( ZSTDMT_initCStream_internal(
cctx->mtctx, prefixDict.dict, prefixDict.dictSize,
cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
cctx->streamStage = zcss_load;
+ cctx->appliedParams.nbThreads = params.nbThreads;
} else
#endif
{
@@ -4178,7 +4172,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
/* compression stage */
#ifdef ZSTD_MULTITHREAD
- if (cctx->requestedParams.nbThreads > 1) {
+ if (cctx->appliedParams.nbThreads > 1) {
+ assert(cctx->mtctx != NULL);
size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
DEBUGLOG(5, "ZSTDMT_compressStream_generic : %u", (U32)flushMin);
if ( ZSTD_isError(flushMin)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 41278677f..bf418df54 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -342,9 +342,9 @@ void ZSTDMT_compressChunk(void* jobDescription)
} else { /* srcStart points at reloaded section */
if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
{ ZSTD_CCtx_params jobParams = job->params;
- /* Force loading dictionary in "content-only" mode (no header analysis) */
size_t const forceWindowError =
ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstChunk);
+ /* Force loading dictionary in "content-only" mode (no header analysis) */
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, job->srcStart, job->dictSize, ZSTD_dm_rawContent, jobParams, job->fullFrameSize);
if (ZSTD_isError(initError) || ZSTD_isError(forceWindowError)) {
job->cSize = initError;
From 82d636b76adfcfc7f253fee4663d7a1acaab37d8 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 18:03:06 -0700
Subject: [PATCH 068/248] Rename applyCCtxParams()
---
lib/compress/zstd_compress.c | 3 ++-
lib/zstd.h | 9 +++++----
tests/roundTripCrash.c | 2 +-
tests/zstreamtest.c | 6 +++---
4 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 4251bbb01..436e73cee 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -465,7 +465,8 @@ size_t ZSTD_CCtxParam_setParameter(
*
* Pledged srcSize is treated as unknown.
*/
-size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
+size_t ZSTD_CCtx_setParametersUsingCCtxParams(
+ ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
if (cctx->cdict) return ERROR(stage_wrong);
diff --git a/lib/zstd.h b/lib/zstd.h
index 8ac564884..e062f6d2b 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -1109,7 +1109,7 @@ size_t ZSTD_compress_generic_simpleArgs (
* - ZSTD_CCtxParam_setParameter() : Push parameters one by one into an
* existing ZSTD_CCtx_params structure. This is similar to
* ZSTD_CCtx_setParameter().
- * - ZSTD_CCtx_applyCCtxParams() : Apply parameters to an existing CCtx. These
+ * - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to an existing CCtx. These
* parameters will be applied to all subsequent compression jobs.
* - ZSTD_compress_generic() : Do compression using the CCtx.
* - ZSTD_freeCCtxParams() : Free the memory.
@@ -1141,19 +1141,20 @@ ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
/*! ZSTD_CCtxParam_setParameter() :
* Similar to ZSTD_CCtx_setParameter.
* Set one compression parameter, selected by enum ZSTD_cParameter.
- * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_applyCCtxParams().
+ * Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams().
* Note : when `value` is an enum, cast it to unsigned for proper type checking.
* @result : 0, or an error code (which can be tested with ZSTD_isError()).
*/
ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
-/*! ZSTD_CCtx_applyCCtxParams() :
+/*! ZSTD_CCtx_setParametersUsingCCtxParams() :
* Apply a set of ZSTD_CCtx_params to the compression context.
* This must be done before the dictionary is loaded.
* The pledgedSrcSize is treated as unknown.
* Multithreading parameters are applied only if nbThreads > 1.
*/
-ZSTDLIB_API size_t ZSTD_CCtx_applyCCtxParams(ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
+ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
+ ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
/**
Block functions
diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c
index cb0221c58..41e5d4472 100644
--- a/tests/roundTripCrash.c
+++ b/tests/roundTripCrash.c
@@ -98,7 +98,7 @@ static size_t cctxParamRoundTripTest(void* resultBuff, size_t resultBuffCapacity
/* Apply parameters */
- CHECK_Z( ZSTD_CCtx_applyCCtxParams(cctx, cctxParams) );
+ CHECK_Z( ZSTD_CCtx_setParametersUsingCCtxParams(cctx, cctxParams) );
CHECK_Z (ZSTD_compress_generic(cctx, &outBuffer, &inBuffer, ZSTD_e_end) );
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 5d6ef4168..f8683ac78 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1381,7 +1381,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
/* Apply parameters */
if (useOpaqueAPI) {
- CHECK_Z (ZSTD_CCtx_applyCCtxParams(zc, cctxParams) );
+ CHECK_Z (ZSTD_CCtx_setParametersUsingCCtxParams(zc, cctxParams) );
}
if (FUZ_rand(&lseed) & 1) {
@@ -1393,8 +1393,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (dict && dictSize) {
/* test that compression parameters are rejected (correctly) after loading a non-NULL dictionary */
if (useOpaqueAPI) {
- size_t const setError = ZSTD_CCtx_applyCCtxParams(zc, cctxParams);
- CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_applyCCtxParams should have failed");
+ size_t const setError = ZSTD_CCtx_setParametersUsingCCtxParams(zc, cctxParams);
+ CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParametersUsingCCtxParams should have failed");
} else {
size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1);
CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed");
From 623e3cd40b368b48a62456a0f8f950474b969238 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 18:04:32 -0700
Subject: [PATCH 069/248] Use ZSTD_dm_rawContent in zstdmt_compress
---
lib/compress/zstdmt_compress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index bf418df54..86afe5065 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -768,7 +768,7 @@ size_t ZSTDMT_initCStream_internal(
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- ZSTD_dlm_byCopy, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */
+ ZSTD_dlm_byCopy, ZSTD_dm_rawContent, /* note : a loadPrefix becomes an internal CDict */
params.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
From a6e20e1bd7942ed6cae5382b81e11b81ea2fa701 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 18:36:18 -0700
Subject: [PATCH 070/248] Add test for raw content starting with dict header
---
lib/compress/zstd_compress.c | 1 -
tests/fuzzer.c | 20 ++++++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 436e73cee..7249f6fca 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -4174,7 +4174,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
/* compression stage */
#ifdef ZSTD_MULTITHREAD
if (cctx->appliedParams.nbThreads > 1) {
- assert(cctx->mtctx != NULL);
size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
DEBUGLOG(5, "ZSTDMT_compressStream_generic : %u", (U32)flushMin);
if ( ZSTD_isError(flushMin)
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 9f661175a..db4b33519 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -810,6 +810,26 @@ static int basicUnitTests(U32 seed, double compressibility)
}
DISPLAYLEVEL(4, "OK \n");
+ DISPLAYLEVEL(4, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_auto should fail", testNb++);
+ {
+ size_t ret;
+ MEM_writeLE32(dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
+ ret = ZSTD_CCtx_loadDictionary_advanced(
+ cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dm_auto);
+ if (!ZSTD_isError(ret)) goto _output_error;
+ }
+ DISPLAYLEVEL(4, "OK \n");
+
+ DISPLAYLEVEL(4, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_rawContent should pass", testNb++);
+ {
+ size_t ret;
+ MEM_writeLE32(dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
+ ret = ZSTD_CCtx_loadDictionary_advanced(
+ cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dm_rawContent);
+ if (ZSTD_isError(ret)) goto _output_error;
+ }
+ DISPLAYLEVEL(4, "OK \n");
+
ZSTD_freeCCtx(cctx);
free(dictBuffer);
free(samplesSizes);
From ee65701720f710cf4b568a42f2917faa4b33d2be Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 29 Aug 2017 20:27:35 -0700
Subject: [PATCH 071/248] Minor fixes; remove formatting only changes
---
lib/common/zstd_internal.h | 16 ++++++++--------
lib/compress/zstd_compress.c | 31 ++++++++++++++-----------------
tests/fuzzer.c | 4 ++--
3 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 6097f8e6f..19c0a6261 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -352,12 +352,10 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
* expects params to be valid.
* must receive dict, or cdict, or none, but not both.
* @return : 0, or an error code */
-size_t ZSTD_initCStream_internal(
- ZSTD_CStream* zcs,
- const void* dict, size_t dictSize,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params,
- unsigned long long pledgedSrcSize);
+size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
/*! ZSTD_compressStream_generic() :
* Private use only. To be called from zstdmt_compress.c in single-thread mode. */
@@ -370,14 +368,16 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
* as the name implies */
ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);
-/* INTERNAL */
+/* ZSTD_compressBegin_advanced_internal() :
+ * Private use only. To be called from zstdmt_compress.c. */
size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_dictMode_e dictMode,
ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize);
-/* INTERNAL */
+/* ZSTD_compress_advanced_internal() :
+ * Private use only. To be called from zstdmt_compress.c. */
size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 7249f6fca..206e0976a 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -516,8 +516,7 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
ZSTD_getCParamsFromCCtxParams(cctx->requestedParams, 0, dictSize);
cctx->cdictLocal = ZSTD_createCDict_advanced(
dict, dictSize,
- dictLoadMethod,
- dictMode,
+ dictLoadMethod, dictMode,
cParams, cctx->customMem);
cctx->cdict = cctx->cdictLocal;
if (cctx->cdictLocal == NULL)
@@ -564,7 +563,6 @@ size_t ZSTD_CCtx_refPrefix_advanced(
return 0;
}
-
static void ZSTD_startNewCompression(ZSTD_CCtx* cctx)
{
cctx->streamStage = zcss_init;
@@ -785,7 +783,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
if (crp == ZSTDcrp_continue) {
if (ZSTD_equivalentParams(params, zc->appliedParams)) {
- DEBUGLOG(5, "ZSTD_equivalentCParams()==1");
+ DEBUGLOG(5, "ZSTD_equivalentParams()==1");
zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
zc->entropy->offcode_repeatMode = FSE_repeat_none;
zc->entropy->matchlength_repeatMode = FSE_repeat_none;
@@ -3122,7 +3120,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
if (frame && (cctx->stage==ZSTDcs_init)) {
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity,cctx->appliedParams,
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
if (ZSTD_isError(fhSize)) return fhSize;
dstCapacity -= fhSize;
@@ -3582,7 +3580,7 @@ size_t ZSTD_estimateCDictSize_advanced(
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
{
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
- return ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
+ return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);
}
size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
@@ -3624,6 +3622,7 @@ static size_t ZSTD_initCDict_internal(
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN,
ZSTDb_not_buffered) );
}
+
return 0;
}
@@ -3637,6 +3636,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
+
if (!cdict || !cctx) {
ZSTD_free(cdict, customMem);
ZSTD_freeCCtx(cctx);
@@ -3650,6 +3650,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
ZSTD_freeCDict(cdict);
return NULL;
}
+
return cdict;
}
}
@@ -3822,11 +3823,10 @@ size_t ZSTD_CStreamOutSize(void)
return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
}
-static size_t ZSTD_resetCStream_internal(
- ZSTD_CStream* zcs,
- const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
- const ZSTD_CDict* cdict,
- const ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
+static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
+ const ZSTD_CDict* cdict,
+ const ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
DEBUGLOG(4, "ZSTD_resetCStream_internal");
/* params are supposed to be fully validated at this point */
@@ -3862,9 +3862,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
* Assumption 1 : params are valid
* Assumption 2 : either dict, or cdict, is defined, not both */
size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
- const void* dict, size_t dictSize,
- const ZSTD_CDict* cdict,
- ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
+ const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize)
{
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
@@ -3876,8 +3875,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
return ERROR(memory_allocation);
}
ZSTD_freeCDict(zcs->cdictLocal);
- zcs->cdictLocal = ZSTD_createCDict_advanced(
- dict, dictSize,
+ zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
ZSTD_dlm_byCopy, ZSTD_dm_auto,
params.cParams, zcs->customMem);
zcs->cdict = zcs->cdictLocal;
@@ -4156,7 +4154,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
}
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
-
CHECK_F( ZSTDMT_initCStream_internal(
cctx->mtctx, prefixDict.dict, prefixDict.dictSize,
cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index db4b33519..439ab39d9 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -813,7 +813,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_auto should fail", testNb++);
{
size_t ret;
- MEM_writeLE32(dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
+ MEM_writeLE32((char*)dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
ret = ZSTD_CCtx_loadDictionary_advanced(
cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dm_auto);
if (!ZSTD_isError(ret)) goto _output_error;
@@ -823,7 +823,7 @@ static int basicUnitTests(U32 seed, double compressibility)
DISPLAYLEVEL(4, "test%3i : Loading rawContent starting with dict header w/ ZSTD_dm_rawContent should pass", testNb++);
{
size_t ret;
- MEM_writeLE32(dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
+ MEM_writeLE32((char*)dictBuffer+2, ZSTD_MAGIC_DICTIONARY);
ret = ZSTD_CCtx_loadDictionary_advanced(
cctx, (const char*)dictBuffer+2, dictSize-2, ZSTD_dlm_byRef, ZSTD_dm_rawContent);
if (ZSTD_isError(ret)) goto _output_error;
From 90a31bfa162ce0aaac9f3645ab553bbc417b5bc3 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 30 Aug 2017 14:36:54 -0700
Subject: [PATCH 072/248] Pass dictMode to ZSTDMT_initCStream; fix nits
- Return error code in estimate{CCtx,CStream}Size functions
---
lib/compress/zstd_compress.c | 45 +++++++++++++++-------------------
lib/compress/zstdmt_compress.c | 15 ++++++------
lib/zstd.h | 8 +++---
tests/zstreamtest.c | 22 +++++++++++++++++
4 files changed, 54 insertions(+), 36 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 206e0976a..5adeb480b 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -233,7 +233,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
ZSTD_compressionParameters cParams)
{
ZSTD_CCtx_params cctxParams;
- memset(&cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ memset(&cctxParams, 0, sizeof(cctxParams));
cctxParams.cParams = cParams;
cctxParams.compressionLevel = ZSTD_CLEVEL_CUSTOM;
return cctxParams;
@@ -271,7 +271,7 @@ size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params)
size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
if (!cctxParams) { return ERROR(GENERIC); }
- memset(cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ memset(cctxParams, 0, sizeof(*cctxParams));
cctxParams->compressionLevel = compressionLevel;
return 0;
}
@@ -280,7 +280,7 @@ size_t ZSTD_initCCtxParams_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameter
{
if (!cctxParams) { return ERROR(GENERIC); }
CHECK_F( ZSTD_checkCParams(params.cParams) );
- memset(cctxParams, 0, sizeof(ZSTD_CCtx_params));
+ memset(cctxParams, 0, sizeof(*cctxParams));
cctxParams->cParams = params.cParams;
cctxParams->fParams = params.fParams;
cctxParams->compressionLevel = ZSTD_CLEVEL_CUSTOM;
@@ -543,7 +543,7 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
cctx->cdict = cdict;
- memset(&cctx->prefixDict, 0, sizeof(ZSTD_prefixDict)); /* exclusive */
+ memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* exclusive */
return 0;
}
@@ -657,9 +657,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params)
{
/* Estimate CCtx size is supported for single-threaded compression only. */
- if (params->nbThreads > 1) {
- return 0;
- }
+ if (params->nbThreads > 1) { return ERROR(GENERIC); }
{ ZSTD_compressionParameters const cParams =
ZSTD_getCParamsFromCCtxParams(*params, 0, 0);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
@@ -701,9 +699,7 @@ size_t ZSTD_estimateCCtxSize(int compressionLevel)
size_t ZSTD_estimateCStreamSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params)
{
- if (params->nbThreads > 1) {
- return 0;
- }
+ if (params->nbThreads > 1) { return ERROR(GENERIC); }
{ size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced_usingCCtxParams(params);
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
@@ -3171,7 +3167,7 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
{
- ZSTD_compressionParameters cParams =
+ ZSTD_compressionParameters const cParams =
ZSTD_getCParamsFromCCtxParams(cctx->appliedParams, 0, 0);
return MIN (ZSTD_BLOCKSIZE_MAX, 1 << cParams.windowLog);
}
@@ -3413,7 +3409,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params cctxParams =
+ ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
return ZSTD_compressBegin_advanced_internal(cctx, dict, dictSize, ZSTD_dm_auto,
cctxParams,
@@ -3423,7 +3419,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- ZSTD_CCtx_params cctxParams =
+ ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
cctxParams, 0, ZSTDb_not_buffered);
@@ -3505,7 +3501,7 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
const void* dict,size_t dictSize,
ZSTD_parameters params)
{
- ZSTD_CCtx_params cctxParams =
+ ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
return ZSTD_compress_advanced_internal(cctx,
dst, dstCapacity,
@@ -3611,10 +3607,7 @@ static size_t ZSTD_initCDict_internal(
}
cdict->dictContentSize = dictSize;
- { ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
- 0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
- ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
- cctxParams.fParams = fParams;
+ { ZSTD_CCtx_params cctxParams = cdict->refContext->requestedParams;
cctxParams.cParams = cParams;
CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
cdict->dictContent, dictSize, dictMode,
@@ -3923,7 +3916,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
const void* dict, size_t dictSize,
ZSTD_parameters params, unsigned long long pledgedSrcSize)
{
- ZSTD_CCtx_params cctxParams =
+ ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
CHECK_F( ZSTD_checkCParams(params.cParams) );
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, pledgedSrcSize);
@@ -3932,7 +3925,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
{
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
- ZSTD_CCtx_params cctxParams =
+ ZSTD_CCtx_params const cctxParams =
ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, cctxParams, 0);
}
@@ -3940,9 +3933,9 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
{
ZSTD_CCtx_params cctxParams;
- ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
- params.fParams.contentSizeFlag = (pledgedSrcSize>0);
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
+ cctxParams.fParams.contentSizeFlag = (pledgedSrcSize>0);
return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, pledgedSrcSize);
}
@@ -4122,7 +4115,8 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
* must receive dict, or cdict, or none, but not both.
* @return : 0, or an error code */
size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
- const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
+ const ZSTD_CDict* cdict,
ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
@@ -4142,7 +4136,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
ZSTD_CCtx_params params = cctx->requestedParams;
params.cParams = ZSTD_getCParamsFromCCtxParams(
cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
- memset(&cctx->prefixDict, 0, sizeof(ZSTD_prefixDict)); /* single usage */
+ memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); /* single usage */
assert(prefixDict.dict==NULL || cctx->cdict==NULL); /* only one can be set */
#ifdef ZSTD_MULTITHREAD
@@ -4155,7 +4149,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
CHECK_F( ZSTDMT_initCStream_internal(
- cctx->mtctx, prefixDict.dict, prefixDict.dictSize,
+ cctx->mtctx,
+ prefixDict.dict, prefixDict.dictSize, ZSTD_dm_rawContent,
cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
cctx->streamStage = zcss_load;
cctx->appliedParams.nbThreads = params.nbThreads;
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 86afe5065..166f99d72 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -191,7 +191,7 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
static ZSTD_CCtx_params ZSTDMT_makeJobCCtxParams(ZSTD_CCtx_params const params)
{
ZSTD_CCtx_params jobParams;
- memset(&jobParams, 0, sizeof(ZSTD_CCtx_params));
+ memset(&jobParams, 0, sizeof(jobParams));
jobParams.cParams = params.cParams;
jobParams.fParams = params.fParams;
@@ -737,7 +737,8 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs)
}
size_t ZSTDMT_initCStream_internal(
- ZSTDMT_CCtx* zcs, const void* dict, size_t dictSize,
+ ZSTDMT_CCtx* zcs,
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
const ZSTD_CDict* cdict, ZSTD_CCtx_params params,
unsigned long long pledgedSrcSize)
{
@@ -768,7 +769,7 @@ size_t ZSTDMT_initCStream_internal(
DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal);
ZSTD_freeCDict(zcs->cdictLocal);
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
- ZSTD_dlm_byCopy, ZSTD_dm_rawContent, /* note : a loadPrefix becomes an internal CDict */
+ ZSTD_dlm_byCopy, dictMode, /* note : a loadPrefix becomes an internal CDict */
params.cParams, zcs->cMem);
zcs->cdict = zcs->cdictLocal;
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
@@ -807,7 +808,7 @@ size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
DEBUGLOG(5, "ZSTDMT_initCStream_advanced");
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
- return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, NULL,
+ return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, ZSTD_dm_auto, NULL,
cctxParams, pledgedSrcSize);
}
@@ -820,7 +821,7 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
cctxParams.cParams = ZSTD_getCParamsFromCDict(cdict);
cctxParams.fParams = fParams;
if (cdict==NULL) return ERROR(dictionary_wrong); /* method incompatible with NULL cdict */
- return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
+ return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, ZSTD_dm_auto, cdict,
cctxParams, pledgedSrcSize);
}
@@ -831,7 +832,7 @@ size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize)
{
if (zcs->params.nbThreads==1)
return ZSTD_resetCStream(zcs->cctxPool->cctx[0], pledgedSrcSize);
- return ZSTDMT_initCStream_internal(zcs, NULL, 0, 0, zcs->params,
+ return ZSTDMT_initCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, 0, zcs->params,
pledgedSrcSize);
}
@@ -840,7 +841,7 @@ size_t ZSTDMT_initCStream(ZSTDMT_CCtx* zcs, int compressionLevel) {
ZSTD_CCtx_params cctxParams = zcs->params;
cctxParams.cParams = params.cParams;
cctxParams.fParams = params.fParams;
- return ZSTDMT_initCStream_internal(zcs, NULL, 0, NULL, cctxParams, 0);
+ return ZSTDMT_initCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, NULL, cctxParams, 0);
}
diff --git a/lib/zstd.h b/lib/zstd.h
index e062f6d2b..c11964408 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -498,7 +498,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced_usingCParams() can provide a tighter estimation.
* ZSTD_estimateCCtxSize_advanced_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCCtxSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
+ * ZSTD_estimateCCtxSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbThreads is > 1.
* Note : CCtx estimation is only correct for single-threaded compression */
ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced_usingCParams(ZSTD_compressionParameters cParams);
@@ -510,7 +510,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
* It will also consider src size to be arbitrarily "large", which is worst case.
* If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced_usingCParams() can provide a tighter estimation.
* ZSTD_estimateCStreamSize_advanced_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
- * ZSTD_estimateCStreamSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return 0 if ZSTD_p_nbThreads is set to a value > 1.
+ * ZSTD_estimateCStreamSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbThreads is set to a value > 1.
* Note : CStream estimation is only correct for single-threaded compression.
* ZSTD_DStream memory budget depends on window Size.
* This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -727,9 +727,9 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
ZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */
ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */
-ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. */
+ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. Note: dict is loaded with ZSTD_dm_auto (treated as a full zstd dictionary if it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.*/
ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
- ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
+ ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0. dict is loaded with ZSTD_dm_auto and ZSTD_dlm_byCopy. */
ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */
ZSTDLIB_API size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index f8683ac78..8be6a5910 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -149,6 +149,8 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
U32 testNb = 1;
ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem);
ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem);
+ ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2);
+
ZSTD_inBuffer inBuff, inBuff2;
ZSTD_outBuffer outBuff;
buffer_t dictionary = g_nullBuffer;
@@ -605,6 +607,25 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
if (ZSTD_findDecompressedSize(compressedBuffer, cSize) != ZSTD_CONTENTSIZE_UNKNOWN) goto _output_error;
DISPLAYLEVEL(3, "OK \n");
+ /* Basic multithreading compression test */
+ DISPLAYLEVEL(3, "test%3i : compress %u bytes with multiple threads : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
+ { ZSTD_parameters const params = ZSTD_getParams(1, 0, 0);
+ size_t const r = ZSTDMT_initCStream_advanced(mtctx, CNBuffer, dictSize, params, CNBufferSize);
+ if (ZSTD_isError(r)) goto _output_error; }
+ outBuff.dst = (char*)(compressedBuffer);
+ outBuff.size = compressedBufferSize;
+ outBuff.pos = 0;
+ inBuff.src = CNBuffer;
+ inBuff.size = CNBufferSize;
+ inBuff.pos = 0;
+ { size_t const r = ZSTDMT_compressStream_generic(mtctx, &outBuff, &inBuff, ZSTD_e_end);
+ if (ZSTD_isError(r)) goto _output_error; }
+ if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */
+ { size_t const r = ZSTDMT_endStream(mtctx, &outBuff);
+ if (r != 0) goto _output_error; } /* error, or some data not flushed */
+ DISPLAYLEVEL(3, "OK \n");
+
+
/* Overlen overwriting window data bug */
DISPLAYLEVEL(3, "test%3i : wildcopy doesn't overwrite potential match data : ", testNb++);
{ /* This test has a window size of 1024 bytes and consists of 3 blocks:
@@ -643,6 +664,7 @@ _end:
FUZ_freeDictionary(dictionary);
ZSTD_freeCStream(zc);
ZSTD_freeDStream(zd);
+ ZSTDMT_freeCCtx(mtctx);
free(CNBuffer);
free(compressedBuffer);
free(decodedBuffer);
From 9023898f1e2f51a2bc31367b11eb382e6e724496 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Wed, 30 Aug 2017 17:44:12 -0700
Subject: [PATCH 073/248] updated NEWS
---
NEWS | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/NEWS b/NEWS
index 59687532f..ef7dc71b4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+v1.3.2
+fix : a rare compression bug when compression generates very large distances (only possible at --ultra -22)
+build: better compatibility with reproducible builds, by Bernhard M. Wiedemann (@bmwiedemann) (#818)
+changed : examples license changed to BSD + GPLv2
+
v1.3.1
New license : BSD + GPLv2
perf: substantially decreased memory usage in Multi-threading mode, thanks to reports by Tino Reichardt (@mcmilk)
From e9dc204f42426f9f92459216875c5171ddd98d23 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 11:24:54 -0700
Subject: [PATCH 074/248] fixed a bunch of headers after license change (#825)
---
Makefile | 8 ++++----
build/cmake/CMakeLists.txt | 6 +++---
build/cmake/contrib/CMakeLists.txt | 14 +++++---------
build/cmake/contrib/gen_html/CMakeLists.txt | 13 +++++--------
build/cmake/contrib/pzstd/CMakeLists.txt | 13 +++++--------
contrib/gen_html/Makefile | 10 +++++-----
contrib/long_distance_matching/Makefile | 13 ++++++-------
contrib/pzstd/ErrorHolder.h | 8 ++++----
contrib/pzstd/Logging.h | 8 ++++----
contrib/pzstd/Options.h | 8 ++++----
contrib/pzstd/SkippableFrame.cpp | 8 ++++----
contrib/pzstd/SkippableFrame.h | 8 ++++----
contrib/pzstd/main.cpp | 8 ++++----
contrib/pzstd/test/RoundTrip.h | 8 ++++----
contrib/pzstd/utils/Likely.h | 8 ++++----
contrib/pzstd/utils/ScopeGuard.h | 8 ++++----
contrib/pzstd/utils/ThreadPool.h | 8 ++++----
contrib/pzstd/utils/test/BufferTest.cpp | 8 ++++----
contrib/pzstd/utils/test/RangeTest.cpp | 8 ++++----
contrib/pzstd/utils/test/ResourcePoolTest.cpp | 8 ++++----
contrib/pzstd/utils/test/ScopeGuardTest.cpp | 8 ++++----
contrib/pzstd/utils/test/ThreadPoolTest.cpp | 8 ++++----
contrib/seekable_format/examples/Makefile | 6 +++---
examples/Makefile | 6 +++---
lib/common/threading.c | 12 ++++++------
lib/dll/example/Makefile | 10 +++++-----
tests/fuzz/fuzz_helpers.h | 8 ++++----
tests/fuzz/simple_decompress.c | 10 +++++-----
tests/gzip/Makefile | 10 +++++-----
29 files changed, 124 insertions(+), 135 deletions(-)
diff --git a/Makefile b/Makefile
index a72f99fcb..423d0a18b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,10 @@
# ################################################################
-# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PRGDIR = programs
diff --git a/build/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt
index 6e30c5325..8e8824e7c 100644
--- a/build/cmake/CMakeLists.txt
+++ b/build/cmake/CMakeLists.txt
@@ -2,9 +2,9 @@
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PROJECT(zstd)
diff --git a/build/cmake/contrib/CMakeLists.txt b/build/cmake/contrib/CMakeLists.txt
index c7d97aa95..8c7bc78ae 100644
--- a/build/cmake/contrib/CMakeLists.txt
+++ b/build/cmake/contrib/CMakeLists.txt
@@ -1,17 +1,13 @@
# ################################################################
-# * Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
-# * All rights reserved.
-# *
-# * This source code is licensed under the BSD-style license found in the
-# * LICENSE file in the root directory of this source tree. An additional grant
-# * of patent rights can be found in the PATENTS file in the same directory.
+# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+# All rights reserved.
#
-# You can contact the author at :
-# - zstd homepage : http://www.zstd.net/
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PROJECT(contrib)
ADD_SUBDIRECTORY(pzstd)
ADD_SUBDIRECTORY(gen_html)
-
diff --git a/build/cmake/contrib/gen_html/CMakeLists.txt b/build/cmake/contrib/gen_html/CMakeLists.txt
index c10c62b54..01d190672 100644
--- a/build/cmake/contrib/gen_html/CMakeLists.txt
+++ b/build/cmake/contrib/gen_html/CMakeLists.txt
@@ -1,13 +1,10 @@
# ################################################################
-# * Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
-# * All rights reserved.
-# *
-# * This source code is licensed under the BSD-style license found in the
-# * LICENSE file in the root directory of this source tree. An additional grant
-# * of patent rights can be found in the PATENTS file in the same directory.
+# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
+# All rights reserved.
#
-# You can contact the author at :
-# - zstd homepage : http://www.zstd.net/
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PROJECT(gen_html)
diff --git a/build/cmake/contrib/pzstd/CMakeLists.txt b/build/cmake/contrib/pzstd/CMakeLists.txt
index 71def02cd..e6db47198 100644
--- a/build/cmake/contrib/pzstd/CMakeLists.txt
+++ b/build/cmake/contrib/pzstd/CMakeLists.txt
@@ -1,13 +1,10 @@
# ################################################################
-# * Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
-# * All rights reserved.
-# *
-# * This source code is licensed under the BSD-style license found in the
-# * LICENSE file in the root directory of this source tree. An additional grant
-# * of patent rights can be found in the PATENTS file in the same directory.
+# Copyright (c) 2016-present, Facebook, Inc.
+# All rights reserved.
#
-# You can contact the author at :
-# - zstd homepage : http://www.zstd.net/
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PROJECT(pzstd)
diff --git a/contrib/gen_html/Makefile b/contrib/gen_html/Makefile
index ea68b11fc..d9b32e351 100644
--- a/contrib/gen_html/Makefile
+++ b/contrib/gen_html/Makefile
@@ -1,11 +1,11 @@
-# ##########################################################################
+# ################################################################
# Copyright (c) 2016-present, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-# ##########################################################################
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
CFLAGS ?= -O3
CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wno-comment
diff --git a/contrib/long_distance_matching/Makefile b/contrib/long_distance_matching/Makefile
index 4193cb323..6ed1fab45 100644
--- a/contrib/long_distance_matching/Makefile
+++ b/contrib/long_distance_matching/Makefile
@@ -1,10 +1,10 @@
# ################################################################
-# Copyright (c) 2016-present, Facebook, Inc.
+# Copyright (c) 2017-present, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
# This Makefile presumes libzstd is installed, using `sudo make install`
@@ -25,8 +25,8 @@ LDFLAGS += -lzstd
default: all
-all: ldm
-
+all: ldm
+
ldm: ldm_common.c ldm.c main.c
$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@
@@ -34,4 +34,3 @@ clean:
@rm -f core *.o tmp* result* *.ldm *.ldm.dec \
ldm
@echo Cleaning completed
-
diff --git a/contrib/pzstd/ErrorHolder.h b/contrib/pzstd/ErrorHolder.h
index 188badcad..829651c59 100644
--- a/contrib/pzstd/ErrorHolder.h
+++ b/contrib/pzstd/ErrorHolder.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/Logging.h b/contrib/pzstd/Logging.h
index 76c982ab2..16a63932c 100644
--- a/contrib/pzstd/Logging.h
+++ b/contrib/pzstd/Logging.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/Options.h b/contrib/pzstd/Options.h
index d58de017e..f4f2aaa49 100644
--- a/contrib/pzstd/Options.h
+++ b/contrib/pzstd/Options.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/SkippableFrame.cpp b/contrib/pzstd/SkippableFrame.cpp
index 5dc95e5ab..769866dfc 100644
--- a/contrib/pzstd/SkippableFrame.cpp
+++ b/contrib/pzstd/SkippableFrame.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "SkippableFrame.h"
#include "mem.h"
diff --git a/contrib/pzstd/SkippableFrame.h b/contrib/pzstd/SkippableFrame.h
index 9dc95c1f5..60deed040 100644
--- a/contrib/pzstd/SkippableFrame.h
+++ b/contrib/pzstd/SkippableFrame.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/main.cpp b/contrib/pzstd/main.cpp
index 7d8dbfbcf..b93f043b1 100644
--- a/contrib/pzstd/main.cpp
+++ b/contrib/pzstd/main.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "ErrorHolder.h"
#include "Options.h"
diff --git a/contrib/pzstd/test/RoundTrip.h b/contrib/pzstd/test/RoundTrip.h
index 8b9088459..c6364ecb4 100644
--- a/contrib/pzstd/test/RoundTrip.h
+++ b/contrib/pzstd/test/RoundTrip.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/Likely.h b/contrib/pzstd/utils/Likely.h
index c8ea102b1..7cea8da27 100644
--- a/contrib/pzstd/utils/Likely.h
+++ b/contrib/pzstd/utils/Likely.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/contrib/pzstd/utils/ScopeGuard.h b/contrib/pzstd/utils/ScopeGuard.h
index 5a333e0ab..31768f43d 100644
--- a/contrib/pzstd/utils/ScopeGuard.h
+++ b/contrib/pzstd/utils/ScopeGuard.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/ThreadPool.h b/contrib/pzstd/utils/ThreadPool.h
index 99b3ecfa5..8ece8e0da 100644
--- a/contrib/pzstd/utils/ThreadPool.h
+++ b/contrib/pzstd/utils/ThreadPool.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/test/BufferTest.cpp b/contrib/pzstd/utils/test/BufferTest.cpp
index 66ec961e2..fbba74e82 100644
--- a/contrib/pzstd/utils/test/BufferTest.cpp
+++ b/contrib/pzstd/utils/test/BufferTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "utils/Buffer.h"
#include "utils/Range.h"
diff --git a/contrib/pzstd/utils/test/RangeTest.cpp b/contrib/pzstd/utils/test/RangeTest.cpp
index c761c8aff..755b50fa6 100644
--- a/contrib/pzstd/utils/test/RangeTest.cpp
+++ b/contrib/pzstd/utils/test/RangeTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "utils/Range.h"
diff --git a/contrib/pzstd/utils/test/ResourcePoolTest.cpp b/contrib/pzstd/utils/test/ResourcePoolTest.cpp
index a6a86b345..6fe145180 100644
--- a/contrib/pzstd/utils/test/ResourcePoolTest.cpp
+++ b/contrib/pzstd/utils/test/ResourcePoolTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "utils/ResourcePool.h"
diff --git a/contrib/pzstd/utils/test/ScopeGuardTest.cpp b/contrib/pzstd/utils/test/ScopeGuardTest.cpp
index 0c4dc0357..7bc624da7 100644
--- a/contrib/pzstd/utils/test/ScopeGuardTest.cpp
+++ b/contrib/pzstd/utils/test/ScopeGuardTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "utils/ScopeGuard.h"
diff --git a/contrib/pzstd/utils/test/ThreadPoolTest.cpp b/contrib/pzstd/utils/test/ThreadPoolTest.cpp
index 89085afd4..703fd4c9c 100644
--- a/contrib/pzstd/utils/test/ThreadPoolTest.cpp
+++ b/contrib/pzstd/utils/test/ThreadPoolTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "utils/ThreadPool.h"
diff --git a/contrib/seekable_format/examples/Makefile b/contrib/seekable_format/examples/Makefile
index 625e1fcc8..1847aa7e7 100644
--- a/contrib/seekable_format/examples/Makefile
+++ b/contrib/seekable_format/examples/Makefile
@@ -2,9 +2,9 @@
# Copyright (c) 2017-present, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
# This Makefile presumes libzstd is built, using `make` in / or /lib/
diff --git a/examples/Makefile b/examples/Makefile
index e279a537d..d1dbc56db 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -2,9 +2,9 @@
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
# This Makefile presumes libzstd is installed, using `sudo make install`
diff --git a/lib/common/threading.c b/lib/common/threading.c
index 141376c56..4e47b6b91 100644
--- a/lib/common/threading.c
+++ b/lib/common/threading.c
@@ -2,9 +2,9 @@
* Copyright (c) 2016 Tino Reichardt
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*
* You can contact the author at:
* - zstdmt source repository: https://github.com/mcmilk/zstdmt
@@ -15,9 +15,9 @@
*/
/* When ZSTD_MULTITHREAD is not defined, this file would become an empty translation unit.
-* Include some ISO C header code to prevent this and portably avoid related warnings.
-* (Visual C++: C4206 / GCC: -Wpedantic / Clang: -Wempty-translation-unit)
-*/
+ * Include some ISO C header code to prevent this and portably avoid related warnings.
+ * (Visual C++: C4206 / GCC: -Wpedantic / Clang: -Wempty-translation-unit)
+ */
#include
diff --git a/lib/dll/example/Makefile b/lib/dll/example/Makefile
index 36041a0e3..45d0db3cd 100644
--- a/lib/dll/example/Makefile
+++ b/lib/dll/example/Makefile
@@ -1,11 +1,11 @@
-# ##########################################################################
+# ################################################################
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-# ##########################################################################
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
VOID := /dev/null
ZSTDDIR := ../include
diff --git a/tests/fuzz/fuzz_helpers.h b/tests/fuzz/fuzz_helpers.h
index 5f07fa4de..f7cc3d5bb 100644
--- a/tests/fuzz/fuzz_helpers.h
+++ b/tests/fuzz/fuzz_helpers.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/tests/fuzz/simple_decompress.c b/tests/fuzz/simple_decompress.c
index c22ad7c53..a225b9dc7 100644
--- a/tests/fuzz/simple_decompress.c
+++ b/tests/fuzz/simple_decompress.c
@@ -1,10 +1,10 @@
-/**
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/tests/gzip/Makefile b/tests/gzip/Makefile
index b02fb693f..40a0ba97d 100644
--- a/tests/gzip/Makefile
+++ b/tests/gzip/Makefile
@@ -1,10 +1,10 @@
# ################################################################
-# Copyright (c) 2017-present, Yann Collet, Facebook, Inc.
+# Copyright (c) 2017-present, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PRGDIR = ../../programs
@@ -12,7 +12,7 @@ VOID = /dev/null
export PATH := .:$(PATH)
.PHONY: all
-#all: test-gzip-env
+#all: test-gzip-env
all: test-helin-segv test-hufts test-keep test-list test-memcpy-abuse test-mixed
all: test-null-suffix-clobber test-stdin test-trailing-nul test-unpack-invalid
all: test-zdiff test-zgrep-context test-zgrep-f test-zgrep-signal test-znew-k test-z-suffix
From e21384fffb279a1201d3895a4c81dbfd0d44e2a2 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 12:11:57 -0700
Subject: [PATCH 075/248] fixed more file headers after license change (#825)
---
NEWS | 3 ++-
build/cmake/programs/CMakeLists.txt | 13 +++++--------
contrib/adaptive-compression/datagencli.c | 8 ++++----
contrib/gen_html/gen_html.cpp | 6 +++---
contrib/pzstd/Makefile | 10 +++++-----
contrib/pzstd/Pzstd.h | 8 ++++----
contrib/pzstd/test/PzstdTest.cpp | 8 ++++----
contrib/pzstd/test/RoundTripTest.cpp | 8 ++++----
contrib/pzstd/utils/Buffer.h | 8 ++++----
contrib/pzstd/utils/FileSystem.h | 8 ++++----
contrib/pzstd/utils/Range.h | 8 ++++----
contrib/pzstd/utils/ResourcePool.h | 8 ++++----
contrib/pzstd/utils/WorkQueue.h | 8 ++++----
contrib/pzstd/utils/test/WorkQueueTest.cpp | 8 ++++----
doc/educational_decoder/harness.c | 6 +++---
doc/educational_decoder/zstd_decompress.h | 8 ++++----
lib/common/threading.h | 6 +++---
tests/fuzz/Makefile | 12 +++++-------
tests/fuzz/fuzz.h | 8 ++++----
tests/fuzz/regression_driver.c | 8 ++++----
tests/fuzz/simple_round_trip.c | 8 ++++----
tests/fuzz/stream_decompress.c | 10 +++++-----
tests/fuzz/stream_round_trip.c | 8 ++++----
23 files changed, 91 insertions(+), 95 deletions(-)
diff --git a/NEWS b/NEWS
index ef7dc71b4..3ee7d0c32 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,8 @@
v1.3.2
+license : changed /examples license to BSD + GPLv2
+license : fix a few header files to reflect new license (#825)
fix : a rare compression bug when compression generates very large distances (only possible at --ultra -22)
build: better compatibility with reproducible builds, by Bernhard M. Wiedemann (@bmwiedemann) (#818)
-changed : examples license changed to BSD + GPLv2
v1.3.1
New license : BSD + GPLv2
diff --git a/build/cmake/programs/CMakeLists.txt b/build/cmake/programs/CMakeLists.txt
index 13dd31572..9251fd295 100644
--- a/build/cmake/programs/CMakeLists.txt
+++ b/build/cmake/programs/CMakeLists.txt
@@ -1,13 +1,10 @@
# ################################################################
-# * Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
-# * All rights reserved.
-# *
-# * This source code is licensed under the BSD-style license found in the
-# * LICENSE file in the root directory of this source tree. An additional grant
-# * of patent rights can be found in the PATENTS file in the same directory.
+# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
+# All rights reserved.
#
-# You can contact the author at :
-# - zstd homepage : http://www.zstd.net/
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PROJECT(programs)
diff --git a/contrib/adaptive-compression/datagencli.c b/contrib/adaptive-compression/datagencli.c
index 8a81939d1..bf9601f20 100644
--- a/contrib/adaptive-compression/datagencli.c
+++ b/contrib/adaptive-compression/datagencli.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
diff --git a/contrib/gen_html/gen_html.cpp b/contrib/gen_html/gen_html.cpp
index e5261c086..90d5b21a3 100644
--- a/contrib/gen_html/gen_html.cpp
+++ b/contrib/gen_html/gen_html.cpp
@@ -2,9 +2,9 @@
* Copyright (c) 2016-present, Przemyslaw Skibinski, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include
diff --git a/contrib/pzstd/Makefile b/contrib/pzstd/Makefile
index cec6959e6..40531e216 100644
--- a/contrib/pzstd/Makefile
+++ b/contrib/pzstd/Makefile
@@ -1,11 +1,11 @@
-# ##########################################################################
+# ################################################################
# Copyright (c) 2016-present, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-# ##########################################################################
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
# Standard variables for installation
DESTDIR ?=
diff --git a/contrib/pzstd/Pzstd.h b/contrib/pzstd/Pzstd.h
index 1e29a7170..79d1fcca2 100644
--- a/contrib/pzstd/Pzstd.h
+++ b/contrib/pzstd/Pzstd.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/test/PzstdTest.cpp b/contrib/pzstd/test/PzstdTest.cpp
index cadfa83f7..5c7d66310 100644
--- a/contrib/pzstd/test/PzstdTest.cpp
+++ b/contrib/pzstd/test/PzstdTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "Pzstd.h"
extern "C" {
diff --git a/contrib/pzstd/test/RoundTripTest.cpp b/contrib/pzstd/test/RoundTripTest.cpp
index ed2ea770c..36af0673a 100644
--- a/contrib/pzstd/test/RoundTripTest.cpp
+++ b/contrib/pzstd/test/RoundTripTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
extern "C" {
#include "datagen.h"
diff --git a/contrib/pzstd/utils/Buffer.h b/contrib/pzstd/utils/Buffer.h
index ab25bac9c..f69c3b4d9 100644
--- a/contrib/pzstd/utils/Buffer.h
+++ b/contrib/pzstd/utils/Buffer.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/FileSystem.h b/contrib/pzstd/utils/FileSystem.h
index 7d597047f..3cfbe86e5 100644
--- a/contrib/pzstd/utils/FileSystem.h
+++ b/contrib/pzstd/utils/FileSystem.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/Range.h b/contrib/pzstd/utils/Range.h
index 111e98f58..7e2559cc9 100644
--- a/contrib/pzstd/utils/Range.h
+++ b/contrib/pzstd/utils/Range.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/contrib/pzstd/utils/ResourcePool.h b/contrib/pzstd/utils/ResourcePool.h
index ed011306b..a6ff5ffc5 100644
--- a/contrib/pzstd/utils/ResourcePool.h
+++ b/contrib/pzstd/utils/ResourcePool.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/WorkQueue.h b/contrib/pzstd/utils/WorkQueue.h
index 780e5360f..1d14d922c 100644
--- a/contrib/pzstd/utils/WorkQueue.h
+++ b/contrib/pzstd/utils/WorkQueue.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#pragma once
diff --git a/contrib/pzstd/utils/test/WorkQueueTest.cpp b/contrib/pzstd/utils/test/WorkQueueTest.cpp
index 8caf170d2..14cf77304 100644
--- a/contrib/pzstd/utils/test/WorkQueueTest.cpp
+++ b/contrib/pzstd/utils/test/WorkQueueTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "utils/Buffer.h"
#include "utils/WorkQueue.h"
diff --git a/doc/educational_decoder/harness.c b/doc/educational_decoder/harness.c
index 982e066e2..47882b168 100644
--- a/doc/educational_decoder/harness.c
+++ b/doc/educational_decoder/harness.c
@@ -2,9 +2,9 @@
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include
diff --git a/doc/educational_decoder/zstd_decompress.h b/doc/educational_decoder/zstd_decompress.h
index 41009909b..a01fde331 100644
--- a/doc/educational_decoder/zstd_decompress.h
+++ b/doc/educational_decoder/zstd_decompress.h
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2017-present, Facebook, Inc.
+ * Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/******* EXPOSED TYPES ********************************************************/
diff --git a/lib/common/threading.h b/lib/common/threading.h
index bd4b654c2..8194bc6fa 100644
--- a/lib/common/threading.h
+++ b/lib/common/threading.h
@@ -2,9 +2,9 @@
* Copyright (c) 2016 Tino Reichardt
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*
* You can contact the author at:
* - zstdmt source repository: https://github.com/mcmilk/zstdmt
diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile
index da22ed0d0..c6327068f 100644
--- a/tests/fuzz/Makefile
+++ b/tests/fuzz/Makefile
@@ -1,13 +1,11 @@
-# ##########################################################################
+# ################################################################
# Copyright (c) 2016-present, Facebook, Inc.
# All rights reserved.
#
-# This Makefile is validated for Linux, and macOS targets
-#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-# ##########################################################################
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
CFLAGS ?= -O3
CXXFLAGS ?= -O3
diff --git a/tests/fuzz/fuzz.h b/tests/fuzz/fuzz.h
index 5b71aba89..3017db3aa 100644
--- a/tests/fuzz/fuzz.h
+++ b/tests/fuzz/fuzz.h
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/tests/fuzz/regression_driver.c b/tests/fuzz/regression_driver.c
index eee5f0a2a..41fdcc940 100644
--- a/tests/fuzz/regression_driver.c
+++ b/tests/fuzz/regression_driver.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "fuzz.h"
diff --git a/tests/fuzz/simple_round_trip.c b/tests/fuzz/simple_round_trip.c
index 703ea5826..63472bb44 100644
--- a/tests/fuzz/simple_round_trip.c
+++ b/tests/fuzz/simple_round_trip.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/tests/fuzz/stream_decompress.c b/tests/fuzz/stream_decompress.c
index 778a426de..ae853dc8c 100644
--- a/tests/fuzz/stream_decompress.c
+++ b/tests/fuzz/stream_decompress.c
@@ -1,10 +1,10 @@
-/**
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+/*
+ * Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
diff --git a/tests/fuzz/stream_round_trip.c b/tests/fuzz/stream_round_trip.c
index 17c7dfdd2..74adbeaba 100644
--- a/tests/fuzz/stream_round_trip.c
+++ b/tests/fuzz/stream_round_trip.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/**
From b0cb081dc81a4455f90624e0c849b8bad5f51820 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 12:20:50 -0700
Subject: [PATCH 076/248] last batch of header files changed to reflect new
license (#825)
only remains to update contrib/linux-kernel (@terrelln)
---
build/cmake/lib/CMakeLists.txt | 21 +++++++++------------
contrib/adaptive-compression/adapt.c | 8 ++++----
contrib/pzstd/Options.cpp | 8 ++++----
contrib/pzstd/Pzstd.cpp | 8 ++++----
contrib/pzstd/test/OptionsTest.cpp | 8 ++++----
contrib/seekable_format/zstdseek_compress.c | 8 ++++----
doc/educational_decoder/zstd_decompress.c | 8 ++++----
lib/Makefile | 14 ++++++--------
programs/Makefile | 10 ++++------
tests/Makefile | 14 ++++++--------
tests/test-zstd-speed.py | 10 +++++-----
tests/test-zstd-versions.py | 10 +++++-----
12 files changed, 59 insertions(+), 68 deletions(-)
diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt
index f763733bc..8371192c5 100644
--- a/build/cmake/lib/CMakeLists.txt
+++ b/build/cmake/lib/CMakeLists.txt
@@ -1,13 +1,10 @@
# ################################################################
-# * Copyright (c) 2014-present, Yann Collet, Facebook, Inc.
-# * All rights reserved.
-# *
-# * This source code is licensed under the BSD-style license found in the
-# * LICENSE file in the root directory of this source tree. An additional grant
-# * of patent rights can be found in the PATENTS file in the same directory.
+# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
+# All rights reserved.
#
-# You can contact the author at :
-# - zstd homepage : http://www.zstd.net/
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ################################################################
PROJECT(libzstd)
@@ -151,10 +148,10 @@ IF (UNIX)
ENDIF (UNIX)
# install target
-INSTALL(FILES
- ${LIBRARY_DIR}/zstd.h
- ${LIBRARY_DIR}/deprecated/zbuff.h
- ${LIBRARY_DIR}/dictBuilder/zdict.h
+INSTALL(FILES
+ ${LIBRARY_DIR}/zstd.h
+ ${LIBRARY_DIR}/deprecated/zbuff.h
+ ${LIBRARY_DIR}/dictBuilder/zdict.h
${LIBRARY_DIR}/common/zstd_errors.h
DESTINATION "include")
diff --git a/contrib/adaptive-compression/adapt.c b/contrib/adaptive-compression/adapt.c
index e449e2a5f..8f9c678c5 100644
--- a/contrib/adaptive-compression/adapt.c
+++ b/contrib/adaptive-compression/adapt.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include /* fprintf */
diff --git a/contrib/pzstd/Options.cpp b/contrib/pzstd/Options.cpp
index 1f53f2bff..d9b216b42 100644
--- a/contrib/pzstd/Options.cpp
+++ b/contrib/pzstd/Options.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "Options.h"
#include "util.h"
diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp
index ae5d73444..1eb4ce14c 100644
--- a/contrib/pzstd/Pzstd.cpp
+++ b/contrib/pzstd/Pzstd.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "Pzstd.h"
#include "SkippableFrame.h"
diff --git a/contrib/pzstd/test/OptionsTest.cpp b/contrib/pzstd/test/OptionsTest.cpp
index b3efe2b7e..e60114825 100644
--- a/contrib/pzstd/test/OptionsTest.cpp
+++ b/contrib/pzstd/test/OptionsTest.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include "Options.h"
diff --git a/contrib/seekable_format/zstdseek_compress.c b/contrib/seekable_format/zstdseek_compress.c
index 5fe26ed28..df2074988 100644
--- a/contrib/seekable_format/zstdseek_compress.c
+++ b/contrib/seekable_format/zstdseek_compress.c
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
#include /* malloc, free */
diff --git a/doc/educational_decoder/zstd_decompress.c b/doc/educational_decoder/zstd_decompress.c
index af10db528..bea0e0ce1 100644
--- a/doc/educational_decoder/zstd_decompress.c
+++ b/doc/educational_decoder/zstd_decompress.c
@@ -2,9 +2,9 @@
* Copyright (c) 2017-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/// Zstandard educational decoder implementation
@@ -1289,7 +1289,7 @@ static void execute_sequences(frame_context_t *const ctx, ostream_t *const out,
// Copy any leftover literals
{
size_t len = IO_istream_len(&litstream);
- copy_literals(len, &litstream, out);
+ copy_literals(len, &litstream, out);
total_output += len;
}
diff --git a/lib/Makefile b/lib/Makefile
index e31ce0438..b12fd6135 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,13 +1,11 @@
-# ##########################################################################
-# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+# ################################################################
+# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
-#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-# ##########################################################################
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
# Version numbers
LIBVER_MAJOR_SCRIPT:=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./zstd.h`
diff --git a/programs/Makefile b/programs/Makefile
index 5fd3703d4..62b558eeb 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -1,12 +1,10 @@
-# ##########################################################################
+# ################################################################
# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
-#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
# ##########################################################################
# zstd : Command Line Utility, supporting gzip-like arguments
# zstd32 : Same as zstd, but forced to compile in 32-bits mode
diff --git a/tests/Makefile b/tests/Makefile
index 3be79c159..4bffe9137 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,13 +1,11 @@
-# ##########################################################################
-# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+# ################################################################
+# Copyright (c) 2015-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
-#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-# ##########################################################################
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
# datagen : Synthetic and parametrable data generator, for tests
# fullbench : Precisely measure speed for each zstd inner functions
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode
diff --git a/tests/test-zstd-speed.py b/tests/test-zstd-speed.py
index 56108a5ca..1096d5e4e 100755
--- a/tests/test-zstd-speed.py
+++ b/tests/test-zstd-speed.py
@@ -1,13 +1,13 @@
#! /usr/bin/env python3
-#
+# ################################################################
# Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-#
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ##########################################################################
# Limitations:
# - doesn't support filenames with spaces
diff --git a/tests/test-zstd-versions.py b/tests/test-zstd-versions.py
index a5a713009..f2deac1f2 100755
--- a/tests/test-zstd-versions.py
+++ b/tests/test-zstd-versions.py
@@ -1,14 +1,14 @@
#!/usr/bin/env python3
"""Test zstd interoperability between versions"""
-#
+# ################################################################
# Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
# All rights reserved.
#
-# This source code is licensed under the BSD-style license found in the
-# LICENSE file in the root directory of this source tree. An additional grant
-# of patent rights can be found in the PATENTS file in the same directory.
-#
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# ################################################################
import filecmp
import glob
From f9252d8347d3faa8197fdcc1aa9f570c3e2c9b8e Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Thu, 31 Aug 2017 12:48:36 -0700
Subject: [PATCH 077/248] [linux-kernel] Update license
---
.../0002-lib-Add-zstd-modules.patch | 70 +++++++------------
contrib/linux-kernel/include/linux/zstd.h | 2 -
contrib/linux-kernel/lib/zstd/compress.c | 2 -
contrib/linux-kernel/lib/zstd/decompress.c | 2 -
contrib/linux-kernel/lib/zstd/error_private.h | 2 -
contrib/linux-kernel/lib/zstd/mem.h | 2 -
contrib/linux-kernel/lib/zstd/zstd_common.c | 2 -
contrib/linux-kernel/lib/zstd/zstd_internal.h | 2 -
contrib/linux-kernel/lib/zstd/zstd_opt.h | 2 -
contrib/linux-kernel/test/DecompressCrash.c | 6 +-
contrib/linux-kernel/test/RoundTripCrash.c | 6 +-
contrib/linux-kernel/xxhash_test.c | 14 ++--
contrib/linux-kernel/zstd_compress_test.c | 12 +---
contrib/linux-kernel/zstd_decompress_test.c | 12 +---
14 files changed, 43 insertions(+), 93 deletions(-)
diff --git a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
index eb8b8b288..c3bbaed73 100644
--- a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
+++ b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
@@ -1,4 +1,4 @@
-From b7f044163968d724be55bf4841fd80babe036dc2 Mon Sep 17 00:00:00 2001
+From 2b29ec569f8438a0307debd29873859ca6d407fc Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Mon, 17 Jul 2017 17:08:19 -0700
Subject: [PATCH v5 2/5] lib: Add zstd modules
@@ -121,26 +121,26 @@ v4 -> v5:
- Fix rare compression bug from upstream commit 308047eb5d
- Fix bug introduced in v3 when working around the gcc-7 bug
- include/linux/zstd.h | 1157 +++++++++++++++
+ include/linux/zstd.h | 1155 +++++++++++++++
lib/Kconfig | 8 +
lib/Makefile | 2 +
lib/zstd/Makefile | 18 +
lib/zstd/bitstream.h | 374 +++++
- lib/zstd/compress.c | 3484 +++++++++++++++++++++++++++++++++++++++++++++
- lib/zstd/decompress.c | 2528 ++++++++++++++++++++++++++++++++
+ lib/zstd/compress.c | 3482 +++++++++++++++++++++++++++++++++++++++++++++
+ lib/zstd/decompress.c | 2526 ++++++++++++++++++++++++++++++++
lib/zstd/entropy_common.c | 243 ++++
- lib/zstd/error_private.h | 53 +
+ lib/zstd/error_private.h | 51 +
lib/zstd/fse.h | 575 ++++++++
lib/zstd/fse_compress.c | 795 +++++++++++
lib/zstd/fse_decompress.c | 332 +++++
lib/zstd/huf.h | 212 +++
lib/zstd/huf_compress.c | 770 ++++++++++
lib/zstd/huf_decompress.c | 960 +++++++++++++
- lib/zstd/mem.h | 151 ++
- lib/zstd/zstd_common.c | 75 +
- lib/zstd/zstd_internal.h | 263 ++++
- lib/zstd/zstd_opt.h | 1014 +++++++++++++
- 19 files changed, 13014 insertions(+)
+ lib/zstd/mem.h | 149 ++
+ lib/zstd/zstd_common.c | 73 +
+ lib/zstd/zstd_internal.h | 261 ++++
+ lib/zstd/zstd_opt.h | 1012 +++++++++++++
+ 19 files changed, 12998 insertions(+)
create mode 100644 include/linux/zstd.h
create mode 100644 lib/zstd/Makefile
create mode 100644 lib/zstd/bitstream.h
@@ -161,18 +161,16 @@ v4 -> v5:
diff --git a/include/linux/zstd.h b/include/linux/zstd.h
new file mode 100644
-index 0000000..249575e
+index 0000000..305efd0
--- /dev/null
+++ b/include/linux/zstd.h
-@@ -0,0 +1,1157 @@
+@@ -0,0 +1,1155 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -1760,18 +1758,16 @@ index 0000000..a826b99
+#endif /* BITSTREAM_H_MODULE */
diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
new file mode 100644
-index 0000000..f9166cf
+index 0000000..ff18ae6
--- /dev/null
+++ b/lib/zstd/compress.c
-@@ -0,0 +1,3484 @@
+@@ -0,0 +1,3482 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -5250,18 +5246,16 @@ index 0000000..f9166cf
+MODULE_DESCRIPTION("Zstd Compressor");
diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
new file mode 100644
-index 0000000..b178467
+index 0000000..72df4828
--- /dev/null
+++ b/lib/zstd/decompress.c
-@@ -0,0 +1,2528 @@
+@@ -0,0 +1,2526 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -8033,18 +8027,16 @@ index 0000000..2b0a643
+}
diff --git a/lib/zstd/error_private.h b/lib/zstd/error_private.h
new file mode 100644
-index 0000000..1a60b31
+index 0000000..2062ff0
--- /dev/null
+++ b/lib/zstd/error_private.h
-@@ -0,0 +1,53 @@
+@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -11772,18 +11764,16 @@ index 0000000..6526482
+}
diff --git a/lib/zstd/mem.h b/lib/zstd/mem.h
new file mode 100644
-index 0000000..3a0f34c
+index 0000000..42a697b
--- /dev/null
+++ b/lib/zstd/mem.h
-@@ -0,0 +1,151 @@
+@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -11929,18 +11919,16 @@ index 0000000..3a0f34c
+#endif /* MEM_H_MODULE */
diff --git a/lib/zstd/zstd_common.c b/lib/zstd/zstd_common.c
new file mode 100644
-index 0000000..a282624
+index 0000000..e5f06d7
--- /dev/null
+++ b/lib/zstd/zstd_common.c
-@@ -0,0 +1,75 @@
+@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -12010,18 +11998,16 @@ index 0000000..a282624
+}
diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h
new file mode 100644
-index 0000000..1a79fab
+index 0000000..a0fb83e
--- /dev/null
+++ b/lib/zstd/zstd_internal.h
-@@ -0,0 +1,263 @@
+@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -12279,18 +12265,16 @@ index 0000000..1a79fab
+#endif /* ZSTD_CCOMMON_H_MODULE */
diff --git a/lib/zstd/zstd_opt.h b/lib/zstd/zstd_opt.h
new file mode 100644
-index 0000000..55e1b4c
+index 0000000..ecdd725
--- /dev/null
+++ b/lib/zstd/zstd_opt.h
-@@ -0,0 +1,1014 @@
+@@ -0,0 +1,1012 @@
+/**
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of https://github.com/facebook/zstd.
-+ * An additional grant of patent rights can be found in the PATENTS file in the
-+ * same directory.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
@@ -13298,4 +13282,4 @@ index 0000000..55e1b4c
+
+#endif /* ZSTD_OPT_H_91842398743 */
--
-2.9.3
+2.9.5
diff --git a/contrib/linux-kernel/include/linux/zstd.h b/contrib/linux-kernel/include/linux/zstd.h
index 249575e24..305efd093 100644
--- a/contrib/linux-kernel/include/linux/zstd.h
+++ b/contrib/linux-kernel/include/linux/zstd.h
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
index f9166cf4f..ff18ae6d6 100644
--- a/contrib/linux-kernel/lib/zstd/compress.c
+++ b/contrib/linux-kernel/lib/zstd/compress.c
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
index b17846725..72df4828d 100644
--- a/contrib/linux-kernel/lib/zstd/decompress.c
+++ b/contrib/linux-kernel/lib/zstd/decompress.c
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/error_private.h b/contrib/linux-kernel/lib/zstd/error_private.h
index 1a60b31f7..2062ff05a 100644
--- a/contrib/linux-kernel/lib/zstd/error_private.h
+++ b/contrib/linux-kernel/lib/zstd/error_private.h
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/mem.h b/contrib/linux-kernel/lib/zstd/mem.h
index 3a0f34c87..42a697b74 100644
--- a/contrib/linux-kernel/lib/zstd/mem.h
+++ b/contrib/linux-kernel/lib/zstd/mem.h
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/zstd_common.c b/contrib/linux-kernel/lib/zstd/zstd_common.c
index a282624ee..e5f06d771 100644
--- a/contrib/linux-kernel/lib/zstd/zstd_common.c
+++ b/contrib/linux-kernel/lib/zstd/zstd_common.c
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/zstd_internal.h b/contrib/linux-kernel/lib/zstd/zstd_internal.h
index 1a79fab9e..a0fb83e34 100644
--- a/contrib/linux-kernel/lib/zstd/zstd_internal.h
+++ b/contrib/linux-kernel/lib/zstd/zstd_internal.h
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/lib/zstd/zstd_opt.h b/contrib/linux-kernel/lib/zstd/zstd_opt.h
index 55e1b4cba..ecdd7259e 100644
--- a/contrib/linux-kernel/lib/zstd/zstd_opt.h
+++ b/contrib/linux-kernel/lib/zstd/zstd_opt.h
@@ -4,8 +4,6 @@
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of https://github.com/facebook/zstd.
- * An additional grant of patent rights can be found in the PATENTS file in the
- * same directory.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
diff --git a/contrib/linux-kernel/test/DecompressCrash.c b/contrib/linux-kernel/test/DecompressCrash.c
index b5b673aad..2ab7dfe52 100644
--- a/contrib/linux-kernel/test/DecompressCrash.c
+++ b/contrib/linux-kernel/test/DecompressCrash.c
@@ -2,9 +2,9 @@
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/*
diff --git a/contrib/linux-kernel/test/RoundTripCrash.c b/contrib/linux-kernel/test/RoundTripCrash.c
index 44c67f3ab..4f968023d 100644
--- a/contrib/linux-kernel/test/RoundTripCrash.c
+++ b/contrib/linux-kernel/test/RoundTripCrash.c
@@ -2,9 +2,9 @@
* Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/*
diff --git a/contrib/linux-kernel/xxhash_test.c b/contrib/linux-kernel/xxhash_test.c
index 5c1101b6f..eb0fb1cd7 100644
--- a/contrib/linux-kernel/xxhash_test.c
+++ b/contrib/linux-kernel/xxhash_test.c
@@ -2,19 +2,13 @@
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation. This program is dual-licensed; you may select
- * either version 2 of the GNU General Public License ("GPL") or BSD license
- * ("BSD").
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/* DO_XXH should be 32 or 64 for xxh32 and xxh64 respectively */
-#define DO_XXH 0
+#define DO_XXH 0
/* DO_CRC should be 0 or 1 */
#define DO_CRC 0
/* Buffer size */
diff --git a/contrib/linux-kernel/zstd_compress_test.c b/contrib/linux-kernel/zstd_compress_test.c
index bf856b796..dc17adf81 100644
--- a/contrib/linux-kernel/zstd_compress_test.c
+++ b/contrib/linux-kernel/zstd_compress_test.c
@@ -2,15 +2,9 @@
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation. This program is dual-licensed; you may select
- * either version 2 of the GNU General Public License ("GPL") or BSD license
- * ("BSD").
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/* Compression level or 0 to disable */
diff --git a/contrib/linux-kernel/zstd_decompress_test.c b/contrib/linux-kernel/zstd_decompress_test.c
index 4905a5ac5..f6efddd30 100644
--- a/contrib/linux-kernel/zstd_decompress_test.c
+++ b/contrib/linux-kernel/zstd_decompress_test.c
@@ -2,15 +2,9 @@
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License version 2 as published by the
- * Free Software Foundation. This program is dual-licensed; you may select
- * either version 2 of the GNU General Public License ("GPL") or BSD license
- * ("BSD").
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
*/
/* Compression level or 0 to disable */
From 6a546efb8c90adf7865801e313da433ce8406ce1 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 28 Jul 2017 15:51:33 -0700
Subject: [PATCH 078/248] Add long distance matcher
Move last literals section to ZSTD_block_internal
---
lib/common/zstd_internal.h | 14 +
lib/compress/zstd_compress.c | 934 +++++++++++++++++++++++++++++++----
lib/compress/zstd_opt.h | 24 +-
lib/zstd.h | 4 +-
programs/bench.c | 6 +-
programs/bench.h | 1 +
programs/fileio.c | 6 +
programs/fileio.h | 1 +
programs/zstdcli.c | 7 +-
tests/fuzzer.c | 4 +-
tests/playTests.sh | 22 +
tests/zstreamtest.c | 2 +
12 files changed, 901 insertions(+), 124 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 19c0a6261..49b21c2db 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -274,6 +274,20 @@ typedef struct {
const BYTE* cachedLiterals;
} optState_t;
+typedef struct {
+ U32 offset;
+ U32 checksum;
+} ldmEntry_t;
+
+typedef struct {
+ ldmEntry_t* hashTable;
+ BYTE* bucketOffsets;
+ U32 ldmEnable; /* 1 if enable long distance matching */
+ U32 hashLog; /* log size of hashTable */
+ U32 bucketLog; /* log number of buckets, at most 4 */
+ U32 hashEveryLog;
+} ldmState_t;
+
typedef struct {
U32 hufCTable[HUF_CTABLE_SIZE_U32(255)];
FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 5adeb480b..331b21207 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -36,6 +36,13 @@ static const U32 g_searchStrength = 8; /* control skip over incompressible dat
#define HASH_READ_SIZE 8
typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
+#define LDM_BUCKET_SIZE_LOG 3
+#define LDM_BUCKET_SIZE_LOG_MAX 4
+#define LDM_MIN_MATCH_LENGTH 64
+#define LDM_WINDOW_LOG 27
+#define LDM_HASH_LOG 20
+#define LDM_HASH_CHAR_OFFSET 10
+
/*-*************************************
* Helper functions
@@ -46,7 +53,6 @@ size_t ZSTD_compressBound(size_t srcSize) {
return srcSize + (srcSize >> 8) + margin;
}
-
/*-*************************************
* Sequence storage
***************************************/
@@ -101,6 +107,7 @@ struct ZSTD_CCtx_s {
seqStore_t seqStore; /* sequences storage ptrs */
optState_t optState;
+ ldmState_t ldmState; /* long distance matching state */
U32* hashTable;
U32* hashTable3;
U32* chainTable;
@@ -354,6 +361,16 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->requestedParams.nbThreads);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+ case ZSTD_p_longDistanceMatching:
+ /* TODO */
+ if (cctx->cdict) return ERROR(stage_wrong);
+ cctx->ldmState.ldmEnable = value>0;
+ if (value != 0) {
+ ZSTD_cLevelToCParams(cctx);
+ cctx->requestedParams.cParams.windowLog = LDM_WINDOW_LOG;
+ }
+ return 0;
+
default: return ERROR(parameter_unsupported);
}
}
@@ -453,6 +470,10 @@ size_t ZSTD_CCtxParam_setParameter(
if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_overlapSectionLog, value);
+ case ZSTD_p_longDistanceMatching :
+ /* TODO */
+ return ERROR(parameter_unsupported);
+
default: return ERROR(parameter_unsupported);
}
}
@@ -677,7 +698,11 @@ size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* pa
((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<appliedParams)) {
+ /* TODO: For now, reset if long distance matching is enabled */
+ if (ZSTD_equivalentParams(params, zc->appliedParams) &&
+ !zc->ldmState.ldmEnable) {
DEBUGLOG(5, "ZSTD_equivalentParams()==1");
zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
zc->entropy->offcode_repeatMode = FSE_repeat_none;
@@ -787,6 +814,15 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
} }
+ {
+ zc->ldmState.hashLog = LDM_HASH_LOG;
+ zc->ldmState.bucketLog =
+ MIN(LDM_BUCKET_SIZE_LOG, LDM_BUCKET_SIZE_LOG_MAX);
+ zc->ldmState.hashEveryLog =
+ params.cParams.windowLog < zc->ldmState.hashLog ?
+ 0 : params.cParams.windowLog - zc->ldmState.hashLog;
+ }
+
{ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
size_t const maxNbSeq = blockSize / divider;
@@ -802,6 +838,14 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? ((size_t)1 << params.cParams.windowLog) + blockSize : 0;
void* ptr;
+ size_t const ldmHSize = ((size_t)1) << zc->ldmState.hashLog;
+ size_t const ldmBucketSize =
+ ((size_t)1) << (zc->ldmState.hashLog - zc->ldmState.bucketLog);
+ size_t const ldmPotentialSpace =
+ ldmBucketSize + (ldmHSize * (sizeof(ldmEntry_t)));
+ size_t const ldmSpace = zc->ldmState.ldmEnable ?
+ ldmPotentialSpace : 0;
+
/* Check if workSpace is large enough, alloc a new one if needed */
{ size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<workSpaceSize < neededSpace) { /* too small : resize /*/
+ if (zc->workSpaceSize < neededSpace) { /* too small : resize */
DEBUGLOG(5, "Need to update workSpaceSize from %uK to %uK \n",
(unsigned)zc->workSpaceSize>>10,
(unsigned)neededSpace>>10);
@@ -878,6 +922,16 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
ptr = zc->optState.priceTable + ZSTD_OPT_NUM+1;
}
+ /* ldm space */
+ if (zc->ldmState.ldmEnable) {
+ if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, ldmSpace);
+ assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
+ zc->ldmState.hashTable = (ldmEntry_t*)ptr;
+ ptr = zc->ldmState.hashTable + ldmHSize;
+ zc->ldmState.bucketOffsets = (BYTE*)ptr;
+ ptr = zc->ldmState.bucketOffsets + ldmBucketSize;
+ }
+
/* table Space */
if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
@@ -990,6 +1044,18 @@ static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reduce
}
}
+/*! ZSTD_ldm_reduceTable() :
+ * reduce table indexes by `reducerValue` */
+static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size,
+ U32 const reducerValue)
+{
+ U32 u;
+ for (u = 0; u < size; u++) {
+ if (table[u].offset < reducerValue) table[u].offset = 0;
+ else table[u].offset -= reducerValue;
+ }
+}
+
/*! ZSTD_reduceIndex() :
* rescale all indexes to avoid future overflow (indexes are U32) */
static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
@@ -1002,6 +1068,12 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
{ U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
+
+ { if (zc->ldmState.ldmEnable) {
+ U32 const ldmHSize = 1 << LDM_HASH_LOG;
+ ZSTD_ldm_reduceTable(zc->ldmState.hashTable, ldmHSize, reducerValue);
+ }
+ }
}
@@ -1611,7 +1683,6 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
}
}
-
/*-*************************************
* Fast Scan
***************************************/
@@ -1630,11 +1701,10 @@ static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
}
}
-
FORCE_INLINE
-void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
- const void* src, size_t srcSize,
- const U32 mls)
+size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
{
U32* const hashTable = cctx->hashTable;
U32 const hBits = cctx->appliedParams.cParams.hashLog;
@@ -1681,7 +1751,6 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
-
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
}
@@ -1711,15 +1780,11 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
-
-static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
+static size_t ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
const void* src, size_t srcSize)
{
const U32 mls = ctx->appliedParams.cParams.searchLength;
@@ -1727,18 +1792,19 @@ static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
{
default: /* includes case 3 */
case 4 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4);
case 5 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5);
case 6 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6);
case 7 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7);
}
}
-static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
+static size_t ZSTD_compressBlock_fast_extDict_generic(
+ ZSTD_CCtx* ctx,
const void* src, size_t srcSize,
const U32 mls)
{
@@ -1825,15 +1891,11 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
/* save reps for next block */
seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
-
-static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
+static size_t ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
const void* src, size_t srcSize)
{
U32 const mls = ctx->appliedParams.cParams.searchLength;
@@ -1841,13 +1903,13 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
{
default: /* includes case 3 */
case 4 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4);
case 5 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5);
case 6 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6);
case 7 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7);
}
}
@@ -1875,7 +1937,7 @@ static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U3
FORCE_INLINE
-void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
+size_t ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
const void* src, size_t srcSize,
const U32 mls)
{
@@ -1921,6 +1983,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
ip++;
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
} else {
+
U32 offset;
if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
@@ -1982,33 +2045,32 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
-static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
{
const U32 mls = ctx->appliedParams.cParams.searchLength;
switch(mls)
{
default: /* includes case 3 */
case 4 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4);
case 5 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5);
case 6 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6);
case 7 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7);
}
}
-static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
+static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
+ ZSTD_CCtx* ctx,
const void* src, size_t srcSize,
const U32 mls)
{
@@ -2131,15 +2193,12 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
/* save reps for next block */
seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
-static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
+static size_t ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
const void* src, size_t srcSize)
{
U32 const mls = ctx->appliedParams.cParams.searchLength;
@@ -2147,13 +2206,13 @@ static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
{
default: /* includes case 3 */
case 4 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4);
case 5 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5);
case 6 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6);
case 7 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7);
}
}
@@ -2546,9 +2605,9 @@ FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
* Common parser - lazy strategy
*********************************/
FORCE_INLINE
-void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize,
- const U32 searchMethod, const U32 depth)
+size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 searchMethod, const U32 depth)
{
seqStore_t* seqStorePtr = &(ctx->seqStore);
const BYTE* const istart = (const BYTE*)src;
@@ -2678,37 +2737,38 @@ _storeSequence:
seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
-static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src,
+ size_t srcSize)
{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
+ return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
}
-static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src,
+ size_t srcSize)
{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
+ return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
}
-static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src,
+ size_t srcSize)
{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
+ return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
}
-static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src,
+ size_t srcSize)
{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
+ return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
}
FORCE_INLINE
-void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
+size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
const void* src, size_t srcSize,
const U32 searchMethod, const U32 depth)
{
@@ -2774,7 +2834,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
/* let's try to find a better solution */
if (depth>=1)
while (iprepToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
-void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+size_t ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
+ return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
}
-static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
+ return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
}
-static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
+ return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
}
-static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
+ return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
}
/* The optimal parser */
#include "zstd_opt.h"
-static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
+ return ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
#else
(void)ctx; (void)src; (void)srcSize;
- return;
+ return 0;
#endif
}
-static void ZSTD_compressBlock_btultra(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_btultra(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
+ return ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
#else
(void)ctx; (void)src; (void)srcSize;
- return;
+ return 0;
#endif
}
-static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
+ return ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
#else
(void)ctx; (void)src; (void)srcSize;
- return;
+ return 0;
#endif
}
-static void ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static size_t ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
{
#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
+ return ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
#else
(void)ctx; (void)src; (void)srcSize;
- return;
+ return 0;
#endif
}
-
/* ZSTD_selectBlockCompressor() :
* assumption : strat is a valid strategy */
-typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+typedef size_t (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
{
static const ZSTD_blockCompressor blockCompressor[2][(unsigned)ZSTD_btultra+1] = {
@@ -2967,18 +3023,687 @@ static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int
return blockCompressor[extDict!=0][(U32)strat];
}
+/*-*************************************
+* Long distance matching
+***************************************/
+
+/** ZSTD_ldm_getSmallHash() :
+ * numBits should be <= 32
+ * @return : the most significant numBits of value */
+static U32 ZSTD_ldm_getSmallHash(U64 value, U32 numBits)
+{
+ assert(numBits <= 32);
+ return (U32)(value >> (64 - numBits));
+}
+
+/** ZSTD_ldm_getChecksum() :
+ * numBitsToDiscard should be <= 32
+ * @return : the next most significant 32 bits after numBitsToDiscard */
+static U32 ZSTD_ldm_getChecksum(U64 hash, U32 numBitsToDiscard)
+{
+ assert(numBitsToDiscard <= 32);
+ return (hash >> (64 - 32 - numBitsToDiscard)) & 0xFFFFFFFF;
+}
+
+/** ZSTD_ldm_getTag() ;
+ * Given the hash, returns the most significant numTagBits bits
+ * after (32 + hbits) bits.
+ *
+ * If there are not enough bits remaining, return the last
+ * numTagBits bits. */
+static U32 ZSTD_ldm_getTag(U64 hash, U32 hbits, U32 numTagBits)
+{
+ if (32 - hbits < numTagBits) {
+ return hash & ((1 << numTagBits) - 1);
+ } else {
+ return (hash >> (32 - hbits - numTagBits)) & ((1 << numTagBits) - 1);
+ }
+}
+
+/** ZSTD_ldm_getBucket() :
+ * Returns a pointer to the start of the bucket associated with hash. */
+static ldmEntry_t* ZSTD_ldm_getBucket(ldmState_t* ldmState, size_t hash)
+{
+ return ldmState->hashTable + (hash << ldmState->bucketLog);
+}
+
+/** ZSTD_ldm_insertEntry() :
+ * Insert the entry with corresponding hash into the hash table */
+static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
+ size_t const hash, const ldmEntry_t entry)
+{
+ BYTE* const bucketOffsets = ldmState->bucketOffsets;
+ *(ZSTD_ldm_getBucket(ldmState, hash) + bucketOffsets[hash]) = entry;
+ bucketOffsets[hash]++;
+ bucketOffsets[hash] &= (1 << ldmState->bucketLog) - 1;
+}
+
+/** ZSTD_ldm_makeEntryAndInsertByTag() :
+ *
+ * Gets the small hash, checksum, and tag from the rollingHash.
+ *
+ * If the tag matches (1 << ldmState->hashEveryLog)-1, then
+ * creates an ldmEntry from the offset, and inserts it into the hash table.
+ *
+ * hBits is the length of the small hash, which is the most significant hBits
+ * of rollingHash. The checksum is the next 32 most significant bits, followed
+ * by ldmState->hashEveryLog bits that make up the tag. */
+static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
+ U64 rollingHash, U32 hBits,
+ U32 const offset)
+{
+ U32 const tag = ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog);
+ U32 const tagMask = (1 << ldmState->hashEveryLog) - 1;
+ if (tag == tagMask) {
+ U32 const hash = ZSTD_ldm_getSmallHash(rollingHash, hBits);
+ U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
+ ldmEntry_t entry;
+ entry.offset = offset;
+ entry.checksum = checksum;
+ ZSTD_ldm_insertEntry(ldmState, hash, entry);
+ }
+}
+
+/** ZSTD_ldm_getRollingHash() :
+ * Get a 64-bit hash using the first len bytes from buf.
+ *
+ * Giving bytes s = s_1, s_2, ... s_k, the hash is defined to be
+ * H(s) = s_1*(a^(k-1)) + s_2*(a^(k-2)) + ... + s_k*(a^0)
+ *
+ * where the constant a is defined to be prime8bytes.
+ *
+ * The implementation adds an offset to each byte, so
+ * H(s) = (s_1 + HASH_CHAR_OFFSET)*(a^(k-1)) + ... */
+static U64 ZSTD_ldm_getRollingHash(const BYTE* buf, U32 len)
+{
+ U64 ret = 0;
+ U32 i;
+ for (i = 0; i < len; i++) {
+ ret *= prime8bytes;
+ ret += buf[i] + LDM_HASH_CHAR_OFFSET;
+ }
+ return ret;
+}
+
+/** ZSTD_ldm_ipow() :
+ * Return base^exp. */
+static U64 ZSTD_ldm_ipow(U64 base, U64 exp)
+{
+ U64 ret = 1;
+ while (exp) {
+ if (exp & 1) { ret *= base; }
+ exp >>= 1;
+ base *= base;
+ }
+ return ret;
+}
+
+/** ZSTD_ldm_updateHash() :
+ * Updates hash by removing toRemove and adding toAdd.
+ *
+ * Note: this currently relies on compiler optimization to avoid
+ * recalculating hashPower. */
+static U64 ZSTD_ldm_updateHash(U64 hash, BYTE toRemove, BYTE toAdd)
+{
+ U64 const hashPower = ZSTD_ldm_ipow(prime8bytes, LDM_MIN_MATCH_LENGTH - 1);
+ hash -= ((toRemove + LDM_HASH_CHAR_OFFSET) * hashPower);
+ hash *= prime8bytes;
+ hash += toAdd + LDM_HASH_CHAR_OFFSET;
+ return hash;
+}
+
+/** ZSTD_ldm_countBackwardsMatch() :
+ * Returns the number of bytes that match backwards before pIn and pMatch.
+ *
+ * We count only bytes where pMatch >= pBase and pIn >= pAnchor. */
+static size_t ZSTD_ldm_countBackwardsMatch(
+ const BYTE* pIn, const BYTE* pAnchor,
+ const BYTE* pMatch, const BYTE* pBase)
+{
+ size_t matchLength = 0;
+ while (pIn > pAnchor && pMatch > pBase && pIn[-1] == pMatch[-1]) {
+ pIn--;
+ pMatch--;
+ matchLength++;
+ }
+ return matchLength;
+}
+
+/** ZSTD_ldm_fillFastTables() :
+ *
+ * Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies.
+ * This is similar to ZSTD_loadDictionaryContent.
+ *
+ * The tables for the other strategies are filled within their
+ * block compressors. */
+static size_t ZSTD_ldm_fillFastTables(ZSTD_CCtx* zc, const void* end)
+{
+ const BYTE* const iend = (const BYTE*)end;
+ const U32 mls = zc->appliedParams.cParams.searchLength;
+
+ switch(zc->appliedParams.cParams.strategy)
+ {
+ case ZSTD_fast:
+ ZSTD_fillHashTable(zc, iend, mls);
+ zc->nextToUpdate = (U32)(iend - zc->base);
+ break;
+
+ case ZSTD_dfast:
+ ZSTD_fillDoubleHashTable(zc, iend, mls);
+ zc->nextToUpdate = (U32)(iend - zc->base);
+ break;
+
+ case ZSTD_greedy:
+ case ZSTD_lazy:
+ case ZSTD_lazy2:
+ case ZSTD_btlazy2:
+ case ZSTD_btopt:
+ case ZSTD_btultra:
+ break;
+ default:
+ assert(0); /* not possible : not a valid strategy id */
+ }
+
+ return 0;
+}
+
+/** ZSTD_ldm_fillLdmHashTable() :
+ *
+ * Fills hashTable from (lastHashed + 1) to iend (non-inclusive).
+ * lastHash is the rolling hash that corresponds to lastHashed.
+ *
+ * Returns the rolling hash corresponding to position iend-1. */
+static U64 ZSTD_ldm_fillLdmHashTable(ldmState_t* state,
+ U64 lastHash, const BYTE* lastHashed,
+ const BYTE* iend, const BYTE* base,
+ U32 hBits)
+{
+ U64 rollingHash = lastHash;
+ const BYTE* cur = lastHashed + 1;
+
+ while (cur < iend) {
+ rollingHash = ZSTD_ldm_updateHash(rollingHash, cur[-1],
+ cur[LDM_MIN_MATCH_LENGTH-1]);
+ ZSTD_ldm_makeEntryAndInsertByTag(state,
+ rollingHash, hBits,
+ (U32)(cur - base));
+ ++cur;
+ }
+ return rollingHash;
+}
+
+
+/** ZSTD_ldm_limitTableUpdate() :
+ *
+ * Sets cctx->nextToUpdate to a position corresponding closer to anchor
+ * if it is far way
+ * (after a long match, only update tables a limited amount). */
+static void ZSTD_ldm_limitTableUpdate(ZSTD_CCtx* cctx, const BYTE* anchor)
+{
+ U32 const current = (U32)(anchor - cctx->base);
+ if (current > cctx->nextToUpdate + 1024) {
+ cctx->nextToUpdate =
+ current - MIN(512, current - cctx->nextToUpdate - 1024);
+ }
+}
+
+/** ZSTD_compressBlock_ldm_generic() :
+ *
+ * This is a block compressor intended for long distance matching.
+ *
+ * The function searches for matches of length at least LDM_MIN_MATCH_LENGTH
+ * using a hash table in cctx->ldmState. Matches can be at a distance of
+ * up to LDM_WINDOW_LOG.
+ *
+ * Upon finding a match, the unmatched literals are compressed using a
+ * ZSTD_blockCompressor (depending on the strategy in the compression
+ * parameters), which stores the matched sequences. The "long distance"
+ * match is then stored with the remaining literals from the
+ * ZSTD_blockCompressor. */
+FORCE_INLINE
+size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
+ const void* src, size_t srcSize)
+{
+ ldmState_t* const ldmState = &(cctx->ldmState);
+ const U32 hBits = ldmState->hashLog - ldmState->bucketLog;
+ const U32 ldmBucketSize = (1 << ldmState->bucketLog);
+ const U32 ldmTagMask = (1 << ldmState->hashEveryLog) - 1;
+ seqStore_t* const seqStorePtr = &(cctx->seqStore);
+ const BYTE* const base = cctx->base;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = cctx->dictLimit;
+ const BYTE* const lowest = base + lowestIndex;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - LDM_MIN_MATCH_LENGTH;
+
+ const ZSTD_blockCompressor blockCompressor =
+ ZSTD_selectBlockCompressor(cctx->appliedParams.cParams.strategy, 0);
+ U32* const repToConfirm = seqStorePtr->repToConfirm;
+ U32 savedRep[ZSTD_REP_NUM];
+ U64 rollingHash = 0;
+ const BYTE* lastHashed = NULL;
+ size_t i, lastLiterals;
+
+ /* Save seqStorePtr->rep and copy repToConfirm */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ savedRep[i] = repToConfirm[i] = seqStorePtr->rep[i];
+
+ /* Main Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
+ size_t mLength;
+ U32 const current = (U32)(ip - base);
+ size_t forwardMatchLength = 0, backwardMatchLength = 0;
+ ldmEntry_t* bestEntry = NULL;
+ if (ip != istart) {
+ rollingHash = ZSTD_ldm_updateHash(rollingHash, lastHashed[0],
+ lastHashed[LDM_MIN_MATCH_LENGTH]);
+ } else {
+ rollingHash = ZSTD_ldm_getRollingHash(ip, LDM_MIN_MATCH_LENGTH);
+ }
+ lastHashed = ip;
+
+ /* Do not insert and do not look for a match */
+ if (ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog) !=
+ ldmTagMask) {
+ ip++;
+ continue;
+ }
+
+ /* Get the best entry and compute the match lengths */
+ {
+ ldmEntry_t* const bucket =
+ ZSTD_ldm_getBucket(ldmState,
+ ZSTD_ldm_getSmallHash(rollingHash, hBits));
+ ldmEntry_t* cur;
+ size_t bestMatchLength = 0;
+ U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
+
+ for (cur = bucket; cur < bucket + ldmBucketSize; ++cur) {
+ const BYTE* const pMatch = cur->offset + base;
+ size_t curForwardMatchLength, curBackwardMatchLength,
+ curTotalMatchLength;
+ if (cur->checksum != checksum || cur->offset <= lowestIndex) {
+ continue;
+ }
+
+ curForwardMatchLength = ZSTD_count(ip, pMatch, iend);
+ if (curForwardMatchLength < LDM_MIN_MATCH_LENGTH) {
+ continue;
+ }
+ curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch(
+ ip, anchor, pMatch, lowest);
+ curTotalMatchLength = curForwardMatchLength +
+ curBackwardMatchLength;
+
+ if (curTotalMatchLength > bestMatchLength) {
+ bestMatchLength = curTotalMatchLength;
+ forwardMatchLength = curForwardMatchLength;
+ backwardMatchLength = curBackwardMatchLength;
+ bestEntry = cur;
+ }
+ }
+ }
+
+ /* No match found -- continue searching */
+ if (bestEntry == NULL) {
+ ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash,
+ hBits, current);
+ ip++;
+ continue;
+ }
+
+ /* Match found */
+ mLength = forwardMatchLength + backwardMatchLength;
+ ip -= backwardMatchLength;
+
+ /* Call the block compressor on the remaining literals */
+ {
+ U32 const matchIndex = bestEntry->offset;
+ const BYTE* const match = base + matchIndex - backwardMatchLength;
+ U32 const offset = (U32)(ip - match);
+
+ /* Overwrite rep codes */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ seqStorePtr->rep[i] = repToConfirm[i];
+
+ /* Fill tables for block compressor */
+ ZSTD_ldm_limitTableUpdate(cctx, anchor);
+ ZSTD_ldm_fillFastTables(cctx, anchor);
+
+ /* Call block compressor and get remaining literals */
+ lastLiterals = blockCompressor(cctx, anchor, ip - anchor);
+ cctx->nextToUpdate = (U32)(ip - base);
+
+ /* Update repToConfirm with the new offset */
+ for (i = ZSTD_REP_NUM - 1; i > 0; i--)
+ repToConfirm[i] = repToConfirm[i-1];
+ repToConfirm[0] = offset;
+
+ /* Store the sequence with the leftover literals */
+ ZSTD_storeSeq(seqStorePtr, lastLiterals, ip - lastLiterals,
+ offset + ZSTD_REP_MOVE, mLength - MINMATCH);
+ }
+
+ /* Insert the current entry into the hash table */
+ ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
+ (U32)(lastHashed - base));
+
+ assert(ip + backwardMatchLength == lastHashed);
+
+ /* Fill the hash table from lastHashed+1 to ip+mLength*/
+ /* Heuristic: don't need to fill the entire table at end of block */
+ if (ip + mLength < ilimit) {
+ rollingHash = ZSTD_ldm_fillLdmHashTable(
+ ldmState, rollingHash, lastHashed,
+ ip + mLength, base, hBits);
+ lastHashed = ip + mLength - 1;
+ }
+ ip += mLength;
+ anchor = ip;
+
+ /* Check immediate repcode */
+ while ( (ip < ilimit)
+ && ( (repToConfirm[1] > 0)
+ && (MEM_read32(ip) == MEM_read32(ip - repToConfirm[1])) )) {
+
+ size_t const rLength = ZSTD_count(ip+4, ip+4-repToConfirm[1],
+ iend) + 4;
+ /* Swap repToConfirm[1] <=> repToConfirm[0] */
+ {
+ U32 const tmpOff = repToConfirm[1];
+ repToConfirm[1] = repToConfirm[0];
+ repToConfirm[0] = tmpOff;
+ }
+
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
+
+ /* Fill the hash table from lastHashed+1 to ip+rLength*/
+ if (ip + rLength < ilimit) {
+ rollingHash = ZSTD_ldm_fillLdmHashTable(
+ ldmState, rollingHash, lastHashed,
+ ip + rLength, base, hBits);
+ lastHashed = ip + rLength - 1;
+ }
+ ip += rLength;
+ anchor = ip;
+
+ continue; /* faster when present ... (?) */
+ }
+ }
+
+ /* Overwrite rep */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ seqStorePtr->rep[i] = repToConfirm[i];
+
+ ZSTD_ldm_limitTableUpdate(cctx, anchor);
+ ZSTD_ldm_fillFastTables(cctx, anchor);
+
+ lastLiterals = blockCompressor(cctx, anchor, iend - anchor);
+ cctx->nextToUpdate = (U32)(ip - base);
+
+ /* Restore seqStorePtr->rep */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ seqStorePtr->rep[i] = savedRep[i];
+
+ /* Return the last literals size */
+ return lastLiterals;
+}
+
+static size_t ZSTD_compressBlock_ldm(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ return ZSTD_compressBlock_ldm_generic(ctx, src, srcSize);
+}
+
+static size_t ZSTD_compressBlock_ldm_extDict_generic(
+ ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ ldmState_t* ldmState = &(ctx->ldmState);
+ const U32 hBits = ldmState->hashLog - ldmState->bucketLog;
+ const U32 ldmBucketSize = (1 << ldmState->bucketLog);
+ const U32 ldmTagMask = (1 << ldmState->hashEveryLog) - 1;
+ seqStore_t* const seqStorePtr = &(ctx->seqStore);
+ const BYTE* const base = ctx->base;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const dictStart = dictBase + lowestIndex;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const lowPrefixPtr = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - LDM_MIN_MATCH_LENGTH;
+
+ const ZSTD_blockCompressor blockCompressor =
+ ZSTD_selectBlockCompressor(ctx->appliedParams.cParams.strategy, 1);
+ U32* const repToConfirm = seqStorePtr->repToConfirm;
+ U32 savedRep[ZSTD_REP_NUM];
+ U64 rollingHash = 0;
+ const BYTE* lastHashed = NULL;
+ size_t i, lastLiterals;
+
+ /* Save seqStorePtr->rep and copy repToConfirm */
+ for (i = 0; i < ZSTD_REP_NUM; i++) {
+ savedRep[i] = repToConfirm[i] = seqStorePtr->rep[i];
+ }
+
+ /* Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
+ size_t mLength;
+ const U32 current = (U32)(ip-base);
+ size_t forwardMatchLength = 0, backwardMatchLength = 0;
+ ldmEntry_t* bestEntry = NULL;
+ if (ip != istart) {
+ rollingHash = ZSTD_ldm_updateHash(rollingHash, lastHashed[0],
+ lastHashed[LDM_MIN_MATCH_LENGTH]);
+ } else {
+ rollingHash = ZSTD_ldm_getRollingHash(ip, LDM_MIN_MATCH_LENGTH);
+ }
+ lastHashed = ip;
+
+ if (ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog) !=
+ ldmTagMask) {
+ /* Don't insert and don't look for a match */
+ ip++;
+ continue;
+ }
+
+ /* Get the best entry and compute the match lengths */
+ {
+ ldmEntry_t* const bucket =
+ ZSTD_ldm_getBucket(ldmState,
+ ZSTD_ldm_getSmallHash(rollingHash, hBits));
+ ldmEntry_t* cur;
+ size_t bestMatchLength = 0;
+ U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
+
+ for (cur = bucket; cur < bucket + ldmBucketSize; ++cur) {
+ const BYTE* const curMatchBase =
+ cur->offset < dictLimit ? dictBase : base;
+ const BYTE* const pMatch = curMatchBase + cur->offset;
+ const BYTE* const matchEnd =
+ cur->offset < dictLimit ? dictEnd : iend;
+ const BYTE* const lowMatchPtr =
+ cur->offset < dictLimit ? dictStart : lowPrefixPtr;
+ size_t curForwardMatchLength, curBackwardMatchLength,
+ curTotalMatchLength;
+
+ if (cur->checksum != checksum || cur->offset <= lowestIndex) {
+ continue;
+ }
+
+ curForwardMatchLength = ZSTD_count_2segments(
+ ip, pMatch, iend,
+ matchEnd, lowPrefixPtr);
+ if (curForwardMatchLength < LDM_MIN_MATCH_LENGTH) {
+ continue;
+ }
+ curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch(
+ ip, anchor, pMatch, lowMatchPtr);
+ curTotalMatchLength = curForwardMatchLength +
+ curBackwardMatchLength;
+
+ if (curTotalMatchLength > bestMatchLength) {
+ bestMatchLength = curTotalMatchLength;
+ forwardMatchLength = curForwardMatchLength;
+ backwardMatchLength = curBackwardMatchLength;
+ bestEntry = cur;
+ }
+ }
+ }
+
+ /* No match found -- continue searching */
+ if (bestEntry == NULL) {
+ ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
+ (U32)(lastHashed - base));
+ ip++;
+ continue;
+ }
+
+ /* Match found */
+ mLength = forwardMatchLength + backwardMatchLength;
+ ip -= backwardMatchLength;
+
+ /* Call the block compressor on the remaining literals */
+ {
+ U32 const matchIndex = bestEntry->offset;
+ U32 const offset = current - matchIndex;
+
+ /* Overwrite rep codes */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ seqStorePtr->rep[i] = repToConfirm[i];
+
+ /* Fill the hash table for the block compressor */
+ ZSTD_ldm_limitTableUpdate(ctx, anchor);
+ ZSTD_ldm_fillFastTables(ctx, anchor);
+
+ /* Call block compressor and get remaining literals */
+ lastLiterals = blockCompressor(ctx, anchor, ip - anchor);
+ ctx->nextToUpdate = (U32)(ip - base);
+
+ /* Update repToConfirm with the new offset */
+ for (i = ZSTD_REP_NUM - 1; i > 0; i--)
+ repToConfirm[i] = repToConfirm[i-1];
+ repToConfirm[0] = offset;
+
+ /* Store the sequence with the leftover literals */
+ ZSTD_storeSeq(seqStorePtr, lastLiterals, ip - lastLiterals,
+ offset + ZSTD_REP_MOVE, mLength - MINMATCH);
+ }
+
+ /* Insert the current entry into the hash table */
+ ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
+ (U32)(lastHashed - base));
+
+ /* Fill the hash table from lastHashed+1 to ip+mLength */
+ assert(ip + backwardMatchLength == lastHashed);
+ if (ip + mLength < ilimit) {
+ rollingHash = ZSTD_ldm_fillLdmHashTable(
+ ldmState, rollingHash, lastHashed,
+ ip + mLength, base, hBits);
+ lastHashed = ip + mLength - 1;
+ }
+ ip += mLength;
+ anchor = ip;
+
+ /* check immediate repcode */
+ while (ip < ilimit) {
+ U32 const current2 = (U32)(ip-base);
+ U32 const repIndex2 = current2 - repToConfirm[1];
+ const BYTE* repMatch2 = repIndex2 < dictLimit ?
+ dictBase + repIndex2 : base + repIndex2;
+ if ( (((U32)((dictLimit-1) - repIndex2) >= 3) &
+ (repIndex2 > lowestIndex)) /* intentional overflow */
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
+ const BYTE* const repEnd2 = repIndex2 < dictLimit ?
+ dictEnd : iend;
+ size_t const repLength2 =
+ ZSTD_count_2segments(ip+4, repMatch2+4, iend,
+ repEnd2, lowPrefixPtr) + 4;
+
+ U32 tmpOffset = repToConfirm[1];
+ repToConfirm[1] = repToConfirm[0];
+ repToConfirm[0] = tmpOffset;
+
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
+
+ /* Fill the hash table from lastHashed+1 to ip+repLength2*/
+ if (ip + repLength2 < ilimit) {
+ rollingHash = ZSTD_ldm_fillLdmHashTable(
+ ldmState, rollingHash, lastHashed,
+ ip + repLength2, base, hBits);
+ lastHashed = ip + repLength2 - 1;
+ }
+ ip += repLength2;
+ anchor = ip;
+ continue;
+ }
+ break;
+ }
+ }
+
+ /* Overwrite rep */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ seqStorePtr->rep[i] = repToConfirm[i];
+
+ ZSTD_ldm_limitTableUpdate(ctx, anchor);
+ ZSTD_ldm_fillFastTables(ctx, anchor);
+
+ /* Call the block compressor one last time on the last literals */
+ lastLiterals = blockCompressor(ctx, anchor, iend - anchor);
+ ctx->nextToUpdate = (U32)(ip - base);
+
+ /* Restore seqStorePtr->rep */
+ for (i = 0; i < ZSTD_REP_NUM; i++)
+ seqStorePtr->rep[i] = savedRep[i];
+
+ /* Return the last literals size */
+ return lastLiterals;
+}
+
+static size_t ZSTD_compressBlock_ldm_extDict(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ return ZSTD_compressBlock_ldm_extDict_generic(ctx, src, srcSize);
+}
+
+static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
+ const BYTE* anchor, size_t lastLLSize)
+{
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+}
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
{
- ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, zc->lowLimit < zc->dictLimit);
const BYTE* const base = zc->base;
const BYTE* const istart = (const BYTE*)src;
const U32 current = (U32)(istart-base);
+ size_t lastLLSize;
+ const BYTE* anchor;
+ const ZSTD_blockCompressor blockCompressor =
+ zc->ldmState.ldmEnable ?
+ (zc->lowLimit < zc->dictLimit ? ZSTD_compressBlock_ldm_extDict :
+ ZSTD_compressBlock_ldm) :
+ ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
+ zc->lowLimit < zc->dictLimit);
+
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
ZSTD_resetSeqStore(&(zc->seqStore));
if (current > zc->nextToUpdate + 384)
zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384)); /* limited update after finding a very long match */
- blockCompressor(zc, src, srcSize);
+
+ lastLLSize = blockCompressor(zc, src, srcSize);
+
+ /* Last literals */
+ anchor = (const BYTE*)src + srcSize - lastLLSize;
+ ZSTD_storeLastLiterals(&zc->seqStore, anchor, lastLLSize);
+
return ZSTD_compressSequences(&zc->seqStore, zc->entropy, &zc->appliedParams.cParams, dst, dstCapacity, srcSize);
}
@@ -3203,7 +3928,6 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
case ZSTD_fast:
ZSTD_fillHashTable (zc, iend, zc->appliedParams.cParams.searchLength);
break;
-
case ZSTD_dfast:
ZSTD_fillDoubleHashTable (zc, iend, zc->appliedParams.cParams.searchLength);
break;
diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h
index 53e806eb7..575cfa661 100644
--- a/lib/compress/zstd_opt.h
+++ b/lib/compress/zstd_opt.h
@@ -413,8 +413,9 @@ static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
* Optimal parser
*********************************/
FORCE_INLINE
-void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize, const int ultra)
+size_t ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const int ultra)
{
seqStore_t* seqStorePtr = &(ctx->seqStore);
optState_t* optStatePtr = &(ctx->optState);
@@ -654,17 +655,15 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
/* Save reps for next block */
{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
FORCE_INLINE
-void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize, const int ultra)
+size_t ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const int ultra)
{
seqStore_t* seqStorePtr = &(ctx->seqStore);
optState_t* optStatePtr = &(ctx->optState);
@@ -928,11 +927,8 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
/* Save reps for next block */
{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
- /* Last Literals */
- { size_t lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
+ /* Return the last literals size */
+ return iend - anchor;
}
#endif /* ZSTD_OPT_H_91842398743 */
diff --git a/lib/zstd.h b/lib/zstd.h
index c11964408..c9fa34f36 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -978,7 +978,9 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
-
+ ZSTD_p_longDistanceMatching, /* Enable long distance matching.
+ * This increases the memory usage as well as the
+ * window size. */
} ZSTD_cParameter;
diff --git a/programs/bench.c b/programs/bench.c
index 7731d079e..a2c4efcf3 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -129,7 +129,10 @@ void BMK_setNbThreads(unsigned nbThreads) {
#endif
g_nbThreads = nbThreads;
}
-
+static U32 g_ldmFlag = 0;
+void BMK_setLdmFlag(unsigned ldmFlag) {
+ g_ldmFlag = ldmFlag;
+}
/* ********************************************************
* Bench functions
@@ -271,6 +274,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
ZSTD_CCtx_setParameter(ctx, ZSTD_p_searchLog, comprParams->searchLog);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_minMatch, comprParams->searchLength);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_targetLength, comprParams->targetLength);
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_longDistanceMatching, g_ldmFlag);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionStrategy, comprParams->strategy);
ZSTD_CCtx_loadDictionary(ctx, dictBuffer, dictBufferSize);
#else
diff --git a/programs/bench.h b/programs/bench.h
index 77a527f8f..03f56d06b 100644
--- a/programs/bench.h
+++ b/programs/bench.h
@@ -25,5 +25,6 @@ void BMK_setNbThreads(unsigned nbThreads);
void BMK_setNotificationLevel(unsigned level);
void BMK_setAdditionalParam(int additionalParam);
void BMK_setDecodeOnlyMode(unsigned decodeFlag);
+void BMK_setLdmFlag(unsigned ldmFlag);
#endif /* BENCH_H_121279284357 */
diff --git a/programs/fileio.c b/programs/fileio.c
index 1dd8008e8..8d024a9b3 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -213,6 +213,10 @@ void FIO_setOverlapLog(unsigned overlapLog){
DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n");
g_overlapLog = overlapLog;
}
+static U32 g_ldmFlag = 0;
+void FIO_setLdmFlag(unsigned ldmFlag) {
+ g_ldmFlag = (ldmFlag>0);
+}
/*-*************************************
@@ -407,6 +411,8 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_minMatch, comprParams->searchLength) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_targetLength, comprParams->targetLength) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionStrategy, (U32)comprParams->strategy) );
+ /* long distance matching */
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_longDistanceMatching, g_ldmFlag) );
/* multi-threading */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_nbThreads, g_nbThreads) );
/* dictionary */
diff --git a/programs/fileio.h b/programs/fileio.h
index 9d9167df9..06cf414df 100644
--- a/programs/fileio.h
+++ b/programs/fileio.h
@@ -56,6 +56,7 @@ void FIO_setMemLimit(unsigned memLimit);
void FIO_setNbThreads(unsigned nbThreads);
void FIO_setBlockSize(unsigned blockSize);
void FIO_setOverlapLog(unsigned overlapLog);
+void FIO_setLdmFlag(unsigned ldmFlag);
/*-*************************************
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index b1268c1f3..cf0710f7c 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -152,6 +152,7 @@ static int usage_advanced(const char* programName)
#endif
DISPLAY( " -M# : Set a memory usage limit for decompression \n");
DISPLAY( "--list : list information about a zstd compressed file \n");
+ DISPLAY( "--long : enable long distance matching\n");
DISPLAY( "-- : All arguments after \"--\" are treated as files \n");
#ifndef ZSTD_NODICT
DISPLAY( "\n");
@@ -333,7 +334,8 @@ int main(int argCount, const char* argv[])
ultra=0,
lastCommand = 0,
nbThreads = 1,
- setRealTimePrio = 0;
+ setRealTimePrio = 0,
+ ldmFlag = 0;
unsigned bench_nbSeconds = 3; /* would be better if this value was synchronized from bench */
size_t blockSize = 0;
zstd_operation_mode operation = zom_compress;
@@ -440,6 +442,7 @@ int main(int argCount, const char* argv[])
#ifdef ZSTD_LZ4COMPRESS
if (!strcmp(argument, "--format=lz4")) { suffix = LZ4_EXTENSION; FIO_setCompressionType(FIO_lz4Compression); continue; }
#endif
+ if (!strcmp(argument, "--long")) { ldmFlag = 1; continue; }
/* long commands with arguments */
#ifndef ZSTD_NODICT
@@ -690,6 +693,7 @@ int main(int argCount, const char* argv[])
BMK_setBlockSize(blockSize);
BMK_setNbThreads(nbThreads);
BMK_setNbSeconds(bench_nbSeconds);
+ BMK_setLdmFlag(ldmFlag);
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast, &compressionParams, setRealTimePrio);
#endif
(void)bench_nbSeconds;
@@ -757,6 +761,7 @@ int main(int argCount, const char* argv[])
#ifndef ZSTD_NOCOMPRESS
FIO_setNbThreads(nbThreads);
FIO_setBlockSize((U32)blockSize);
+ FIO_setLdmFlag(ldmFlag);
if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(g_overlapLog);
if ((filenameIdx==1) && outFileName)
operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel, &compressionParams);
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 439ab39d9..ca67483dd 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -440,8 +440,6 @@ static int basicUnitTests(U32 seed, double compressibility)
free(staticDCtxBuffer);
}
-
-
/* ZSTDMT simple MT compression test */
DISPLAYLEVEL(4, "test%3i : create ZSTDMT CCtx : ", testNb++);
{ ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2);
@@ -1342,6 +1340,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
dictSize = FUZ_rLogLength(&lseed, dictLog); /* needed also for decompression */
dict = srcBuffer + (FUZ_rand(&lseed) % (srcBufferSize - dictSize));
+
if (FUZ_rand(&lseed) & 0xF) {
CHECK_Z ( ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel) );
} else {
@@ -1350,6 +1349,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
!(FUZ_rand(&lseed)&3) /* contentChecksumFlag*/,
0 /*NodictID*/ }; /* note : since dictionary is fake, dictIDflag has no impact */
ZSTD_parameters const p = FUZ_makeParams(cPar, fPar);
+
CHECK_Z ( ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0) );
}
CHECK_Z( ZSTD_copyCCtx(ctx, refCtx, 0) );
diff --git a/tests/playTests.sh b/tests/playTests.sh
index 77853b1a4..8fb2768c2 100755
--- a/tests/playTests.sh
+++ b/tests/playTests.sh
@@ -544,6 +544,15 @@ roundTripTest -g516K 19 # btopt
fileRoundTripTest -g500K
+$ECHO "\n**** zstd long distance matching round-trip tests **** "
+roundTripTest -g0 "2 --long"
+roundTripTest -g1000K "1 --long"
+roundTripTest -g517K "6 --long"
+roundTripTest -g516K "16 --long"
+roundTripTest -g518K "19 --long"
+fileRoundTripTest -g5M "3 --long"
+
+
if [ -n "$hasMT" ]
then
$ECHO "\n**** zstdmt round-trip tests **** "
@@ -551,6 +560,9 @@ then
roundTripTest -g8M "3 -T2"
roundTripTest -g8000K "2 --threads=2"
fileRoundTripTest -g4M "19 -T2 -B1M"
+
+ $ECHO "\n**** zstdmt long distance matching round-trip tests **** "
+ roundTripTest -g8M "3 --long -T2"
else
$ECHO "\n**** no multithreading, skipping zstdmt tests **** "
fi
@@ -639,6 +651,15 @@ roundTripTest -g6000000000 -P99 1
fileRoundTripTest -g4193M -P99 1
+$ECHO "\n**** zstd long, long distance matching round-trip tests **** "
+roundTripTest -g0 "2 --long"
+roundTripTest -g270000000 "1 --long"
+roundTripTest -g140000000 -P60 "5 --long"
+roundTripTest -g70000000 -P70 "8 --long"
+roundTripTest -g18000001 -P80 "18 --long"
+fileRoundTripTest -g4100M -P99 "1 --long"
+
+
if [ -n "$hasMT" ]
then
$ECHO "\n**** zstdmt long round-trip tests **** "
@@ -646,6 +667,7 @@ then
roundTripTest -g6000000000 -P99 "1 -T2"
roundTripTest -g1500000000 -P97 "1 -T999"
fileRoundTripTest -g4195M -P98 " -T0"
+ roundTripTest -g1500000000 -P97 "1 --long -T999"
else
$ECHO "\n**** no multithreading, skipping zstdmt tests **** "
fi
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 8be6a5910..3baa10ef0 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1380,6 +1380,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_minMatch, cParams.searchLength, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed) & 63) );
+
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1, useOpaqueAPI) );
From 8e298382a897de70ad2c9fc2b138192340fc37de Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 14:30:52 -0700
Subject: [PATCH 079/248] changed target allarch into allzstd
allzstd contains only zstd-related tests.
allmost = allzstd + zwrapper tests (which require zlib)
---
Makefile | 17 +++++++----------
appveyor.yml | 12 ++++++------
programs/Makefile | 1 -
3 files changed, 13 insertions(+), 17 deletions(-)
diff --git a/Makefile b/Makefile
index 423d0a18b..e8bdcea33 100644
--- a/Makefile
+++ b/Makefile
@@ -29,15 +29,12 @@ default: lib-release zstd-release
all: | allmost examples manual
.PHONY: allmost
-allmost:
- $(MAKE) -C $(ZSTDDIR) all
- $(MAKE) -C $(PRGDIR) all
- $(MAKE) -C $(TESTDIR) all
+allmost: allzstd
$(MAKE) -C $(ZWRAPDIR) all
#skip zwrapper, can't build that on alternate architectures without the proper zlib installed
-.PHONY: allarch
-allarch:
+.PHONY: allzstd
+allzstd:
$(MAKE) -C $(ZSTDDIR) all
$(MAKE) -C $(PRGDIR) all
$(MAKE) -C $(TESTDIR) all
@@ -158,16 +155,16 @@ m32build: clean
$(MAKE) all32
armbuild: clean
- CC=arm-linux-gnueabi-gcc CFLAGS="-Werror" $(MAKE) allarch
+ CC=arm-linux-gnueabi-gcc CFLAGS="-Werror" $(MAKE) allzstd
aarch64build: clean
- CC=aarch64-linux-gnu-gcc CFLAGS="-Werror" $(MAKE) allarch
+ CC=aarch64-linux-gnu-gcc CFLAGS="-Werror" $(MAKE) allzstd
ppcbuild: clean
- CC=powerpc-linux-gnu-gcc CLAGS="-m32 -Wno-attributes -Werror" $(MAKE) allarch
+ CC=powerpc-linux-gnu-gcc CLAGS="-m32 -Wno-attributes -Werror" $(MAKE) allzstd
ppc64build: clean
- CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) allarch
+ CC=powerpc-linux-gnu-gcc CFLAGS="-m64 -Werror" $(MAKE) allzstd
armfuzz: clean
CC=arm-linux-gnueabi-gcc QEMU_SYS=qemu-arm-static MOREFLAGS="-static" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) fuzztest
diff --git a/appveyor.yml b/appveyor.yml
index 1815563e7..91f117952 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,19 +9,19 @@
- COMPILER: "gcc"
HOST: "mingw"
PLATFORM: "x64"
- SCRIPT: "make allarch && make -C tests test-symbols fullbench-dll fullbench-lib"
+ SCRIPT: "make allzstd && make -C tests test-symbols fullbench-dll fullbench-lib"
ARTIFACT: "true"
BUILD: "true"
- COMPILER: "gcc"
HOST: "mingw"
PLATFORM: "x86"
- SCRIPT: "make allarch"
+ SCRIPT: "make allzstd"
ARTIFACT: "true"
BUILD: "true"
- COMPILER: "clang"
HOST: "mingw"
PLATFORM: "x64"
- SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make allarch"
+ SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make allzstd"
BUILD: "true"
- COMPILER: "gcc"
@@ -172,15 +172,15 @@
- COMPILER: "gcc"
HOST: "mingw"
PLATFORM: "x64"
- SCRIPT: "make allarch"
+ SCRIPT: "make allzstd"
- COMPILER: "gcc"
HOST: "mingw"
PLATFORM: "x86"
- SCRIPT: "make allarch"
+ SCRIPT: "make allzstd"
- COMPILER: "clang"
HOST: "mingw"
PLATFORM: "x64"
- SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make allarch"
+ SCRIPT: "MOREFLAGS='--target=x86_64-w64-mingw32 -Werror -Wconversion -Wno-sign-conversion' make allzstd"
- COMPILER: "visual"
HOST: "visual"
diff --git a/programs/Makefile b/programs/Makefile
index 62b558eeb..5a7c373bf 100644
--- a/programs/Makefile
+++ b/programs/Makefile
@@ -67,7 +67,6 @@ else
endif
ZSTDLIB_FILES := $(sort $(wildcard $(ZSTD_FILES)) $(wildcard $(ZSTDLEGACY_FILES)) $(wildcard $(ZDICT_FILES)))
-ZSTDLIB_OBJ := $(patsubst %.c,%.o,$(ZSTDLIB_FILES))
# Define *.exe as extension for Windows systems
ifneq (,$(filter Windows%,$(OS)))
From 179b161dc13bd7a1a28c9aac5824c3b65f448f0e Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 15:02:14 -0700
Subject: [PATCH 080/248] fixed poolTest
needs more dependencies from zstd for custom allocators and error codes
---
tests/.gitignore | 1 +
tests/Makefile | 23 ++++++++++-------------
2 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/tests/.gitignore b/tests/.gitignore
index f408a7491..24290195e 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -48,6 +48,7 @@ grillResults.txt
_*
tmp*
*.zst
+*.gz
result
out
diff --git a/tests/Makefile b/tests/Makefile
index 4bffe9137..f6f3f7534 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -44,10 +44,6 @@ ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
ZBUFF_FILES := $(ZSTDDIR)/deprecated/*.c
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
-ZSTD_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZSTD_FILES)) )
-ZBUFF_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZBUFF_FILES)) )
-ZDICT_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZDICT_FILES)) )
-
# Define *.exe as extension for Windows systems
ifneq (,$(filter Windows%,$(OS)))
@@ -75,7 +71,7 @@ all: fullbench fuzzer zstreamtest paramgrill datagen decodecorpus
all32: fullbench32 fuzzer32 zstreamtest32
-allnothread: fullbench fuzzer paramgrill datagen decodecorpus
+allnothread: fullbench fuzzer paramgrill datagen decodecorpus
dll: fuzzer-dll zstreamtest-dll
@@ -89,7 +85,7 @@ zstd-nolegacy:
$(MAKE) -C $(PRGDIR) $@
gzstd:
- $(MAKE) -C $(PRGDIR) $@
+ $(MAKE) -C $(PRGDIR) zstd HAVE_ZLIB=1
fullbench32: CPPFLAGS += -m32
fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP)
@@ -190,8 +186,8 @@ else
$(CC) $(FLAGS) $^ -o $@$(EXT) -Wl,-rpath=$(ZSTDDIR) $(ZSTDDIR)/libzstd.so
endif
-poolTests : poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c
- $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT)
+poolTests : poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/error_private.c
+ $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT)
namespaceTest:
if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi
@@ -282,13 +278,13 @@ test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd-nolegacy
test-zstd-nolegacy: zstd-nolegacy zstd-playTests
test-gzstd: gzstd
- $(PRGDIR)/zstd README.md test-zstd-speed.py
- gzip README.md test-zstd-speed.py
+ $(PRGDIR)/zstd -f README.md test-zstd-speed.py
+ gzip -f README.md test-zstd-speed.py
cat README.md.zst test-zstd-speed.py.gz >zstd_gz.zst
cat README.md.gz test-zstd-speed.py.zst >gz_zstd.gz
- $(PRGDIR)/zstd -d README.md.gz -o README2.md
- $(PRGDIR)/zstd -d README.md.gz test-zstd-speed.py.gz
- $(PRGDIR)/zstd -d zstd_gz.zst gz_zstd.gz
+ $(PRGDIR)/zstd -df README.md.gz -o README2.md
+ $(PRGDIR)/zstd -df README.md.gz test-zstd-speed.py.gz
+ $(PRGDIR)/zstd -df zstd_gz.zst gz_zstd.gz
$(DIFF) -q zstd_gz gz_zstd
echo Hello World ZSTD | $(PRGDIR)/zstd -c - >hello.zst
echo Hello World GZIP | gzip -c - >hello.gz
@@ -296,6 +292,7 @@ test-gzstd: gzstd
cat hello.zst hello.gz hello.txt >hello_zst_gz_txt.gz
$(PRGDIR)/zstd -dcf hello.*
$(PRGDIR)/zstd -dcf -
Date: Thu, 31 Aug 2017 15:02:14 -0700
Subject: [PATCH 081/248] fixed poolTests
needs more dependencies from zstd for custom allocators and error codes
---
tests/.gitignore | 2 ++
tests/Makefile | 23 ++++++++++-------------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/tests/.gitignore b/tests/.gitignore
index f408a7491..b16e26e3d 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -21,6 +21,7 @@ symbols
legacy
decodecorpus
pool
+poolTests
invalidDictionaries
# Tmp test directory
@@ -48,6 +49,7 @@ grillResults.txt
_*
tmp*
*.zst
+*.gz
result
out
diff --git a/tests/Makefile b/tests/Makefile
index 4bffe9137..f6f3f7534 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -44,10 +44,6 @@ ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES)
ZBUFF_FILES := $(ZSTDDIR)/deprecated/*.c
ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
-ZSTD_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZSTD_FILES)) )
-ZBUFF_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZBUFF_FILES)) )
-ZDICT_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZDICT_FILES)) )
-
# Define *.exe as extension for Windows systems
ifneq (,$(filter Windows%,$(OS)))
@@ -75,7 +71,7 @@ all: fullbench fuzzer zstreamtest paramgrill datagen decodecorpus
all32: fullbench32 fuzzer32 zstreamtest32
-allnothread: fullbench fuzzer paramgrill datagen decodecorpus
+allnothread: fullbench fuzzer paramgrill datagen decodecorpus
dll: fuzzer-dll zstreamtest-dll
@@ -89,7 +85,7 @@ zstd-nolegacy:
$(MAKE) -C $(PRGDIR) $@
gzstd:
- $(MAKE) -C $(PRGDIR) $@
+ $(MAKE) -C $(PRGDIR) zstd HAVE_ZLIB=1
fullbench32: CPPFLAGS += -m32
fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP)
@@ -190,8 +186,8 @@ else
$(CC) $(FLAGS) $^ -o $@$(EXT) -Wl,-rpath=$(ZSTDDIR) $(ZSTDDIR)/libzstd.so
endif
-poolTests : poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c
- $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT)
+poolTests : poolTests.c $(ZSTDDIR)/common/pool.c $(ZSTDDIR)/common/threading.c $(ZSTDDIR)/common/zstd_common.c $(ZSTDDIR)/common/error_private.c
+ $(CC) $(FLAGS) $(MULTITHREAD) $^ -o $@$(EXT)
namespaceTest:
if $(CC) namespaceTest.c ../lib/common/xxhash.c -o $@ ; then echo compilation should fail; exit 1 ; fi
@@ -282,13 +278,13 @@ test-zstd-nolegacy: ZSTD = $(PRGDIR)/zstd-nolegacy
test-zstd-nolegacy: zstd-nolegacy zstd-playTests
test-gzstd: gzstd
- $(PRGDIR)/zstd README.md test-zstd-speed.py
- gzip README.md test-zstd-speed.py
+ $(PRGDIR)/zstd -f README.md test-zstd-speed.py
+ gzip -f README.md test-zstd-speed.py
cat README.md.zst test-zstd-speed.py.gz >zstd_gz.zst
cat README.md.gz test-zstd-speed.py.zst >gz_zstd.gz
- $(PRGDIR)/zstd -d README.md.gz -o README2.md
- $(PRGDIR)/zstd -d README.md.gz test-zstd-speed.py.gz
- $(PRGDIR)/zstd -d zstd_gz.zst gz_zstd.gz
+ $(PRGDIR)/zstd -df README.md.gz -o README2.md
+ $(PRGDIR)/zstd -df README.md.gz test-zstd-speed.py.gz
+ $(PRGDIR)/zstd -df zstd_gz.zst gz_zstd.gz
$(DIFF) -q zstd_gz gz_zstd
echo Hello World ZSTD | $(PRGDIR)/zstd -c - >hello.zst
echo Hello World GZIP | gzip -c - >hello.gz
@@ -296,6 +292,7 @@ test-gzstd: gzstd
cat hello.zst hello.gz hello.txt >hello_zst_gz_txt.gz
$(PRGDIR)/zstd -dcf hello.*
$(PRGDIR)/zstd -dcf -
Date: Thu, 31 Aug 2017 15:24:17 -0700
Subject: [PATCH 082/248] blind attempt at removing gcc dependency
from appveyor's mingw builds, for #815
---
appveyor.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/appveyor.yml b/appveyor.yml
index 1815563e7..99fa834b4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,13 +9,13 @@
- COMPILER: "gcc"
HOST: "mingw"
PLATFORM: "x64"
- SCRIPT: "make allarch && make -C tests test-symbols fullbench-dll fullbench-lib"
+ SCRIPT: "make allarch MOREFLAGS=-static && make -C tests test-symbols fullbench-dll fullbench-lib"
ARTIFACT: "true"
BUILD: "true"
- COMPILER: "gcc"
HOST: "mingw"
PLATFORM: "x86"
- SCRIPT: "make allarch"
+ SCRIPT: "make allarch MOREFLAGS=-static"
ARTIFACT: "true"
BUILD: "true"
- COMPILER: "clang"
From 4299c271323d988c4e76d907f0a6710e2cd959d2 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 16:58:47 -0700
Subject: [PATCH 083/248] improved console log of utils.h
removed a warning when compiling on Windows
---
programs/util.h | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/programs/util.h b/programs/util.h
index d6e1dfc20..384dec1bd 100644
--- a/programs/util.h
+++ b/programs/util.h
@@ -105,13 +105,21 @@ extern "C" {
#endif
+/*-****************************************
+* Console log
+******************************************/
+static int g_utilDisplayLevel;
+#define UTIL_DISPLAY(...) fprintf(stderr, __VA_ARGS__)
+#define UTIL_DISPLAYLEVEL(l, ...) { if (g_utilDisplayLevel>=l) { UTIL_DISPLAY(__VA_ARGS__); } }
+
+
/*-****************************************
* Time functions
******************************************/
#if defined(_WIN32) /* Windows */
typedef LARGE_INTEGER UTIL_freq_t;
typedef LARGE_INTEGER UTIL_time_t;
- UTIL_STATIC void UTIL_initTimer(UTIL_freq_t* ticksPerSecond) { if (!QueryPerformanceFrequency(ticksPerSecond)) fprintf(stderr, "ERROR: QueryPerformance not present\n"); }
+ UTIL_STATIC void UTIL_initTimer(UTIL_freq_t* ticksPerSecond) { if (!QueryPerformanceFrequency(ticksPerSecond)) UTIL_DISPLAYLEVEL(1, "ERROR: QueryPerformance not present\n"); }
UTIL_STATIC void UTIL_getTime(UTIL_time_t* x) { QueryPerformanceCounter(x); }
UTIL_STATIC U64 UTIL_getSpanTimeMicro(UTIL_freq_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000ULL*(clockEnd.QuadPart - clockStart.QuadPart)/ticksPerSecond.QuadPart; }
UTIL_STATIC U64 UTIL_getSpanTimeNano(UTIL_freq_t ticksPerSecond, UTIL_time_t clockStart, UTIL_time_t clockEnd) { return 1000000000ULL*(clockEnd.QuadPart - clockStart.QuadPart)/ticksPerSecond.QuadPart; }
@@ -284,10 +292,6 @@ UTIL_STATIC void *UTIL_realloc(void *ptr, size_t size)
return NULL;
}
-static int g_utilDisplayLevel;
-#define UTIL_DISPLAY(...) fprintf(stderr, __VA_ARGS__)
-#define UTIL_DISPLAYLEVEL(l, ...) { if (g_utilDisplayLevel>=l) { UTIL_DISPLAY(__VA_ARGS__); } }
-
#ifdef _WIN32
# define UTIL_HAS_CREATEFILELIST
@@ -309,7 +313,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_
hFile=FindFirstFileA(path, &cFile);
if (hFile == INVALID_HANDLE_VALUE) {
- fprintf(stderr, "Cannot open directory '%s'\n", dirName);
+ UTIL_DISPLAYLEVEL(1, "Cannot open directory '%s'\n", dirName);
return 0;
}
free(path);
@@ -363,7 +367,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_
int dirLength, fnameLength, pathLength, nbFiles = 0;
if (!(dir = opendir(dirName))) {
- fprintf(stderr, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
+ UTIL_DISPLAYLEVEL(1, "Cannot open directory '%s': %s\n", dirName, strerror(errno));
return 0;
}
@@ -408,7 +412,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_
}
if (errno != 0) {
- fprintf(stderr, "readdir(%s) error: %s\n", dirName, strerror(errno));
+ UTIL_DISPLAYLEVEL(1, "readdir(%s) error: %s\n", dirName, strerror(errno));
free(*bufStart);
*bufStart = NULL;
}
@@ -421,7 +425,7 @@ UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_
UTIL_STATIC int UTIL_prepareFileList(const char *dirName, char** bufStart, size_t* pos, char** bufEnd, int followLinks)
{
(void)bufStart; (void)bufEnd; (void)pos;
- fprintf(stderr, "Directory %s ignored (compiled without _WIN32 or _POSIX_C_SOURCE)\n", dirName);
+ UTIL_DISPLAYLEVEL(1, "Directory %s ignored (compiled without _WIN32 or _POSIX_C_SOURCE)\n", dirName);
return 0;
}
From 369c29dd1a953d91e581cf559cf8bd5b002b525f Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 18:25:56 -0700
Subject: [PATCH 084/248] fixed impact of merge conflict for longRange
---
lib/compress/zstdmt_compress.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 93d4a3cec..20122f359 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -447,8 +447,6 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
ZSTDMT_initializeCCtxParameters(&mtctx->params, nbThreads);
mtctx->cMem = cMem;
mtctx->allJobsCompleted = 1;
- mtctx->sectionSize = 0;
- mtctx->overlapLog = ZSTDMT_OVERLAPLOG_DEFAULT;
mtctx->factory = POOL_create_advanced(nbThreads, 0, cMem);
mtctx->jobs = ZSTDMT_allocJobsTable(&nbJobs, cMem);
mtctx->jobIDMask = nbJobs - 1;
@@ -528,7 +526,7 @@ size_t ZSTDMT_CCtxParam_setMTCtxParameter(
params->jobSize = value;
return 0;
case ZSTDMT_p_overlapSectionLog :
- DEBUGLOG(5, "ZSTDMT_p_overlapSectionLog : %u", value);
+ DEBUGLOG(4, "ZSTDMT_p_overlapSectionLog : %u", value);
params->overlapSizeLog = (value >= 9) ? 9 : value;
return 0;
default :
From 0c314cde4b9e0776cfdc690422e99945895c9bec Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Thu, 31 Aug 2017 18:28:19 -0700
Subject: [PATCH 085/248] updated zstd API manual
for new CCtxParams object
---
doc/zstd_manual.html | 133 ++++++++++++++++++++++++++++++-------------
1 file changed, 95 insertions(+), 38 deletions(-)
diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
index c166e7258..83b75fd86 100644
--- a/doc/zstd_manual.html
+++ b/doc/zstd_manual.html
@@ -27,7 +27,8 @@
Buffer-less and synchronous inner streaming functions
Buffer-less streaming compression (synchronous mode)
Buffer-less streaming decompression (synchronous mode)
-Block functions
+ZSTD_CCtx_params
+Block functions
Introduction
@@ -402,25 +403,29 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
size_t ZSTD_estimateCCtxSize(int compressionLevel);
-size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
+size_t ZSTD_estimateCCtxSize_advanced_usingCParams(ZSTD_compressionParameters cParams);
+size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params);
size_t ZSTD_estimateDCtxSize(void);
These functions make it possible to estimate memory usage
of a future {D,C}Ctx, before its creation.
ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one.
It will also consider src size to be arbitrarily "large", which is worst case.
- If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation.
- ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced_usingCParams() can provide a tighter estimation.
+ ZSTD_estimateCCtxSize_advanced_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ ZSTD_estimateCCtxSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbThreads is > 1.
Note : CCtx estimation is only correct for single-threaded compression
size_t ZSTD_estimateCStreamSize(int compressionLevel);
-size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
+size_t ZSTD_estimateCStreamSize_advanced_usingCParams(ZSTD_compressionParameters cParams);
+size_t ZSTD_estimateCStreamSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params);
size_t ZSTD_estimateDStreamSize(size_t windowSize);
size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one.
It will also consider src size to be arbitrarily "large", which is worst case.
- If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
- ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced_usingCParams() can provide a tighter estimation.
+ ZSTD_estimateCStreamSize_advanced_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
+ ZSTD_estimateCStreamSize_advanced_usingCCtxParams() can be used in tandem with ZSTD_CCtxParam_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_p_nbThreads is set to a value > 1.
Note : CStream estimation is only correct for single-threaded compression.
ZSTD_DStream memory budget depends on window Size.
This information can be passed manually, using ZSTD_estimateDStreamSize,
@@ -430,12 +435,18 @@ size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
In this case, get total size by adding ZSTD_estimate?DictSize
+typedef enum {
+ ZSTD_dlm_byCopy = 0, /* Copy dictionary content internally. */
+ ZSTD_dlm_byRef, /* Reference dictionary content -- the dictionary buffer must outlives its users. */
+} ZSTD_dictLoadMethod_e;
+
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
-size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
-size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
+size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);
+size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);
ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
- ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
- Note : dictionary created "byReference" are smaller
+ ZSTD_estimateCStreamSize_advanced_usingCParams() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
+ Note : dictionary created by reference using ZSTD_dlm_byRef are smaller
+
Advanced compression functions
@@ -461,16 +472,6 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
-typedef enum {
- ZSTD_p_forceWindow, /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
- ZSTD_p_forceRawDict /* Force loading dictionary in "content-only" mode (no header analysis) */
-} ZSTD_CCtxParameter;
-
-size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value);
- Set advanced parameters, selected through enum ZSTD_CCtxParameter
- @result : 0, or an error code (which can be tested with ZSTD_isError())
-
-
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
Create a digested dictionary for compression
Dictionary content is simply referenced, and therefore stays in dictBuffer.
@@ -483,7 +484,8 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
} ZSTD_dictMode_e;
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams,
ZSTD_customMem customMem);
Create a ZSTD_CDict using external alloc and free, and customized compression parameters
@@ -492,7 +494,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
ZSTD_CDict* ZSTD_initStaticCDict(
void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_dictMode_e dictMode,
+ ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode,
ZSTD_compressionParameters cParams);
Generate a digested dictionary in provided memory area.
workspace: The memory area to emplace the dictionary into.
@@ -580,13 +582,14 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
- unsigned byReference, ZSTD_customMem customMem);
+ ZSTD_dictLoadMethod_e dictLoadMethod,
+ ZSTD_customMem customMem);
Create a ZSTD_DDict using external alloc and free, optionally by reference
ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
const void* dict, size_t dictSize,
- unsigned byReference);
+ ZSTD_dictLoadMethod_e dictLoadMethod);
Generate a digested dictionary in provided memory area.
workspace: The memory area to emplace the dictionary into.
Provided pointer must 8-bytes aligned.
@@ -628,9 +631,9 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
Advanced Streaming compression functions
ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize);
/**< same as ZSTD_initStaticCCtx() */
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */
-size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. */
+size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. Note: dict is loaded with ZSTD_dm_auto (treated as a full zstd dictionary if it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.*/
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
- ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
+ ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0. dict is loaded with ZSTD_dm_auto and ZSTD_dlm_byCopy. */
size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */
size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
@@ -819,12 +822,6 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
ZSTD_p_checksumFlag, /* A 32-bits checksum of content is written at end of frame (default:0) */
ZSTD_p_dictIDFlag, /* When applicable, dictID of dictionary is provided in frame header (default:1) */
- /* dictionary parameters (must be set before ZSTD_CCtx_loadDictionary) */
- ZSTD_p_dictMode=300, /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e.
- * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
- ZSTD_p_refDictContent, /* Dictionary content will be referenced, instead of copied (default:0==byCopy).
- * It requires that dictionary buffer outlives its users */
-
/* multi-threading parameters */
ZSTD_p_nbThreads=400, /* Select how many threads a compression job can spawn (default:1)
* More threads improve speed, but also increase memory usage.
@@ -861,18 +858,25 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
+size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode);
Create an internal CDict from dict buffer.
Decompression will have to use same buffer.
@result : 0, or an error code (which can be tested with ZSTD_isError()).
Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
meaning "return to no-dictionary mode".
- Note 1 : `dict` content will be copied internally,
- except if ZSTD_p_refDictContent is set before loading.
+ Note 1 : `dict` content will be copied internally. Use
+ ZSTD_CCtx_loadDictionary_byReference() to reference dictionary
+ content instead. The dictionary buffer must then outlive its
+ users.
Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
For this reason, compression parameters cannot be changed anymore after loading a dictionary.
It's also a CPU-heavy operation, with non-negligible impact on latency.
Note 3 : Dictionary will be used for all future compression jobs.
- To return to "no-dictionary" situation, load a NULL dictionary
+ To return to "no-dictionary" situation, load a NULL dictionary
+ Note 5 : Use ZSTD_CCtx_loadDictionary_advanced() to select how dictionary
+ content will be interpreted.
+
size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
@@ -889,6 +893,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);
+size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictMode_e dictMode);
Reference a prefix (single-usage dictionary) for next compression job.
Decompression need same prefix to properly regenerate data.
Prefix is **only used once**. Tables are discarded at end of compression job.
@@ -899,7 +904,9 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
Note 1 : Prefix buffer is referenced. It must outlive compression job.
Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
It's a CPU-heavy operation, with non-negligible impact on latency.
- Note 3 : it's possible to alter ZSTD_p_dictMode using ZSTD_CCtx_setParameter()
+ Note 3 : By default, the prefix is treated as raw content
+ (ZSTD_dm_rawContent). Use ZSTD_CCtx_refPrefix_advanced() to alter
+ dictMode.
typedef enum {
@@ -949,7 +956,57 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
-Block functions
+ZSTD_CCtx_params
+ - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
+ - ZSTD_CCtxParam_setParameter() : Push parameters one by one into an
+ existing ZSTD_CCtx_params structure. This is similar to
+ ZSTD_CCtx_setParameter().
+ - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to an existing CCtx. These
+ parameters will be applied to all subsequent compression jobs.
+ - ZSTD_compress_generic() : Do compression using the CCtx.
+ - ZSTD_freeCCtxParams() : Free the memory.
+
+ This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation
+ for single-threaded compression.
+
+
+
+size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
+ Reset params to default, with the default compression level.
+
+
+
+size_t ZSTD_initCCtxParams(ZSTD_CCtx_params* cctxParams, int compressionLevel);
+ Initializes the compression parameters of cctxParams according to
+ compression level. All other parameters are reset to their default values.
+
+
+
+size_t ZSTD_initCCtxParams_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
+ Initializes the compression and frame parameters of cctxParams according to
+ params. All other parameters are reset to their default values.
+
+
+
+size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
+ Similar to ZSTD_CCtx_setParameter.
+ Set one compression parameter, selected by enum ZSTD_cParameter.
+ Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams().
+ Note : when `value` is an enum, cast it to unsigned for proper type checking.
+ @result : 0, or an error code (which can be tested with ZSTD_isError()).
+
+
+
+size_t ZSTD_CCtx_setParametersUsingCCtxParams(
+ ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
+ Apply a set of ZSTD_CCtx_params to the compression context.
+ This must be done before the dictionary is loaded.
+ The pledgedSrcSize is treated as unknown.
+ Multithreading parameters are applied only if nbThreads > 1.
+
+
+
+Block functions
Block functions produce and decode raw zstd blocks, without frame metadata.
Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
User will have to take in charge required information to regenerate data, such as compressed and content sizes.
From 370450777403067fe756d4f3b5a80f11bc4ddebf Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Fri, 1 Sep 2017 00:05:37 -0700
Subject: [PATCH 086/248] fixed decompression bug reported by @Etsukata (#828)
---
lib/decompress/zstd_decompress.c | 34 ++++++++++++++------------------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
index 8e82d85a2..436f817a7 100644
--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1088,7 +1088,10 @@ static size_t ZSTD_decompressSequences(
}
-FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int const longOffsets)
+typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
+
+HINT_INLINE
+seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
{
seq_t seq;
@@ -1180,19 +1183,12 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
return seq;
}
-static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const windowSize) {
- if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
- return ZSTD_decodeSequenceLong_generic(seqState, 1);
- } else {
- return ZSTD_decodeSequenceLong_generic(seqState, 0);
- }
-}
HINT_INLINE
size_t ZSTD_execSequenceLong(BYTE* op,
- BYTE* const oend, seq_t sequence,
- const BYTE** litPtr, const BYTE* const litLimit,
- const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
+ BYTE* const oend, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
{
BYTE* const oLitEnd = op + sequence.litLength;
size_t const sequenceLength = sequence.litLength + sequence.matchLength;
@@ -1202,11 +1198,9 @@ size_t ZSTD_execSequenceLong(BYTE* op,
const BYTE* match = sequence.match;
/* check */
-#if 1
if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
-#endif
/* copy Literals */
ZSTD_copy8(op, *litPtr);
@@ -1216,7 +1210,6 @@ size_t ZSTD_execSequenceLong(BYTE* op,
*litPtr = iLitEnd; /* update for next sequence */
/* copy Match */
-#if 1
if (sequence.offset > (size_t)(oLitEnd - base)) {
/* offset beyond prefix */
if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
@@ -1236,8 +1229,8 @@ size_t ZSTD_execSequenceLong(BYTE* op,
return sequenceLength;
}
} }
- /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
-#endif
+ assert(op <= oend_w);
+ assert(sequence.matchLength >= MINMATCH);
/* match within prefix */
if (sequence.offset < 8) {
@@ -1285,9 +1278,12 @@ static size_t ZSTD_decompressSequencesLong(
const BYTE* const base = (const BYTE*) (dctx->base);
const BYTE* const vBase = (const BYTE*) (dctx->vBase);
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
- unsigned const windowSize32 = (unsigned)dctx->fParams.windowSize;
int nbSeq;
+ unsigned long long const regularWindowSizeMax = 1ULL << STREAM_ACCUMULATOR_MIN;
+ ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(dctx->fParams.windowSize >= regularWindowSizeMax);
+ ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
+
/* Build Decoding Tables */
{ size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
if (ZSTD_isError(seqHSize)) return seqHSize;
@@ -1315,13 +1311,13 @@ static size_t ZSTD_decompressSequencesLong(
/* prepare in advance */
for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb
Date: Fri, 1 Sep 2017 00:12:07 -0700
Subject: [PATCH 087/248] fixed minor warning (empty translation unit)
---
lib/common/threading.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/lib/common/threading.c b/lib/common/threading.c
index 4e47b6b91..a82c975b2 100644
--- a/lib/common/threading.c
+++ b/lib/common/threading.c
@@ -14,12 +14,8 @@
* This file will hold wrapper for systems, which do not support pthreads
*/
-/* When ZSTD_MULTITHREAD is not defined, this file would become an empty translation unit.
- * Include some ISO C header code to prevent this and portably avoid related warnings.
- * (Visual C++: C4206 / GCC: -Wpedantic / Clang: -Wempty-translation-unit)
- */
-#include
-
+/* create fake symbol to avoid empty trnaslation unit warning */
+int g_ZSTD_threading_useles_symbol;
#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
From 663939597932d2a28727107805a3ab24e0a48196 Mon Sep 17 00:00:00 2001
From: Eiichi Tsukata
Date: Fri, 1 Sep 2017 16:31:58 +0900
Subject: [PATCH 088/248] tests/fuzz: fix make all target names
---
tests/fuzz/Makefile | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/fuzz/Makefile b/tests/fuzz/Makefile
index c6327068f..dfb8f1913 100644
--- a/tests/fuzz/Makefile
+++ b/tests/fuzz/Makefile
@@ -48,7 +48,11 @@ LIBFUZZER ?= -lFuzzer
default: all
-all: round_trip simple_decompress
+all: \
+ simple_round_trip \
+ stream_round_trip \
+ simple_decompress \
+ stream_decompress
%.o: %.c
$(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $^ -c -o $@
From 7492e7f1c7b5f8420e268857f374a3d2250de641 Mon Sep 17 00:00:00 2001
From: Eiichi Tsukata
Date: Fri, 1 Sep 2017 16:35:43 +0900
Subject: [PATCH 089/248] tests/fuzz: change ZSTD_BLOCKSIZE_ABSOLUTEMAX into
ZSTD_BLOCKSIZE_MAX
ZSTD_BLOCKSIZE_ABSOLUTEMAX is changed at the commit:
https://github.com/facebook/zstd/commit/fa3671eac7097ce4ae9a1a4c53d2d1486c29d48f
---
tests/fuzz/stream_decompress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/fuzz/stream_decompress.c b/tests/fuzz/stream_decompress.c
index ae853dc8c..dfd746972 100644
--- a/tests/fuzz/stream_decompress.c
+++ b/tests/fuzz/stream_decompress.c
@@ -20,7 +20,7 @@
#include "fuzz_helpers.h"
#include "zstd.h"
-static size_t const kBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX;
+static size_t const kBufSize = ZSTD_BLOCKSIZE_MAX;
static ZSTD_DStream *dstream = NULL;
static void* buf = NULL;
From 8081becadce1d706b2eb17ebdc278651d4dcf709 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Thu, 31 Aug 2017 15:40:16 -0700
Subject: [PATCH 090/248] Add long distance matching as a CCtxParam
---
lib/common/zstd_internal.h | 7 ++--
lib/compress/zstd_compress.c | 73 ++++++++++++++++++++--------------
lib/compress/zstdmt_compress.c | 2 +
lib/zstd.h | 8 ++--
programs/bench.c | 2 +-
programs/fileio.c | 7 ++--
tests/fuzzer.c | 5 ++-
tests/zstreamtest.c | 2 +-
8 files changed, 64 insertions(+), 42 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index 49b21c2db..4488ac354 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -281,11 +281,10 @@ typedef struct {
typedef struct {
ldmEntry_t* hashTable;
- BYTE* bucketOffsets;
- U32 ldmEnable; /* 1 if enable long distance matching */
+ BYTE* bucketOffsets; /* next position in bucket to insert entry */
U32 hashLog; /* log size of hashTable */
U32 bucketLog; /* log number of buckets, at most 4 */
- U32 hashEveryLog;
+ U32 hashEveryLog; /* log number of entries to skip */
} ldmState_t;
typedef struct {
@@ -313,6 +312,8 @@ struct ZSTD_CCtx_params_s {
unsigned jobSize;
unsigned overlapSizeLog;
+ U32 enableLdm; /* 1 if enable long distance matching */
+
/* For use with createCCtxParams() and freeCCtxParams() only */
ZSTD_customMem customMem;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 331b21207..42d23759b 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -53,6 +53,7 @@ size_t ZSTD_compressBound(size_t srcSize) {
return srcSize + (srcSize >> 8) + margin;
}
+
/*-*************************************
* Sequence storage
***************************************/
@@ -362,14 +363,11 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
case ZSTD_p_longDistanceMatching:
- /* TODO */
if (cctx->cdict) return ERROR(stage_wrong);
- cctx->ldmState.ldmEnable = value>0;
if (value != 0) {
ZSTD_cLevelToCParams(cctx);
- cctx->requestedParams.cParams.windowLog = LDM_WINDOW_LOG;
}
- return 0;
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
default: return ERROR(parameter_unsupported);
}
@@ -471,8 +469,12 @@ size_t ZSTD_CCtxParam_setParameter(
return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_overlapSectionLog, value);
case ZSTD_p_longDistanceMatching :
- /* TODO */
- return ERROR(parameter_unsupported);
+ params->enableLdm = value>0;
+ if (value != 0) {
+ ZSTD_cLevelToCCtxParams(params);
+ params->cParams.windowLog = LDM_WINDOW_LOG;
+ }
+ return 0;
default: return ERROR(parameter_unsupported);
}
@@ -509,6 +511,9 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
}
+ /* Copy long distance matching parameter */
+ cctx->requestedParams.enableLdm = params->enableLdm;
+
/* customMem is used only for create/free params and can be ignored */
return 0;
}
@@ -675,6 +680,16 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
}
+/* Estimate the space needed for long distance matching tables. */
+static size_t ZSTD_ldm_getTableSize(U32 ldmHashLog, U32 bucketLog) {
+ size_t const ldmHSize = ((size_t)1) << ldmHashLog;
+ size_t const ldmBucketLog =
+ MIN(bucketLog, LDM_BUCKET_SIZE_LOG_MAX);
+ size_t const ldmBucketSize =
+ ((size_t)1) << (ldmHashLog - ldmBucketLog);
+ return ldmBucketSize + (ldmHSize * (sizeof(ldmEntry_t)));
+}
+
size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* params)
{
/* Estimate CCtx size is supported for single-threaded compression only. */
@@ -699,8 +714,10 @@ size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* pa
+ (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
size_t const optSpace = ((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btultra)) ? optBudget : 0;
- /* TODO: Long distance matching is not suported */
- size_t const ldmSpace = 0;
+ /* Ldm parameters can not currently be changed */
+ size_t const ldmSpace = params->enableLdm ?
+ ZSTD_ldm_getTableSize(LDM_HASH_LOG, LDM_BUCKET_SIZE_LOG) : 0;
+
size_t const neededSpace = entropySpace + tableSpace + tokenSpace +
optSpace + ldmSpace;
@@ -762,7 +779,8 @@ static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
ZSTD_CCtx_params params2)
{
- return ZSTD_equivalentCParams(params1.cParams, params2.cParams);
+ return ZSTD_equivalentCParams(params1.cParams, params2.cParams) &&
+ params1.enableLdm == params2.enableLdm;
}
/*! ZSTD_continueCCtx() :
@@ -803,9 +821,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
if (crp == ZSTDcrp_continue) {
- /* TODO: For now, reset if long distance matching is enabled */
- if (ZSTD_equivalentParams(params, zc->appliedParams) &&
- !zc->ldmState.ldmEnable) {
+ if (ZSTD_equivalentParams(params, zc->appliedParams)) {
DEBUGLOG(5, "ZSTD_equivalentParams()==1");
zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
zc->entropy->offcode_repeatMode = FSE_repeat_none;
@@ -838,13 +854,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? ((size_t)1 << params.cParams.windowLog) + blockSize : 0;
void* ptr;
- size_t const ldmHSize = ((size_t)1) << zc->ldmState.hashLog;
- size_t const ldmBucketSize =
- ((size_t)1) << (zc->ldmState.hashLog - zc->ldmState.bucketLog);
- size_t const ldmPotentialSpace =
- ldmBucketSize + (ldmHSize * (sizeof(ldmEntry_t)));
- size_t const ldmSpace = zc->ldmState.ldmEnable ?
- ldmPotentialSpace : 0;
+ size_t const ldmSpace = params.enableLdm ? ZSTD_ldm_getTableSize(zc->ldmState.hashLog, zc->ldmState.bucketLog) : 0;
/* Check if workSpace is large enough, alloc a new one if needed */
{ size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
@@ -923,8 +933,11 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
}
/* ldm space */
- if (zc->ldmState.ldmEnable) {
- if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, ldmSpace);
+ if (params.enableLdm) {
+ size_t const ldmHSize = ((size_t)1) << zc->ldmState.hashLog;
+ size_t const ldmBucketSize =
+ ((size_t)1) << (zc->ldmState.hashLog - zc->ldmState.bucketLog);
+ memset(ptr, 0, ldmSpace);
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
ptr = zc->ldmState.hashTable + ldmHSize;
@@ -1047,7 +1060,7 @@ static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reduce
/*! ZSTD_ldm_reduceTable() :
* reduce table indexes by `reducerValue` */
static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size,
- U32 const reducerValue)
+ U32 const reducerValue)
{
U32 u;
for (u = 0; u < size; u++) {
@@ -1069,8 +1082,8 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
{ U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
- { if (zc->ldmState.ldmEnable) {
- U32 const ldmHSize = 1 << LDM_HASH_LOG;
+ { if (zc->appliedParams.enableLdm) {
+ U32 const ldmHSize = 1 << zc->ldmState.hashLog;
ZSTD_ldm_reduceTable(zc->ldmState.hashTable, ldmHSize, reducerValue);
}
}
@@ -1683,6 +1696,7 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
}
}
+
/*-*************************************
* Fast Scan
***************************************/
@@ -1751,6 +1765,7 @@ size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
offset_2 = offset_1;
offset_1 = offset;
+
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
}
@@ -1983,7 +1998,6 @@ size_t ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
ip++;
ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
} else {
-
U32 offset;
if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
@@ -3405,7 +3419,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
/* Check immediate repcode */
while ( (ip < ilimit)
- && ( (repToConfirm[1] > 0)
+ && ( (repToConfirm[1] > 0) && (repToConfirm[1] <= (U32)(ip-lowest))
&& (MEM_read32(ip) == MEM_read32(ip - repToConfirm[1])) )) {
size_t const rLength = ZSTD_count(ip+4, ip+4-repToConfirm[1],
@@ -3413,7 +3427,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
/* Swap repToConfirm[1] <=> repToConfirm[0] */
{
U32 const tmpOff = repToConfirm[1];
- repToConfirm[1] = repToConfirm[0];
+ repToConfirm[1] = repToConfirm[0];
repToConfirm[0] = tmpOff;
}
@@ -3571,6 +3585,8 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
/* Call the block compressor on the remaining literals */
{
+ /* ip = current - backwardMatchLength
+ * The match is at (bestEntry->offset - backwardMatchLength) */
U32 const matchIndex = bestEntry->offset;
U32 const offset = current - matchIndex;
@@ -3687,7 +3703,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
size_t lastLLSize;
const BYTE* anchor;
const ZSTD_blockCompressor blockCompressor =
- zc->ldmState.ldmEnable ?
+ zc->appliedParams.enableLdm?
(zc->lowLimit < zc->dictLimit ? ZSTD_compressBlock_ldm_extDict :
ZSTD_compressBlock_ldm) :
ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
@@ -4870,7 +4886,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbThreads, cctx->customMem);
if (cctx->mtctx == NULL) return ERROR(memory_allocation);
}
-
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", params.nbThreads);
CHECK_F( ZSTDMT_initCStream_internal(
cctx->mtctx,
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index 166f99d72..ae4308b86 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -196,6 +196,8 @@ static ZSTD_CCtx_params ZSTDMT_makeJobCCtxParams(ZSTD_CCtx_params const params)
jobParams.cParams = params.cParams;
jobParams.fParams = params.fParams;
jobParams.compressionLevel = params.compressionLevel;
+
+ jobParams.enableLdm = params.enableLdm;
return jobParams;
}
diff --git a/lib/zstd.h b/lib/zstd.h
index c9fa34f36..fa2bbf062 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -978,9 +978,11 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
- ZSTD_p_longDistanceMatching, /* Enable long distance matching.
- * This increases the memory usage as well as the
- * window size. */
+ ZSTD_p_longDistanceMatching, /* Enable long distance matching. This
+ * increases the memory usage as well as the
+ * window size. Note: this should be set after
+ * ZSTD_p_compressionLevel and before
+ * ZSTD_p_windowLog. */
} ZSTD_cParameter;
diff --git a/programs/bench.c b/programs/bench.c
index a2c4efcf3..5901205d9 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -269,12 +269,12 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
#ifdef ZSTD_NEWAPI
ZSTD_CCtx_setParameter(ctx, ZSTD_p_nbThreads, g_nbThreads);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionLevel, cLevel);
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_longDistanceMatching, g_ldmFlag);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_windowLog, comprParams->windowLog);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_chainLog, comprParams->chainLog);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_searchLog, comprParams->searchLog);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_minMatch, comprParams->searchLength);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_targetLength, comprParams->targetLength);
- ZSTD_CCtx_setParameter(ctx, ZSTD_p_longDistanceMatching, g_ldmFlag);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionStrategy, comprParams->strategy);
ZSTD_CCtx_loadDictionary(ctx, dictBuffer, dictBufferSize);
#else
diff --git a/programs/fileio.c b/programs/fileio.c
index 8d024a9b3..1d8fb22bf 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -402,8 +402,11 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_dictIDFlag, g_dictIDFlag) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_checksumFlag, g_checksumFlag) );
CHECK( ZSTD_CCtx_setPledgedSrcSize(ress.cctx, srcSize) );
- /* compression parameters */
+ /* compression level */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionLevel, cLevel) );
+ /* long distance matching */
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_longDistanceMatching, g_ldmFlag) );
+ /* compression parameters */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_windowLog, comprParams->windowLog) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_chainLog, comprParams->chainLog) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_hashLog, comprParams->hashLog) );
@@ -411,8 +414,6 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_minMatch, comprParams->searchLength) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_targetLength, comprParams->targetLength) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionStrategy, (U32)comprParams->strategy) );
- /* long distance matching */
- CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_longDistanceMatching, g_ldmFlag) );
/* multi-threading */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_nbThreads, g_nbThreads) );
/* dictionary */
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index ca67483dd..1d11af2e5 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -440,6 +440,8 @@ static int basicUnitTests(U32 seed, double compressibility)
free(staticDCtxBuffer);
}
+
+
/* ZSTDMT simple MT compression test */
DISPLAYLEVEL(4, "test%3i : create ZSTDMT CCtx : ", testNb++);
{ ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2);
@@ -1340,7 +1342,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
dictSize = FUZ_rLogLength(&lseed, dictLog); /* needed also for decompression */
dict = srcBuffer + (FUZ_rand(&lseed) % (srcBufferSize - dictSize));
-
+ CHECK_Z ( ZSTD_CCtx_setParameter(refCtx, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed)&255) );
if (FUZ_rand(&lseed) & 0xF) {
CHECK_Z ( ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel) );
} else {
@@ -1349,7 +1351,6 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
!(FUZ_rand(&lseed)&3) /* contentChecksumFlag*/,
0 /*NodictID*/ }; /* note : since dictionary is fake, dictIDflag has no impact */
ZSTD_parameters const p = FUZ_makeParams(cPar, fPar);
-
CHECK_Z ( ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0) );
}
CHECK_Z( ZSTD_copyCCtx(ctx, refCtx, 0) );
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 3baa10ef0..ba86fbcbb 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1380,7 +1380,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_minMatch, cParams.searchLength, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed) & 63) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed) & 63, useOpaqueAPI) );
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
From 36aa8b59993e18a8759a11c3302530a715444986 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Fri, 1 Sep 2017 11:40:59 -0700
Subject: [PATCH 091/248] improved decoding speed
---
lib/decompress/zstd_decompress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
index 436f817a7..bc8f93851 100644
--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1281,7 +1281,7 @@ static size_t ZSTD_decompressSequencesLong(
int nbSeq;
unsigned long long const regularWindowSizeMax = 1ULL << STREAM_ACCUMULATOR_MIN;
- ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(dctx->fParams.windowSize >= regularWindowSizeMax);
+ ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (dctx->fParams.windowSize >= regularWindowSizeMax));
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
/* Build Decoding Tables */
From 0558850735e850e4553366b5be683e130940aba1 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Fri, 1 Sep 2017 11:46:15 -0700
Subject: [PATCH 092/248] bench stops immediately on decoding error
---
programs/bench.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/programs/bench.c b/programs/bench.c
index a4321246f..d5c04c698 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -373,10 +373,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
blockTable[blockNb].cPtr, blockTable[blockNb].cSize,
ddict);
if (ZSTD_isError(regenSize)) {
- DISPLAY("ZSTD_decompress_usingDDict() failed on block %u of size %u : %s \n",
+ EXM_THROW(2, "ZSTD_decompress_usingDDict() failed on block %u of size %u : %s \n",
blockNb, (U32)blockTable[blockNb].cSize, ZSTD_getErrorName(regenSize));
- clockLoop = 0; /* force immediate test end */
- break;
}
blockTable[blockNb].resSize = regenSize;
}
From 8a5c0c98ae5a7884694589d7a69bc99011add94d Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Fri, 1 Sep 2017 11:56:57 -0700
Subject: [PATCH 093/248] restored 32-bits decoder ability to decode long
offsets (>32 MB, levels 21+)
---
lib/decompress/zstd_decompress.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
index bc8f93851..ada773b9a 100644
--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1365,12 +1365,8 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
ip += litCSize;
srcSize -= litCSize;
}
- if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
- /* likely because of register pressure */
- /* if that's the correct cause, then 32-bits ARM should be affected differently */
- /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
- if (dctx->fParams.windowSize > (1<<23))
- return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
+ if (dctx->fParams.windowSize > (1<<23))
+ return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
}
From ed7ace38e92392eb80c699fbcb457c1ff6576ce1 Mon Sep 17 00:00:00 2001
From: Yann Collet
Date: Fri, 1 Sep 2017 11:58:37 -0700
Subject: [PATCH 094/248] updated NEWS
fix for 32-bits decoder
---
NEWS | 1 +
1 file changed, 1 insertion(+)
diff --git a/NEWS b/NEWS
index 3ee7d0c32..c659e1f47 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
v1.3.2
license : changed /examples license to BSD + GPLv2
license : fix a few header files to reflect new license (#825)
+fix : 32-bits build can now decode large offsets (levels 21+)
fix : a rare compression bug when compression generates very large distances (only possible at --ultra -22)
build: better compatibility with reproducible builds, by Bernhard M. Wiedemann (@bmwiedemann) (#818)
From 767a0b3be191475a2f65548679af6734670cc40c Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 1 Sep 2017 12:24:59 -0700
Subject: [PATCH 095/248] Move ldm hashLog, bucketLog, and mml to cctxParams
---
lib/common/zstd_internal.h | 18 +++-
lib/compress/zstd_compress.c | 183 ++++++++++++++++++++++-----------
lib/compress/zstdmt_compress.c | 2 +-
lib/zstd.h | 11 +-
tests/zstreamtest.c | 2 +
5 files changed, 148 insertions(+), 68 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index d7404c064..b3d9a6c6e 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -255,12 +255,19 @@ typedef struct {
typedef struct {
ldmEntry_t* hashTable;
- BYTE* bucketOffsets; /* next position in bucket to insert entry */
- U32 hashLog; /* log size of hashTable */
- U32 bucketLog; /* log number of buckets, at most 4 */
- U32 hashEveryLog; /* log number of entries to skip */
+ BYTE* bucketOffsets; /* Next position in bucket to insert entry */
+ U32 hashEveryLog; /* Log number of entries to skip */
+ U64 hashPower; /* Used to compute the rolling hash.
+ * Depends on ldmParams.minMatchLength */
} ldmState_t;
+typedef struct {
+ U32 enableLdm; /* 1 if enable long distance matching */
+ U32 hashLog; /* Log size of hashTable */
+ U32 bucketLog; /* Log number of buckets, at most 4 */
+ U32 minMatchLength; /* Minimum match length */
+} ldmParams_t;
+
typedef struct {
U32 hufCTable[HUF_CTABLE_SIZE_U32(255)];
FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
@@ -286,7 +293,8 @@ struct ZSTD_CCtx_params_s {
unsigned jobSize;
unsigned overlapSizeLog;
- U32 enableLdm; /* 1 if enable long distance matching */
+ /* Long distance matching parameters */
+ ldmParams_t ldmParams;
/* For use with createCCtxParams() and freeCCtxParams() only */
ZSTD_customMem customMem;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index c02ee6cfb..e74787f37 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -313,6 +313,16 @@ size_t ZSTDMT_CCtxParam_setMTCtxParameter(
ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, unsigned value);
size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThreads);
+static size_t ZSTD_ldm_initializeParameters(ldmParams_t* params, U32 enableLdm)
+{
+ assert(LDM_BUCKET_SIZE_LOG <= LDM_BUCKET_SIZE_LOG_MAX);
+ params->enableLdm = enableLdm>0;
+ params->hashLog = LDM_HASH_LOG;
+ params->bucketLog = LDM_BUCKET_SIZE_LOG;
+ params->minMatchLength = LDM_MIN_MATCH_LENGTH;
+ return 0;
+}
+
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
{
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
@@ -369,6 +379,12 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
}
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+ case ZSTD_p_ldmHashLog:
+ case ZSTD_p_ldmMinMatch:
+ if (value == 0) return 0; /* special value : 0 means "don't change anything" */
+ if (cctx->cdict) return ERROR(stage_wrong);
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+
default: return ERROR(parameter_unsupported);
}
}
@@ -469,11 +485,22 @@ size_t ZSTD_CCtxParam_setParameter(
return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_overlapSectionLog, value);
case ZSTD_p_longDistanceMatching :
- params->enableLdm = value>0;
if (value != 0) {
ZSTD_cLevelToCCtxParams(params);
params->cParams.windowLog = LDM_WINDOW_LOG;
}
+ return ZSTD_ldm_initializeParameters(¶ms->ldmParams, value);
+
+ case ZSTD_p_ldmHashLog :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
+ params->ldmParams.hashLog = value;
+ return 0;
+
+ case ZSTD_p_ldmMinMatch :
+ if (value == 0) return 0;
+ CLAMPCHECK(value, ZSTD_LDM_SEARCHLENGTH_MIN, ZSTD_LDM_SEARCHLENGTH_MAX);
+ params->ldmParams.minMatchLength = value;
return 0;
default: return ERROR(parameter_unsupported);
@@ -512,7 +539,7 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
}
/* Copy long distance matching parameter */
- cctx->requestedParams.enableLdm = params->enableLdm;
+ cctx->requestedParams.ldmParams = params->ldmParams;
/* customMem is used only for create/free params and can be ignored */
return 0;
@@ -716,8 +743,9 @@ size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* pa
size_t const optSpace = ((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btultra)) ? optBudget : 0;
/* Ldm parameters can not currently be changed */
- size_t const ldmSpace = params->enableLdm ?
- ZSTD_ldm_getTableSize(LDM_HASH_LOG, LDM_BUCKET_SIZE_LOG) : 0;
+ size_t const ldmSpace = params->ldmParams.enableLdm ?
+ ZSTD_ldm_getTableSize(params->ldmParams.hashLog,
+ params->ldmParams.bucketLog) : 0;
size_t const neededSpace = entropySpace + tableSpace + tokenSpace +
optSpace + ldmSpace;
@@ -776,12 +804,24 @@ static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
& ((cParams1.searchLength==3) == (cParams2.searchLength==3)); /* hashlog3 space */
}
+/** The parameters are equivalent if ldm is not enabled in both sets or
+ * all the parameters are equivalent. */
+static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
+ ldmParams_t ldmParams2)
+{
+ return (!ldmParams1.enableLdm && !ldmParams2.enableLdm) ||
+ (ldmParams1.enableLdm == ldmParams2.enableLdm &&
+ ldmParams1.hashLog == ldmParams2.hashLog &&
+ ldmParams1.bucketLog == ldmParams2.bucketLog &&
+ ldmParams1.minMatchLength == ldmParams2.minMatchLength);
+}
+
/** Equivalence for resetCCtx purposes */
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
ZSTD_CCtx_params params2)
{
return ZSTD_equivalentCParams(params1.cParams, params2.cParams) &&
- params1.enableLdm == params2.enableLdm;
+ ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams);
}
/*! ZSTD_continueCCtx() :
@@ -812,6 +852,8 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pl
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
+static U64 ZSTD_ldm_getHashPower(U32 minMatchLength);
+
/*! ZSTD_resetCCtx_internal() :
note : `params` are assumed fully validated at this stage */
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
@@ -831,13 +873,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
} }
- {
- zc->ldmState.hashLog = LDM_HASH_LOG;
- zc->ldmState.bucketLog =
- MIN(LDM_BUCKET_SIZE_LOG, LDM_BUCKET_SIZE_LOG_MAX);
+ if (params.ldmParams.enableLdm) {
zc->ldmState.hashEveryLog =
- params.cParams.windowLog < zc->ldmState.hashLog ?
- 0 : params.cParams.windowLog - zc->ldmState.hashLog;
+ params.cParams.windowLog < params.ldmParams.hashLog ?
+ 0 : params.cParams.windowLog - params.ldmParams.hashLog;
+ zc->ldmState.hashPower =
+ ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
}
{ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
@@ -855,7 +896,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? ((size_t)1 << params.cParams.windowLog) + blockSize : 0;
void* ptr;
- size_t const ldmSpace = params.enableLdm ? ZSTD_ldm_getTableSize(zc->ldmState.hashLog, zc->ldmState.bucketLog) : 0;
+ size_t const ldmSpace = params.ldmParams.enableLdm ?
+ ZSTD_ldm_getTableSize(params.ldmParams.hashLog,
+ params.ldmParams.bucketLog) : 0;
/* Check if workSpace is large enough, alloc a new one if needed */
{ size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
@@ -934,10 +977,10 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
}
/* ldm space */
- if (params.enableLdm) {
- size_t const ldmHSize = ((size_t)1) << zc->ldmState.hashLog;
+ if (params.ldmParams.enableLdm) {
+ size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
size_t const ldmBucketSize =
- ((size_t)1) << (zc->ldmState.hashLog - zc->ldmState.bucketLog);
+ ((size_t)1) << (params.ldmParams.hashLog - params.ldmParams.bucketLog);
memset(ptr, 0, ldmSpace);
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
@@ -1083,8 +1126,8 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
{ U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
- { if (zc->appliedParams.enableLdm) {
- U32 const ldmHSize = 1 << zc->ldmState.hashLog;
+ { if (zc->appliedParams.ldmParams.enableLdm) {
+ U32 const ldmHSize = 1 << zc->appliedParams.ldmParams.hashLog;
ZSTD_ldm_reduceTable(zc->ldmState.hashTable, ldmHSize, reducerValue);
}
}
@@ -3094,20 +3137,22 @@ static U32 ZSTD_ldm_getTag(U64 hash, U32 hbits, U32 numTagBits)
/** ZSTD_ldm_getBucket() :
* Returns a pointer to the start of the bucket associated with hash. */
-static ldmEntry_t* ZSTD_ldm_getBucket(ldmState_t* ldmState, size_t hash)
+static ldmEntry_t* ZSTD_ldm_getBucket(
+ ldmState_t* ldmState, size_t hash, ldmParams_t const ldmParams)
{
- return ldmState->hashTable + (hash << ldmState->bucketLog);
+ return ldmState->hashTable + (hash << ldmParams.bucketLog);
}
/** ZSTD_ldm_insertEntry() :
* Insert the entry with corresponding hash into the hash table */
static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
- size_t const hash, const ldmEntry_t entry)
+ size_t const hash, const ldmEntry_t entry,
+ ldmParams_t const ldmParams)
{
BYTE* const bucketOffsets = ldmState->bucketOffsets;
- *(ZSTD_ldm_getBucket(ldmState, hash) + bucketOffsets[hash]) = entry;
+ *(ZSTD_ldm_getBucket(ldmState, hash, ldmParams) + bucketOffsets[hash]) = entry;
bucketOffsets[hash]++;
- bucketOffsets[hash] &= (1 << ldmState->bucketLog) - 1;
+ bucketOffsets[hash] &= (1 << ldmParams.bucketLog) - 1;
}
/** ZSTD_ldm_makeEntryAndInsertByTag() :
@@ -3122,7 +3167,8 @@ static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
* by ldmState->hashEveryLog bits that make up the tag. */
static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
U64 rollingHash, U32 hBits,
- U32 const offset)
+ U32 const offset,
+ ldmParams_t const ldmParams)
{
U32 const tag = ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog);
U32 const tagMask = (1 << ldmState->hashEveryLog) - 1;
@@ -3132,7 +3178,7 @@ static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
ldmEntry_t entry;
entry.offset = offset;
entry.checksum = checksum;
- ZSTD_ldm_insertEntry(ldmState, hash, entry);
+ ZSTD_ldm_insertEntry(ldmState, hash, entry, ldmParams);
}
}
@@ -3170,14 +3216,15 @@ static U64 ZSTD_ldm_ipow(U64 base, U64 exp)
return ret;
}
+static U64 ZSTD_ldm_getHashPower(U32 minMatchLength) {
+ assert(minMatchLength >= ZSTD_LDM_SEARCHLENGTH_MIN);
+ return ZSTD_ldm_ipow(prime8bytes, minMatchLength - 1);
+}
+
/** ZSTD_ldm_updateHash() :
- * Updates hash by removing toRemove and adding toAdd.
- *
- * Note: this currently relies on compiler optimization to avoid
- * recalculating hashPower. */
-static U64 ZSTD_ldm_updateHash(U64 hash, BYTE toRemove, BYTE toAdd)
+ * Updates hash by removing toRemove and adding toAdd. */
+static U64 ZSTD_ldm_updateHash(U64 hash, BYTE toRemove, BYTE toAdd, U64 hashPower)
{
- U64 const hashPower = ZSTD_ldm_ipow(prime8bytes, LDM_MIN_MATCH_LENGTH - 1);
hash -= ((toRemove + LDM_HASH_CHAR_OFFSET) * hashPower);
hash *= prime8bytes;
hash += toAdd + LDM_HASH_CHAR_OFFSET;
@@ -3248,17 +3295,18 @@ static size_t ZSTD_ldm_fillFastTables(ZSTD_CCtx* zc, const void* end)
static U64 ZSTD_ldm_fillLdmHashTable(ldmState_t* state,
U64 lastHash, const BYTE* lastHashed,
const BYTE* iend, const BYTE* base,
- U32 hBits)
+ U32 hBits, ldmParams_t const ldmParams)
{
U64 rollingHash = lastHash;
const BYTE* cur = lastHashed + 1;
while (cur < iend) {
rollingHash = ZSTD_ldm_updateHash(rollingHash, cur[-1],
- cur[LDM_MIN_MATCH_LENGTH-1]);
+ cur[ldmParams.minMatchLength-1],
+ state->hashPower);
ZSTD_ldm_makeEntryAndInsertByTag(state,
rollingHash, hBits,
- (U32)(cur - base));
+ (U32)(cur - base), ldmParams);
++cur;
}
return rollingHash;
@@ -3283,9 +3331,9 @@ static void ZSTD_ldm_limitTableUpdate(ZSTD_CCtx* cctx, const BYTE* anchor)
*
* This is a block compressor intended for long distance matching.
*
- * The function searches for matches of length at least LDM_MIN_MATCH_LENGTH
- * using a hash table in cctx->ldmState. Matches can be at a distance of
- * up to LDM_WINDOW_LOG.
+ * The function searches for matches of length at least
+ * ldmParams.minMatchLength using a hash table in cctx->ldmState.
+ * Matches can be at a distance of up to cParams.windowLog.
*
* Upon finding a match, the unmatched literals are compressed using a
* ZSTD_blockCompressor (depending on the strategy in the compression
@@ -3297,8 +3345,10 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
const void* src, size_t srcSize)
{
ldmState_t* const ldmState = &(cctx->ldmState);
- const U32 hBits = ldmState->hashLog - ldmState->bucketLog;
- const U32 ldmBucketSize = (1 << ldmState->bucketLog);
+ const ldmParams_t ldmParams = cctx->appliedParams.ldmParams;
+ const U64 hashPower = ldmState->hashPower;
+ const U32 hBits = ldmParams.hashLog - ldmParams.bucketLog;
+ const U32 ldmBucketSize = (1 << ldmParams.bucketLog);
const U32 ldmTagMask = (1 << ldmState->hashEveryLog) - 1;
seqStore_t* const seqStorePtr = &(cctx->seqStore);
const BYTE* const base = cctx->base;
@@ -3308,7 +3358,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
const U32 lowestIndex = cctx->dictLimit;
const BYTE* const lowest = base + lowestIndex;
const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - LDM_MIN_MATCH_LENGTH;
+ const BYTE* const ilimit = iend - ldmParams.minMatchLength;
const ZSTD_blockCompressor blockCompressor =
ZSTD_selectBlockCompressor(cctx->appliedParams.cParams.strategy, 0);
@@ -3330,9 +3380,10 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
ldmEntry_t* bestEntry = NULL;
if (ip != istart) {
rollingHash = ZSTD_ldm_updateHash(rollingHash, lastHashed[0],
- lastHashed[LDM_MIN_MATCH_LENGTH]);
+ lastHashed[ldmParams.minMatchLength],
+ hashPower);
} else {
- rollingHash = ZSTD_ldm_getRollingHash(ip, LDM_MIN_MATCH_LENGTH);
+ rollingHash = ZSTD_ldm_getRollingHash(ip, ldmParams.minMatchLength);
}
lastHashed = ip;
@@ -3347,7 +3398,8 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
{
ldmEntry_t* const bucket =
ZSTD_ldm_getBucket(ldmState,
- ZSTD_ldm_getSmallHash(rollingHash, hBits));
+ ZSTD_ldm_getSmallHash(rollingHash, hBits),
+ ldmParams);
ldmEntry_t* cur;
size_t bestMatchLength = 0;
U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
@@ -3361,7 +3413,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
}
curForwardMatchLength = ZSTD_count(ip, pMatch, iend);
- if (curForwardMatchLength < LDM_MIN_MATCH_LENGTH) {
+ if (curForwardMatchLength < ldmParams.minMatchLength) {
continue;
}
curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch(
@@ -3381,7 +3433,8 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
/* No match found -- continue searching */
if (bestEntry == NULL) {
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash,
- hBits, current);
+ hBits, current,
+ ldmParams);
ip++;
continue;
}
@@ -3420,7 +3473,8 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
/* Insert the current entry into the hash table */
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
- (U32)(lastHashed - base));
+ (U32)(lastHashed - base),
+ ldmParams);
assert(ip + backwardMatchLength == lastHashed);
@@ -3429,12 +3483,11 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
if (ip + mLength < ilimit) {
rollingHash = ZSTD_ldm_fillLdmHashTable(
ldmState, rollingHash, lastHashed,
- ip + mLength, base, hBits);
+ ip + mLength, base, hBits, ldmParams);
lastHashed = ip + mLength - 1;
}
ip += mLength;
anchor = ip;
-
/* Check immediate repcode */
while ( (ip < ilimit)
&& ( (repToConfirm[1] > 0) && (repToConfirm[1] <= (U32)(ip-lowest))
@@ -3455,7 +3508,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
if (ip + rLength < ilimit) {
rollingHash = ZSTD_ldm_fillLdmHashTable(
ldmState, rollingHash, lastHashed,
- ip + rLength, base, hBits);
+ ip + rLength, base, hBits, ldmParams);
lastHashed = ip + rLength - 1;
}
ip += rLength;
@@ -3494,9 +3547,11 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
const void* src, size_t srcSize)
{
ldmState_t* ldmState = &(ctx->ldmState);
- const U32 hBits = ldmState->hashLog - ldmState->bucketLog;
- const U32 ldmBucketSize = (1 << ldmState->bucketLog);
- const U32 ldmTagMask = (1 << ldmState->hashEveryLog) - 1;
+ const ldmParams_t ldmParams = ctx->appliedParams.ldmParams;
+ const U64 hashPower = ldmState->hashPower;
+ const U32 hBits = ldmParams.hashLog - ldmParams.bucketLog;
+ const U32 ldmBucketSize = (1 << ldmParams.bucketLog);
+ const U32 ldmTagMask = (1 << ctx->ldmState.hashEveryLog) - 1;
seqStore_t* const seqStorePtr = &(ctx->seqStore);
const BYTE* const base = ctx->base;
const BYTE* const dictBase = ctx->dictBase;
@@ -3509,7 +3564,7 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
const BYTE* const lowPrefixPtr = base + dictLimit;
const BYTE* const dictEnd = dictBase + dictLimit;
const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - LDM_MIN_MATCH_LENGTH;
+ const BYTE* const ilimit = iend - ldmParams.minMatchLength;
const ZSTD_blockCompressor blockCompressor =
ZSTD_selectBlockCompressor(ctx->appliedParams.cParams.strategy, 1);
@@ -3532,9 +3587,10 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
ldmEntry_t* bestEntry = NULL;
if (ip != istart) {
rollingHash = ZSTD_ldm_updateHash(rollingHash, lastHashed[0],
- lastHashed[LDM_MIN_MATCH_LENGTH]);
+ lastHashed[ldmParams.minMatchLength],
+ hashPower);
} else {
- rollingHash = ZSTD_ldm_getRollingHash(ip, LDM_MIN_MATCH_LENGTH);
+ rollingHash = ZSTD_ldm_getRollingHash(ip, ldmParams.minMatchLength);
}
lastHashed = ip;
@@ -3549,7 +3605,8 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
{
ldmEntry_t* const bucket =
ZSTD_ldm_getBucket(ldmState,
- ZSTD_ldm_getSmallHash(rollingHash, hBits));
+ ZSTD_ldm_getSmallHash(rollingHash, hBits),
+ ldmParams);
ldmEntry_t* cur;
size_t bestMatchLength = 0;
U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
@@ -3572,7 +3629,7 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
curForwardMatchLength = ZSTD_count_2segments(
ip, pMatch, iend,
matchEnd, lowPrefixPtr);
- if (curForwardMatchLength < LDM_MIN_MATCH_LENGTH) {
+ if (curForwardMatchLength < ldmParams.minMatchLength) {
continue;
}
curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch(
@@ -3592,7 +3649,8 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
/* No match found -- continue searching */
if (bestEntry == NULL) {
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
- (U32)(lastHashed - base));
+ (U32)(lastHashed - base),
+ ldmParams);
ip++;
continue;
}
@@ -3632,14 +3690,16 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
/* Insert the current entry into the hash table */
ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,
- (U32)(lastHashed - base));
+ (U32)(lastHashed - base),
+ ldmParams);
/* Fill the hash table from lastHashed+1 to ip+mLength */
assert(ip + backwardMatchLength == lastHashed);
if (ip + mLength < ilimit) {
rollingHash = ZSTD_ldm_fillLdmHashTable(
ldmState, rollingHash, lastHashed,
- ip + mLength, base, hBits);
+ ip + mLength, base, hBits,
+ ldmParams);
lastHashed = ip + mLength - 1;
}
ip += mLength;
@@ -3670,7 +3730,8 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
if (ip + repLength2 < ilimit) {
rollingHash = ZSTD_ldm_fillLdmHashTable(
ldmState, rollingHash, lastHashed,
- ip + repLength2, base, hBits);
+ ip + repLength2, base, hBits,
+ ldmParams);
lastHashed = ip + repLength2 - 1;
}
ip += repLength2;
@@ -3721,7 +3782,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
size_t lastLLSize;
const BYTE* anchor;
const ZSTD_blockCompressor blockCompressor =
- zc->appliedParams.enableLdm?
+ zc->appliedParams.ldmParams.enableLdm ?
(zc->lowLimit < zc->dictLimit ? ZSTD_compressBlock_ldm_extDict :
ZSTD_compressBlock_ldm) :
ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
index f6266ade7..ac451c35e 100644
--- a/lib/compress/zstdmt_compress.c
+++ b/lib/compress/zstdmt_compress.c
@@ -197,7 +197,7 @@ static ZSTD_CCtx_params ZSTDMT_makeJobCCtxParams(ZSTD_CCtx_params const params)
jobParams.fParams = params.fParams;
jobParams.compressionLevel = params.compressionLevel;
- jobParams.enableLdm = params.enableLdm;
+ jobParams.ldmParams = params.ldmParams;
return jobParams;
}
diff --git a/lib/zstd.h b/lib/zstd.h
index c49710402..bed583c92 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -390,6 +390,8 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output
#define ZSTD_SEARCHLENGTH_MIN 3 /* only for ZSTD_btopt, other strategies are limited to 4 */
#define ZSTD_TARGETLENGTH_MIN 4
#define ZSTD_TARGETLENGTH_MAX 999
+#define ZSTD_LDM_SEARCHLENGTH_MIN 4
+#define ZSTD_LDM_SEARCHLENGTH_MAX 4096
#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
#define ZSTD_FRAMEHEADERSIZE_MIN 6
@@ -980,7 +982,14 @@ typedef enum {
* increases the memory usage as well as the
* window size. Note: this should be set after
* ZSTD_p_compressionLevel and before
- * ZSTD_p_windowLog. */
+ * ZSTD_p_windowLog and other LDM parameters. */
+ ZSTD_p_ldmHashLog, /* Size of the table for long distance matching.
+ * Must be clamped between ZSTD_HASHLOG_MIN and
+ * ZSTD_HASHLOG_MAX */
+ ZSTD_p_ldmMinMatch, /* Minimum size of searched matches for long distance matcher.
+ * Must be clamped between ZSTD_LDM_SEARCHLENGTH_MIN
+ * and ZSTD_LDM_SEARCHLENGTH_MAX. */
+
} ZSTD_cParameter;
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index f248d2609..dedb7eb39 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1381,6 +1381,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed) & 63, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 7) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmMinMatch, FUZ_rand(&lseed) % 128 + 4, useOpaqueAPI ) );
+ if (FUZ_rand(&lseed) & 7) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmHashLog, FUZ_rand(&lseed) % 18 + 10, useOpaqueAPI ) );
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
From a1f04d518d34decb2ec5c6471d406fb8dad249ae Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Fri, 1 Sep 2017 14:52:51 -0700
Subject: [PATCH 096/248] Move hashEveryLog to cctxParams and update cli
---
lib/common/zstd_internal.h | 2 +-
lib/compress/zstd_compress.c | 47 ++++++++++++++++++++++++------------
lib/zstd.h | 13 +++++++---
programs/bench.c | 22 +++++++++++++++++
programs/bench.h | 3 +++
programs/fileio.c | 19 +++++++++++++++
programs/fileio.h | 3 +++
programs/zstdcli.c | 16 ++++++++++++
tests/fuzzer.c | 1 -
tests/zstreamtest.c | 2 --
10 files changed, 105 insertions(+), 23 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index b3d9a6c6e..cd4146462 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -256,7 +256,6 @@ typedef struct {
typedef struct {
ldmEntry_t* hashTable;
BYTE* bucketOffsets; /* Next position in bucket to insert entry */
- U32 hashEveryLog; /* Log number of entries to skip */
U64 hashPower; /* Used to compute the rolling hash.
* Depends on ldmParams.minMatchLength */
} ldmState_t;
@@ -266,6 +265,7 @@ typedef struct {
U32 hashLog; /* Log size of hashTable */
U32 bucketLog; /* Log number of buckets, at most 4 */
U32 minMatchLength; /* Minimum match length */
+ U32 hashEveryLog; /* Log number of entries to skip */
} ldmParams_t;
typedef struct {
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index e74787f37..fc8e9b0f3 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -42,6 +42,7 @@ typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZS
#define LDM_WINDOW_LOG 27
#define LDM_HASH_LOG 20
#define LDM_HASH_CHAR_OFFSET 10
+#define LDM_HASHEVERYLOG_NOTSET 9999
/*-*************************************
@@ -320,6 +321,7 @@ static size_t ZSTD_ldm_initializeParameters(ldmParams_t* params, U32 enableLdm)
params->hashLog = LDM_HASH_LOG;
params->bucketLog = LDM_BUCKET_SIZE_LOG;
params->minMatchLength = LDM_MIN_MATCH_LENGTH;
+ params->hashEveryLog = LDM_HASHEVERYLOG_NOTSET;
return 0;
}
@@ -385,6 +387,10 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
if (cctx->cdict) return ERROR(stage_wrong);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+ case ZSTD_p_ldmHashEveryLog:
+ if (cctx->cdict) return ERROR(stage_wrong);
+ return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+
default: return ERROR(parameter_unsupported);
}
}
@@ -503,6 +509,13 @@ size_t ZSTD_CCtxParam_setParameter(
params->ldmParams.minMatchLength = value;
return 0;
+ case ZSTD_p_ldmHashEveryLog :
+ if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN) {
+ return ERROR(parameter_outOfBound);
+ }
+ params->ldmParams.hashEveryLog = value;
+ return 0;
+
default: return ERROR(parameter_unsupported);
}
}
@@ -538,7 +551,7 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
cctx, ZSTD_p_overlapSizeLog, params->overlapSizeLog) );
}
- /* Copy long distance matching parameter */
+ /* Copy long distance matching parameters */
cctx->requestedParams.ldmParams = params->ldmParams;
/* customMem is used only for create/free params and can be ignored */
@@ -742,7 +755,6 @@ size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* pa
+ (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
size_t const optSpace = ((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btultra)) ? optBudget : 0;
- /* Ldm parameters can not currently be changed */
size_t const ldmSpace = params->ldmParams.enableLdm ?
ZSTD_ldm_getTableSize(params->ldmParams.hashLog,
params->ldmParams.bucketLog) : 0;
@@ -813,7 +825,8 @@ static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
(ldmParams1.enableLdm == ldmParams2.enableLdm &&
ldmParams1.hashLog == ldmParams2.hashLog &&
ldmParams1.bucketLog == ldmParams2.bucketLog &&
- ldmParams1.minMatchLength == ldmParams2.minMatchLength);
+ ldmParams1.minMatchLength == ldmParams2.minMatchLength &&
+ ldmParams1.hashEveryLog == ldmParams2.hashEveryLog);
}
/** Equivalence for resetCCtx purposes */
@@ -866,6 +879,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
if (crp == ZSTDcrp_continue) {
if (ZSTD_equivalentParams(params, zc->appliedParams)) {
DEBUGLOG(5, "ZSTD_equivalentParams()==1");
+ assert(!(params.ldmParams.enableLdm &&
+ params.ldmParams.hashEveryLog == LDM_HASHEVERYLOG_NOTSET));
zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
zc->entropy->offcode_repeatMode = FSE_repeat_none;
zc->entropy->matchlength_repeatMode = FSE_repeat_none;
@@ -874,9 +889,11 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
} }
if (params.ldmParams.enableLdm) {
- zc->ldmState.hashEveryLog =
- params.cParams.windowLog < params.ldmParams.hashLog ?
- 0 : params.cParams.windowLog - params.ldmParams.hashLog;
+ if (params.ldmParams.hashEveryLog == LDM_HASHEVERYLOG_NOTSET) {
+ params.ldmParams.hashEveryLog =
+ params.cParams.windowLog < params.ldmParams.hashLog ?
+ 0 : params.cParams.windowLog - params.ldmParams.hashLog;
+ }
zc->ldmState.hashPower =
ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
}
@@ -3159,19 +3176,19 @@ static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
*
* Gets the small hash, checksum, and tag from the rollingHash.
*
- * If the tag matches (1 << ldmState->hashEveryLog)-1, then
+ * If the tag matches (1 << ldmParams.hashEveryLog)-1, then
* creates an ldmEntry from the offset, and inserts it into the hash table.
*
* hBits is the length of the small hash, which is the most significant hBits
* of rollingHash. The checksum is the next 32 most significant bits, followed
- * by ldmState->hashEveryLog bits that make up the tag. */
+ * by ldmParams.hashEveryLog bits that make up the tag. */
static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
U64 rollingHash, U32 hBits,
U32 const offset,
ldmParams_t const ldmParams)
{
- U32 const tag = ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog);
- U32 const tagMask = (1 << ldmState->hashEveryLog) - 1;
+ U32 const tag = ZSTD_ldm_getTag(rollingHash, hBits, ldmParams.hashEveryLog);
+ U32 const tagMask = (1 << ldmParams.hashEveryLog) - 1;
if (tag == tagMask) {
U32 const hash = ZSTD_ldm_getSmallHash(rollingHash, hBits);
U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);
@@ -3349,7 +3366,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
const U64 hashPower = ldmState->hashPower;
const U32 hBits = ldmParams.hashLog - ldmParams.bucketLog;
const U32 ldmBucketSize = (1 << ldmParams.bucketLog);
- const U32 ldmTagMask = (1 << ldmState->hashEveryLog) - 1;
+ const U32 ldmTagMask = (1 << ldmParams.hashEveryLog) - 1;
seqStore_t* const seqStorePtr = &(cctx->seqStore);
const BYTE* const base = cctx->base;
const BYTE* const istart = (const BYTE*)src;
@@ -3388,7 +3405,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
lastHashed = ip;
/* Do not insert and do not look for a match */
- if (ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog) !=
+ if (ZSTD_ldm_getTag(rollingHash, hBits, ldmParams.hashEveryLog) !=
ldmTagMask) {
ip++;
continue;
@@ -3546,12 +3563,12 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
ZSTD_CCtx* ctx,
const void* src, size_t srcSize)
{
- ldmState_t* ldmState = &(ctx->ldmState);
+ ldmState_t* const ldmState = &(ctx->ldmState);
const ldmParams_t ldmParams = ctx->appliedParams.ldmParams;
const U64 hashPower = ldmState->hashPower;
const U32 hBits = ldmParams.hashLog - ldmParams.bucketLog;
const U32 ldmBucketSize = (1 << ldmParams.bucketLog);
- const U32 ldmTagMask = (1 << ctx->ldmState.hashEveryLog) - 1;
+ const U32 ldmTagMask = (1 << ldmParams.hashEveryLog) - 1;
seqStore_t* const seqStorePtr = &(ctx->seqStore);
const BYTE* const base = ctx->base;
const BYTE* const dictBase = ctx->dictBase;
@@ -3594,7 +3611,7 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
}
lastHashed = ip;
- if (ZSTD_ldm_getTag(rollingHash, hBits, ldmState->hashEveryLog) !=
+ if (ZSTD_ldm_getTag(rollingHash, hBits, ldmParams.hashEveryLog) !=
ldmTagMask) {
/* Don't insert and don't look for a match */
ip++;
diff --git a/lib/zstd.h b/lib/zstd.h
index bed583c92..a7ad9771b 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -984,11 +984,16 @@ typedef enum {
* ZSTD_p_compressionLevel and before
* ZSTD_p_windowLog and other LDM parameters. */
ZSTD_p_ldmHashLog, /* Size of the table for long distance matching.
- * Must be clamped between ZSTD_HASHLOG_MIN and
- * ZSTD_HASHLOG_MAX */
+ * Must be clamped between ZSTD_HASHLOG_MIN and
+ * ZSTD_HASHLOG_MAX */
ZSTD_p_ldmMinMatch, /* Minimum size of searched matches for long distance matcher.
- * Must be clamped between ZSTD_LDM_SEARCHLENGTH_MIN
- * and ZSTD_LDM_SEARCHLENGTH_MAX. */
+ * Must be clamped between ZSTD_LDM_SEARCHLENGTH_MIN
+ * and ZSTD_LDM_SEARCHLENGTH_MAX. */
+ ZSTD_p_ldmHashEveryLog, /* Frequency of inserting/looking up entries in the
+ * LDM hash table. The default is
+ * (windowLog - ldmHashLog) to optimize hash table
+ * usage. Must be clamped between 0 and
+ * ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN. */
} ZSTD_cParameter;
diff --git a/programs/bench.c b/programs/bench.c
index d77f9a20d..2a2510a2c 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -134,6 +134,23 @@ void BMK_setLdmFlag(unsigned ldmFlag) {
g_ldmFlag = ldmFlag;
}
+static U32 g_ldmMinMatch = 0;
+void BMK_setLdmMinMatch(unsigned ldmMinMatch) {
+ g_ldmMinMatch = ldmMinMatch;
+}
+
+static U32 g_ldmHashLog = 0;
+void BMK_setLdmHashLog(unsigned ldmHashLog) {
+ g_ldmHashLog = ldmHashLog;
+}
+
+#define BMK_LDM_HASHEVERYLOG_NOTSET 9999
+static U32 g_ldmHashEveryLog = BMK_LDM_HASHEVERYLOG_NOTSET;
+void BMK_setLdmHashEveryLog(unsigned ldmHashEveryLog) {
+ g_ldmHashEveryLog = ldmHashEveryLog;
+}
+
+
/* ********************************************************
* Bench functions
**********************************************************/
@@ -270,6 +287,11 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
ZSTD_CCtx_setParameter(ctx, ZSTD_p_nbThreads, g_nbThreads);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionLevel, cLevel);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_longDistanceMatching, g_ldmFlag);
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmMinMatch, g_ldmMinMatch);
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmHashLog, g_ldmHashLog);
+ if (g_ldmHashEveryLog != BMK_LDM_HASHEVERYLOG_NOTSET) {
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmHashEveryLog, g_ldmHashEveryLog);
+ }
ZSTD_CCtx_setParameter(ctx, ZSTD_p_windowLog, comprParams->windowLog);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_chainLog, comprParams->chainLog);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_searchLog, comprParams->searchLog);
diff --git a/programs/bench.h b/programs/bench.h
index 7fb73c4d8..04d220a92 100644
--- a/programs/bench.h
+++ b/programs/bench.h
@@ -26,5 +26,8 @@ void BMK_setNotificationLevel(unsigned level);
void BMK_setAdditionalParam(int additionalParam);
void BMK_setDecodeOnlyMode(unsigned decodeFlag);
void BMK_setLdmFlag(unsigned ldmFlag);
+void BMK_setLdmMinMatch(unsigned ldmMinMatch);
+void BMK_setLdmHashLog(unsigned ldmHashLog);
+void BMK_setLdmHashEveryLog(unsigned ldmHashEveryLog);
#endif /* BENCH_H_121279284357 */
diff --git a/programs/fileio.c b/programs/fileio.c
index c86b25339..fc390afed 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -217,6 +217,20 @@ static U32 g_ldmFlag = 0;
void FIO_setLdmFlag(unsigned ldmFlag) {
g_ldmFlag = (ldmFlag>0);
}
+static U32 g_ldmHashLog = 0;
+void FIO_setLdmHashLog(unsigned ldmHashLog) {
+ g_ldmHashLog = ldmHashLog;
+}
+static U32 g_ldmMinMatch = 0;
+void FIO_setLdmMinMatch(unsigned ldmMinMatch) {
+ g_ldmMinMatch = ldmMinMatch;
+}
+#define FIO_LDM_HASHEVERYLOG_NOTSET 9999
+static U32 g_ldmHashEveryLog = FIO_LDM_HASHEVERYLOG_NOTSET;
+void FIO_setLdmHashEveryLog(unsigned ldmHashEveryLog) {
+ g_ldmHashEveryLog = ldmHashEveryLog;
+}
+
/*-*************************************
@@ -406,6 +420,11 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionLevel, cLevel) );
/* long distance matching */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_longDistanceMatching, g_ldmFlag) );
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmHashLog, g_ldmHashLog) );
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmMinMatch, g_ldmMinMatch) );
+ if (g_ldmHashEveryLog != FIO_LDM_HASHEVERYLOG_NOTSET) {
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmHashEveryLog, g_ldmHashEveryLog) );
+ }
/* compression parameters */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_windowLog, comprParams->windowLog) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_chainLog, comprParams->chainLog) );
diff --git a/programs/fileio.h b/programs/fileio.h
index 7e200b06e..fabb46db9 100644
--- a/programs/fileio.h
+++ b/programs/fileio.h
@@ -57,6 +57,9 @@ void FIO_setNbThreads(unsigned nbThreads);
void FIO_setBlockSize(unsigned blockSize);
void FIO_setOverlapLog(unsigned overlapLog);
void FIO_setLdmFlag(unsigned ldmFlag);
+void FIO_setLdmHashLog(unsigned ldmHashLog);
+void FIO_setLdmMinMatch(unsigned ldmMinMatch);
+void FIO_setLdmHashEveryLog(unsigned ldmHashEveryLog);
/*-*************************************
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index b5fd1be5a..78d6b339e 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -72,7 +72,11 @@ static const unsigned g_defaultMaxDictSize = 110 KB;
static const int g_defaultDictCLevel = 3;
static const unsigned g_defaultSelectivityLevel = 9;
#define OVERLAP_LOG_DEFAULT 9999
+#define LDM_HASHEVERYLOG_DEFAULT 9999
static U32 g_overlapLog = OVERLAP_LOG_DEFAULT;
+static U32 g_ldmHashLog = 0;
+static U32 g_ldmMinMatch = 0;
+static U32 g_ldmHashEveryLog = LDM_HASHEVERYLOG_DEFAULT;
/*-************************************
@@ -305,6 +309,9 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi
if (longCommandWArg(&stringPtr, "targetLength=") || longCommandWArg(&stringPtr, "tlen=")) { params->targetLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "strategy=") || longCommandWArg(&stringPtr, "strat=")) { params->strategy = (ZSTD_strategy)(readU32FromChar(&stringPtr)); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "overlapLog=") || longCommandWArg(&stringPtr, "ovlog=")) { g_overlapLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmHashLog=") || longCommandWArg(&stringPtr, "ldmHlog=")) { g_ldmHashLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmSearchLength=") || longCommandWArg(&stringPtr, "ldmSlen=")) { g_ldmMinMatch = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmHashEveryLog=")) { g_ldmHashEveryLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
return 0;
}
@@ -724,6 +731,9 @@ int main(int argCount, const char* argv[])
BMK_setNbThreads(nbThreads);
BMK_setNbSeconds(bench_nbSeconds);
BMK_setLdmFlag(ldmFlag);
+ BMK_setLdmMinMatch(g_ldmMinMatch);
+ BMK_setLdmHashLog(g_ldmHashLog);
+ BMK_setLdmHashEveryLog(g_ldmHashEveryLog);
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast, &compressionParams, setRealTimePrio);
#endif
(void)bench_nbSeconds; (void)blockSize; (void)setRealTimePrio;
@@ -792,6 +802,12 @@ int main(int argCount, const char* argv[])
FIO_setNbThreads(nbThreads);
FIO_setBlockSize((U32)blockSize);
FIO_setLdmFlag(ldmFlag);
+ FIO_setLdmHashLog(g_ldmHashLog);
+ FIO_setLdmMinMatch(g_ldmMinMatch);
+ if (g_ldmHashEveryLog != LDM_HASHEVERYLOG_DEFAULT) {
+ FIO_setLdmHashEveryLog(g_ldmHashEveryLog);
+ }
+
if (g_overlapLog!=OVERLAP_LOG_DEFAULT) FIO_setOverlapLog(g_overlapLog);
if ((filenameIdx==1) && outFileName)
operationResult = FIO_compressFilename(outFileName, filenameTable[0], dictFileName, cLevel, &compressionParams);
diff --git a/tests/fuzzer.c b/tests/fuzzer.c
index 3b3e23b38..b23498705 100644
--- a/tests/fuzzer.c
+++ b/tests/fuzzer.c
@@ -1342,7 +1342,6 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
dictSize = FUZ_rLogLength(&lseed, dictLog); /* needed also for decompression */
dict = srcBuffer + (FUZ_rand(&lseed) % (srcBufferSize - dictSize));
- CHECK_Z ( ZSTD_CCtx_setParameter(refCtx, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed)&255) );
if (FUZ_rand(&lseed) & 0xF) {
CHECK_Z ( ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel) );
} else {
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index dedb7eb39..f248d2609 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1381,8 +1381,6 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed) & 63, useOpaqueAPI) );
- if (FUZ_rand(&lseed) & 7) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmMinMatch, FUZ_rand(&lseed) % 128 + 4, useOpaqueAPI ) );
- if (FUZ_rand(&lseed) & 7) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmHashLog, FUZ_rand(&lseed) % 18 + 10, useOpaqueAPI ) );
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
From 67d4a6161cc1237cf958d3abb4d8ce1a6623119c Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Sat, 2 Sep 2017 21:10:36 -0700
Subject: [PATCH 097/248] Add ldmBucketSizeLog param
---
lib/common/zstd_internal.h | 2 +-
lib/compress/zstd_compress.c | 77 ++++++++++++++++++++++++++----------
lib/zstd.h | 28 +++++++------
programs/bench.c | 16 ++++++--
programs/bench.h | 1 +
programs/fileio.c | 18 +++++++--
programs/fileio.h | 1 +
programs/zstdcli.c | 18 +++++++--
tests/zstreamtest.c | 2 +-
9 files changed, 116 insertions(+), 47 deletions(-)
diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
index cd4146462..2a270c3e4 100644
--- a/lib/common/zstd_internal.h
+++ b/lib/common/zstd_internal.h
@@ -263,7 +263,7 @@ typedef struct {
typedef struct {
U32 enableLdm; /* 1 if enable long distance matching */
U32 hashLog; /* Log size of hashTable */
- U32 bucketLog; /* Log number of buckets, at most 4 */
+ U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */
U32 minMatchLength; /* Minimum match length */
U32 hashEveryLog; /* Log number of entries to skip */
} ldmParams_t;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index fc8e9b0f3..d4d3ae961 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -37,7 +37,6 @@ static const U32 g_searchStrength = 8; /* control skip over incompressible dat
typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
#define LDM_BUCKET_SIZE_LOG 3
-#define LDM_BUCKET_SIZE_LOG_MAX 4
#define LDM_MIN_MATCH_LENGTH 64
#define LDM_WINDOW_LOG 27
#define LDM_HASH_LOG 20
@@ -202,6 +201,33 @@ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
+ cctx->outBuffSize + cctx->inBuffSize
+ ZSTDMT_sizeof_CCtx(cctx->mtctx);
}
+#if 0
+static void ZSTD_debugPrintCCtxParams(ZSTD_CCtx_params* params)
+{
+ DEBUGLOG(2, "======CCtxParams======");
+ DEBUGLOG(2, "cParams: %u %u %u %u %u %u %u",
+ params->cParams.windowLog,
+ params->cParams.chainLog,
+ params->cParams.hashLog,
+ params->cParams.searchLog,
+ params->cParams.searchLength,
+ params->cParams.targetLength,
+ params->cParams.strategy);
+ DEBUGLOG(2, "fParams: %u %u %u",
+ params->fParams.contentSizeFlag,
+ params->fParams.checksumFlag,
+ params->fParams.noDictIDFlag);
+ DEBUGLOG(2, "cLevel, forceWindow: %u %u",
+ params->compressionLevel,
+ params->forceWindow);
+ DEBUGLOG(2, "ldm: %u %u %u %u %u",
+ params->ldmParams.enableLdm,
+ params->ldmParams.hashLog,
+ params->ldmParams.bucketSizeLog,
+ params->ldmParams.minMatchLength,
+ params->ldmParams.hashEveryLog);
+}
+#endif
size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
{
@@ -316,10 +342,10 @@ size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThre
static size_t ZSTD_ldm_initializeParameters(ldmParams_t* params, U32 enableLdm)
{
- assert(LDM_BUCKET_SIZE_LOG <= LDM_BUCKET_SIZE_LOG_MAX);
+ assert(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX);
params->enableLdm = enableLdm>0;
params->hashLog = LDM_HASH_LOG;
- params->bucketLog = LDM_BUCKET_SIZE_LOG;
+ params->bucketSizeLog = LDM_BUCKET_SIZE_LOG;
params->minMatchLength = LDM_MIN_MATCH_LENGTH;
params->hashEveryLog = LDM_HASHEVERYLOG_NOTSET;
return 0;
@@ -374,7 +400,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->requestedParams.nbThreads);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
- case ZSTD_p_longDistanceMatching:
+ case ZSTD_p_enableLongDistanceMatching:
if (cctx->cdict) return ERROR(stage_wrong);
if (value != 0) {
ZSTD_cLevelToCParams(cctx);
@@ -387,6 +413,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
if (cctx->cdict) return ERROR(stage_wrong);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
+ case ZSTD_p_ldmBucketSizeLog:
case ZSTD_p_ldmHashEveryLog:
if (cctx->cdict) return ERROR(stage_wrong);
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
@@ -490,7 +517,7 @@ size_t ZSTD_CCtxParam_setParameter(
if (params->nbThreads <= 1) return ERROR(parameter_unsupported);
return ZSTDMT_CCtxParam_setMTCtxParameter(params, ZSTDMT_p_overlapSectionLog, value);
- case ZSTD_p_longDistanceMatching :
+ case ZSTD_p_enableLongDistanceMatching :
if (value != 0) {
ZSTD_cLevelToCCtxParams(params);
params->cParams.windowLog = LDM_WINDOW_LOG;
@@ -509,6 +536,13 @@ size_t ZSTD_CCtxParam_setParameter(
params->ldmParams.minMatchLength = value;
return 0;
+ case ZSTD_p_ldmBucketSizeLog :
+ if (value > ZSTD_LDM_BUCKETSIZELOG_MAX) {
+ return ERROR(parameter_outOfBound);
+ }
+ params->ldmParams.bucketSizeLog = value;
+ return 0;
+
case ZSTD_p_ldmHashEveryLog :
if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN) {
return ERROR(parameter_outOfBound);
@@ -722,12 +756,11 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
}
/* Estimate the space needed for long distance matching tables. */
-static size_t ZSTD_ldm_getTableSize(U32 ldmHashLog, U32 bucketLog) {
- size_t const ldmHSize = ((size_t)1) << ldmHashLog;
- size_t const ldmBucketLog =
- MIN(bucketLog, LDM_BUCKET_SIZE_LOG_MAX);
+static size_t ZSTD_ldm_getTableSize(U32 hashLog, U32 bucketSizeLog) {
+ size_t const ldmHSize = ((size_t)1) << hashLog;
+ size_t const ldmBucketSizeLog = MIN(bucketSizeLog, hashLog);
size_t const ldmBucketSize =
- ((size_t)1) << (ldmHashLog - ldmBucketLog);
+ ((size_t)1) << (hashLog - ldmBucketSizeLog);
return ldmBucketSize + (ldmHSize * (sizeof(ldmEntry_t)));
}
@@ -757,7 +790,7 @@ size_t ZSTD_estimateCCtxSize_advanced_usingCCtxParams(const ZSTD_CCtx_params* pa
size_t const ldmSpace = params->ldmParams.enableLdm ?
ZSTD_ldm_getTableSize(params->ldmParams.hashLog,
- params->ldmParams.bucketLog) : 0;
+ params->ldmParams.bucketSizeLog) : 0;
size_t const neededSpace = entropySpace + tableSpace + tokenSpace +
optSpace + ldmSpace;
@@ -824,7 +857,7 @@ static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
return (!ldmParams1.enableLdm && !ldmParams2.enableLdm) ||
(ldmParams1.enableLdm == ldmParams2.enableLdm &&
ldmParams1.hashLog == ldmParams2.hashLog &&
- ldmParams1.bucketLog == ldmParams2.bucketLog &&
+ ldmParams1.bucketSizeLog == ldmParams2.bucketSizeLog &&
ldmParams1.minMatchLength == ldmParams2.minMatchLength &&
ldmParams1.hashEveryLog == ldmParams2.hashEveryLog);
}
@@ -889,11 +922,14 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
} }
if (params.ldmParams.enableLdm) {
+ /* Adjust long distance matching parameters */
if (params.ldmParams.hashEveryLog == LDM_HASHEVERYLOG_NOTSET) {
params.ldmParams.hashEveryLog =
params.cParams.windowLog < params.ldmParams.hashLog ?
0 : params.cParams.windowLog - params.ldmParams.hashLog;
}
+ params.ldmParams.bucketSizeLog =
+ MIN(params.ldmParams.bucketSizeLog, params.ldmParams.hashLog);
zc->ldmState.hashPower =
ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
}
@@ -915,7 +951,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const ldmSpace = params.ldmParams.enableLdm ?
ZSTD_ldm_getTableSize(params.ldmParams.hashLog,
- params.ldmParams.bucketLog) : 0;
+ params.ldmParams.bucketSizeLog) : 0;
/* Check if workSpace is large enough, alloc a new one if needed */
{ size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
@@ -997,7 +1033,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
if (params.ldmParams.enableLdm) {
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
size_t const ldmBucketSize =
- ((size_t)1) << (params.ldmParams.hashLog - params.ldmParams.bucketLog);
+ ((size_t)1) << (params.ldmParams.hashLog - params.ldmParams.bucketSizeLog);
memset(ptr, 0, ldmSpace);
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
@@ -3157,7 +3193,7 @@ static U32 ZSTD_ldm_getTag(U64 hash, U32 hbits, U32 numTagBits)
static ldmEntry_t* ZSTD_ldm_getBucket(
ldmState_t* ldmState, size_t hash, ldmParams_t const ldmParams)
{
- return ldmState->hashTable + (hash << ldmParams.bucketLog);
+ return ldmState->hashTable + (hash << ldmParams.bucketSizeLog);
}
/** ZSTD_ldm_insertEntry() :
@@ -3169,7 +3205,7 @@ static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
BYTE* const bucketOffsets = ldmState->bucketOffsets;
*(ZSTD_ldm_getBucket(ldmState, hash, ldmParams) + bucketOffsets[hash]) = entry;
bucketOffsets[hash]++;
- bucketOffsets[hash] &= (1 << ldmParams.bucketLog) - 1;
+ bucketOffsets[hash] &= (1 << ldmParams.bucketSizeLog) - 1;
}
/** ZSTD_ldm_makeEntryAndInsertByTag() :
@@ -3364,8 +3400,8 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
ldmState_t* const ldmState = &(cctx->ldmState);
const ldmParams_t ldmParams = cctx->appliedParams.ldmParams;
const U64 hashPower = ldmState->hashPower;
- const U32 hBits = ldmParams.hashLog - ldmParams.bucketLog;
- const U32 ldmBucketSize = (1 << ldmParams.bucketLog);
+ const U32 hBits = ldmParams.hashLog - ldmParams.bucketSizeLog;
+ const U32 ldmBucketSize = (1 << ldmParams.bucketSizeLog);
const U32 ldmTagMask = (1 << ldmParams.hashEveryLog) - 1;
seqStore_t* const seqStorePtr = &(cctx->seqStore);
const BYTE* const base = cctx->base;
@@ -3566,8 +3602,8 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
ldmState_t* const ldmState = &(ctx->ldmState);
const ldmParams_t ldmParams = ctx->appliedParams.ldmParams;
const U64 hashPower = ldmState->hashPower;
- const U32 hBits = ldmParams.hashLog - ldmParams.bucketLog;
- const U32 ldmBucketSize = (1 << ldmParams.bucketLog);
+ const U32 hBits = ldmParams.hashLog - ldmParams.bucketSizeLog;
+ const U32 ldmBucketSize = (1 << ldmParams.bucketSizeLog);
const U32 ldmTagMask = (1 << ldmParams.hashEveryLog) - 1;
seqStore_t* const seqStorePtr = &(ctx->seqStore);
const BYTE* const base = ctx->base;
@@ -5009,7 +5045,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
return flushMin;
}
#endif
-
CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
DEBUGLOG(5, "completed ZSTD_compress_generic");
return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
diff --git a/lib/zstd.h b/lib/zstd.h
index a7ad9771b..e7d4fbdf4 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -392,6 +392,7 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output
#define ZSTD_TARGETLENGTH_MAX 999
#define ZSTD_LDM_SEARCHLENGTH_MIN 4
#define ZSTD_LDM_SEARCHLENGTH_MAX 4096
+#define ZSTD_LDM_BUCKETSIZELOG_MAX 8
#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
#define ZSTD_FRAMEHEADERSIZE_MIN 6
@@ -978,22 +979,25 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
- ZSTD_p_longDistanceMatching, /* Enable long distance matching. This
- * increases the memory usage as well as the
- * window size. Note: this should be set after
- * ZSTD_p_compressionLevel and before
- * ZSTD_p_windowLog and other LDM parameters. */
+ ZSTD_p_enableLongDistanceMatching, /* Enable long distance matching. This increases the memory
+ * usage as well as window size. Note: setting this
+ * parameter resets all the LDM parameters as well as
+ * ZSTD_p_windowLog. It should be set after
+ * ZSTD_p_compressionLevel and before ZSTD_p_windowLog and
+ * other LDM parameters. Setting the compression level
+ * after this parameter overrides the window log, though LDM
+ * will remain enabled until explicitly disabled. */
ZSTD_p_ldmHashLog, /* Size of the table for long distance matching.
- * Must be clamped between ZSTD_HASHLOG_MIN and
- * ZSTD_HASHLOG_MAX */
+ * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. */
ZSTD_p_ldmMinMatch, /* Minimum size of searched matches for long distance matcher.
* Must be clamped between ZSTD_LDM_SEARCHLENGTH_MIN
* and ZSTD_LDM_SEARCHLENGTH_MAX. */
- ZSTD_p_ldmHashEveryLog, /* Frequency of inserting/looking up entries in the
- * LDM hash table. The default is
- * (windowLog - ldmHashLog) to optimize hash table
- * usage. Must be clamped between 0 and
- * ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN. */
+ ZSTD_p_ldmBucketSizeLog, /* Log size of each bucket in the hash table for collision resolution.
+ * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX. */
+ ZSTD_p_ldmHashEveryLog, /* Frequency of inserting/looking up entries in the LDM hash table.
+ * The default is MAX(0, (windowLog - ldmHashLog)) to
+ * optimize hash table usage.
+ * Must be clamped between 0 and ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN. */
} ZSTD_cParameter;
diff --git a/programs/bench.c b/programs/bench.c
index 2a2510a2c..68ac8c886 100644
--- a/programs/bench.c
+++ b/programs/bench.c
@@ -144,8 +144,13 @@ void BMK_setLdmHashLog(unsigned ldmHashLog) {
g_ldmHashLog = ldmHashLog;
}
-#define BMK_LDM_HASHEVERYLOG_NOTSET 9999
-static U32 g_ldmHashEveryLog = BMK_LDM_HASHEVERYLOG_NOTSET;
+#define BMK_LDM_PARAM_NOTSET 9999
+static U32 g_ldmBucketSizeLog = BMK_LDM_PARAM_NOTSET;
+void BMK_setLdmBucketSizeLog(unsigned ldmBucketSizeLog) {
+ g_ldmBucketSizeLog = ldmBucketSizeLog;
+}
+
+static U32 g_ldmHashEveryLog = BMK_LDM_PARAM_NOTSET;
void BMK_setLdmHashEveryLog(unsigned ldmHashEveryLog) {
g_ldmHashEveryLog = ldmHashEveryLog;
}
@@ -286,10 +291,13 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
#ifdef ZSTD_NEWAPI
ZSTD_CCtx_setParameter(ctx, ZSTD_p_nbThreads, g_nbThreads);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionLevel, cLevel);
- ZSTD_CCtx_setParameter(ctx, ZSTD_p_longDistanceMatching, g_ldmFlag);
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_enableLongDistanceMatching, g_ldmFlag);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmMinMatch, g_ldmMinMatch);
ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmHashLog, g_ldmHashLog);
- if (g_ldmHashEveryLog != BMK_LDM_HASHEVERYLOG_NOTSET) {
+ if (g_ldmBucketSizeLog != BMK_LDM_PARAM_NOTSET) {
+ ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmBucketSizeLog, g_ldmBucketSizeLog);
+ }
+ if (g_ldmHashEveryLog != BMK_LDM_PARAM_NOTSET) {
ZSTD_CCtx_setParameter(ctx, ZSTD_p_ldmHashEveryLog, g_ldmHashEveryLog);
}
ZSTD_CCtx_setParameter(ctx, ZSTD_p_windowLog, comprParams->windowLog);
diff --git a/programs/bench.h b/programs/bench.h
index 04d220a92..6fd6c405e 100644
--- a/programs/bench.h
+++ b/programs/bench.h
@@ -28,6 +28,7 @@ void BMK_setDecodeOnlyMode(unsigned decodeFlag);
void BMK_setLdmFlag(unsigned ldmFlag);
void BMK_setLdmMinMatch(unsigned ldmMinMatch);
void BMK_setLdmHashLog(unsigned ldmHashLog);
+void BMK_setLdmBucketSizeLog(unsigned ldmBucketSizeLog);
void BMK_setLdmHashEveryLog(unsigned ldmHashEveryLog);
#endif /* BENCH_H_121279284357 */
diff --git a/programs/fileio.c b/programs/fileio.c
index fc390afed..7322328b8 100644
--- a/programs/fileio.c
+++ b/programs/fileio.c
@@ -225,8 +225,14 @@ static U32 g_ldmMinMatch = 0;
void FIO_setLdmMinMatch(unsigned ldmMinMatch) {
g_ldmMinMatch = ldmMinMatch;
}
-#define FIO_LDM_HASHEVERYLOG_NOTSET 9999
-static U32 g_ldmHashEveryLog = FIO_LDM_HASHEVERYLOG_NOTSET;
+
+#define FIO_LDM_PARAM_NOTSET 9999
+static U32 g_ldmBucketSizeLog = FIO_LDM_PARAM_NOTSET;
+void FIO_setLdmBucketSizeLog(unsigned ldmBucketSizeLog) {
+ g_ldmBucketSizeLog = ldmBucketSizeLog;
+}
+
+static U32 g_ldmHashEveryLog = FIO_LDM_PARAM_NOTSET;
void FIO_setLdmHashEveryLog(unsigned ldmHashEveryLog) {
g_ldmHashEveryLog = ldmHashEveryLog;
}
@@ -419,10 +425,14 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
/* compression level */
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionLevel, cLevel) );
/* long distance matching */
- CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_longDistanceMatching, g_ldmFlag) );
+ CHECK( ZSTD_CCtx_setParameter(
+ ress.cctx, ZSTD_p_enableLongDistanceMatching, g_ldmFlag) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmHashLog, g_ldmHashLog) );
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmMinMatch, g_ldmMinMatch) );
- if (g_ldmHashEveryLog != FIO_LDM_HASHEVERYLOG_NOTSET) {
+ if (g_ldmBucketSizeLog != FIO_LDM_PARAM_NOTSET) {
+ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmBucketSizeLog, g_ldmBucketSizeLog) );
+ }
+ if (g_ldmHashEveryLog != FIO_LDM_PARAM_NOTSET) {
CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_ldmHashEveryLog, g_ldmHashEveryLog) );
}
/* compression parameters */
diff --git a/programs/fileio.h b/programs/fileio.h
index fabb46db9..20ee2ebc8 100644
--- a/programs/fileio.h
+++ b/programs/fileio.h
@@ -59,6 +59,7 @@ void FIO_setOverlapLog(unsigned overlapLog);
void FIO_setLdmFlag(unsigned ldmFlag);
void FIO_setLdmHashLog(unsigned ldmHashLog);
void FIO_setLdmMinMatch(unsigned ldmMinMatch);
+void FIO_setLdmBucketSizeLog(unsigned ldmBucketSizeLog);
void FIO_setLdmHashEveryLog(unsigned ldmHashEveryLog);
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index 78d6b339e..a60537a0c 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -72,11 +72,12 @@ static const unsigned g_defaultMaxDictSize = 110 KB;
static const int g_defaultDictCLevel = 3;
static const unsigned g_defaultSelectivityLevel = 9;
#define OVERLAP_LOG_DEFAULT 9999
-#define LDM_HASHEVERYLOG_DEFAULT 9999
+#define LDM_PARAM_DEFAULT 9999 /* Default for parameters where 0 is valid */
static U32 g_overlapLog = OVERLAP_LOG_DEFAULT;
static U32 g_ldmHashLog = 0;
static U32 g_ldmMinMatch = 0;
-static U32 g_ldmHashEveryLog = LDM_HASHEVERYLOG_DEFAULT;
+static U32 g_ldmHashEveryLog = LDM_PARAM_DEFAULT;
+static U32 g_ldmBucketSizeLog = LDM_PARAM_DEFAULT;
/*-************************************
@@ -311,6 +312,7 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi
if (longCommandWArg(&stringPtr, "overlapLog=") || longCommandWArg(&stringPtr, "ovlog=")) { g_overlapLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "ldmHashLog=") || longCommandWArg(&stringPtr, "ldmHlog=")) { g_ldmHashLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "ldmSearchLength=") || longCommandWArg(&stringPtr, "ldmSlen=")) { g_ldmMinMatch = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmBucketSizeLog=")) { g_ldmBucketSizeLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "ldmHashEveryLog=")) { g_ldmHashEveryLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
return 0;
}
@@ -733,7 +735,12 @@ int main(int argCount, const char* argv[])
BMK_setLdmFlag(ldmFlag);
BMK_setLdmMinMatch(g_ldmMinMatch);
BMK_setLdmHashLog(g_ldmHashLog);
- BMK_setLdmHashEveryLog(g_ldmHashEveryLog);
+ if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) {
+ BMK_setLdmBucketSizeLog(g_ldmBucketSizeLog);
+ }
+ if (g_ldmHashEveryLog != LDM_PARAM_DEFAULT) {
+ BMK_setLdmHashEveryLog(g_ldmHashEveryLog);
+ }
BMK_benchFiles(filenameTable, filenameIdx, dictFileName, cLevel, cLevelLast, &compressionParams, setRealTimePrio);
#endif
(void)bench_nbSeconds; (void)blockSize; (void)setRealTimePrio;
@@ -804,7 +811,10 @@ int main(int argCount, const char* argv[])
FIO_setLdmFlag(ldmFlag);
FIO_setLdmHashLog(g_ldmHashLog);
FIO_setLdmMinMatch(g_ldmMinMatch);
- if (g_ldmHashEveryLog != LDM_HASHEVERYLOG_DEFAULT) {
+ if (g_ldmBucketSizeLog != LDM_PARAM_DEFAULT) {
+ FIO_setLdmBucketSizeLog(g_ldmBucketSizeLog);
+ }
+ if (g_ldmHashEveryLog != LDM_PARAM_DEFAULT) {
FIO_setLdmHashEveryLog(g_ldmHashEveryLog);
}
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index f248d2609..76495d453 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -1380,7 +1380,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_minMatch, cParams.searchLength, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
- if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_longDistanceMatching, FUZ_rand(&lseed) & 63, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_enableLongDistanceMatching, FUZ_rand(&lseed) & 63, useOpaqueAPI) );
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
From 423b133568765ad25f73f5e189fb13805b9baf27 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Tue, 5 Sep 2017 11:18:13 -0700
Subject: [PATCH 098/248] [POOL] Allow free on NULL when multithreading is
disabled
---
lib/common/pool.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/common/pool.c b/lib/common/pool.c
index 9567d112f..d7080f034 100644
--- a/lib/common/pool.c
+++ b/lib/common/pool.c
@@ -236,7 +236,7 @@ POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customM
}
void POOL_free(POOL_ctx* ctx) {
- assert(ctx == &g_ctx);
+ assert(!ctx || ctx == &g_ctx);
(void)ctx;
}
From 643d28c7015635a89703a66425634fff796efe81 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 5 Sep 2017 11:05:57 -0700
Subject: [PATCH 099/248] Add ldm options to 'man zstd'
---
lib/zstd.h | 28 +++++++++++++++-------
programs/zstd.1 | 58 +++++++++++++++++++++++++++++++++++++++++++++-
programs/zstd.1.md | 47 +++++++++++++++++++++++++++++++++++++
3 files changed, 123 insertions(+), 10 deletions(-)
diff --git a/lib/zstd.h b/lib/zstd.h
index e7d4fbdf4..4879c4a63 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -979,24 +979,34 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
- ZSTD_p_enableLongDistanceMatching, /* Enable long distance matching. This increases the memory
- * usage as well as window size. Note: setting this
- * parameter resets all the LDM parameters as well as
- * ZSTD_p_windowLog. It should be set after
+ ZSTD_p_enableLongDistanceMatching, /* Enable long distance matching.
+ * This parameter is designed to improve the compression
+ * ratio for large inputs with long distance matches.
+ * This increases the memory usage as well as window size.
+ * Note: setting this parameter sets all the LDM parameters
+ * as well as ZSTD_p_windowLog. It should be set after
* ZSTD_p_compressionLevel and before ZSTD_p_windowLog and
* other LDM parameters. Setting the compression level
* after this parameter overrides the window log, though LDM
* will remain enabled until explicitly disabled. */
- ZSTD_p_ldmHashLog, /* Size of the table for long distance matching.
- * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. */
+ ZSTD_p_ldmHashLog, /* Size of the table for long distance matching, as a power of 2.
+ * Larger values increase memory usage and compression ratio, but decrease
+ * compression speed.
+ * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX
+ * (default: 20). */
ZSTD_p_ldmMinMatch, /* Minimum size of searched matches for long distance matcher.
+ * Larger/too small values usually decrease compression ratio.
* Must be clamped between ZSTD_LDM_SEARCHLENGTH_MIN
- * and ZSTD_LDM_SEARCHLENGTH_MAX. */
- ZSTD_p_ldmBucketSizeLog, /* Log size of each bucket in the hash table for collision resolution.
- * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX. */
+ * and ZSTD_LDM_SEARCHLENGTH_MAX (default: 64). */
+ ZSTD_p_ldmBucketSizeLog, /* Log size of each bucket in the LDM hash table for collision resolution.
+ * Larger values usually improve collision resolution but may decrease
+ * compression speed.
+ * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX (default: 3). */
ZSTD_p_ldmHashEveryLog, /* Frequency of inserting/looking up entries in the LDM hash table.
* The default is MAX(0, (windowLog - ldmHashLog)) to
* optimize hash table usage.
+ * Larger values improve compression speed. Deviating far from the
+ * default value will likely result in a decrease in compression ratio.
* Must be clamped between 0 and ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN. */
} ZSTD_cParameter;
diff --git a/programs/zstd.1 b/programs/zstd.1
index 5a91eea28..13c804ae5 100644
--- a/programs/zstd.1
+++ b/programs/zstd.1
@@ -1,5 +1,5 @@
.
-.TH "ZSTD" "1" "August 2017" "zstd 1.3.1" "User Commands"
+.TH "ZSTD" "1" "September 2017" "zstd 1.3.1" "User Commands"
.
.SH "NAME"
\fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files
@@ -104,6 +104,10 @@ Display information related to a zstd compressed file, such as size, ratio, and
unlocks high compression levels 20+ (maximum 22), using a lot more memory\. Note that decompression will also require more memory when using these levels\.
.
.TP
+\fB\-\-long\fR
+enables long distance matching\. This increases the window size (\fBwindowLog\fR) and memory usage for both the compressor and decompressor\. This setting is designed to improve the compression ratio for files with long matches at a large distance (up to the maximum window size, 128 MiB)\.
+.
+.TP
\fB\-T#\fR, \fB\-\-threads=#\fR
Compress using \fB#\fR threads (default: 1)\. If \fB#\fR is 0, attempt to detect and use the number of physical CPU cores\. In all cases, the nb of threads is capped to ZSTDMT_NBTHREADS_MAX==256\. This modifier does nothing if \fBzstd\fR is compiled without multithread support\.
.
@@ -322,6 +326,58 @@ Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This pa
.IP
The minimum \fIovlog\fR is 0, and the maximum is 9\. 0 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the amount of reload by a factor 2\. Default \fIovlog\fR is 6, which means "reload \fBwindowSize / 8\fR"\. Exception : the maximum compression level (22) has a default \fIovlog\fR of 9\.
.
+.TP
+\fBldmHashLog\fR=\fIldmHlog\fR, \fBldmHlog\fR=\fIldmHlog\fR
+Specify the maximum size for a hash table used for long distance matching\.
+.
+.IP
+This option is ignored unless long distance matching is enabled\.
+.
+.IP
+Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\.
+.
+.IP
+The minimum \fIldmHlog\fR is 6 and the maximum is 26 (default: 20)\.
+.
+.TP
+\fBldmSearchLength\fR=\fIldmSlen\fR, \fBldmSlen\fR=\fIldmSlen\fR
+Specify the minimum searched length of a match for long distance matching\.
+.
+.IP
+This option is ignored unless long distance matching is enabled\.
+.
+.IP
+Larger/very small values usually decrease compression ratio\.
+.
+.IP
+The minumum \fIldmSlen\fR is 4 and the maximum is 4096 (default: 64)\.
+.
+.TP
+\fBldmBucketSizeLog\fR=\fIldmBucketSizeLog\fR
+Specify the size of each bucket for the hash table used for long distance matching\.
+.
+.IP
+This option is ignored unless long distance matching is enabled\.
+.
+.IP
+Larger bucket sizes improve collision resolution but decrease compression speed\.
+.
+.IP
+The minimum \fIldmBucketSizeLog\fR is 0 and the maximum is 8 (default: 3)\.
+.
+.TP
+\fBldmHashEveryLog\fR=\fIldmHashEveryLog\fR
+Specify the frequency of inserting entries into the long distance matching hash table\.
+.
+.IP
+This option is ignored unless long distance matching is enabled\.
+.
+.IP
+Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\.
+.
+.IP
+The default value is \fBwLog \- ldmHlog\fR\.
+.
.SS "\-B#:"
Select the size of each compression job\. This parameter is available only when multi\-threading is enabled\. Default value is \fB4 * windowSize\fR, which means it varies depending on compression level\. \fB\-B#\fR makes it possible to select a custom value\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 1 MB, or \fBoverlapSize\fR, whichever is largest\.
.
diff --git a/programs/zstd.1.md b/programs/zstd.1.md
index 4310afa1a..5f6aa4500 100644
--- a/programs/zstd.1.md
+++ b/programs/zstd.1.md
@@ -105,6 +105,12 @@ the last one takes effect.
* `--ultra`:
unlocks high compression levels 20+ (maximum 22), using a lot more memory.
Note that decompression will also require more memory when using these levels.
+* `--long`:
+ enables long distance matching.
+ This increases the window size (`windowLog`) and memory usage for both the
+ compressor and decompressor. This setting is designed to improve the
+ compression ratio for files with long matches at a large distance
+ (up to the maximum window size, 128 MiB).
* `-T#`, `--threads=#`:
Compress using `#` threads (default: 1).
If `#` is 0, attempt to detect and use the number of physical CPU cores.
@@ -327,6 +333,47 @@ The list of available _options_:
Default _ovlog_ is 6, which means "reload `windowSize / 8`".
Exception : the maximum compression level (22) has a default _ovlog_ of 9.
+- `ldmHashLog`=_ldmHlog_, `ldmHlog`=_ldmHlog_:
+ Specify the maximum size for a hash table used for long distance matching.
+
+ This option is ignored unless long distance matching is enabled.
+
+ Bigger hash tables usually improve compression ratio at the expense of more
+ memory during compression and a decrease in compression speed.
+
+ The minimum _ldmHlog_ is 6 and the maximum is 26 (default: 20).
+
+- `ldmSearchLength`=_ldmSlen_, `ldmSlen`=_ldmSlen_:
+ Specify the minimum searched length of a match for long distance matching.
+
+ This option is ignored unless long distance matching is enabled.
+
+ Larger/very small values usually decrease compression ratio.
+
+ The minumum _ldmSlen_ is 4 and the maximum is 4096 (default: 64).
+
+- `ldmBucketSizeLog`=_ldmBucketSizeLog_:
+ Specify the size of each bucket for the hash table used for long distance
+ matching.
+
+ This option is ignored unless long distance matching is enabled.
+
+ Larger bucket sizes improve collision resolution but decrease compression
+ speed.
+
+ The minimum _ldmBucketSizeLog_ is 0 and the maximum is 8 (default: 3).
+
+- `ldmHashEveryLog`=_ldmHashEveryLog_:
+ Specify the frequency of inserting entries into the long distance matching
+ hash table.
+
+ This option is ignored unless long distance matching is enabled.
+
+ Larger values will improve compression speed. Deviating far from the
+ default value will likely result in a decrease in compression ratio.
+
+ The default value is `wLog - ldmHlog`.
+
### -B#:
Select the size of each compression job.
This parameter is available only when multi-threading is enabled.
From fd0071da29bad93bcd3526fed2ed9cdf9f46bced Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 5 Sep 2017 15:34:17 -0700
Subject: [PATCH 100/248] Fix parameter handling with ZSTD_copyCCtx
---
lib/compress/zstd_compress.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index d048706c0..978be3c8d 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -918,6 +918,8 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
/*! ZSTD_copyCCtx_internal() :
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
+ * The "context", in this case, refers to the hash and chain tables, entropy
+ * tables, and dictionary offsets.
* Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
* pledgedSrcSize=0 means "empty" if fParams.contentSizeFlag=1
* @return : 0, or an error code */
@@ -931,7 +933,9 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
- { ZSTD_CCtx_params params = srcCCtx->appliedParams;
+ { ZSTD_CCtx_params params = dstCCtx->requestedParams;
+ /* Copy only compression parameters related to tables. */
+ params.cParams = srcCCtx->appliedParams.cParams;
params.fParams = fParams;
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
ZSTDcrp_noMemset, zbuff);
From 08d33fe1c91cb2f6a4f8316c2df3731e904df2c4 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 5 Sep 2017 15:50:14 -0700
Subject: [PATCH 101/248] Fix parameter handling in copyCCtx with cdict
---
lib/compress/zstd_compress.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index d4d3ae961..7863fae0a 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -1094,7 +1094,8 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
- { ZSTD_CCtx_params params = srcCCtx->appliedParams;
+ { ZSTD_CCtx_params params = dstCCtx->requestedParams;
+ params.cParams = srcCCtx->appliedParams.cParams;
params.fParams = fParams;
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
ZSTDcrp_noMemset, zbuff);
From 721726d688a106e2ff13747a789843c74ea3a4e1 Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Fri, 1 Sep 2017 18:28:35 -0700
Subject: [PATCH 102/248] Split parsers out of zstd_compress.c
---
lib/compress/zstd_compress.c | 1609 +------------------------------
lib/compress/zstd_compress.h | 301 ++++++
lib/compress/zstd_double_fast.c | 313 ++++++
lib/compress/zstd_double_fast.h | 27 +
lib/compress/zstd_fast.c | 247 +++++
lib/compress/zstd_fast.h | 29 +
lib/compress/zstd_lazy.c | 752 +++++++++++++++
lib/compress/zstd_lazy.h | 37 +
lib/compress/zstd_opt.c | 954 ++++++++++++++++++
lib/compress/zstd_opt.h | 937 +-----------------
10 files changed, 2679 insertions(+), 2527 deletions(-)
create mode 100644 lib/compress/zstd_compress.h
create mode 100644 lib/compress/zstd_double_fast.c
create mode 100644 lib/compress/zstd_double_fast.h
create mode 100644 lib/compress/zstd_fast.c
create mode 100644 lib/compress/zstd_fast.h
create mode 100644 lib/compress/zstd_lazy.c
create mode 100644 lib/compress/zstd_lazy.h
create mode 100644 lib/compress/zstd_opt.c
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index d048706c0..de5985828 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -25,17 +25,13 @@
#include "fse.h"
#define HUF_STATIC_LINKING_ONLY
#include "huf.h"
-#include "zstd_internal.h" /* includes zstd.h */
-#include "zstdmt_compress.h"
+#include "zstd_compress.h"
+#include "zstd_fast.h"
+#include "zstd_double_fast.h"
+#include "zstd_lazy.h"
+#include "zstd_opt.h"
-/*-*************************************
-* Constants
-***************************************/
-static const U32 g_searchStrength = 8; /* control skip over incompressible data */
-#define HASH_READ_SIZE 8
-typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
-
/*-*************************************
* Helper functions
@@ -61,8 +57,6 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
/*-*************************************
* Context memory management
***************************************/
-typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage;
-
struct ZSTD_CDict_s {
void* dictBuffer;
const void* dictContent;
@@ -70,64 +64,6 @@ struct ZSTD_CDict_s {
ZSTD_CCtx* refContext;
}; /* typedef'd to ZSTD_CDict within "zstd.h" */
-typedef struct ZSTD_prefixDict_s {
- const void* dict;
- size_t dictSize;
- ZSTD_dictMode_e dictMode;
-} ZSTD_prefixDict;
-
-struct ZSTD_CCtx_s {
- const BYTE* nextSrc; /* next block here to continue on current prefix */
- const BYTE* base; /* All regular indexes relative to this position */
- const BYTE* dictBase; /* extDict indexes relative to this position */
- U32 dictLimit; /* below that point, need extDict */
- U32 lowLimit; /* below that point, no more data */
- U32 nextToUpdate; /* index from which to continue dictionary update */
- U32 nextToUpdate3; /* index from which to continue dictionary update */
- U32 hashLog3; /* dispatch table : larger == faster, more memory */
- U32 loadedDictEnd; /* index of end of dictionary */
- ZSTD_compressionStage_e stage;
- U32 dictID;
- ZSTD_CCtx_params requestedParams;
- ZSTD_CCtx_params appliedParams;
- void* workSpace;
- size_t workSpaceSize;
- size_t blockSize;
- U64 pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */
- U64 consumedSrcSize;
- XXH64_state_t xxhState;
- ZSTD_customMem customMem;
- size_t staticSize;
-
- seqStore_t seqStore; /* sequences storage ptrs */
- optState_t optState;
- U32* hashTable;
- U32* hashTable3;
- U32* chainTable;
- ZSTD_entropyCTables_t* entropy;
-
- /* streaming */
- char* inBuff;
- size_t inBuffSize;
- size_t inToCompress;
- size_t inBuffPos;
- size_t inBuffTarget;
- char* outBuff;
- size_t outBuffSize;
- size_t outBuffContentSize;
- size_t outBuffFlushedSize;
- ZSTD_cStreamStage streamStage;
- U32 frameEnded;
-
- /* Dictionary */
- ZSTD_CDict* cdictLocal;
- const ZSTD_CDict* cdict;
- ZSTD_prefixDict prefixDict; /* single-usage dictionary */
-
- /* Multi-threading */
- ZSTDMT_CCtx* mtctx;
-};
-
ZSTD_CCtx* ZSTD_createCCtx(void)
{
@@ -1141,24 +1077,6 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t * entropy,
return lhSize+cLitSize;
}
-static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 16, 17, 17, 18, 18, 19, 19,
- 20, 20, 20, 20, 21, 21, 21, 21,
- 22, 22, 22, 22, 22, 22, 22, 22,
- 23, 23, 23, 23, 23, 23, 23, 23,
- 24, 24, 24, 24, 24, 24, 24, 24,
- 24, 24, 24, 24, 24, 24, 24, 24 };
-
-static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
- 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
-
void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
{
@@ -1445,1523 +1363,6 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
}
-/*! ZSTD_storeSeq() :
- Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
- `offsetCode` : distance to match, or 0 == repCode.
- `matchCode` : matchLength - MINMATCH
-*/
-MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
-{
-#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG >= 6)
- static const BYTE* g_start = NULL;
- U32 const pos = (U32)((const BYTE*)literals - g_start);
- if (g_start==NULL) g_start = (const BYTE*)literals;
- if ((pos > 0) && (pos < 1000000000))
- DEBUGLOG(6, "Cpos %6u :%5u literals & match %3u bytes at distance %6u",
- pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
-#endif
- /* copy Literals */
- assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + 128 KB);
- ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
- seqStorePtr->lit += litLength;
-
- /* literal Length */
- if (litLength>0xFFFF) {
- seqStorePtr->longLengthID = 1;
- seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
- }
- seqStorePtr->sequences[0].litLength = (U16)litLength;
-
- /* match offset */
- seqStorePtr->sequences[0].offset = offsetCode + 1;
-
- /* match Length */
- if (matchCode>0xFFFF) {
- seqStorePtr->longLengthID = 2;
- seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
- }
- seqStorePtr->sequences[0].matchLength = (U16)matchCode;
-
- seqStorePtr->sequences++;
-}
-
-
-/*-*************************************
-* Match length counter
-***************************************/
-static unsigned ZSTD_NbCommonBytes (register size_t val)
-{
- if (MEM_isLittleEndian()) {
- if (MEM_64bits()) {
-# if defined(_MSC_VER) && defined(_WIN64)
- unsigned long r = 0;
- _BitScanForward64( &r, (U64)val );
- return (unsigned)(r>>3);
-# elif defined(__GNUC__) && (__GNUC__ >= 3)
- return (__builtin_ctzll((U64)val) >> 3);
-# else
- static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
- 0, 3, 1, 3, 1, 4, 2, 7,
- 0, 2, 3, 6, 1, 5, 3, 5,
- 1, 3, 4, 4, 2, 5, 6, 7,
- 7, 0, 1, 2, 3, 3, 4, 6,
- 2, 6, 5, 5, 3, 4, 5, 6,
- 7, 1, 2, 4, 6, 4, 4, 5,
- 7, 2, 6, 5, 7, 6, 7, 7 };
- return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
-# endif
- } else { /* 32 bits */
-# if defined(_MSC_VER)
- unsigned long r=0;
- _BitScanForward( &r, (U32)val );
- return (unsigned)(r>>3);
-# elif defined(__GNUC__) && (__GNUC__ >= 3)
- return (__builtin_ctz((U32)val) >> 3);
-# else
- static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
- 3, 2, 2, 1, 3, 2, 0, 1,
- 3, 3, 1, 2, 2, 2, 2, 0,
- 3, 1, 2, 0, 1, 0, 1, 1 };
- return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
-# endif
- }
- } else { /* Big Endian CPU */
- if (MEM_64bits()) {
-# if defined(_MSC_VER) && defined(_WIN64)
- unsigned long r = 0;
- _BitScanReverse64( &r, val );
- return (unsigned)(r>>3);
-# elif defined(__GNUC__) && (__GNUC__ >= 3)
- return (__builtin_clzll(val) >> 3);
-# else
- unsigned r;
- const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */
- if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
- if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
- r += (!val);
- return r;
-# endif
- } else { /* 32 bits */
-# if defined(_MSC_VER)
- unsigned long r = 0;
- _BitScanReverse( &r, (unsigned long)val );
- return (unsigned)(r>>3);
-# elif defined(__GNUC__) && (__GNUC__ >= 3)
- return (__builtin_clz((U32)val) >> 3);
-# else
- unsigned r;
- if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
- r += (!val);
- return r;
-# endif
- } }
-}
-
-
-static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
-{
- const BYTE* const pStart = pIn;
- const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
-
- while (pIn < pInLoopLimit) {
- size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
- if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
- pIn += ZSTD_NbCommonBytes(diff);
- return (size_t)(pIn - pStart);
- }
- if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
- if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
- if ((pIn> (32-h) ; }
-MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
-
-static const U32 prime4bytes = 2654435761U;
-static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
-static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
-
-static const U64 prime5bytes = 889523592379ULL;
-static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; }
-static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
-
-static const U64 prime6bytes = 227718039650203ULL;
-static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; }
-static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
-
-static const U64 prime7bytes = 58295818150454627ULL;
-static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; }
-static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
-
-static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
-static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
-static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
-
-static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
-{
- switch(mls)
- {
- default:
- case 4: return ZSTD_hash4Ptr(p, hBits);
- case 5: return ZSTD_hash5Ptr(p, hBits);
- case 6: return ZSTD_hash6Ptr(p, hBits);
- case 7: return ZSTD_hash7Ptr(p, hBits);
- case 8: return ZSTD_hash8Ptr(p, hBits);
- }
-}
-
-
-/*-*************************************
-* Fast Scan
-***************************************/
-static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
-{
- U32* const hashTable = zc->hashTable;
- U32 const hBits = zc->appliedParams.cParams.hashLog;
- const BYTE* const base = zc->base;
- const BYTE* ip = base + zc->nextToUpdate;
- const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
- const size_t fastHashFillStep = 3;
-
- while(ip <= iend) {
- hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
- ip += fastHashFillStep;
- }
-}
-
-
-FORCE_INLINE_TEMPLATE
-void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
- const void* src, size_t srcSize,
- const U32 mls)
-{
- U32* const hashTable = cctx->hashTable;
- U32 const hBits = cctx->appliedParams.cParams.hashLog;
- seqStore_t* seqStorePtr = &(cctx->seqStore);
- const BYTE* const base = cctx->base;
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const U32 lowestIndex = cctx->dictLimit;
- const BYTE* const lowest = base + lowestIndex;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - HASH_READ_SIZE;
- U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
- U32 offsetSaved = 0;
-
- /* init */
- ip += (ip==lowest);
- { U32 const maxRep = (U32)(ip-lowest);
- if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
- if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
- }
-
- /* Main Search Loop */
- while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
- size_t mLength;
- size_t const h = ZSTD_hashPtr(ip, hBits, mls);
- U32 const current = (U32)(ip-base);
- U32 const matchIndex = hashTable[h];
- const BYTE* match = base + matchIndex;
- hashTable[h] = current; /* update hash table */
-
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
- mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
- ip++;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
- } else {
- U32 offset;
- if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
- ip += ((ip-anchor) >> g_searchStrength) + 1;
- continue;
- }
- mLength = ZSTD_count(ip+4, match+4, iend) + 4;
- offset = (U32)(ip-match);
- while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
- offset_2 = offset_1;
- offset_1 = offset;
-
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
- }
-
- /* match found */
- ip += mLength;
- anchor = ip;
-
- if (ip <= ilimit) {
- /* Fill Table */
- hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
- hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
- /* check immediate repcode */
- while ( (ip <= ilimit)
- && ( (offset_2>0)
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
- /* store sequence */
- size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
- hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
- ip += rLength;
- anchor = ip;
- continue; /* faster when present ... (?) */
- } } }
-
- /* save reps for next block */
- seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
- seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize)
-{
- const U32 mls = ctx->appliedParams.cParams.searchLength;
- switch(mls)
- {
- default: /* includes case 3 */
- case 4 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
- case 5 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
- case 6 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
- case 7 :
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
- }
-}
-
-
-static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize,
- const U32 mls)
-{
- U32* hashTable = ctx->hashTable;
- const U32 hBits = ctx->appliedParams.cParams.hashLog;
- seqStore_t* seqStorePtr = &(ctx->seqStore);
- const BYTE* const base = ctx->base;
- const BYTE* const dictBase = ctx->dictBase;
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const U32 lowestIndex = ctx->lowLimit;
- const BYTE* const dictStart = dictBase + lowestIndex;
- const U32 dictLimit = ctx->dictLimit;
- const BYTE* const lowPrefixPtr = base + dictLimit;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - 8;
- U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
-
- /* Search Loop */
- while (ip < ilimit) { /* < instead of <=, because (ip+1) */
- const size_t h = ZSTD_hashPtr(ip, hBits, mls);
- const U32 matchIndex = hashTable[h];
- const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
- const BYTE* match = matchBase + matchIndex;
- const U32 current = (U32)(ip-base);
- const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
- const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
- const BYTE* repMatch = repBase + repIndex;
- size_t mLength;
- hashTable[h] = current; /* update hash table */
-
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
- && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
- const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
- mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
- ip++;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
- } else {
- if ( (matchIndex < lowestIndex) ||
- (MEM_read32(match) != MEM_read32(ip)) ) {
- ip += ((ip-anchor) >> g_searchStrength) + 1;
- continue;
- }
- { const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
- const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
- U32 offset;
- mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
- while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
- offset = current - matchIndex;
- offset_2 = offset_1;
- offset_1 = offset;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
- } }
-
- /* found a match : store it */
- ip += mLength;
- anchor = ip;
-
- if (ip <= ilimit) {
- /* Fill Table */
- hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
- hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
- /* check immediate repcode */
- while (ip <= ilimit) {
- U32 const current2 = (U32)(ip-base);
- U32 const repIndex2 = current2 - offset_2;
- const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
- if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
- && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
- const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
- size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
- hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
- ip += repLength2;
- anchor = ip;
- continue;
- }
- break;
- } } }
-
- /* save reps for next block */
- seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize)
-{
- U32 const mls = ctx->appliedParams.cParams.searchLength;
- switch(mls)
- {
- default: /* includes case 3 */
- case 4 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
- case 5 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
- case 6 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
- case 7 :
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
- }
-}
-
-
-/*-*************************************
-* Double Fast
-***************************************/
-static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
-{
- U32* const hashLarge = cctx->hashTable;
- U32 const hBitsL = cctx->appliedParams.cParams.hashLog;
- U32* const hashSmall = cctx->chainTable;
- U32 const hBitsS = cctx->appliedParams.cParams.chainLog;
- const BYTE* const base = cctx->base;
- const BYTE* ip = base + cctx->nextToUpdate;
- const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
- const size_t fastHashFillStep = 3;
-
- while(ip <= iend) {
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
- hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
- ip += fastHashFillStep;
- }
-}
-
-
-FORCE_INLINE_TEMPLATE
-void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
- const void* src, size_t srcSize,
- const U32 mls)
-{
- U32* const hashLong = cctx->hashTable;
- const U32 hBitsL = cctx->appliedParams.cParams.hashLog;
- U32* const hashSmall = cctx->chainTable;
- const U32 hBitsS = cctx->appliedParams.cParams.chainLog;
- seqStore_t* seqStorePtr = &(cctx->seqStore);
- const BYTE* const base = cctx->base;
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const U32 lowestIndex = cctx->dictLimit;
- const BYTE* const lowest = base + lowestIndex;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - HASH_READ_SIZE;
- U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
- U32 offsetSaved = 0;
-
- /* init */
- ip += (ip==lowest);
- { U32 const maxRep = (U32)(ip-lowest);
- if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
- if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
- }
-
- /* Main Search Loop */
- while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
- size_t mLength;
- size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
- size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
- U32 const current = (U32)(ip-base);
- U32 const matchIndexL = hashLong[h2];
- U32 const matchIndexS = hashSmall[h];
- const BYTE* matchLong = base + matchIndexL;
- const BYTE* match = base + matchIndexS;
- hashLong[h2] = hashSmall[h] = current; /* update hash tables */
-
- assert(offset_1 <= current); /* supposed guaranteed by construction */
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
- /* favor repcode */
- mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
- ip++;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
- } else {
- U32 offset;
- if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
- mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
- offset = (U32)(ip-matchLong);
- while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
- } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
- size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
- U32 const matchIndexL3 = hashLong[hl3];
- const BYTE* matchL3 = base + matchIndexL3;
- hashLong[hl3] = current + 1;
- if ( (matchIndexL3 > lowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) {
- mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
- ip++;
- offset = (U32)(ip-matchL3);
- while (((ip>anchor) & (matchL3>lowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
- } else {
- mLength = ZSTD_count(ip+4, match+4, iend) + 4;
- offset = (U32)(ip-match);
- while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
- }
- } else {
- ip += ((ip-anchor) >> g_searchStrength) + 1;
- continue;
- }
-
- offset_2 = offset_1;
- offset_1 = offset;
-
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
- }
-
- /* match found */
- ip += mLength;
- anchor = ip;
-
- if (ip <= ilimit) {
- /* Fill Table */
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2; /* here because current+2 could be > iend-8 */
- hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
- hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
-
- /* check immediate repcode */
- while ( (ip <= ilimit)
- && ( (offset_2>0)
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
- /* store sequence */
- size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
- ip += rLength;
- anchor = ip;
- continue; /* faster when present ... (?) */
- } } }
-
- /* save reps for next block */
- seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
- seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- const U32 mls = ctx->appliedParams.cParams.searchLength;
- switch(mls)
- {
- default: /* includes case 3 */
- case 4 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
- case 5 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
- case 6 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
- case 7 :
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
- }
-}
-
-
-static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize,
- const U32 mls)
-{
- U32* const hashLong = ctx->hashTable;
- U32 const hBitsL = ctx->appliedParams.cParams.hashLog;
- U32* const hashSmall = ctx->chainTable;
- U32 const hBitsS = ctx->appliedParams.cParams.chainLog;
- seqStore_t* seqStorePtr = &(ctx->seqStore);
- const BYTE* const base = ctx->base;
- const BYTE* const dictBase = ctx->dictBase;
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const U32 lowestIndex = ctx->lowLimit;
- const BYTE* const dictStart = dictBase + lowestIndex;
- const U32 dictLimit = ctx->dictLimit;
- const BYTE* const lowPrefixPtr = base + dictLimit;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - 8;
- U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
-
- /* Search Loop */
- while (ip < ilimit) { /* < instead of <=, because (ip+1) */
- const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
- const U32 matchIndex = hashSmall[hSmall];
- const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
- const BYTE* match = matchBase + matchIndex;
-
- const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
- const U32 matchLongIndex = hashLong[hLong];
- const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
- const BYTE* matchLong = matchLongBase + matchLongIndex;
-
- const U32 current = (U32)(ip-base);
- const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
- const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
- const BYTE* repMatch = repBase + repIndex;
- size_t mLength;
- hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
-
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
- && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
- const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
- mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
- ip++;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
- } else {
- if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
- const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
- const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
- U32 offset;
- mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
- offset = current - matchLongIndex;
- while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
- offset_2 = offset_1;
- offset_1 = offset;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
-
- } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
- size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
- U32 const matchIndex3 = hashLong[h3];
- const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
- const BYTE* match3 = match3Base + matchIndex3;
- U32 offset;
- hashLong[h3] = current + 1;
- if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
- const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
- const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
- mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
- ip++;
- offset = current+1 - matchIndex3;
- while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
- } else {
- const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
- const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
- mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
- offset = current - matchIndex;
- while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
- }
- offset_2 = offset_1;
- offset_1 = offset;
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
-
- } else {
- ip += ((ip-anchor) >> g_searchStrength) + 1;
- continue;
- } }
-
- /* found a match : store it */
- ip += mLength;
- anchor = ip;
-
- if (ip <= ilimit) {
- /* Fill Table */
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
- hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
- hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
- /* check immediate repcode */
- while (ip <= ilimit) {
- U32 const current2 = (U32)(ip-base);
- U32 const repIndex2 = current2 - offset_2;
- const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
- if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
- && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
- const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
- size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
- ip += repLength2;
- anchor = ip;
- continue;
- }
- break;
- } } }
-
- /* save reps for next block */
- seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize)
-{
- U32 const mls = ctx->appliedParams.cParams.searchLength;
- switch(mls)
- {
- default: /* includes case 3 */
- case 4 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
- case 5 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
- case 6 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
- case 7 :
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
- }
-}
-
-
-/*-*************************************
-* Binary Tree search
-***************************************/
-/** ZSTD_insertBt1() : add one or multiple positions to tree.
-* ip : assumed <= iend-8 .
-* @return : nb of positions added */
-static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
- U32 extDict)
-{
- U32* const hashTable = zc->hashTable;
- U32 const hashLog = zc->appliedParams.cParams.hashLog;
- size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
- U32* const bt = zc->chainTable;
- U32 const btLog = zc->appliedParams.cParams.chainLog - 1;
- U32 const btMask = (1 << btLog) - 1;
- U32 matchIndex = hashTable[h];
- size_t commonLengthSmaller=0, commonLengthLarger=0;
- const BYTE* const base = zc->base;
- const BYTE* const dictBase = zc->dictBase;
- const U32 dictLimit = zc->dictLimit;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const prefixStart = base + dictLimit;
- const BYTE* match;
- const U32 current = (U32)(ip-base);
- const U32 btLow = btMask >= current ? 0 : current - btMask;
- U32* smallerPtr = bt + 2*(current&btMask);
- U32* largerPtr = smallerPtr + 1;
- U32 dummy32; /* to be nullified at the end */
- U32 const windowLow = zc->lowLimit;
- U32 matchEndIdx = current+8;
- size_t bestLength = 8;
-#ifdef ZSTD_C_PREDICT
- U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
- U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
- predictedSmall += (predictedSmall>0);
- predictedLarge += (predictedLarge>0);
-#endif /* ZSTD_C_PREDICT */
-
- hashTable[h] = current; /* Update Hash Table */
-
- while (nbCompares-- && (matchIndex > windowLow)) {
- U32* const nextPtr = bt + 2*(matchIndex & btMask);
- size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
-
-#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
- const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
- if (matchIndex == predictedSmall) {
- /* no need to check length, result known */
- *smallerPtr = matchIndex;
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
- predictedSmall = predictPtr[1] + (predictPtr[1]>0);
- continue;
- }
- if (matchIndex == predictedLarge) {
- *largerPtr = matchIndex;
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- largerPtr = nextPtr;
- matchIndex = nextPtr[0];
- predictedLarge = predictPtr[0] + (predictPtr[0]>0);
- continue;
- }
-#endif
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
- match = base + matchIndex;
- if (match[matchLength] == ip[matchLength])
- matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
- } else {
- match = dictBase + matchIndex;
- matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
- if (matchIndex+matchLength >= dictLimit)
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
- }
-
- if (matchLength > bestLength) {
- bestLength = matchLength;
- if (matchLength > matchEndIdx - matchIndex)
- matchEndIdx = matchIndex + (U32)matchLength;
- }
-
- if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
- break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
-
- if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */
- /* match is smaller than current */
- *smallerPtr = matchIndex; /* update smaller idx */
- commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
- } else {
- /* match is larger than current */
- *largerPtr = matchIndex;
- commonLengthLarger = matchLength;
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- largerPtr = nextPtr;
- matchIndex = nextPtr[0];
- } }
-
- *smallerPtr = *largerPtr = 0;
- if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
- if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
- return 1;
-}
-
-
-static size_t ZSTD_insertBtAndFindBestMatch (
- ZSTD_CCtx* zc,
- const BYTE* const ip, const BYTE* const iend,
- size_t* offsetPtr,
- U32 nbCompares, const U32 mls,
- U32 extDict)
-{
- U32* const hashTable = zc->hashTable;
- U32 const hashLog = zc->appliedParams.cParams.hashLog;
- size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
- U32* const bt = zc->chainTable;
- U32 const btLog = zc->appliedParams.cParams.chainLog - 1;
- U32 const btMask = (1 << btLog) - 1;
- U32 matchIndex = hashTable[h];
- size_t commonLengthSmaller=0, commonLengthLarger=0;
- const BYTE* const base = zc->base;
- const BYTE* const dictBase = zc->dictBase;
- const U32 dictLimit = zc->dictLimit;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const prefixStart = base + dictLimit;
- const U32 current = (U32)(ip-base);
- const U32 btLow = btMask >= current ? 0 : current - btMask;
- const U32 windowLow = zc->lowLimit;
- U32* smallerPtr = bt + 2*(current&btMask);
- U32* largerPtr = bt + 2*(current&btMask) + 1;
- U32 matchEndIdx = current+8;
- U32 dummy32; /* to be nullified at the end */
- size_t bestLength = 0;
-
- hashTable[h] = current; /* Update Hash Table */
-
- while (nbCompares-- && (matchIndex > windowLow)) {
- U32* const nextPtr = bt + 2*(matchIndex & btMask);
- size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
- const BYTE* match;
-
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
- match = base + matchIndex;
- if (match[matchLength] == ip[matchLength])
- matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
- } else {
- match = dictBase + matchIndex;
- matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
- if (matchIndex+matchLength >= dictLimit)
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
- }
-
- if (matchLength > bestLength) {
- if (matchLength > matchEndIdx - matchIndex)
- matchEndIdx = matchIndex + (U32)matchLength;
- if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
- bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
- if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
- break; /* drop, to guarantee consistency (miss a little bit of compression) */
- }
-
- if (match[matchLength] < ip[matchLength]) {
- /* match is smaller than current */
- *smallerPtr = matchIndex; /* update smaller idx */
- commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
- } else {
- /* match is larger than current */
- *largerPtr = matchIndex;
- commonLengthLarger = matchLength;
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- largerPtr = nextPtr;
- matchIndex = nextPtr[0];
- } }
-
- *smallerPtr = *largerPtr = 0;
-
- zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
- return bestLength;
-}
-
-
-static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
-{
- const BYTE* const base = zc->base;
- const U32 target = (U32)(ip - base);
- U32 idx = zc->nextToUpdate;
-
- while(idx < target)
- idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
-}
-
-/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
-static size_t ZSTD_BtFindBestMatch (
- ZSTD_CCtx* zc,
- const BYTE* const ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 mls)
-{
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
- ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
- return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
-}
-
-
-static size_t ZSTD_BtFindBestMatch_selectMLS (
- ZSTD_CCtx* zc, /* Index table will be updated */
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 matchLengthSearch)
-{
- switch(matchLengthSearch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
- case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
- case 7 :
- case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
- }
-}
-
-
-static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
-{
- const BYTE* const base = zc->base;
- const U32 target = (U32)(ip - base);
- U32 idx = zc->nextToUpdate;
-
- while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
-}
-
-
-/** Tree updater, providing best match */
-static size_t ZSTD_BtFindBestMatch_extDict (
- ZSTD_CCtx* zc,
- const BYTE* const ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 mls)
-{
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
- ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
- return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
-}
-
-
-static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
- ZSTD_CCtx* zc, /* Index table will be updated */
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 matchLengthSearch)
-{
- switch(matchLengthSearch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
- case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
- case 7 :
- case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
- }
-}
-
-
-
-/* *********************************
-* Hash Chain
-***********************************/
-#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
-
-/* Update chains up to ip (excluded)
- Assumption : always within prefix (i.e. not within extDict) */
-FORCE_INLINE_TEMPLATE
-U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
-{
- U32* const hashTable = zc->hashTable;
- const U32 hashLog = zc->appliedParams.cParams.hashLog;
- U32* const chainTable = zc->chainTable;
- const U32 chainMask = (1 << zc->appliedParams.cParams.chainLog) - 1;
- const BYTE* const base = zc->base;
- const U32 target = (U32)(ip - base);
- U32 idx = zc->nextToUpdate;
-
- while(idx < target) { /* catch up */
- size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
- NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
- hashTable[h] = idx;
- idx++;
- }
-
- zc->nextToUpdate = target;
- return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
-}
-
-
-/* inlining is important to hardwire a hot branch (template emulation) */
-FORCE_INLINE_TEMPLATE
-size_t ZSTD_HcFindBestMatch_generic (
- ZSTD_CCtx* zc, /* Index table will be updated */
- const BYTE* const ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 mls, const U32 extDict)
-{
- U32* const chainTable = zc->chainTable;
- const U32 chainSize = (1 << zc->appliedParams.cParams.chainLog);
- const U32 chainMask = chainSize-1;
- const BYTE* const base = zc->base;
- const BYTE* const dictBase = zc->dictBase;
- const U32 dictLimit = zc->dictLimit;
- const BYTE* const prefixStart = base + dictLimit;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const U32 lowLimit = zc->lowLimit;
- const U32 current = (U32)(ip-base);
- const U32 minChain = current > chainSize ? current - chainSize : 0;
- int nbAttempts=maxNbAttempts;
- size_t ml=4-1;
-
- /* HC4 match finder */
- U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
-
- for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
- const BYTE* match;
- size_t currentMl=0;
- if ((!extDict) || matchIndex >= dictLimit) {
- match = base + matchIndex;
- if (match[ml] == ip[ml]) /* potentially better */
- currentMl = ZSTD_count(ip, match, iLimit);
- } else {
- match = dictBase + matchIndex;
- if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
- currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
- }
-
- /* save best solution */
- if (currentMl > ml) {
- ml = currentMl;
- *offsetPtr = current - matchIndex + ZSTD_REP_MOVE;
- if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
- }
-
- if (matchIndex <= minChain) break;
- matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
- }
-
- return ml;
-}
-
-
-FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
- ZSTD_CCtx* zc,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 matchLengthSearch)
-{
- switch(matchLengthSearch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
- case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
- case 7 :
- case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
- }
-}
-
-
-FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
- ZSTD_CCtx* zc,
- const BYTE* ip, const BYTE* const iLimit,
- size_t* offsetPtr,
- const U32 maxNbAttempts, const U32 matchLengthSearch)
-{
- switch(matchLengthSearch)
- {
- default : /* includes case 3 */
- case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
- case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
- case 7 :
- case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
- }
-}
-
-
-/* *******************************
-* Common parser - lazy strategy
-*********************************/
-FORCE_INLINE_TEMPLATE
-void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize,
- const U32 searchMethod, const U32 depth)
-{
- seqStore_t* seqStorePtr = &(ctx->seqStore);
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - 8;
- const BYTE* const base = ctx->base + ctx->dictLimit;
-
- U32 const maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
- U32 const mls = ctx->appliedParams.cParams.searchLength;
-
- typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
- size_t* offsetPtr,
- U32 maxNbAttempts, U32 matchLengthSearch);
- searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
- U32 offset_1 = seqStorePtr->rep[0], offset_2 = seqStorePtr->rep[1], savedOffset=0;
-
- /* init */
- ip += (ip==base);
- ctx->nextToUpdate3 = ctx->nextToUpdate;
- { U32 const maxRep = (U32)(ip-base);
- if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
- if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
- }
-
- /* Match Loop */
- while (ip < ilimit) {
- size_t matchLength=0;
- size_t offset=0;
- const BYTE* start=ip+1;
-
- /* check repCode */
- if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
- /* repcode : we take it */
- matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
- if (depth==0) goto _storeSequence;
- }
-
- /* first search (depth 0) */
- { size_t offsetFound = 99999999;
- size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
- if (ml2 > matchLength)
- matchLength = ml2, start = ip, offset=offsetFound;
- }
-
- if (matchLength < 4) {
- ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
- continue;
- }
-
- /* let's try to find a better solution */
- if (depth>=1)
- while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
- size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
- int const gain2 = (int)(mlRep * 3);
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
- if ((mlRep >= 4) && (gain2 > gain1))
- matchLength = mlRep, offset = 0, start = ip;
- }
- { size_t offset2=99999999;
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
- if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
- continue; /* search a better one */
- } }
-
- /* let's find an even better one */
- if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
- size_t const ml2 = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
- int const gain2 = (int)(ml2 * 4);
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
- if ((ml2 >= 4) && (gain2 > gain1))
- matchLength = ml2, offset = 0, start = ip;
- }
- { size_t offset2=99999999;
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
- if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
- continue;
- } } }
- break; /* nothing found : store previous solution */
- }
-
- /* NOTE:
- * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
- * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
- * overflows the pointer, which is undefined behavior.
- */
- /* catch up */
- if (offset) {
- while ( (start > anchor)
- && (start > base+offset-ZSTD_REP_MOVE)
- && (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1]) ) /* only search for offset within prefix */
- { start--; matchLength++; }
- offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
- }
- /* store sequence */
-_storeSequence:
- { size_t const litLength = start - anchor;
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
- anchor = ip = start + matchLength;
- }
-
- /* check immediate repcode */
- while ( (ip <= ilimit)
- && ((offset_2>0)
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
- /* store sequence */
- matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
- ip += matchLength;
- anchor = ip;
- continue; /* faster when present ... (?) */
- } }
-
- /* Save reps for next block */
- seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
- seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
-}
-
-static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
-}
-
-static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
-}
-
-static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
-}
-
-
-FORCE_INLINE_TEMPLATE
-void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize,
- const U32 searchMethod, const U32 depth)
-{
- seqStore_t* seqStorePtr = &(ctx->seqStore);
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - 8;
- const BYTE* const base = ctx->base;
- const U32 dictLimit = ctx->dictLimit;
- const U32 lowestIndex = ctx->lowLimit;
- const BYTE* const prefixStart = base + dictLimit;
- const BYTE* const dictBase = ctx->dictBase;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const dictStart = dictBase + ctx->lowLimit;
-
- const U32 maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
- const U32 mls = ctx->appliedParams.cParams.searchLength;
-
- typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
- size_t* offsetPtr,
- U32 maxNbAttempts, U32 matchLengthSearch);
- searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
-
- U32 offset_1 = seqStorePtr->rep[0], offset_2 = seqStorePtr->rep[1];
-
- /* init */
- ctx->nextToUpdate3 = ctx->nextToUpdate;
- ip += (ip == prefixStart);
-
- /* Match Loop */
- while (ip < ilimit) {
- size_t matchLength=0;
- size_t offset=0;
- const BYTE* start=ip+1;
- U32 current = (U32)(ip-base);
-
- /* check repCode */
- { const U32 repIndex = (U32)(current+1 - offset_1);
- const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
- const BYTE* const repMatch = repBase + repIndex;
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
- if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
- /* repcode detected we should take it */
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
- matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4;
- if (depth==0) goto _storeSequence;
- } }
-
- /* first search (depth 0) */
- { size_t offsetFound = 99999999;
- size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
- if (ml2 > matchLength)
- matchLength = ml2, start = ip, offset=offsetFound;
- }
-
- if (matchLength < 4) {
- ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
- continue;
- }
-
- /* let's try to find a better solution */
- if (depth>=1)
- while (ip= 3) & (repIndex > lowestIndex)) /* intentional overflow */
- if (MEM_read32(ip) == MEM_read32(repMatch)) {
- /* repcode detected */
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
- size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
- int const gain2 = (int)(repLength * 3);
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
- if ((repLength >= 4) && (gain2 > gain1))
- matchLength = repLength, offset = 0, start = ip;
- } }
-
- /* search match, depth 1 */
- { size_t offset2=99999999;
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
- if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
- continue; /* search a better one */
- } }
-
- /* let's find an even better one */
- if ((depth==2) && (ip= 3) & (repIndex > lowestIndex)) /* intentional overflow */
- if (MEM_read32(ip) == MEM_read32(repMatch)) {
- /* repcode detected */
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
- size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
- int const gain2 = (int)(repLength * 4);
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
- if ((repLength >= 4) && (gain2 > gain1))
- matchLength = repLength, offset = 0, start = ip;
- } }
-
- /* search match, depth 2 */
- { size_t offset2=99999999;
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
- if ((ml2 >= 4) && (gain2 > gain1)) {
- matchLength = ml2, offset = offset2, start = ip;
- continue;
- } } }
- break; /* nothing found : store previous solution */
- }
-
- /* catch up */
- if (offset) {
- U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
- const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
- const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
- while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
- offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
- }
-
- /* store sequence */
-_storeSequence:
- { size_t const litLength = start - anchor;
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
- anchor = ip = start + matchLength;
- }
-
- /* check immediate repcode */
- while (ip <= ilimit) {
- const U32 repIndex = (U32)((ip-base) - offset_2);
- const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
- const BYTE* const repMatch = repBase + repIndex;
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
- if (MEM_read32(ip) == MEM_read32(repMatch)) {
- /* repcode detected we should take it */
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
- matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
- ip += matchLength;
- anchor = ip;
- continue; /* faster when present ... (?) */
- }
- break;
- } }
-
- /* Save reps for next block */
- seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
-}
-
-static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
-}
-
-static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
-}
-
-static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
-}
-
-
-/* The optimal parser */
-#include "zstd_opt.h"
-
-static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
-#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
-#else
- (void)ctx; (void)src; (void)srcSize;
- return;
-#endif
-}
-
-static void ZSTD_compressBlock_btultra(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
-#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
-#else
- (void)ctx; (void)src; (void)srcSize;
- return;
-#endif
-}
-
-static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
-#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
-#else
- (void)ctx; (void)src; (void)srcSize;
- return;
-#endif
-}
-
-static void ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
-{
-#ifdef ZSTD_OPT_H_91842398743
- ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
-#else
- (void)ctx; (void)src; (void)srcSize;
- return;
-#endif
-}
-
-
/* ZSTD_selectBlockCompressor() :
* assumption : strat is a valid strategy */
typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
diff --git a/lib/compress/zstd_compress.h b/lib/compress/zstd_compress.h
new file mode 100644
index 000000000..a136a949d
--- /dev/null
+++ b/lib/compress/zstd_compress.h
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+
+#ifndef ZSTD_COMPRESS_H
+#define ZSTD_COMPRESS_H
+
+/*-*************************************
+* Dependencies
+***************************************/
+#include "zstd_internal.h"
+#include "zstdmt_compress.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*-*************************************
+* Constants
+***************************************/
+static const U32 g_searchStrength = 8;
+#define HASH_READ_SIZE 8
+
+
+/*-*************************************
+* Context memory management
+***************************************/
+typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
+typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage;
+
+typedef struct ZSTD_prefixDict_s {
+ const void* dict;
+ size_t dictSize;
+ ZSTD_dictMode_e dictMode;
+} ZSTD_prefixDict;
+
+struct ZSTD_CCtx_s {
+ const BYTE* nextSrc; /* next block here to continue on current prefix */
+ const BYTE* base; /* All regular indexes relative to this position */
+ const BYTE* dictBase; /* extDict indexes relative to this position */
+ U32 dictLimit; /* below that point, need extDict */
+ U32 lowLimit; /* below that point, no more data */
+ U32 nextToUpdate; /* index from which to continue dictionary update */
+ U32 nextToUpdate3; /* index from which to continue dictionary update */
+ U32 hashLog3; /* dispatch table : larger == faster, more memory */
+ U32 loadedDictEnd; /* index of end of dictionary */
+ ZSTD_compressionStage_e stage;
+ U32 dictID;
+ ZSTD_CCtx_params requestedParams;
+ ZSTD_CCtx_params appliedParams;
+ void* workSpace;
+ size_t workSpaceSize;
+ size_t blockSize;
+ U64 pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */
+ U64 consumedSrcSize;
+ XXH64_state_t xxhState;
+ ZSTD_customMem customMem;
+ size_t staticSize;
+
+ seqStore_t seqStore; /* sequences storage ptrs */
+ optState_t optState;
+ U32* hashTable;
+ U32* hashTable3;
+ U32* chainTable;
+ ZSTD_entropyCTables_t* entropy;
+
+ /* streaming */
+ char* inBuff;
+ size_t inBuffSize;
+ size_t inToCompress;
+ size_t inBuffPos;
+ size_t inBuffTarget;
+ char* outBuff;
+ size_t outBuffSize;
+ size_t outBuffContentSize;
+ size_t outBuffFlushedSize;
+ ZSTD_cStreamStage streamStage;
+ U32 frameEnded;
+
+ /* Dictionary */
+ ZSTD_CDict* cdictLocal;
+ const ZSTD_CDict* cdict;
+ ZSTD_prefixDict prefixDict; /* single-usage dictionary */
+
+ /* Multi-threading */
+ ZSTDMT_CCtx* mtctx;
+};
+
+
+static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 16, 17, 17, 18, 18, 19, 19,
+ 20, 20, 20, 20, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 23, 23, 23, 23, 23, 23, 23, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24 };
+
+static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
+ 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
+
+/*! ZSTD_storeSeq() :
+ Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
+ `offsetCode` : distance to match, or 0 == repCode.
+ `matchCode` : matchLength - MINMATCH
+*/
+MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
+{
+#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG >= 6)
+ static const BYTE* g_start = NULL;
+ U32 const pos = (U32)((const BYTE*)literals - g_start);
+ if (g_start==NULL) g_start = (const BYTE*)literals;
+ if ((pos > 0) && (pos < 1000000000))
+ DEBUGLOG(6, "Cpos %6u :%5u literals & match %3u bytes at distance %6u",
+ pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
+#endif
+ /* copy Literals */
+ assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + 128 KB);
+ ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
+ seqStorePtr->lit += litLength;
+
+ /* literal Length */
+ if (litLength>0xFFFF) {
+ seqStorePtr->longLengthID = 1;
+ seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ }
+ seqStorePtr->sequences[0].litLength = (U16)litLength;
+
+ /* match offset */
+ seqStorePtr->sequences[0].offset = offsetCode + 1;
+
+ /* match Length */
+ if (matchCode>0xFFFF) {
+ seqStorePtr->longLengthID = 2;
+ seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ }
+ seqStorePtr->sequences[0].matchLength = (U16)matchCode;
+
+ seqStorePtr->sequences++;
+}
+
+
+/*-*************************************
+* Match length counter
+***************************************/
+static unsigned ZSTD_NbCommonBytes (register size_t val)
+{
+ if (MEM_isLittleEndian()) {
+ if (MEM_64bits()) {
+# if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long r = 0;
+ _BitScanForward64( &r, (U64)val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_ctzll((U64)val) >> 3);
+# else
+ static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
+ 0, 3, 1, 3, 1, 4, 2, 7,
+ 0, 2, 3, 6, 1, 5, 3, 5,
+ 1, 3, 4, 4, 2, 5, 6, 7,
+ 7, 0, 1, 2, 3, 3, 4, 6,
+ 2, 6, 5, 5, 3, 4, 5, 6,
+ 7, 1, 2, 4, 6, 4, 4, 5,
+ 7, 2, 6, 5, 7, 6, 7, 7 };
+ return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
+# endif
+ } else { /* 32 bits */
+# if defined(_MSC_VER)
+ unsigned long r=0;
+ _BitScanForward( &r, (U32)val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_ctz((U32)val) >> 3);
+# else
+ static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
+ 3, 2, 2, 1, 3, 2, 0, 1,
+ 3, 3, 1, 2, 2, 2, 2, 0,
+ 3, 1, 2, 0, 1, 0, 1, 1 };
+ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+# endif
+ }
+ } else { /* Big Endian CPU */
+ if (MEM_64bits()) {
+# if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long r = 0;
+ _BitScanReverse64( &r, val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_clzll(val) >> 3);
+# else
+ unsigned r;
+ const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */
+ if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
+ if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
+ r += (!val);
+ return r;
+# endif
+ } else { /* 32 bits */
+# if defined(_MSC_VER)
+ unsigned long r = 0;
+ _BitScanReverse( &r, (unsigned long)val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_clz((U32)val) >> 3);
+# else
+ unsigned r;
+ if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
+ r += (!val);
+ return r;
+# endif
+ } }
+}
+
+
+MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
+{
+ const BYTE* const pStart = pIn;
+ const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
+
+ while (pIn < pInLoopLimit) {
+ size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
+ if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
+ pIn += ZSTD_NbCommonBytes(diff);
+ return (size_t)(pIn - pStart);
+ }
+ if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
+ if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
+ if ((pIn> (32-h) ; }
+MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
+
+static const U32 prime4bytes = 2654435761U;
+static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
+static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
+
+static const U64 prime5bytes = 889523592379ULL;
+static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; }
+static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
+
+static const U64 prime6bytes = 227718039650203ULL;
+static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; }
+static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
+
+static const U64 prime7bytes = 58295818150454627ULL;
+static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; }
+static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
+
+static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
+static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
+static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
+
+MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
+{
+ switch(mls)
+ {
+ default:
+ case 4: return ZSTD_hash4Ptr(p, hBits);
+ case 5: return ZSTD_hash5Ptr(p, hBits);
+ case 6: return ZSTD_hash6Ptr(p, hBits);
+ case 7: return ZSTD_hash7Ptr(p, hBits);
+ case 8: return ZSTD_hash8Ptr(p, hBits);
+ }
+}
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTD_COMPRESS_H */
diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c
new file mode 100644
index 000000000..437e9a2c6
--- /dev/null
+++ b/lib/compress/zstd_double_fast.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#include "zstd_double_fast.h"
+
+
+void ZSTD_fillDoubleHashTable(ZSTD_CCtx* cctx, const void* end, const U32 mls)
+{
+ U32* const hashLarge = cctx->hashTable;
+ U32 const hBitsL = cctx->appliedParams.cParams.hashLog;
+ U32* const hashSmall = cctx->chainTable;
+ U32 const hBitsS = cctx->appliedParams.cParams.chainLog;
+ const BYTE* const base = cctx->base;
+ const BYTE* ip = base + cctx->nextToUpdate;
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
+ const size_t fastHashFillStep = 3;
+
+ while(ip <= iend) {
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
+ hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
+ ip += fastHashFillStep;
+ }
+}
+
+
+FORCE_INLINE_TEMPLATE
+void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* const hashLong = cctx->hashTable;
+ const U32 hBitsL = cctx->appliedParams.cParams.hashLog;
+ U32* const hashSmall = cctx->chainTable;
+ const U32 hBitsS = cctx->appliedParams.cParams.chainLog;
+ seqStore_t* seqStorePtr = &(cctx->seqStore);
+ const BYTE* const base = cctx->base;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = cctx->dictLimit;
+ const BYTE* const lowest = base + lowestIndex;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
+ U32 offsetSaved = 0;
+
+ /* init */
+ ip += (ip==lowest);
+ { U32 const maxRep = (U32)(ip-lowest);
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
+ }
+
+ /* Main Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
+ size_t mLength;
+ size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
+ size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
+ U32 const current = (U32)(ip-base);
+ U32 const matchIndexL = hashLong[h2];
+ U32 const matchIndexS = hashSmall[h];
+ const BYTE* matchLong = base + matchIndexL;
+ const BYTE* match = base + matchIndexS;
+ hashLong[h2] = hashSmall[h] = current; /* update hash tables */
+
+ assert(offset_1 <= current); /* supposed guaranteed by construction */
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
+ /* favor repcode */
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ U32 offset;
+ if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
+ mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
+ offset = (U32)(ip-matchLong);
+ while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
+ } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
+ size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
+ U32 const matchIndexL3 = hashLong[hl3];
+ const BYTE* matchL3 = base + matchIndexL3;
+ hashLong[hl3] = current + 1;
+ if ( (matchIndexL3 > lowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) {
+ mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
+ ip++;
+ offset = (U32)(ip-matchL3);
+ while (((ip>anchor) & (matchL3>lowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
+ } else {
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
+ offset = (U32)(ip-match);
+ while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ }
+ } else {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ }
+
+ offset_2 = offset_1;
+ offset_1 = offset;
+
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ }
+
+ /* match found */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
+ hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2; /* here because current+2 could be > iend-8 */
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
+ hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
+
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ( (offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
+ ip += rLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ } } }
+
+ /* save reps for next block */
+ seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
+ seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
+ }
+}
+
+
+static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* const hashLong = ctx->hashTable;
+ U32 const hBitsL = ctx->appliedParams.cParams.hashLog;
+ U32* const hashSmall = ctx->chainTable;
+ U32 const hBitsS = ctx->appliedParams.cParams.chainLog;
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const base = ctx->base;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const dictStart = dictBase + lowestIndex;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const lowPrefixPtr = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
+
+ /* Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
+ const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
+ const U32 matchIndex = hashSmall[hSmall];
+ const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
+ const BYTE* match = matchBase + matchIndex;
+
+ const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
+ const U32 matchLongIndex = hashLong[hLong];
+ const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
+ const BYTE* matchLong = matchLongBase + matchLongIndex;
+
+ const U32 current = (U32)(ip-base);
+ const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
+ const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* repMatch = repBase + repIndex;
+ size_t mLength;
+ hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
+
+ if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
+ const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
+ const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
+ U32 offset;
+ mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
+ offset = current - matchLongIndex;
+ while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
+ offset_2 = offset_1;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+
+ } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
+ size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
+ U32 const matchIndex3 = hashLong[h3];
+ const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
+ const BYTE* match3 = match3Base + matchIndex3;
+ U32 offset;
+ hashLong[h3] = current + 1;
+ if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
+ const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
+ mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
+ ip++;
+ offset = current+1 - matchIndex3;
+ while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
+ } else {
+ const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
+ offset = current - matchIndex;
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ }
+ offset_2 = offset_1;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+
+ } else {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ } }
+
+ /* found a match : store it */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
+ hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
+ hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+ /* check immediate repcode */
+ while (ip <= ilimit) {
+ U32 const current2 = (U32)(ip-base);
+ U32 const repIndex2 = current2 - offset_2;
+ const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
+ if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
+ const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
+ ip += repLength2;
+ anchor = ip;
+ continue;
+ }
+ break;
+ } } }
+
+ /* save reps for next block */
+ seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ U32 const mls = ctx->appliedParams.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
+ }
+}
diff --git a/lib/compress/zstd_double_fast.h b/lib/compress/zstd_double_fast.h
new file mode 100644
index 000000000..64f8bfef6
--- /dev/null
+++ b/lib/compress/zstd_double_fast.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#ifndef ZSTD_DOUBLE_FAST_H
+#define ZSTD_DOUBLE_FAST_H
+
+#include "zstd_compress.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+void ZSTD_fillDoubleHashTable(ZSTD_CCtx* cctx, const void* end, const U32 mls);
+void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTD_DOUBLE_FAST_H */
diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c
new file mode 100644
index 000000000..82ab15a4c
--- /dev/null
+++ b/lib/compress/zstd_fast.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#include "zstd_fast.h"
+
+
+void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
+{
+ U32* const hashTable = zc->hashTable;
+ U32 const hBits = zc->appliedParams.cParams.hashLog;
+ const BYTE* const base = zc->base;
+ const BYTE* ip = base + zc->nextToUpdate;
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
+ const size_t fastHashFillStep = 3;
+
+ while(ip <= iend) {
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
+ ip += fastHashFillStep;
+ }
+}
+
+
+FORCE_INLINE_TEMPLATE
+void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* const hashTable = cctx->hashTable;
+ U32 const hBits = cctx->appliedParams.cParams.hashLog;
+ seqStore_t* seqStorePtr = &(cctx->seqStore);
+ const BYTE* const base = cctx->base;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = cctx->dictLimit;
+ const BYTE* const lowest = base + lowestIndex;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
+ U32 offsetSaved = 0;
+
+ /* init */
+ ip += (ip==lowest);
+ { U32 const maxRep = (U32)(ip-lowest);
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
+ }
+
+ /* Main Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
+ size_t mLength;
+ size_t const h = ZSTD_hashPtr(ip, hBits, mls);
+ U32 const current = (U32)(ip-base);
+ U32 const matchIndex = hashTable[h];
+ const BYTE* match = base + matchIndex;
+ hashTable[h] = current; /* update hash table */
+
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ U32 offset;
+ if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ }
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
+ offset = (U32)(ip-match);
+ while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ offset_2 = offset_1;
+ offset_1 = offset;
+
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ }
+
+ /* match found */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
+ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ( (offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
+ ip += rLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ } } }
+
+ /* save reps for next block */
+ seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
+ seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
+ }
+}
+
+
+static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* hashTable = ctx->hashTable;
+ const U32 hBits = ctx->appliedParams.cParams.hashLog;
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const base = ctx->base;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const dictStart = dictBase + lowestIndex;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const lowPrefixPtr = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
+
+ /* Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
+ const size_t h = ZSTD_hashPtr(ip, hBits, mls);
+ const U32 matchIndex = hashTable[h];
+ const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
+ const BYTE* match = matchBase + matchIndex;
+ const U32 current = (U32)(ip-base);
+ const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
+ const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* repMatch = repBase + repIndex;
+ size_t mLength;
+ hashTable[h] = current; /* update hash table */
+
+ if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
+ const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ if ( (matchIndex < lowestIndex) ||
+ (MEM_read32(match) != MEM_read32(ip)) ) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ }
+ { const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
+ U32 offset;
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ offset = current - matchIndex;
+ offset_2 = offset_1;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ } }
+
+ /* found a match : store it */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
+ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
+ /* check immediate repcode */
+ while (ip <= ilimit) {
+ U32 const current2 = (U32)(ip-base);
+ U32 const repIndex2 = current2 - offset_2;
+ const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
+ if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
+ const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
+ ip += repLength2;
+ anchor = ip;
+ continue;
+ }
+ break;
+ } } }
+
+ /* save reps for next block */
+ seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ U32 const mls = ctx->appliedParams.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
+ }
+}
diff --git a/lib/compress/zstd_fast.h b/lib/compress/zstd_fast.h
new file mode 100644
index 000000000..f18b4617e
--- /dev/null
+++ b/lib/compress/zstd_fast.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#ifndef ZSTD_FAST_H
+#define ZSTD_FAST_H
+
+#include "zstd_compress.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+void ZSTD_fillHashTable(ZSTD_CCtx* zc, const void* end, const U32 mls);
+void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize);
+void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTD_FAST_H */
diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c
new file mode 100644
index 000000000..00ec1e286
--- /dev/null
+++ b/lib/compress/zstd_lazy.c
@@ -0,0 +1,752 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#include "zstd_lazy.h"
+
+
+/*-*************************************
+* Binary Tree search
+***************************************/
+/** ZSTD_insertBt1() : add one or multiple positions to tree.
+* ip : assumed <= iend-8 .
+* @return : nb of positions added */
+static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
+ U32 extDict)
+{
+ U32* const hashTable = zc->hashTable;
+ U32 const hashLog = zc->appliedParams.cParams.hashLog;
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
+ U32* const bt = zc->chainTable;
+ U32 const btLog = zc->appliedParams.cParams.chainLog - 1;
+ U32 const btMask = (1 << btLog) - 1;
+ U32 matchIndex = hashTable[h];
+ size_t commonLengthSmaller=0, commonLengthLarger=0;
+ const BYTE* const base = zc->base;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* match;
+ const U32 current = (U32)(ip-base);
+ const U32 btLow = btMask >= current ? 0 : current - btMask;
+ U32* smallerPtr = bt + 2*(current&btMask);
+ U32* largerPtr = smallerPtr + 1;
+ U32 dummy32; /* to be nullified at the end */
+ U32 const windowLow = zc->lowLimit;
+ U32 matchEndIdx = current+8;
+ size_t bestLength = 8;
+#ifdef ZSTD_C_PREDICT
+ U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
+ U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
+ predictedSmall += (predictedSmall>0);
+ predictedLarge += (predictedLarge>0);
+#endif /* ZSTD_C_PREDICT */
+
+ hashTable[h] = current; /* Update Hash Table */
+
+ while (nbCompares-- && (matchIndex > windowLow)) {
+ U32* const nextPtr = bt + 2*(matchIndex & btMask);
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
+
+#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
+ const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
+ if (matchIndex == predictedSmall) {
+ /* no need to check length, result known */
+ *smallerPtr = matchIndex;
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ predictedSmall = predictPtr[1] + (predictPtr[1]>0);
+ continue;
+ }
+ if (matchIndex == predictedLarge) {
+ *largerPtr = matchIndex;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ predictedLarge = predictPtr[0] + (predictPtr[0]>0);
+ continue;
+ }
+#endif
+ if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+ match = base + matchIndex;
+ if (match[matchLength] == ip[matchLength])
+ matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
+ } else {
+ match = dictBase + matchIndex;
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
+ if (matchIndex+matchLength >= dictLimit)
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
+ }
+
+ if (matchLength > bestLength) {
+ bestLength = matchLength;
+ if (matchLength > matchEndIdx - matchIndex)
+ matchEndIdx = matchIndex + (U32)matchLength;
+ }
+
+ if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
+ break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
+
+ if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */
+ /* match is smaller than current */
+ *smallerPtr = matchIndex; /* update smaller idx */
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ } else {
+ /* match is larger than current */
+ *largerPtr = matchIndex;
+ commonLengthLarger = matchLength;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ } }
+
+ *smallerPtr = *largerPtr = 0;
+ if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
+ if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
+ return 1;
+}
+
+
+static size_t ZSTD_insertBtAndFindBestMatch (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iend,
+ size_t* offsetPtr,
+ U32 nbCompares, const U32 mls,
+ U32 extDict)
+{
+ U32* const hashTable = zc->hashTable;
+ U32 const hashLog = zc->appliedParams.cParams.hashLog;
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
+ U32* const bt = zc->chainTable;
+ U32 const btLog = zc->appliedParams.cParams.chainLog - 1;
+ U32 const btMask = (1 << btLog) - 1;
+ U32 matchIndex = hashTable[h];
+ size_t commonLengthSmaller=0, commonLengthLarger=0;
+ const BYTE* const base = zc->base;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const U32 current = (U32)(ip-base);
+ const U32 btLow = btMask >= current ? 0 : current - btMask;
+ const U32 windowLow = zc->lowLimit;
+ U32* smallerPtr = bt + 2*(current&btMask);
+ U32* largerPtr = bt + 2*(current&btMask) + 1;
+ U32 matchEndIdx = current+8;
+ U32 dummy32; /* to be nullified at the end */
+ size_t bestLength = 0;
+
+ hashTable[h] = current; /* Update Hash Table */
+
+ while (nbCompares-- && (matchIndex > windowLow)) {
+ U32* const nextPtr = bt + 2*(matchIndex & btMask);
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
+ const BYTE* match;
+
+ if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+ match = base + matchIndex;
+ if (match[matchLength] == ip[matchLength])
+ matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
+ } else {
+ match = dictBase + matchIndex;
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
+ if (matchIndex+matchLength >= dictLimit)
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
+ }
+
+ if (matchLength > bestLength) {
+ if (matchLength > matchEndIdx - matchIndex)
+ matchEndIdx = matchIndex + (U32)matchLength;
+ if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
+ bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
+ if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
+ break; /* drop, to guarantee consistency (miss a little bit of compression) */
+ }
+
+ if (match[matchLength] < ip[matchLength]) {
+ /* match is smaller than current */
+ *smallerPtr = matchIndex; /* update smaller idx */
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ } else {
+ /* match is larger than current */
+ *largerPtr = matchIndex;
+ commonLengthLarger = matchLength;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ } }
+
+ *smallerPtr = *largerPtr = 0;
+
+ zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
+ return bestLength;
+}
+
+
+void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
+{
+ const BYTE* const base = zc->base;
+ const U32 target = (U32)(ip - base);
+ U32 idx = zc->nextToUpdate;
+
+ while(idx < target)
+ idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
+}
+
+/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
+static size_t ZSTD_BtFindBestMatch (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 mls)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
+}
+
+
+static size_t ZSTD_BtFindBestMatch_selectMLS (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
+ case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
+ case 7 :
+ case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
+ }
+}
+
+
+void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
+{
+ const BYTE* const base = zc->base;
+ const U32 target = (U32)(ip - base);
+ U32 idx = zc->nextToUpdate;
+
+ while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
+}
+
+
+/** Tree updater, providing best match */
+static size_t ZSTD_BtFindBestMatch_extDict (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 mls)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
+}
+
+
+static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
+ case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
+ case 7 :
+ case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
+ }
+}
+
+
+
+/* *********************************
+* Hash Chain
+***********************************/
+#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
+
+/* Update chains up to ip (excluded)
+ Assumption : always within prefix (i.e. not within extDict) */
+U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
+{
+ U32* const hashTable = zc->hashTable;
+ const U32 hashLog = zc->appliedParams.cParams.hashLog;
+ U32* const chainTable = zc->chainTable;
+ const U32 chainMask = (1 << zc->appliedParams.cParams.chainLog) - 1;
+ const BYTE* const base = zc->base;
+ const U32 target = (U32)(ip - base);
+ U32 idx = zc->nextToUpdate;
+
+ while(idx < target) { /* catch up */
+ size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
+ NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
+ hashTable[h] = idx;
+ idx++;
+ }
+
+ zc->nextToUpdate = target;
+ return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
+}
+
+
+/* inlining is important to hardwire a hot branch (template emulation) */
+FORCE_INLINE_TEMPLATE
+size_t ZSTD_HcFindBestMatch_generic (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* const ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 mls, const U32 extDict)
+{
+ U32* const chainTable = zc->chainTable;
+ const U32 chainSize = (1 << zc->appliedParams.cParams.chainLog);
+ const U32 chainMask = chainSize-1;
+ const BYTE* const base = zc->base;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const U32 lowLimit = zc->lowLimit;
+ const U32 current = (U32)(ip-base);
+ const U32 minChain = current > chainSize ? current - chainSize : 0;
+ int nbAttempts=maxNbAttempts;
+ size_t ml=4-1;
+
+ /* HC4 match finder */
+ U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
+
+ for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
+ const BYTE* match;
+ size_t currentMl=0;
+ if ((!extDict) || matchIndex >= dictLimit) {
+ match = base + matchIndex;
+ if (match[ml] == ip[ml]) /* potentially better */
+ currentMl = ZSTD_count(ip, match, iLimit);
+ } else {
+ match = dictBase + matchIndex;
+ if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
+ currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
+ }
+
+ /* save best solution */
+ if (currentMl > ml) {
+ ml = currentMl;
+ *offsetPtr = current - matchIndex + ZSTD_REP_MOVE;
+ if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
+ }
+
+ if (matchIndex <= minChain) break;
+ matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
+ }
+
+ return ml;
+}
+
+
+FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
+ ZSTD_CCtx* zc,
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
+ case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
+ case 7 :
+ case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
+ }
+}
+
+
+FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
+ ZSTD_CCtx* zc,
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
+ case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
+ case 7 :
+ case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
+ }
+}
+
+
+/* *******************************
+* Common parser - lazy strategy
+*********************************/
+FORCE_INLINE_TEMPLATE
+void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 searchMethod, const U32 depth)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base + ctx->dictLimit;
+
+ U32 const maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
+ U32 const mls = ctx->appliedParams.cParams.searchLength;
+
+ typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
+ size_t* offsetPtr,
+ U32 maxNbAttempts, U32 matchLengthSearch);
+ searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
+ U32 offset_1 = seqStorePtr->rep[0], offset_2 = seqStorePtr->rep[1], savedOffset=0;
+
+ /* init */
+ ip += (ip==base);
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ { U32 const maxRep = (U32)(ip-base);
+ if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
+ }
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ size_t matchLength=0;
+ size_t offset=0;
+ const BYTE* start=ip+1;
+
+ /* check repCode */
+ if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
+ /* repcode : we take it */
+ matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ if (depth==0) goto _storeSequence;
+ }
+
+ /* first search (depth 0) */
+ { size_t offsetFound = 99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
+ if (ml2 > matchLength)
+ matchLength = ml2, start = ip, offset=offsetFound;
+ }
+
+ if (matchLength < 4) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
+ continue;
+ }
+
+ /* let's try to find a better solution */
+ if (depth>=1)
+ while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
+ size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
+ int const gain2 = (int)(mlRep * 3);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((mlRep >= 4) && (gain2 > gain1))
+ matchLength = mlRep, offset = 0, start = ip;
+ }
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue; /* search a better one */
+ } }
+
+ /* let's find an even better one */
+ if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
+ size_t const ml2 = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
+ int const gain2 = (int)(ml2 * 4);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((ml2 >= 4) && (gain2 > gain1))
+ matchLength = ml2, offset = 0, start = ip;
+ }
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue;
+ } } }
+ break; /* nothing found : store previous solution */
+ }
+
+ /* NOTE:
+ * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
+ * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
+ * overflows the pointer, which is undefined behavior.
+ */
+ /* catch up */
+ if (offset) {
+ while ( (start > anchor)
+ && (start > base+offset-ZSTD_REP_MOVE)
+ && (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1]) ) /* only search for offset within prefix */
+ { start--; matchLength++; }
+ offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
+ }
+ /* store sequence */
+_storeSequence:
+ { size_t const litLength = start - anchor;
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
+ anchor = ip = start + matchLength;
+ }
+
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ((offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
+ ip += matchLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ } }
+
+ /* Save reps for next block */
+ seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
+ seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
+}
+
+void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
+}
+
+void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
+}
+
+void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
+}
+
+
+FORCE_INLINE_TEMPLATE
+void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 searchMethod, const U32 depth)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base;
+ const U32 dictLimit = ctx->dictLimit;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const dictStart = dictBase + ctx->lowLimit;
+
+ const U32 maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
+
+ typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
+ size_t* offsetPtr,
+ U32 maxNbAttempts, U32 matchLengthSearch);
+ searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
+
+ U32 offset_1 = seqStorePtr->rep[0], offset_2 = seqStorePtr->rep[1];
+
+ /* init */
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ ip += (ip == prefixStart);
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ size_t matchLength=0;
+ size_t offset=0;
+ const BYTE* start=ip+1;
+ U32 current = (U32)(ip-base);
+
+ /* check repCode */
+ { const U32 repIndex = (U32)(current+1 - offset_1);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
+ /* repcode detected we should take it */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ if (depth==0) goto _storeSequence;
+ } }
+
+ /* first search (depth 0) */
+ { size_t offsetFound = 99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
+ if (ml2 > matchLength)
+ matchLength = ml2, start = ip, offset=offsetFound;
+ }
+
+ if (matchLength < 4) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
+ continue;
+ }
+
+ /* let's try to find a better solution */
+ if (depth>=1)
+ while (ip= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip) == MEM_read32(repMatch)) {
+ /* repcode detected */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ int const gain2 = (int)(repLength * 3);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((repLength >= 4) && (gain2 > gain1))
+ matchLength = repLength, offset = 0, start = ip;
+ } }
+
+ /* search match, depth 1 */
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue; /* search a better one */
+ } }
+
+ /* let's find an even better one */
+ if ((depth==2) && (ip= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip) == MEM_read32(repMatch)) {
+ /* repcode detected */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ int const gain2 = (int)(repLength * 4);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((repLength >= 4) && (gain2 > gain1))
+ matchLength = repLength, offset = 0, start = ip;
+ } }
+
+ /* search match, depth 2 */
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue;
+ } } }
+ break; /* nothing found : store previous solution */
+ }
+
+ /* catch up */
+ if (offset) {
+ U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
+ const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
+ const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
+ while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
+ offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
+ }
+
+ /* store sequence */
+_storeSequence:
+ { size_t const litLength = start - anchor;
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
+ anchor = ip = start + matchLength;
+ }
+
+ /* check immediate repcode */
+ while (ip <= ilimit) {
+ const U32 repIndex = (U32)((ip-base) - offset_2);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip) == MEM_read32(repMatch)) {
+ /* repcode detected we should take it */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
+ ip += matchLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ }
+ break;
+ } }
+
+ /* Save reps for next block */
+ seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
+}
+
+void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
+}
+
+void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
+}
+
+void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
+}
diff --git a/lib/compress/zstd_lazy.h b/lib/compress/zstd_lazy.h
new file mode 100644
index 000000000..451cddf96
--- /dev/null
+++ b/lib/compress/zstd_lazy.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#ifndef ZSTD_LAZY_H
+#define ZSTD_LAZY_H
+
+#include "zstd_compress.h"
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls);
+void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls);
+void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls);
+
+void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+
+void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTD_LAZY_H */
diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c
new file mode 100644
index 000000000..03e945516
--- /dev/null
+++ b/lib/compress/zstd_opt.c
@@ -0,0 +1,954 @@
+/*
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#include "zstd_opt.h"
+#include "zstd_lazy.h"
+
+
+#define ZSTD_LITFREQ_ADD 2
+#define ZSTD_FREQ_DIV 4
+#define ZSTD_MAX_PRICE (1<<30)
+
+/*-*************************************
+* Price functions for optimal parser
+***************************************/
+static void ZSTD_setLog2Prices(optState_t* optPtr)
+{
+ optPtr->log2matchLengthSum = ZSTD_highbit32(optPtr->matchLengthSum+1);
+ optPtr->log2litLengthSum = ZSTD_highbit32(optPtr->litLengthSum+1);
+ optPtr->log2litSum = ZSTD_highbit32(optPtr->litSum+1);
+ optPtr->log2offCodeSum = ZSTD_highbit32(optPtr->offCodeSum+1);
+ optPtr->factor = 1 + ((optPtr->litSum>>5) / optPtr->litLengthSum) + ((optPtr->litSum<<1) / (optPtr->litSum + optPtr->matchSum));
+}
+
+
+static void ZSTD_rescaleFreqs(optState_t* optPtr, const BYTE* src, size_t srcSize)
+{
+ unsigned u;
+
+ optPtr->cachedLiterals = NULL;
+ optPtr->cachedPrice = optPtr->cachedLitLength = 0;
+ optPtr->staticPrices = 0;
+
+ if (optPtr->litLengthSum == 0) {
+ if (srcSize <= 1024) optPtr->staticPrices = 1;
+
+ assert(optPtr->litFreq!=NULL);
+ for (u=0; u<=MaxLit; u++)
+ optPtr->litFreq[u] = 0;
+ for (u=0; ulitFreq[src[u]]++;
+
+ optPtr->litSum = 0;
+ optPtr->litLengthSum = MaxLL+1;
+ optPtr->matchLengthSum = MaxML+1;
+ optPtr->offCodeSum = (MaxOff+1);
+ optPtr->matchSum = (ZSTD_LITFREQ_ADD<litFreq[u] = 1 + (optPtr->litFreq[u]>>ZSTD_FREQ_DIV);
+ optPtr->litSum += optPtr->litFreq[u];
+ }
+ for (u=0; u<=MaxLL; u++)
+ optPtr->litLengthFreq[u] = 1;
+ for (u=0; u<=MaxML; u++)
+ optPtr->matchLengthFreq[u] = 1;
+ for (u=0; u<=MaxOff; u++)
+ optPtr->offCodeFreq[u] = 1;
+ } else {
+ optPtr->matchLengthSum = 0;
+ optPtr->litLengthSum = 0;
+ optPtr->offCodeSum = 0;
+ optPtr->matchSum = 0;
+ optPtr->litSum = 0;
+
+ for (u=0; u<=MaxLit; u++) {
+ optPtr->litFreq[u] = 1 + (optPtr->litFreq[u]>>(ZSTD_FREQ_DIV+1));
+ optPtr->litSum += optPtr->litFreq[u];
+ }
+ for (u=0; u<=MaxLL; u++) {
+ optPtr->litLengthFreq[u] = 1 + (optPtr->litLengthFreq[u]>>(ZSTD_FREQ_DIV+1));
+ optPtr->litLengthSum += optPtr->litLengthFreq[u];
+ }
+ for (u=0; u<=MaxML; u++) {
+ optPtr->matchLengthFreq[u] = 1 + (optPtr->matchLengthFreq[u]>>ZSTD_FREQ_DIV);
+ optPtr->matchLengthSum += optPtr->matchLengthFreq[u];
+ optPtr->matchSum += optPtr->matchLengthFreq[u] * (u + 3);
+ }
+ optPtr->matchSum *= ZSTD_LITFREQ_ADD;
+ for (u=0; u<=MaxOff; u++) {
+ optPtr->offCodeFreq[u] = 1 + (optPtr->offCodeFreq[u]>>ZSTD_FREQ_DIV);
+ optPtr->offCodeSum += optPtr->offCodeFreq[u];
+ }
+ }
+
+ ZSTD_setLog2Prices(optPtr);
+}
+
+
+static U32 ZSTD_getLiteralPrice(optState_t* optPtr, U32 litLength, const BYTE* literals)
+{
+ U32 price, u;
+
+ if (optPtr->staticPrices)
+ return ZSTD_highbit32((U32)litLength+1) + (litLength*6);
+
+ if (litLength == 0)
+ return optPtr->log2litLengthSum - ZSTD_highbit32(optPtr->litLengthFreq[0]+1);
+
+ /* literals */
+ if (optPtr->cachedLiterals == literals) {
+ U32 const additional = litLength - optPtr->cachedLitLength;
+ const BYTE* literals2 = optPtr->cachedLiterals + optPtr->cachedLitLength;
+ price = optPtr->cachedPrice + additional * optPtr->log2litSum;
+ for (u=0; u < additional; u++)
+ price -= ZSTD_highbit32(optPtr->litFreq[literals2[u]]+1);
+ optPtr->cachedPrice = price;
+ optPtr->cachedLitLength = litLength;
+ } else {
+ price = litLength * optPtr->log2litSum;
+ for (u=0; u < litLength; u++)
+ price -= ZSTD_highbit32(optPtr->litFreq[literals[u]]+1);
+
+ if (litLength >= 12) {
+ optPtr->cachedLiterals = literals;
+ optPtr->cachedPrice = price;
+ optPtr->cachedLitLength = litLength;
+ }
+ }
+
+ /* literal Length */
+ { const BYTE LL_deltaCode = 19;
+ const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
+ price += LL_bits[llCode] + optPtr->log2litLengthSum - ZSTD_highbit32(optPtr->litLengthFreq[llCode]+1);
+ }
+
+ return price;
+}
+
+
+FORCE_INLINE_TEMPLATE U32 ZSTD_getPrice(optState_t* optPtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength, const int ultra)
+{
+ /* offset */
+ U32 price;
+ BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
+
+ if (optPtr->staticPrices)
+ return ZSTD_getLiteralPrice(optPtr, litLength, literals) + ZSTD_highbit32((U32)matchLength+1) + 16 + offCode;
+
+ price = offCode + optPtr->log2offCodeSum - ZSTD_highbit32(optPtr->offCodeFreq[offCode]+1);
+ if (!ultra && offCode >= 20) price += (offCode-19)*2;
+
+ /* match Length */
+ { const BYTE ML_deltaCode = 36;
+ const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
+ price += ML_bits[mlCode] + optPtr->log2matchLengthSum - ZSTD_highbit32(optPtr->matchLengthFreq[mlCode]+1);
+ }
+
+ return price + ZSTD_getLiteralPrice(optPtr, litLength, literals) + optPtr->factor;
+}
+
+
+static void ZSTD_updatePrice(optState_t* optPtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
+{
+ U32 u;
+
+ /* literals */
+ optPtr->litSum += litLength*ZSTD_LITFREQ_ADD;
+ for (u=0; u < litLength; u++)
+ optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
+
+ /* literal Length */
+ { const BYTE LL_deltaCode = 19;
+ const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
+ optPtr->litLengthFreq[llCode]++;
+ optPtr->litLengthSum++;
+ }
+
+ /* match offset */
+ { BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
+ optPtr->offCodeSum++;
+ optPtr->offCodeFreq[offCode]++;
+ }
+
+ /* match Length */
+ { const BYTE ML_deltaCode = 36;
+ const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
+ optPtr->matchLengthFreq[mlCode]++;
+ optPtr->matchLengthSum++;
+ }
+
+ ZSTD_setLog2Prices(optPtr);
+}
+
+
+#define SET_PRICE(pos, mlen_, offset_, litlen_, price_) \
+ { \
+ while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
+ opt[pos].mlen = mlen_; \
+ opt[pos].off = offset_; \
+ opt[pos].litlen = litlen_; \
+ opt[pos].price = price_; \
+ }
+
+
+/* function safe only for comparisons */
+static U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
+{
+ switch (length)
+ {
+ default :
+ case 4 : return MEM_read32(memPtr);
+ case 3 : if (MEM_isLittleEndian())
+ return MEM_read32(memPtr)<<8;
+ else
+ return MEM_read32(memPtr)>>8;
+ }
+}
+
+
+/* Update hashTable3 up to ip (excluded)
+ Assumption : always within prefix (i.e. not within extDict) */
+static
+U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip)
+{
+ U32* const hashTable3 = zc->hashTable3;
+ U32 const hashLog3 = zc->hashLog3;
+ const BYTE* const base = zc->base;
+ U32 idx = zc->nextToUpdate3;
+ const U32 target = zc->nextToUpdate3 = (U32)(ip - base);
+ const size_t hash3 = ZSTD_hash3Ptr(ip, hashLog3);
+
+ while(idx < target) {
+ hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;
+ idx++;
+ }
+
+ return hashTable3[hash3];
+}
+
+
+/*-*************************************
+* Binary Tree search
+***************************************/
+static U32 ZSTD_insertBtAndGetAllMatches (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ U32 nbCompares, const U32 mls,
+ U32 extDict, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ const BYTE* const base = zc->base;
+ const U32 current = (U32)(ip-base);
+ const U32 hashLog = zc->appliedParams.cParams.hashLog;
+ const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
+ U32* const hashTable = zc->hashTable;
+ U32 matchIndex = hashTable[h];
+ U32* const bt = zc->chainTable;
+ const U32 btLog = zc->appliedParams.cParams.chainLog - 1;
+ const U32 btMask= (1U << btLog) - 1;
+ size_t commonLengthSmaller=0, commonLengthLarger=0;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const U32 btLow = btMask >= current ? 0 : current - btMask;
+ const U32 windowLow = zc->lowLimit;
+ U32* smallerPtr = bt + 2*(current&btMask);
+ U32* largerPtr = bt + 2*(current&btMask) + 1;
+ U32 matchEndIdx = current+8;
+ U32 dummy32; /* to be nullified at the end */
+ U32 mnum = 0;
+
+ const U32 minMatch = (mls == 3) ? 3 : 4;
+ size_t bestLength = minMatchLen-1;
+
+ if (minMatch == 3) { /* HC3 match finder */
+ U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip);
+ if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) {
+ const BYTE* match;
+ size_t currentMl=0;
+ if ((!extDict) || matchIndex3 >= dictLimit) {
+ match = base + matchIndex3;
+ if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
+ } else {
+ match = dictBase + matchIndex3;
+ if (ZSTD_readMINMATCH(match, MINMATCH) == ZSTD_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
+ currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
+ }
+
+ /* save best solution */
+ if (currentMl > bestLength) {
+ bestLength = currentMl;
+ matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
+ matches[mnum].len = (U32)currentMl;
+ mnum++;
+ if (currentMl > ZSTD_OPT_NUM) goto update;
+ if (ip+currentMl == iLimit) goto update; /* best possible, and avoid read overflow*/
+ }
+ }
+ }
+
+ hashTable[h] = current; /* Update Hash Table */
+
+ while (nbCompares-- && (matchIndex > windowLow)) {
+ U32* nextPtr = bt + 2*(matchIndex & btMask);
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
+ const BYTE* match;
+
+ if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+ match = base + matchIndex;
+ if (match[matchLength] == ip[matchLength]) {
+ matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
+ }
+ } else {
+ match = dictBase + matchIndex;
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
+ if (matchIndex+matchLength >= dictLimit)
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
+ }
+
+ if (matchLength > bestLength) {
+ if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
+ bestLength = matchLength;
+ matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
+ matches[mnum].len = (U32)matchLength;
+ mnum++;
+ if (matchLength > ZSTD_OPT_NUM) break;
+ if (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */
+ break; /* drop, to guarantee consistency (miss a little bit of compression) */
+ }
+
+ if (match[matchLength] < ip[matchLength]) {
+ /* match is smaller than current */
+ *smallerPtr = matchIndex; /* update smaller idx */
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ } else {
+ /* match is larger than current */
+ *largerPtr = matchIndex;
+ commonLengthLarger = matchLength;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ } }
+
+ *smallerPtr = *largerPtr = 0;
+
+update:
+ zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
+ return mnum;
+}
+
+
+/** Tree updater, providing best match */
+static U32 ZSTD_BtGetAllMatches (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches, minMatchLen);
+}
+
+
+static U32 ZSTD_BtGetAllMatches_selectMLS (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iHighLimit,
+ const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ switch(matchLengthSearch)
+ {
+ case 3 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
+ default :
+ case 4 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
+ case 5 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
+ case 7 :
+ case 6 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
+ }
+}
+
+/** Tree updater, providing best match */
+static U32 ZSTD_BtGetAllMatches_extDict (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 1, matches, minMatchLen);
+}
+
+
+static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iHighLimit,
+ const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ switch(matchLengthSearch)
+ {
+ case 3 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
+ default :
+ case 4 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
+ case 5 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
+ case 7 :
+ case 6 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
+ }
+}
+
+
+/*-*******************************
+* Optimal parser
+*********************************/
+FORCE_INLINE_TEMPLATE
+void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize, const int ultra)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ optState_t* optStatePtr = &(ctx->optState);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base;
+ const BYTE* const prefixStart = base + ctx->dictLimit;
+
+ const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;
+ const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
+ const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;
+
+ ZSTD_optimal_t* opt = optStatePtr->priceTable;
+ ZSTD_match_t* matches = optStatePtr->matchTable;
+ const BYTE* inr;
+ U32 offset, rep[ZSTD_REP_NUM];
+
+ /* init */
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize);
+ ip += (ip==prefixStart);
+ { U32 i; for (i=0; irep[i]; }
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ U32 cur, match_num, last_pos, litlen, price;
+ U32 u, mlen, best_mlen, best_off, litLength;
+ memset(opt, 0, sizeof(ZSTD_optimal_t));
+ last_pos = 0;
+ litlen = (U32)(ip - anchor);
+
+ /* check repCode */
+ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
+ for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
+ && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repCur, minMatch))) {
+ mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
+ if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
+ goto _storeSequence;
+ }
+ best_off = i - (ip == anchor);
+ do {
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
+
+ if (!last_pos && !match_num) { ip++; continue; }
+
+ if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ cur = 0;
+ last_pos = 1;
+ goto _storeSequence;
+ }
+
+ /* set prices using matches at position = 0 */
+ best_mlen = (last_pos) ? last_pos : minMatch;
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+ while (mlen <= best_mlen) {
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */
+ mlen++;
+ } }
+
+ if (last_pos < minMatch) { ip++; continue; }
+
+ /* initialize opt[0] */
+ { U32 i ; for (i=0; i litlen) {
+ price = opt[cur - litlen].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-litlen);
+ } else
+ price = ZSTD_getLiteralPrice(optStatePtr, litlen, anchor);
+ } else {
+ litlen = 1;
+ price = opt[cur - 1].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-1);
+ }
+
+ if (cur > last_pos || price <= opt[cur].price)
+ SET_PRICE(cur, 1, 0, litlen, price);
+
+ if (cur == last_pos) break;
+
+ if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */
+ continue;
+
+ mlen = opt[cur].mlen;
+ if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
+ opt[cur].rep[2] = opt[cur-mlen].rep[1];
+ opt[cur].rep[1] = opt[cur-mlen].rep[0];
+ opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
+ } else {
+ opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
+ opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
+ opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
+ }
+
+ best_mlen = minMatch;
+ { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
+ for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
+ && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) {
+ mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
+
+ if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ best_off = i - (opt[cur].mlen != 1);
+ if (mlen > best_mlen) best_mlen = mlen;
+
+ do {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
+ } else
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
+ SET_PRICE(cur + mlen, mlen, i, litlen, price);
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
+
+ if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ /* set prices using matches at position = cur */
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+
+ while (mlen <= best_mlen) {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen)
+ price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
+ else
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
+ SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
+
+ mlen++;
+ } } }
+
+ best_mlen = opt[last_pos].mlen;
+ best_off = opt[last_pos].off;
+ cur = last_pos - best_mlen;
+
+ /* store sequence */
+_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
+ opt[0].mlen = 1;
+
+ while (1) {
+ mlen = opt[cur].mlen;
+ offset = opt[cur].off;
+ opt[cur].mlen = best_mlen;
+ opt[cur].off = best_off;
+ best_mlen = mlen;
+ best_off = offset;
+ if (mlen > cur) break;
+ cur -= mlen;
+ }
+
+ for (u = 0; u <= last_pos;) {
+ u += opt[u].mlen;
+ }
+
+ for (cur=0; cur < last_pos; ) {
+ mlen = opt[cur].mlen;
+ if (mlen == 1) { ip++; cur++; continue; }
+ offset = opt[cur].off;
+ cur += mlen;
+ litLength = (U32)(ip - anchor);
+
+ if (offset > ZSTD_REP_MOVE_OPT) {
+ rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = offset - ZSTD_REP_MOVE_OPT;
+ offset--;
+ } else {
+ if (offset != 0) {
+ best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
+ if (offset != 1) rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = best_off;
+ }
+ if (litLength==0) offset--;
+ }
+
+ ZSTD_updatePrice(optStatePtr, litLength, anchor, offset, mlen-MINMATCH);
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
+ anchor = ip = ip + mlen;
+ } } /* for (cur=0; cur < last_pos; ) */
+
+ /* Save reps for next block */
+ { int i; for (i=0; irepToConfirm[i] = rep[i]; }
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
+}
+
+void ZSTD_compressBlock_btultra(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
+}
+
+
+FORCE_INLINE_TEMPLATE
+void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize, const int ultra)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ optState_t* optStatePtr = &(ctx->optState);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base;
+ const U32 lowestIndex = ctx->lowLimit;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+
+ const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;
+ const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
+ const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;
+
+ ZSTD_optimal_t* opt = optStatePtr->priceTable;
+ ZSTD_match_t* matches = optStatePtr->matchTable;
+ const BYTE* inr;
+
+ /* init */
+ U32 offset, rep[ZSTD_REP_NUM];
+ { U32 i; for (i=0; irep[i]; }
+
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize);
+ ip += (ip==prefixStart);
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ U32 cur, match_num, last_pos, litlen, price;
+ U32 u, mlen, best_mlen, best_off, litLength;
+ U32 current = (U32)(ip-base);
+ memset(opt, 0, sizeof(ZSTD_optimal_t));
+ last_pos = 0;
+ opt[0].litlen = (U32)(ip - anchor);
+
+ /* check repCode */
+ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
+ for (i = (ip==anchor); i 0 && repCur <= (S32)current)
+ && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
+ && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
+ /* repcode detected we should take it */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
+
+ if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
+ goto _storeSequence;
+ }
+
+ best_off = i - (ip==anchor);
+ litlen = opt[0].litlen;
+ do {
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */
+
+ if (!last_pos && !match_num) { ip++; continue; }
+
+ { U32 i; for (i=0; i sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ cur = 0;
+ last_pos = 1;
+ goto _storeSequence;
+ }
+
+ best_mlen = (last_pos) ? last_pos : minMatch;
+
+ /* set prices using matches at position = 0 */
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+ litlen = opt[0].litlen;
+ while (mlen <= best_mlen) {
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, matches[u].off, litlen, price);
+ mlen++;
+ } }
+
+ if (last_pos < minMatch) {
+ ip++; continue;
+ }
+
+ /* check further positions */
+ for (cur = 1; cur <= last_pos; cur++) {
+ inr = ip + cur;
+
+ if (opt[cur-1].mlen == 1) {
+ litlen = opt[cur-1].litlen + 1;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-litlen);
+ } else
+ price = ZSTD_getLiteralPrice(optStatePtr, litlen, anchor);
+ } else {
+ litlen = 1;
+ price = opt[cur - 1].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-1);
+ }
+
+ if (cur > last_pos || price <= opt[cur].price)
+ SET_PRICE(cur, 1, 0, litlen, price);
+
+ if (cur == last_pos) break;
+
+ if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */
+ continue;
+
+ mlen = opt[cur].mlen;
+ if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
+ opt[cur].rep[2] = opt[cur-mlen].rep[1];
+ opt[cur].rep[1] = opt[cur-mlen].rep[0];
+ opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
+ } else {
+ opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
+ opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
+ opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
+ }
+
+ best_mlen = minMatch;
+ { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
+ for (i = (mlen != 1); i 0 && repCur <= (S32)(current+cur))
+ && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
+ && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
+ /* repcode detected */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
+
+ if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ best_off = i - (opt[cur].mlen != 1);
+ if (mlen > best_mlen) best_mlen = mlen;
+
+ do {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
+ } else
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
+ SET_PRICE(cur + mlen, mlen, i, litlen, price);
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
+
+ if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ /* set prices using matches at position = cur */
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+
+ while (mlen <= best_mlen) {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen)
+ price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
+ else
+ price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
+ SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
+
+ mlen++;
+ } } } /* for (cur = 1; cur <= last_pos; cur++) */
+
+ best_mlen = opt[last_pos].mlen;
+ best_off = opt[last_pos].off;
+ cur = last_pos - best_mlen;
+
+ /* store sequence */
+_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
+ opt[0].mlen = 1;
+
+ while (1) {
+ mlen = opt[cur].mlen;
+ offset = opt[cur].off;
+ opt[cur].mlen = best_mlen;
+ opt[cur].off = best_off;
+ best_mlen = mlen;
+ best_off = offset;
+ if (mlen > cur) break;
+ cur -= mlen;
+ }
+
+ for (u = 0; u <= last_pos; ) {
+ u += opt[u].mlen;
+ }
+
+ for (cur=0; cur < last_pos; ) {
+ mlen = opt[cur].mlen;
+ if (mlen == 1) { ip++; cur++; continue; }
+ offset = opt[cur].off;
+ cur += mlen;
+ litLength = (U32)(ip - anchor);
+
+ if (offset > ZSTD_REP_MOVE_OPT) {
+ rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = offset - ZSTD_REP_MOVE_OPT;
+ offset--;
+ } else {
+ if (offset != 0) {
+ best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
+ if (offset != 1) rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = best_off;
+ }
+
+ if (litLength==0) offset--;
+ }
+
+ ZSTD_updatePrice(optStatePtr, litLength, anchor, offset, mlen-MINMATCH);
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
+ anchor = ip = ip + mlen;
+ } } /* for (cur=0; cur < last_pos; ) */
+
+ /* Save reps for next block */
+ { int i; for (i=0; irepToConfirm[i] = rep[i]; }
+
+ /* Last Literals */
+ { size_t lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
+}
+
+void ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
+}
diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h
index 4d938c80d..0991a1f13 100644
--- a/lib/compress/zstd_opt.h
+++ b/lib/compress/zstd_opt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under both the BSD-style license (found in the
@@ -7,932 +7,23 @@
* in the COPYING file in the root directory of this source tree).
*/
+#ifndef ZSTD_OPT_H
+#define ZSTD_OPT_H
-/* Note : this file is intended to be included within zstd_compress.c */
+#include "zstd_compress.h"
+#if defined (__cplusplus)
+extern "C" {
+#endif
-#ifndef ZSTD_OPT_H_91842398743
-#define ZSTD_OPT_H_91842398743
+void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_btultra(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+void ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
-#define ZSTD_LITFREQ_ADD 2
-#define ZSTD_FREQ_DIV 4
-#define ZSTD_MAX_PRICE (1<<30)
-
-/*-*************************************
-* Price functions for optimal parser
-***************************************/
-static void ZSTD_setLog2Prices(optState_t* optPtr)
-{
- optPtr->log2matchLengthSum = ZSTD_highbit32(optPtr->matchLengthSum+1);
- optPtr->log2litLengthSum = ZSTD_highbit32(optPtr->litLengthSum+1);
- optPtr->log2litSum = ZSTD_highbit32(optPtr->litSum+1);
- optPtr->log2offCodeSum = ZSTD_highbit32(optPtr->offCodeSum+1);
- optPtr->factor = 1 + ((optPtr->litSum>>5) / optPtr->litLengthSum) + ((optPtr->litSum<<1) / (optPtr->litSum + optPtr->matchSum));
+#if defined (__cplusplus)
}
+#endif
-
-static void ZSTD_rescaleFreqs(optState_t* optPtr, const BYTE* src, size_t srcSize)
-{
- unsigned u;
-
- optPtr->cachedLiterals = NULL;
- optPtr->cachedPrice = optPtr->cachedLitLength = 0;
- optPtr->staticPrices = 0;
-
- if (optPtr->litLengthSum == 0) {
- if (srcSize <= 1024) optPtr->staticPrices = 1;
-
- assert(optPtr->litFreq!=NULL);
- for (u=0; u<=MaxLit; u++)
- optPtr->litFreq[u] = 0;
- for (u=0; ulitFreq[src[u]]++;
-
- optPtr->litSum = 0;
- optPtr->litLengthSum = MaxLL+1;
- optPtr->matchLengthSum = MaxML+1;
- optPtr->offCodeSum = (MaxOff+1);
- optPtr->matchSum = (ZSTD_LITFREQ_ADD<litFreq[u] = 1 + (optPtr->litFreq[u]>>ZSTD_FREQ_DIV);
- optPtr->litSum += optPtr->litFreq[u];
- }
- for (u=0; u<=MaxLL; u++)
- optPtr->litLengthFreq[u] = 1;
- for (u=0; u<=MaxML; u++)
- optPtr->matchLengthFreq[u] = 1;
- for (u=0; u<=MaxOff; u++)
- optPtr->offCodeFreq[u] = 1;
- } else {
- optPtr->matchLengthSum = 0;
- optPtr->litLengthSum = 0;
- optPtr->offCodeSum = 0;
- optPtr->matchSum = 0;
- optPtr->litSum = 0;
-
- for (u=0; u<=MaxLit; u++) {
- optPtr->litFreq[u] = 1 + (optPtr->litFreq[u]>>(ZSTD_FREQ_DIV+1));
- optPtr->litSum += optPtr->litFreq[u];
- }
- for (u=0; u<=MaxLL; u++) {
- optPtr->litLengthFreq[u] = 1 + (optPtr->litLengthFreq[u]>>(ZSTD_FREQ_DIV+1));
- optPtr->litLengthSum += optPtr->litLengthFreq[u];
- }
- for (u=0; u<=MaxML; u++) {
- optPtr->matchLengthFreq[u] = 1 + (optPtr->matchLengthFreq[u]>>ZSTD_FREQ_DIV);
- optPtr->matchLengthSum += optPtr->matchLengthFreq[u];
- optPtr->matchSum += optPtr->matchLengthFreq[u] * (u + 3);
- }
- optPtr->matchSum *= ZSTD_LITFREQ_ADD;
- for (u=0; u<=MaxOff; u++) {
- optPtr->offCodeFreq[u] = 1 + (optPtr->offCodeFreq[u]>>ZSTD_FREQ_DIV);
- optPtr->offCodeSum += optPtr->offCodeFreq[u];
- }
- }
-
- ZSTD_setLog2Prices(optPtr);
-}
-
-
-static U32 ZSTD_getLiteralPrice(optState_t* optPtr, U32 litLength, const BYTE* literals)
-{
- U32 price, u;
-
- if (optPtr->staticPrices)
- return ZSTD_highbit32((U32)litLength+1) + (litLength*6);
-
- if (litLength == 0)
- return optPtr->log2litLengthSum - ZSTD_highbit32(optPtr->litLengthFreq[0]+1);
-
- /* literals */
- if (optPtr->cachedLiterals == literals) {
- U32 const additional = litLength - optPtr->cachedLitLength;
- const BYTE* literals2 = optPtr->cachedLiterals + optPtr->cachedLitLength;
- price = optPtr->cachedPrice + additional * optPtr->log2litSum;
- for (u=0; u < additional; u++)
- price -= ZSTD_highbit32(optPtr->litFreq[literals2[u]]+1);
- optPtr->cachedPrice = price;
- optPtr->cachedLitLength = litLength;
- } else {
- price = litLength * optPtr->log2litSum;
- for (u=0; u < litLength; u++)
- price -= ZSTD_highbit32(optPtr->litFreq[literals[u]]+1);
-
- if (litLength >= 12) {
- optPtr->cachedLiterals = literals;
- optPtr->cachedPrice = price;
- optPtr->cachedLitLength = litLength;
- }
- }
-
- /* literal Length */
- { const BYTE LL_deltaCode = 19;
- const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
- price += LL_bits[llCode] + optPtr->log2litLengthSum - ZSTD_highbit32(optPtr->litLengthFreq[llCode]+1);
- }
-
- return price;
-}
-
-
-FORCE_INLINE_TEMPLATE U32 ZSTD_getPrice(optState_t* optPtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength, const int ultra)
-{
- /* offset */
- U32 price;
- BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
-
- if (optPtr->staticPrices)
- return ZSTD_getLiteralPrice(optPtr, litLength, literals) + ZSTD_highbit32((U32)matchLength+1) + 16 + offCode;
-
- price = offCode + optPtr->log2offCodeSum - ZSTD_highbit32(optPtr->offCodeFreq[offCode]+1);
- if (!ultra && offCode >= 20) price += (offCode-19)*2;
-
- /* match Length */
- { const BYTE ML_deltaCode = 36;
- const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
- price += ML_bits[mlCode] + optPtr->log2matchLengthSum - ZSTD_highbit32(optPtr->matchLengthFreq[mlCode]+1);
- }
-
- return price + ZSTD_getLiteralPrice(optPtr, litLength, literals) + optPtr->factor;
-}
-
-
-static void ZSTD_updatePrice(optState_t* optPtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
-{
- U32 u;
-
- /* literals */
- optPtr->litSum += litLength*ZSTD_LITFREQ_ADD;
- for (u=0; u < litLength; u++)
- optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
-
- /* literal Length */
- { const BYTE LL_deltaCode = 19;
- const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
- optPtr->litLengthFreq[llCode]++;
- optPtr->litLengthSum++;
- }
-
- /* match offset */
- { BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
- optPtr->offCodeSum++;
- optPtr->offCodeFreq[offCode]++;
- }
-
- /* match Length */
- { const BYTE ML_deltaCode = 36;
- const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
- optPtr->matchLengthFreq[mlCode]++;
- optPtr->matchLengthSum++;
- }
-
- ZSTD_setLog2Prices(optPtr);
-}
-
-
-#define SET_PRICE(pos, mlen_, offset_, litlen_, price_) \
- { \
- while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
- opt[pos].mlen = mlen_; \
- opt[pos].off = offset_; \
- opt[pos].litlen = litlen_; \
- opt[pos].price = price_; \
- }
-
-
-/* function safe only for comparisons */
-static U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
-{
- switch (length)
- {
- default :
- case 4 : return MEM_read32(memPtr);
- case 3 : if (MEM_isLittleEndian())
- return MEM_read32(memPtr)<<8;
- else
- return MEM_read32(memPtr)>>8;
- }
-}
-
-
-/* Update hashTable3 up to ip (excluded)
- Assumption : always within prefix (i.e. not within extDict) */
-static
-U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip)
-{
- U32* const hashTable3 = zc->hashTable3;
- U32 const hashLog3 = zc->hashLog3;
- const BYTE* const base = zc->base;
- U32 idx = zc->nextToUpdate3;
- const U32 target = zc->nextToUpdate3 = (U32)(ip - base);
- const size_t hash3 = ZSTD_hash3Ptr(ip, hashLog3);
-
- while(idx < target) {
- hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;
- idx++;
- }
-
- return hashTable3[hash3];
-}
-
-
-/*-*************************************
-* Binary Tree search
-***************************************/
-static U32 ZSTD_insertBtAndGetAllMatches (
- ZSTD_CCtx* zc,
- const BYTE* const ip, const BYTE* const iLimit,
- U32 nbCompares, const U32 mls,
- U32 extDict, ZSTD_match_t* matches, const U32 minMatchLen)
-{
- const BYTE* const base = zc->base;
- const U32 current = (U32)(ip-base);
- const U32 hashLog = zc->appliedParams.cParams.hashLog;
- const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
- U32* const hashTable = zc->hashTable;
- U32 matchIndex = hashTable[h];
- U32* const bt = zc->chainTable;
- const U32 btLog = zc->appliedParams.cParams.chainLog - 1;
- const U32 btMask= (1U << btLog) - 1;
- size_t commonLengthSmaller=0, commonLengthLarger=0;
- const BYTE* const dictBase = zc->dictBase;
- const U32 dictLimit = zc->dictLimit;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const prefixStart = base + dictLimit;
- const U32 btLow = btMask >= current ? 0 : current - btMask;
- const U32 windowLow = zc->lowLimit;
- U32* smallerPtr = bt + 2*(current&btMask);
- U32* largerPtr = bt + 2*(current&btMask) + 1;
- U32 matchEndIdx = current+8;
- U32 dummy32; /* to be nullified at the end */
- U32 mnum = 0;
-
- const U32 minMatch = (mls == 3) ? 3 : 4;
- size_t bestLength = minMatchLen-1;
-
- if (minMatch == 3) { /* HC3 match finder */
- U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip);
- if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) {
- const BYTE* match;
- size_t currentMl=0;
- if ((!extDict) || matchIndex3 >= dictLimit) {
- match = base + matchIndex3;
- if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
- } else {
- match = dictBase + matchIndex3;
- if (ZSTD_readMINMATCH(match, MINMATCH) == ZSTD_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
- currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
- }
-
- /* save best solution */
- if (currentMl > bestLength) {
- bestLength = currentMl;
- matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
- matches[mnum].len = (U32)currentMl;
- mnum++;
- if (currentMl > ZSTD_OPT_NUM) goto update;
- if (ip+currentMl == iLimit) goto update; /* best possible, and avoid read overflow*/
- }
- }
- }
-
- hashTable[h] = current; /* Update Hash Table */
-
- while (nbCompares-- && (matchIndex > windowLow)) {
- U32* nextPtr = bt + 2*(matchIndex & btMask);
- size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
- const BYTE* match;
-
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
- match = base + matchIndex;
- if (match[matchLength] == ip[matchLength]) {
- matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
- }
- } else {
- match = dictBase + matchIndex;
- matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
- if (matchIndex+matchLength >= dictLimit)
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
- }
-
- if (matchLength > bestLength) {
- if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
- bestLength = matchLength;
- matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
- matches[mnum].len = (U32)matchLength;
- mnum++;
- if (matchLength > ZSTD_OPT_NUM) break;
- if (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */
- break; /* drop, to guarantee consistency (miss a little bit of compression) */
- }
-
- if (match[matchLength] < ip[matchLength]) {
- /* match is smaller than current */
- *smallerPtr = matchIndex; /* update smaller idx */
- commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
- } else {
- /* match is larger than current */
- *largerPtr = matchIndex;
- commonLengthLarger = matchLength;
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
- largerPtr = nextPtr;
- matchIndex = nextPtr[0];
- } }
-
- *smallerPtr = *largerPtr = 0;
-
-update:
- zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
- return mnum;
-}
-
-
-/** Tree updater, providing best match */
-static U32 ZSTD_BtGetAllMatches (
- ZSTD_CCtx* zc,
- const BYTE* const ip, const BYTE* const iLimit,
- const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
-{
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
- ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
- return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches, minMatchLen);
-}
-
-
-static U32 ZSTD_BtGetAllMatches_selectMLS (
- ZSTD_CCtx* zc, /* Index table will be updated */
- const BYTE* ip, const BYTE* const iHighLimit,
- const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
-{
- switch(matchLengthSearch)
- {
- case 3 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
- default :
- case 4 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
- case 5 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
- case 7 :
- case 6 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
- }
-}
-
-/** Tree updater, providing best match */
-static U32 ZSTD_BtGetAllMatches_extDict (
- ZSTD_CCtx* zc,
- const BYTE* const ip, const BYTE* const iLimit,
- const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
-{
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
- ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
- return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 1, matches, minMatchLen);
-}
-
-
-static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
- ZSTD_CCtx* zc, /* Index table will be updated */
- const BYTE* ip, const BYTE* const iHighLimit,
- const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
-{
- switch(matchLengthSearch)
- {
- case 3 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
- default :
- case 4 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
- case 5 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
- case 7 :
- case 6 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
- }
-}
-
-
-/*-*******************************
-* Optimal parser
-*********************************/
-FORCE_INLINE_TEMPLATE
-void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize, const int ultra)
-{
- seqStore_t* seqStorePtr = &(ctx->seqStore);
- optState_t* optStatePtr = &(ctx->optState);
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - 8;
- const BYTE* const base = ctx->base;
- const BYTE* const prefixStart = base + ctx->dictLimit;
-
- const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;
- const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;
- const U32 mls = ctx->appliedParams.cParams.searchLength;
- const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;
-
- ZSTD_optimal_t* opt = optStatePtr->priceTable;
- ZSTD_match_t* matches = optStatePtr->matchTable;
- const BYTE* inr;
- U32 offset, rep[ZSTD_REP_NUM];
-
- /* init */
- ctx->nextToUpdate3 = ctx->nextToUpdate;
- ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize);
- ip += (ip==prefixStart);
- { U32 i; for (i=0; irep[i]; }
-
- /* Match Loop */
- while (ip < ilimit) {
- U32 cur, match_num, last_pos, litlen, price;
- U32 u, mlen, best_mlen, best_off, litLength;
- memset(opt, 0, sizeof(ZSTD_optimal_t));
- last_pos = 0;
- litlen = (U32)(ip - anchor);
-
- /* check repCode */
- { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
- for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
- && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repCur, minMatch))) {
- mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
- if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
- best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
- goto _storeSequence;
- }
- best_off = i - (ip == anchor);
- do {
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
- if (mlen > last_pos || price < opt[mlen].price)
- SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
- mlen--;
- } while (mlen >= minMatch);
- } } }
-
- match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
-
- if (!last_pos && !match_num) { ip++; continue; }
-
- if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
- best_mlen = matches[match_num-1].len;
- best_off = matches[match_num-1].off;
- cur = 0;
- last_pos = 1;
- goto _storeSequence;
- }
-
- /* set prices using matches at position = 0 */
- best_mlen = (last_pos) ? last_pos : minMatch;
- for (u = 0; u < match_num; u++) {
- mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
- best_mlen = matches[u].len;
- while (mlen <= best_mlen) {
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
- if (mlen > last_pos || price < opt[mlen].price)
- SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */
- mlen++;
- } }
-
- if (last_pos < minMatch) { ip++; continue; }
-
- /* initialize opt[0] */
- { U32 i ; for (i=0; i litlen) {
- price = opt[cur - litlen].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-litlen);
- } else
- price = ZSTD_getLiteralPrice(optStatePtr, litlen, anchor);
- } else {
- litlen = 1;
- price = opt[cur - 1].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-1);
- }
-
- if (cur > last_pos || price <= opt[cur].price)
- SET_PRICE(cur, 1, 0, litlen, price);
-
- if (cur == last_pos) break;
-
- if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */
- continue;
-
- mlen = opt[cur].mlen;
- if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
- opt[cur].rep[2] = opt[cur-mlen].rep[1];
- opt[cur].rep[1] = opt[cur-mlen].rep[0];
- opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
- } else {
- opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
- opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
- opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
- }
-
- best_mlen = minMatch;
- { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
- for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
- && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) {
- mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
-
- if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
- best_mlen = mlen; best_off = i; last_pos = cur + 1;
- goto _storeSequence;
- }
-
- best_off = i - (opt[cur].mlen != 1);
- if (mlen > best_mlen) best_mlen = mlen;
-
- do {
- if (opt[cur].mlen == 1) {
- litlen = opt[cur].litlen;
- if (cur > litlen) {
- price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
- } else
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
- } else {
- litlen = 0;
- price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
- }
-
- if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
- SET_PRICE(cur + mlen, mlen, i, litlen, price);
- mlen--;
- } while (mlen >= minMatch);
- } } }
-
- match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
-
- if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
- best_mlen = matches[match_num-1].len;
- best_off = matches[match_num-1].off;
- last_pos = cur + 1;
- goto _storeSequence;
- }
-
- /* set prices using matches at position = cur */
- for (u = 0; u < match_num; u++) {
- mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
- best_mlen = matches[u].len;
-
- while (mlen <= best_mlen) {
- if (opt[cur].mlen == 1) {
- litlen = opt[cur].litlen;
- if (cur > litlen)
- price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
- else
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
- } else {
- litlen = 0;
- price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
- }
-
- if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
- SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
-
- mlen++;
- } } }
-
- best_mlen = opt[last_pos].mlen;
- best_off = opt[last_pos].off;
- cur = last_pos - best_mlen;
-
- /* store sequence */
-_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
- opt[0].mlen = 1;
-
- while (1) {
- mlen = opt[cur].mlen;
- offset = opt[cur].off;
- opt[cur].mlen = best_mlen;
- opt[cur].off = best_off;
- best_mlen = mlen;
- best_off = offset;
- if (mlen > cur) break;
- cur -= mlen;
- }
-
- for (u = 0; u <= last_pos;) {
- u += opt[u].mlen;
- }
-
- for (cur=0; cur < last_pos; ) {
- mlen = opt[cur].mlen;
- if (mlen == 1) { ip++; cur++; continue; }
- offset = opt[cur].off;
- cur += mlen;
- litLength = (U32)(ip - anchor);
-
- if (offset > ZSTD_REP_MOVE_OPT) {
- rep[2] = rep[1];
- rep[1] = rep[0];
- rep[0] = offset - ZSTD_REP_MOVE_OPT;
- offset--;
- } else {
- if (offset != 0) {
- best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
- if (offset != 1) rep[2] = rep[1];
- rep[1] = rep[0];
- rep[0] = best_off;
- }
- if (litLength==0) offset--;
- }
-
- ZSTD_updatePrice(optStatePtr, litLength, anchor, offset, mlen-MINMATCH);
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
- anchor = ip = ip + mlen;
- } } /* for (cur=0; cur < last_pos; ) */
-
- /* Save reps for next block */
- { int i; for (i=0; irepToConfirm[i] = rep[i]; }
-
- /* Last Literals */
- { size_t const lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-
-FORCE_INLINE_TEMPLATE
-void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
- const void* src, size_t srcSize, const int ultra)
-{
- seqStore_t* seqStorePtr = &(ctx->seqStore);
- optState_t* optStatePtr = &(ctx->optState);
- const BYTE* const istart = (const BYTE*)src;
- const BYTE* ip = istart;
- const BYTE* anchor = istart;
- const BYTE* const iend = istart + srcSize;
- const BYTE* const ilimit = iend - 8;
- const BYTE* const base = ctx->base;
- const U32 lowestIndex = ctx->lowLimit;
- const U32 dictLimit = ctx->dictLimit;
- const BYTE* const prefixStart = base + dictLimit;
- const BYTE* const dictBase = ctx->dictBase;
- const BYTE* const dictEnd = dictBase + dictLimit;
-
- const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;
- const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;
- const U32 mls = ctx->appliedParams.cParams.searchLength;
- const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;
-
- ZSTD_optimal_t* opt = optStatePtr->priceTable;
- ZSTD_match_t* matches = optStatePtr->matchTable;
- const BYTE* inr;
-
- /* init */
- U32 offset, rep[ZSTD_REP_NUM];
- { U32 i; for (i=0; irep[i]; }
-
- ctx->nextToUpdate3 = ctx->nextToUpdate;
- ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize);
- ip += (ip==prefixStart);
-
- /* Match Loop */
- while (ip < ilimit) {
- U32 cur, match_num, last_pos, litlen, price;
- U32 u, mlen, best_mlen, best_off, litLength;
- U32 current = (U32)(ip-base);
- memset(opt, 0, sizeof(ZSTD_optimal_t));
- last_pos = 0;
- opt[0].litlen = (U32)(ip - anchor);
-
- /* check repCode */
- { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
- for (i = (ip==anchor); i 0 && repCur <= (S32)current)
- && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
- && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
- /* repcode detected we should take it */
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
- mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
-
- if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
- best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
- goto _storeSequence;
- }
-
- best_off = i - (ip==anchor);
- litlen = opt[0].litlen;
- do {
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
- if (mlen > last_pos || price < opt[mlen].price)
- SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
- mlen--;
- } while (mlen >= minMatch);
- } } }
-
- match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */
-
- if (!last_pos && !match_num) { ip++; continue; }
-
- { U32 i; for (i=0; i sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
- best_mlen = matches[match_num-1].len;
- best_off = matches[match_num-1].off;
- cur = 0;
- last_pos = 1;
- goto _storeSequence;
- }
-
- best_mlen = (last_pos) ? last_pos : minMatch;
-
- /* set prices using matches at position = 0 */
- for (u = 0; u < match_num; u++) {
- mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
- best_mlen = matches[u].len;
- litlen = opt[0].litlen;
- while (mlen <= best_mlen) {
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
- if (mlen > last_pos || price < opt[mlen].price)
- SET_PRICE(mlen, mlen, matches[u].off, litlen, price);
- mlen++;
- } }
-
- if (last_pos < minMatch) {
- ip++; continue;
- }
-
- /* check further positions */
- for (cur = 1; cur <= last_pos; cur++) {
- inr = ip + cur;
-
- if (opt[cur-1].mlen == 1) {
- litlen = opt[cur-1].litlen + 1;
- if (cur > litlen) {
- price = opt[cur - litlen].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-litlen);
- } else
- price = ZSTD_getLiteralPrice(optStatePtr, litlen, anchor);
- } else {
- litlen = 1;
- price = opt[cur - 1].price + ZSTD_getLiteralPrice(optStatePtr, litlen, inr-1);
- }
-
- if (cur > last_pos || price <= opt[cur].price)
- SET_PRICE(cur, 1, 0, litlen, price);
-
- if (cur == last_pos) break;
-
- if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */
- continue;
-
- mlen = opt[cur].mlen;
- if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
- opt[cur].rep[2] = opt[cur-mlen].rep[1];
- opt[cur].rep[1] = opt[cur-mlen].rep[0];
- opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
- } else {
- opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
- opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
- opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
- }
-
- best_mlen = minMatch;
- { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
- for (i = (mlen != 1); i 0 && repCur <= (S32)(current+cur))
- && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
- && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
- /* repcode detected */
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
- mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
-
- if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
- best_mlen = mlen; best_off = i; last_pos = cur + 1;
- goto _storeSequence;
- }
-
- best_off = i - (opt[cur].mlen != 1);
- if (mlen > best_mlen) best_mlen = mlen;
-
- do {
- if (opt[cur].mlen == 1) {
- litlen = opt[cur].litlen;
- if (cur > litlen) {
- price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
- } else
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
- } else {
- litlen = 0;
- price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
- }
-
- if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
- SET_PRICE(cur + mlen, mlen, i, litlen, price);
- mlen--;
- } while (mlen >= minMatch);
- } } }
-
- match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
-
- if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
- best_mlen = matches[match_num-1].len;
- best_off = matches[match_num-1].off;
- last_pos = cur + 1;
- goto _storeSequence;
- }
-
- /* set prices using matches at position = cur */
- for (u = 0; u < match_num; u++) {
- mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
- best_mlen = matches[u].len;
-
- while (mlen <= best_mlen) {
- if (opt[cur].mlen == 1) {
- litlen = opt[cur].litlen;
- if (cur > litlen)
- price = opt[cur - litlen].price + ZSTD_getPrice(optStatePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
- else
- price = ZSTD_getPrice(optStatePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
- } else {
- litlen = 0;
- price = opt[cur].price + ZSTD_getPrice(optStatePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
- }
-
- if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
- SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
-
- mlen++;
- } } } /* for (cur = 1; cur <= last_pos; cur++) */
-
- best_mlen = opt[last_pos].mlen;
- best_off = opt[last_pos].off;
- cur = last_pos - best_mlen;
-
- /* store sequence */
-_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
- opt[0].mlen = 1;
-
- while (1) {
- mlen = opt[cur].mlen;
- offset = opt[cur].off;
- opt[cur].mlen = best_mlen;
- opt[cur].off = best_off;
- best_mlen = mlen;
- best_off = offset;
- if (mlen > cur) break;
- cur -= mlen;
- }
-
- for (u = 0; u <= last_pos; ) {
- u += opt[u].mlen;
- }
-
- for (cur=0; cur < last_pos; ) {
- mlen = opt[cur].mlen;
- if (mlen == 1) { ip++; cur++; continue; }
- offset = opt[cur].off;
- cur += mlen;
- litLength = (U32)(ip - anchor);
-
- if (offset > ZSTD_REP_MOVE_OPT) {
- rep[2] = rep[1];
- rep[1] = rep[0];
- rep[0] = offset - ZSTD_REP_MOVE_OPT;
- offset--;
- } else {
- if (offset != 0) {
- best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
- if (offset != 1) rep[2] = rep[1];
- rep[1] = rep[0];
- rep[0] = best_off;
- }
-
- if (litLength==0) offset--;
- }
-
- ZSTD_updatePrice(optStatePtr, litLength, anchor, offset, mlen-MINMATCH);
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
- anchor = ip = ip + mlen;
- } } /* for (cur=0; cur < last_pos; ) */
-
- /* Save reps for next block */
- { int i; for (i=0; irepToConfirm[i] = rep[i]; }
-
- /* Last Literals */
- { size_t lastLLSize = iend - anchor;
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
- seqStorePtr->lit += lastLLSize;
- }
-}
-
-#endif /* ZSTD_OPT_H_91842398743 */
+#endif /* ZSTD_OPT_H */
From a4eac0db2916592f073011c971e822c4329a063d Mon Sep 17 00:00:00 2001
From: Nick Terrell
Date: Fri, 1 Sep 2017 18:22:31 -0700
Subject: [PATCH 103/248] Update build scripts
---
build/VS2008/fullbench/fullbench.vcproj | 36 +++++++++++++++++-
build/VS2008/fuzzer/fuzzer.vcproj | 36 +++++++++++++++++-
build/VS2008/zstd/zstd.vcproj | 40 ++++++++++++++++++--
build/VS2008/zstdlib/zstdlib.vcproj | 36 +++++++++++++++++-
build/VS2010/fullbench/fullbench.vcxproj | 8 ++++
build/VS2010/fuzzer/fuzzer.vcxproj | 8 ++++
build/VS2010/libzstd-dll/libzstd-dll.vcxproj | 8 ++++
build/VS2010/libzstd/libzstd.vcxproj | 8 ++++
build/VS2010/zstd/zstd.vcxproj | 8 ++++
build/cmake/lib/CMakeLists.txt | 9 +++++
10 files changed, 187 insertions(+), 10 deletions(-)
diff --git a/build/VS2008/fullbench/fullbench.vcproj b/build/VS2008/fullbench/fullbench.vcproj
index 942934561..05ec5ca06 100644
--- a/build/VS2008/fullbench/fullbench.vcproj
+++ b/build/VS2008/fullbench/fullbench.vcproj
@@ -388,6 +388,22 @@
RelativePath="..\..\..\tests\fullbench.c"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/VS2008/fuzzer/fuzzer.vcproj b/build/VS2008/fuzzer/fuzzer.vcproj
index f1719e8ac..700dd7ebd 100644
--- a/build/VS2008/fuzzer/fuzzer.vcproj
+++ b/build/VS2008/fuzzer/fuzzer.vcproj
@@ -400,6 +400,22 @@
RelativePath="..\..\..\lib\decompress\zstd_decompress.c"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/VS2008/zstd/zstd.vcproj b/build/VS2008/zstd/zstd.vcproj
index 2e2923d55..86dd3a254 100644
--- a/build/VS2008/zstd/zstd.vcproj
+++ b/build/VS2008/zstd/zstd.vcproj
@@ -444,6 +444,22 @@
RelativePath="..\..\..\lib\compress\zstdmt_compress.c"
>
+
+
+
+
+
+
+
+
-
-
@@ -558,6 +570,26 @@
RelativePath="..\..\..\lib\compress\zstdmt_compress.h"
>
+
+
+
+
+
+
+
+
+
+
diff --git a/build/VS2008/zstdlib/zstdlib.vcproj b/build/VS2008/zstdlib/zstdlib.vcproj
index ac85f7aeb..ac8f896c3 100644
--- a/build/VS2008/zstdlib/zstdlib.vcproj
+++ b/build/VS2008/zstdlib/zstdlib.vcproj
@@ -388,6 +388,22 @@
RelativePath="..\..\..\lib\compress\zstd_compress.c"
>
+
+
+
+
+
+
+
+
@@ -495,11 +511,27 @@
>
+
+
+
+
+
+
+
+
+
+
+
+
@@ -180,6 +184,10 @@
+
+
+
+
diff --git a/build/VS2010/fuzzer/fuzzer.vcxproj b/build/VS2010/fuzzer/fuzzer.vcxproj
index 12a4b9313..9f00899da 100644
--- a/build/VS2010/fuzzer/fuzzer.vcxproj
+++ b/build/VS2010/fuzzer/fuzzer.vcxproj
@@ -165,6 +165,10 @@
+
+
+
+
@@ -183,6 +187,10 @@
+
+
+
+
diff --git a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj
index 364b3bea5..0a4be69df 100644
--- a/build/VS2010/libzstd-dll/libzstd-dll.vcxproj
+++ b/build/VS2010/libzstd-dll/libzstd-dll.vcxproj
@@ -29,6 +29,10 @@
+
+
+
+
@@ -67,6 +71,10 @@
+
+
+
+
diff --git a/build/VS2010/libzstd/libzstd.vcxproj b/build/VS2010/libzstd/libzstd.vcxproj
index 6087d737c..51b840677 100644
--- a/build/VS2010/libzstd/libzstd.vcxproj
+++ b/build/VS2010/libzstd/libzstd.vcxproj
@@ -29,6 +29,10 @@
+
+
+
+
@@ -67,6 +71,10 @@
+
+
+
+
diff --git a/build/VS2010/zstd/zstd.vcxproj b/build/VS2010/zstd/zstd.vcxproj
index 438dc6173..90470180d 100644
--- a/build/VS2010/zstd/zstd.vcxproj
+++ b/build/VS2010/zstd/zstd.vcxproj
@@ -30,6 +30,10 @@
+
+
+
+
@@ -60,6 +64,10 @@
+
+
+
+
diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt
index 8371192c5..f4b7e3753 100644
--- a/build/cmake/lib/CMakeLists.txt
+++ b/build/cmake/lib/CMakeLists.txt
@@ -38,6 +38,10 @@ SET(Sources
${LIBRARY_DIR}/compress/huf_compress.c
${LIBRARY_DIR}/compress/zstd_compress.c
${LIBRARY_DIR}/compress/zstdmt_compress.c
+ ${LIBRARY_DIR}/compress/zstd_fast.c
+ ${LIBRARY_DIR}/compress/zstd_double_fast.c
+ ${LIBRARY_DIR}/compress/zstd_lazy.c
+ ${LIBRARY_DIR}/compress/zstd_opt.c
${LIBRARY_DIR}/decompress/huf_decompress.c
${LIBRARY_DIR}/decompress/zstd_decompress.c
${LIBRARY_DIR}/dictBuilder/cover.c
@@ -58,6 +62,11 @@ SET(Headers
${LIBRARY_DIR}/common/huf.h
${LIBRARY_DIR}/common/mem.h
${LIBRARY_DIR}/common/zstd_internal.h
+ ${LIBRARY_DIR}/compress/zstd_compress.h
+ ${LIBRARY_DIR}/compress/zstd_fast.h
+ ${LIBRARY_DIR}/compress/zstd_double_fast.h
+ ${LIBRARY_DIR}/compress/zstd_lazy.h
+ ${LIBRARY_DIR}/compress/zstd_opt.h
${LIBRARY_DIR}/compress/zstdmt_compress.h
${LIBRARY_DIR}/dictBuilder/zdict.h
${LIBRARY_DIR}/deprecated/zbuff.h)
From 98b85426f1e777b6e607dc1281e292dc00a2f6e5 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 5 Sep 2017 20:41:37 -0700
Subject: [PATCH 104/248] Fix setting of nextToUpdate at end of ldm matcher
---
lib/compress/zstd_compress.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 7863fae0a..bbca6729d 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -1030,6 +1030,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
}
/* ldm space */
+ /* TODO */
if (params.ldmParams.enableLdm) {
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
size_t const ldmBucketSize =
@@ -3580,7 +3581,7 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
ZSTD_ldm_fillFastTables(cctx, anchor);
lastLiterals = blockCompressor(cctx, anchor, iend - anchor);
- cctx->nextToUpdate = (U32)(ip - base);
+ cctx->nextToUpdate = (U32)(iend - base);
/* Restore seqStorePtr->rep */
for (i = 0; i < ZSTD_REP_NUM; i++)
@@ -3805,7 +3806,7 @@ static size_t ZSTD_compressBlock_ldm_extDict_generic(
/* Call the block compressor one last time on the last literals */
lastLiterals = blockCompressor(ctx, anchor, iend - anchor);
- ctx->nextToUpdate = (U32)(ip - base);
+ ctx->nextToUpdate = (U32)(iend - base);
/* Restore seqStorePtr->rep */
for (i = 0; i < ZSTD_REP_NUM; i++)
From c706de53959eb9e245183f5c39220245600c7ada Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 5 Sep 2017 21:11:18 -0700
Subject: [PATCH 105/248] Rename and add short ldm parameters in cli
---
lib/compress/zstd_compress.c | 13 +++++--------
lib/zstd.h | 2 +-
programs/zstd.1 | 16 ++++++++--------
programs/zstd.1.md | 18 +++++++++---------
programs/zstdcli.c | 8 ++++----
5 files changed, 27 insertions(+), 30 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index bbca6729d..b88d53de5 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -342,7 +342,7 @@ size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThre
static size_t ZSTD_ldm_initializeParameters(ldmParams_t* params, U32 enableLdm)
{
- assert(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX);
+ ZSTD_STATIC_ASSERT(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX);
params->enableLdm = enableLdm>0;
params->hashLog = LDM_HASH_LOG;
params->bucketSizeLog = LDM_BUCKET_SIZE_LOG;
@@ -3568,8 +3568,6 @@ size_t ZSTD_compressBlock_ldm_generic(ZSTD_CCtx* cctx,
}
ip += rLength;
anchor = ip;
-
- continue; /* faster when present ... (?) */
}
}
@@ -3836,12 +3834,11 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
const U32 current = (U32)(istart-base);
size_t lastLLSize;
const BYTE* anchor;
+ U32 const extDict = zc->lowLimit < zc->dictLimit;
const ZSTD_blockCompressor blockCompressor =
- zc->appliedParams.ldmParams.enableLdm ?
- (zc->lowLimit < zc->dictLimit ? ZSTD_compressBlock_ldm_extDict :
- ZSTD_compressBlock_ldm) :
- ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
- zc->lowLimit < zc->dictLimit);
+ zc->appliedParams.ldmParams.enableLdm
+ ? (extDict ? ZSTD_compressBlock_ldm_extDict : ZSTD_compressBlock_ldm)
+ : ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, extDict);
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
ZSTD_resetSeqStore(&(zc->seqStore));
diff --git a/lib/zstd.h b/lib/zstd.h
index 4879c4a63..662657b23 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -979,7 +979,7 @@ typedef enum {
/* advanced parameters - may not remain available after API update */
ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
* even when referencing into Dictionary content (default:0) */
- ZSTD_p_enableLongDistanceMatching, /* Enable long distance matching.
+ ZSTD_p_enableLongDistanceMatching=1200, /* Enable long distance matching.
* This parameter is designed to improve the compression
* ratio for large inputs with long distance matches.
* This increases the memory usage as well as window size.
diff --git a/programs/zstd.1 b/programs/zstd.1
index 13c804ae5..0fad1d277 100644
--- a/programs/zstd.1
+++ b/programs/zstd.1
@@ -327,7 +327,7 @@ Determine \fBoverlapSize\fR, amount of data reloaded from previous job\. This pa
The minimum \fIovlog\fR is 0, and the maximum is 9\. 0 means "no overlap", hence completely independent jobs\. 9 means "full overlap", meaning up to \fBwindowSize\fR is reloaded from previous job\. Reducing \fIovlog\fR by 1 reduces the amount of reload by a factor 2\. Default \fIovlog\fR is 6, which means "reload \fBwindowSize / 8\fR"\. Exception : the maximum compression level (22) has a default \fIovlog\fR of 9\.
.
.TP
-\fBldmHashLog\fR=\fIldmHlog\fR, \fBldmHlog\fR=\fIldmHlog\fR
+\fBldmHashLog\fR=\fIldmhlog\fR, \fBldmhlog\fR=\fIldmhlog\fR
Specify the maximum size for a hash table used for long distance matching\.
.
.IP
@@ -337,10 +337,10 @@ This option is ignored unless long distance matching is enabled\.
Bigger hash tables usually improve compression ratio at the expense of more memory during compression and a decrease in compression speed\.
.
.IP
-The minimum \fIldmHlog\fR is 6 and the maximum is 26 (default: 20)\.
+The minimum \fIldmhlog\fR is 6 and the maximum is 26 (default: 20)\.
.
.TP
-\fBldmSearchLength\fR=\fIldmSlen\fR, \fBldmSlen\fR=\fIldmSlen\fR
+\fBldmSearchLength\fR=\fIldmslen\fR, \fBldmSlen\fR=\fIldmslen\fR
Specify the minimum searched length of a match for long distance matching\.
.
.IP
@@ -350,10 +350,10 @@ This option is ignored unless long distance matching is enabled\.
Larger/very small values usually decrease compression ratio\.
.
.IP
-The minumum \fIldmSlen\fR is 4 and the maximum is 4096 (default: 64)\.
+The minumum \fIldmslen\fR is 4 and the maximum is 4096 (default: 64)\.
.
.TP
-\fBldmBucketSizeLog\fR=\fIldmBucketSizeLog\fR
+\fBldmBucketSizeLog\fR=\fIldmblog\fR, \fBldmblog\fR=\fIldmblog\fR
Specify the size of each bucket for the hash table used for long distance matching\.
.
.IP
@@ -363,10 +363,10 @@ This option is ignored unless long distance matching is enabled\.
Larger bucket sizes improve collision resolution but decrease compression speed\.
.
.IP
-The minimum \fIldmBucketSizeLog\fR is 0 and the maximum is 8 (default: 3)\.
+The minimum \fIldmblog\fR is 0 and the maximum is 8 (default: 3)\.
.
.TP
-\fBldmHashEveryLog\fR=\fIldmHashEveryLog\fR
+\fBldmHashEveryLog\fR=\fIldmhevery\fR, \fBldmhevery\fR=\fIldmhevery\fR
Specify the frequency of inserting entries into the long distance matching hash table\.
.
.IP
@@ -376,7 +376,7 @@ This option is ignored unless long distance matching is enabled\.
Larger values will improve compression speed\. Deviating far from the default value will likely result in a decrease in compression ratio\.
.
.IP
-The default value is \fBwLog \- ldmHlog\fR\.
+The default value is \fBwlog \- ldmhlog\fR\.
.
.SS "\-B#:"
Select the size of each compression job\. This parameter is available only when multi\-threading is enabled\. Default value is \fB4 * windowSize\fR, which means it varies depending on compression level\. \fB\-B#\fR makes it possible to select a custom value\. Note that job size must respect a minimum value which is enforced transparently\. This minimum is either 1 MB, or \fBoverlapSize\fR, whichever is largest\.
diff --git a/programs/zstd.1.md b/programs/zstd.1.md
index 5f6aa4500..2fcedde3c 100644
--- a/programs/zstd.1.md
+++ b/programs/zstd.1.md
@@ -333,7 +333,7 @@ The list of available _options_:
Default _ovlog_ is 6, which means "reload `windowSize / 8`".
Exception : the maximum compression level (22) has a default _ovlog_ of 9.
-- `ldmHashLog`=_ldmHlog_, `ldmHlog`=_ldmHlog_:
+- `ldmHashLog`=_ldmhlog_, `ldmhlog`=_ldmhlog_:
Specify the maximum size for a hash table used for long distance matching.
This option is ignored unless long distance matching is enabled.
@@ -341,18 +341,18 @@ The list of available _options_:
Bigger hash tables usually improve compression ratio at the expense of more
memory during compression and a decrease in compression speed.
- The minimum _ldmHlog_ is 6 and the maximum is 26 (default: 20).
+ The minimum _ldmhlog_ is 6 and the maximum is 26 (default: 20).
-- `ldmSearchLength`=_ldmSlen_, `ldmSlen`=_ldmSlen_:
+- `ldmSearchLength`=_ldmslen_, `ldmslen`=_ldmslen_:
Specify the minimum searched length of a match for long distance matching.
This option is ignored unless long distance matching is enabled.
Larger/very small values usually decrease compression ratio.
- The minumum _ldmSlen_ is 4 and the maximum is 4096 (default: 64).
+ The minumum _ldmslen_ is 4 and the maximum is 4096 (default: 64).
-- `ldmBucketSizeLog`=_ldmBucketSizeLog_:
+- `ldmBucketSizeLog`=_ldmblog_, `ldmblog`=_ldmblog_:
Specify the size of each bucket for the hash table used for long distance
matching.
@@ -361,9 +361,9 @@ The list of available _options_:
Larger bucket sizes improve collision resolution but decrease compression
speed.
- The minimum _ldmBucketSizeLog_ is 0 and the maximum is 8 (default: 3).
+ The minimum _ldmblog_ is 0 and the maximum is 8 (default: 3).
-- `ldmHashEveryLog`=_ldmHashEveryLog_:
+- `ldmHashEveryLog`=_ldmhevery_, `ldmhevery`=_ldmhevery_:
Specify the frequency of inserting entries into the long distance matching
hash table.
@@ -372,8 +372,8 @@ The list of available _options_:
Larger values will improve compression speed. Deviating far from the
default value will likely result in a decrease in compression ratio.
- The default value is `wLog - ldmHlog`.
-
+ The default value is `wlog - ldmhlog`.
+
### -B#:
Select the size of each compression job.
This parameter is available only when multi-threading is enabled.
diff --git a/programs/zstdcli.c b/programs/zstdcli.c
index a60537a0c..a3d508515 100644
--- a/programs/zstdcli.c
+++ b/programs/zstdcli.c
@@ -310,10 +310,10 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi
if (longCommandWArg(&stringPtr, "targetLength=") || longCommandWArg(&stringPtr, "tlen=")) { params->targetLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "strategy=") || longCommandWArg(&stringPtr, "strat=")) { params->strategy = (ZSTD_strategy)(readU32FromChar(&stringPtr)); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
if (longCommandWArg(&stringPtr, "overlapLog=") || longCommandWArg(&stringPtr, "ovlog=")) { g_overlapLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
- if (longCommandWArg(&stringPtr, "ldmHashLog=") || longCommandWArg(&stringPtr, "ldmHlog=")) { g_ldmHashLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
- if (longCommandWArg(&stringPtr, "ldmSearchLength=") || longCommandWArg(&stringPtr, "ldmSlen=")) { g_ldmMinMatch = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
- if (longCommandWArg(&stringPtr, "ldmBucketSizeLog=")) { g_ldmBucketSizeLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
- if (longCommandWArg(&stringPtr, "ldmHashEveryLog=")) { g_ldmHashEveryLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmHashLog=") || longCommandWArg(&stringPtr, "ldmhlog=")) { g_ldmHashLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmSearchLength=") || longCommandWArg(&stringPtr, "ldmslen=")) { g_ldmMinMatch = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmBucketSizeLog=") || longCommandWArg(&stringPtr, "ldmblog")) { g_ldmBucketSizeLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
+ if (longCommandWArg(&stringPtr, "ldmHashEveryLog=") || longCommandWArg(&stringPtr, "ldmhevery")) { g_ldmHashEveryLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; }
return 0;
}
From af4068a697f67bebdc100279d55c485271e96ab7 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Tue, 5 Sep 2017 22:14:41 -0700
Subject: [PATCH 106/248] Fix function name in tests/fuzz/regression_driver
---
tests/fuzz/regression_driver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/fuzz/regression_driver.c b/tests/fuzz/regression_driver.c
index 41fdcc940..36ae3884f 100644
--- a/tests/fuzz/regression_driver.c
+++ b/tests/fuzz/regression_driver.c
@@ -39,7 +39,7 @@ int main(int argc, char const **argv) {
FILE *file;
/* Check that it is a regular file, and that the fileSize is valid */
- FUZZ_ASSERT_MSG(UTIL_isRegFile(fileName), fileName);
+ FUZZ_ASSERT_MSG(UTIL_isRegularFile(fileName), fileName);
FUZZ_ASSERT_MSG(fileSize <= kMaxFileSize, fileName);
/* Ensure we have a large enough buffer allocated */
if (fileSize > bufferSize) {
From 9e4060200b08623fe03daa6f95125d0e575eb0a2 Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 6 Sep 2017 08:39:46 -0700
Subject: [PATCH 107/248] Add tests and fix pointer alignment
---
lib/compress/zstd_compress.c | 43 ++++++++++++++++++++++--------------
lib/zstd.h | 8 +++----
tests/zstreamtest.c | 12 ++++++++++
3 files changed, 42 insertions(+), 21 deletions(-)
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index b88d53de5..99d5d7963 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -532,7 +532,7 @@ size_t ZSTD_CCtxParam_setParameter(
case ZSTD_p_ldmMinMatch :
if (value == 0) return 0;
- CLAMPCHECK(value, ZSTD_LDM_SEARCHLENGTH_MIN, ZSTD_LDM_SEARCHLENGTH_MAX);
+ CLAMPCHECK(value, ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX);
params->ldmParams.minMatchLength = value;
return 0;
@@ -929,7 +929,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
0 : params.cParams.windowLog - params.ldmParams.hashLog;
}
params.ldmParams.bucketSizeLog =
- MIN(params.ldmParams.bucketSizeLog, params.ldmParams.hashLog);
+ MIN(params.ldmParams.bucketSizeLog, params.ldmParams.hashLog);
zc->ldmState.hashPower =
ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
}
@@ -949,10 +949,6 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? ((size_t)1 << params.cParams.windowLog) + blockSize : 0;
void* ptr;
- size_t const ldmSpace = params.ldmParams.enableLdm ?
- ZSTD_ldm_getTableSize(params.ldmParams.hashLog,
- params.ldmParams.bucketSizeLog) : 0;
-
/* Check if workSpace is large enough, alloc a new one if needed */
{ size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<optState.priceTable + ZSTD_OPT_NUM+1;
}
- /* ldm space */
- /* TODO */
+ /* ldm hash table */
+ /* initialize bucketOffsets table later for pointer alignment */
if (params.ldmParams.enableLdm) {
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
- size_t const ldmBucketSize =
- ((size_t)1) << (params.ldmParams.hashLog - params.ldmParams.bucketSizeLog);
- memset(ptr, 0, ldmSpace);
+ memset(ptr, 0, ldmHSize * sizeof(ldmEntry_t));
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
ptr = zc->ldmState.hashTable + ldmHSize;
- zc->ldmState.bucketOffsets = (BYTE*)ptr;
- ptr = zc->ldmState.bucketOffsets + ldmBucketSize;
}
/* table Space */
@@ -1060,6 +1055,17 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
ptr = zc->seqStore.litStart + blockSize;
+ /* ldm bucketOffsets table */
+ if (params.ldmParams.enableLdm) {
+ size_t const ldmBucketSize =
+ ((size_t)1) << (params.ldmParams.hashLog -
+ params.ldmParams.bucketSizeLog);
+ assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
+ memset(ptr, 0, ldmBucketSize);
+ zc->ldmState.bucketOffsets = (BYTE*)ptr;
+ ptr = zc->ldmState.bucketOffsets + ldmBucketSize;
+ }
+
/* buffers */
zc->inBuffSize = buffInSize;
zc->inBuff = (char*)ptr;
@@ -3159,11 +3165,12 @@ static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int
/** ZSTD_ldm_getSmallHash() :
* numBits should be <= 32
- * @return : the most significant numBits of value */
+ * If numBits==0, returns 0.
+ * @return : the most significant numBits of value. */
static U32 ZSTD_ldm_getSmallHash(U64 value, U32 numBits)
{
assert(numBits <= 32);
- return (U32)(value >> (64 - numBits));
+ return numBits == 0 ? 0 : (U32)(value >> (64 - numBits));
}
/** ZSTD_ldm_getChecksum() :
@@ -3183,6 +3190,7 @@ static U32 ZSTD_ldm_getChecksum(U64 hash, U32 numBitsToDiscard)
* numTagBits bits. */
static U32 ZSTD_ldm_getTag(U64 hash, U32 hbits, U32 numTagBits)
{
+ assert(numTagBits <= 32 && hbits <= 32);
if (32 - hbits < numTagBits) {
return hash & ((1 << numTagBits) - 1);
} else {
@@ -3221,7 +3229,8 @@ static void ZSTD_ldm_insertEntry(ldmState_t* ldmState,
* of rollingHash. The checksum is the next 32 most significant bits, followed
* by ldmParams.hashEveryLog bits that make up the tag. */
static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,
- U64 rollingHash, U32 hBits,
+ U64 const rollingHash,
+ U32 const hBits,
U32 const offset,
ldmParams_t const ldmParams)
{
@@ -3272,7 +3281,7 @@ static U64 ZSTD_ldm_ipow(U64 base, U64 exp)
}
static U64 ZSTD_ldm_getHashPower(U32 minMatchLength) {
- assert(minMatchLength >= ZSTD_LDM_SEARCHLENGTH_MIN);
+ assert(minMatchLength >= ZSTD_LDM_MINMATCH_MIN);
return ZSTD_ldm_ipow(prime8bytes, minMatchLength - 1);
}
diff --git a/lib/zstd.h b/lib/zstd.h
index 662657b23..794a855a4 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -390,8 +390,8 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output
#define ZSTD_SEARCHLENGTH_MIN 3 /* only for ZSTD_btopt, other strategies are limited to 4 */
#define ZSTD_TARGETLENGTH_MIN 4
#define ZSTD_TARGETLENGTH_MAX 999
-#define ZSTD_LDM_SEARCHLENGTH_MIN 4
-#define ZSTD_LDM_SEARCHLENGTH_MAX 4096
+#define ZSTD_LDM_MINMATCH_MIN 4
+#define ZSTD_LDM_MINMATCH_MAX 4096
#define ZSTD_LDM_BUCKETSIZELOG_MAX 8
#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
@@ -996,8 +996,8 @@ typedef enum {
* (default: 20). */
ZSTD_p_ldmMinMatch, /* Minimum size of searched matches for long distance matcher.
* Larger/too small values usually decrease compression ratio.
- * Must be clamped between ZSTD_LDM_SEARCHLENGTH_MIN
- * and ZSTD_LDM_SEARCHLENGTH_MAX (default: 64). */
+ * Must be clamped between ZSTD_LDM_MINMATCH_MIN
+ * and ZSTD_LDM_MINMATCH_MAX (default: 64). */
ZSTD_p_ldmBucketSizeLog, /* Log size of each bucket in the LDM hash table for collision resolution.
* Larger values usually improve collision resolution but may decrease
* compression speed.
diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
index 76495d453..1a9aa5064 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -709,6 +709,13 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
+/* Return value in range minVal <= v <= maxVal */
+static U32 FUZ_randomClampedLength(U32* seed, U32 minVal, U32 maxVal)
+{
+ U32 const mod = maxVal < minVal ? 1 : (maxVal + 1) - minVal;
+ return (U32)((FUZ_rand(seed) % mod) + minVal);
+}
+
#define CHECK(cond, ...) { \
if (cond) { \
DISPLAY("Error => "); \
@@ -1380,7 +1387,12 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_minMatch, cParams.searchLength, useOpaqueAPI) );
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_targetLength, cParams.targetLength, useOpaqueAPI) );
+ /* mess with long distance matching parameters */
if (FUZ_rand(&lseed) & 1) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_enableLongDistanceMatching, FUZ_rand(&lseed) & 63, useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 3) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmHashLog, FUZ_randomClampedLength(&lseed, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX), useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 3) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmMinMatch, FUZ_randomClampedLength(&lseed, ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX), useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 3) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmBucketSizeLog, FUZ_randomClampedLength(&lseed, 0, ZSTD_LDM_BUCKETSIZELOG_MAX), useOpaqueAPI) );
+ if (FUZ_rand(&lseed) & 3) CHECK_Z( setCCtxParameter(zc, cctxParams, ZSTD_p_ldmHashEveryLog, FUZ_randomClampedLength(&lseed, 0, ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN), useOpaqueAPI) );
/* unconditionally set, to be sync with decoder */
/* mess with frame parameters */
From 8c33cfe0bc167274415f711643ce39cc02c0848f Mon Sep 17 00:00:00 2001
From: Stella Lau
Date: Wed, 6 Sep 2017 11:03:35 -0700
Subject: [PATCH 108/248] Add ldm documentation in README
---
doc/images/ldmCspeed.png | Bin 0 -> 72251 bytes
doc/images/ldmDspeed.png | Bin 0 -> 27594 bytes
programs/README.md | 58 +++++++++++++++++++++++++++++++++++++++
programs/zstdcli.c | 2 +-
4 files changed, 59 insertions(+), 1 deletion(-)
create mode 100644 doc/images/ldmCspeed.png
create mode 100644 doc/images/ldmDspeed.png
diff --git a/doc/images/ldmCspeed.png b/doc/images/ldmCspeed.png
new file mode 100644
index 0000000000000000000000000000000000000000..d3bfce4c80123bc9bd6ef8f46c76fe79065defa8
GIT binary patch
literal 72251
zcmeAS@N?(olHy`uVBq!ia0y~yU{hjXU|z|=#=yWZJ=dO{fq{XsILO_JVcj{ImkbOH
zoCO|{#S9GMLLkhTKL1h>1A_yDr;B4q1>>8$l_fFPYt?_qJ22b{pD1$F^@`WTNjk1U
zcQz(z=Xy^wKic;u(>?3E#of6YGr!4qUOqm#EZcL+6NApl*DPy=ewU;votn9^*2cI~
z_;zk|P|j-An}Ji7rDjdv(JfRibjMLhfg|Bwt%D;2rwErfW9W+W-lsyp-m5+RH%4jU
z&!c1qXD7gmdG%b?fTa+}@HId|e{$@=|PyAlmja
z@wWP}4qK~L^TiL{7>EiM4gra&2cDgs{rU52_fk=HVYo0lql<$>sq2A-3odhd{2T-f
zt?birn&8U9BIsHmqlDohs7-F_3LO%2=Wpi3;%AVOMkS`E4kZgdK@bO9*en(naOpXB
z{wCH?Q*dZ-5M*?85tM1i6<&=OIXRTvo5DF8;KfjVtaoloUENnjQ<_vcSNK(ecQOKXZI>#gd4i
zfQ!h%!VX*(NX%_eNGhp2r-mz*MtCyNa#*l>^=hVhhm-{r3??`ncCdb{j4h}fRJoTt
zcz82?ey{xB7w#K#Z*Q|GeHC(MzP+Pq9lQd<=Wb4aeup?DJCW+M?O70y?EnB!?HIw
z1YciY-~W7mz1_bb{r`XLF<7*Dv$0&|lZk)!d^w>VzV6KV`j1D&AGeCfb=3a;c67P@
z-!tVqy}keL`uF{IzcS>UbYgZG$klu}xZ^<+_ov6v+w*$ue=WA}IxbhO
zvu@w7S36!VoBeC54vbH^7B&4?ct+U=&;`_7Ur
zeE022u>aHDcAsaS|I#Lq=^l0NWuNuC6aBWI&lvyQ{a?W$;SCFmU~>9PFHiNhtxtEZixC%Za){kv+7|9{Sv?=!Byzai0ij&1d~
zJ&(%-6byL{fIc>h*DgG(EHgfZ_`;+(nd^Y>%_t4d0M;#Q8U0Uk>
z`EUBUIi1PJ`@ULV7iVH|Qx7OKRWi%JXR}KVYrb#f6!-Z5z&jw!Z+2k3p_Tf2JN0UZCahT`P|#r%9&W&)B^$?
zTLh9SnwOhmmK%*;A|BofORrbo|9x+h-M#yN&fY)5U;pE9Ms{}hw{PG6#O?pUysv=P#$o#n#T|V6+bwUifa_+62-|9@x?O4`-(iv>cK+!Suk<>kHmKjzlWo0bv6zc~dY
z8Xa8O1eIU32V*PQR~R-%=kGPWw0gtaJ3Ec{{duZ?e3|d;q_?-WeoU|bmcG|m`O+ru
zOzYBDAq#(2zF%qQa_iZ-xz+a!tvLiFb~YqkRo-5#h8b*(Ork0ql8$!$xbxgjJoD$$
zkk=1iE}#Fdc30%)w5Rj^=h@ucz5ac>33t*8E1}xkzkM1UUNSXxTw1$D1w9E0C^#%Q
z#2WOV;N{Zk&-{1h-`{s{`CRk-xPO+qw@ogTJvh)<)45zEi6`tr)q>A&lpPW>7#)vX
zaEroLO9r?yx%bJOoL_cwlImXn+PkIKk517HR%#Xg{r&y>yYW9hT%P~W^BVv5}#1qhP?AsvMcv
zRxGtnW1)~m;Ukxt@4N5!y35y^fJ%jkT_u@vHaYkA*>20ZIm!O$-12)jce?~X-1u(S
z>vcDFm1f)g|MR)<{oe1-o^RW>?bxrcuOEMTdHLhV{(76R^>MKo@8&Wz8VU)x^aw6F
zjV+iA?3h-v9a;bH)%s(gq+aoKYWSz{hv!aD*YEeQ`!xCEx$=FRH?00{E4umL-uu7z
zR{VI_uG}hSUH8lZeL?(VmStC_LNOqhpk<7z=Ctn|G)41zhq@*
zb{=l$f8KbgRXk3@*Vor|zQWmg6(0_=FJ8P@IsQ=Q!6sJ2D%Ye~BaI_W}tp-Qi0iz9}(U#z7
zQ+Tv50PdP#4i}8%&QQW9j*`++-+AX=a5j3XT`)NLYq2%92IZ9o2QImJ)$evz{Cc@O
z`Sdj1isd|6R@4
zf77$!zzJ3sL0khX!YUi`?(VAibW;8E?(_3(t)HElDa_6%b0S`ILB#H|T%GuRd+uM(
zy|>45Tkh>^`SJJlpKp6#eI}iW#Z6D4Lt^J#V{8)$GZY%cv9P&}_}u)$zU6@AsA;SibxDyy{1`?<>z&9+#5(Q~a`0qf9`8nbAHn
zx#5Knwh-xAf1vjJUGdAyd|#JezPdX6xVzn_i9e2+?-R`Y<{Y(e<+^q2;%9$RW##kr
z^?m+!dox4hCk~CUSh?_URV=;c1wBm9+XPypMbq53Y~AYW?(Uwry_|_fEx!Qd1^n(G@3_&b+imQ<{+}S^YtJ)*GGJ&W8Ew^=uqH
za~tL_-?+I%mC5tK`6>47EXVu~oWFb{a+gqJr@)Vs{&kb?e_J*?PwLCJ|6lz7i_A95
zJ=NTGv|If6rKR4Ff4yGc|Ep^Mc3X{E%q(t-0TUgMX#9E{f^9}4E9Ak}>v7#*yc!R&
z+y6NDS%j-pF|O+6($9TsBQ`44JvOgX290)q?z`y-8uZXI>WJ8yb@fHn(;Oz2qQ*n{
zAAijJ#NKq^1?wN1-g_5BIYe0g*odm^5tfi&zgdUSTb^QdLAF|KQ5iWNAUi?Z`+ff
zpPTzJ{{QRxUj3Sf+=kiL)_gvtgM&hxc;^WPfGIqucE_WsAd@+ZsR+}N0G
zu{_JW!GV*hsY7Uji6W*W9Tpg|{(JZSpPpR(pN}SBujg72Yn-MTXPM!{iTbC=lI*u?UZ($c3#
zS6!au^D@f(UPbbILwODX328>hBR4E|aba5C$SIg%cTJ3cO||W|x0W~G|C7F-)%m5W
z=5J#}_4!#57Tc>|F0AWa^~F0oJKN^d3FV)cmor^?eQmAu2KDPP#lClHzu*12F?M&^
zQD=VJDdMZ*HmCXitNZli;GOq{Oa(Q%*&6i*S)>|>H5KD
z_Qyv$g)0+Zw{nZS)&6}Fy(=riLP}U;bHn@%M$Efyu!L_B=aN|hOY;tAM!zy$y){-V
zYi^o{PTZadj=;6eFLti>au5g%J^VBgOKH4EH$cPZ@3(me?Rl5KeGp#Q!obLMSX{t`
z=l&T;I_@6|jkws7?H
z9!UQG*dG%@&%cAt(-S>Ctt&1|;{o$%L$o3cq0mFyR4;WFkfeo6XcA;*Y
z@xJeG_EjVuK6qo}`;a*&_dS1Yl)72*QcH*Qx;g4C8ofcrrFr`s3Sd)z9yAF_TvMn?KE^=0&`Y-SZjiSvUk{R4|HWsnzk=Fk(qei#SRX3JwV-pegqkmeavO0ZM6b#sLeCC5Ns+Q}|X;%x8e+_b(RfVY&n&
z5)k4b5IE(yBbG8)O7yIe{AKl$JG8)ZK)
z%>)&*U8aRS42(>VLG7dRB6BQLPzGBZqO0Bi9Q?o4ux``Gj4M}{vMkd6egEL$4iTp{
zd((YQ%pzD)Gh%f)1SI?!9gkFG?G}gl7`fhQ6k_q4XD7{X^C@c2r(>OVYhNcl+;i;5
zf%AHOywQC}`)ZeeN?xhv64j@9wnf0{%fn9-85+9;1zbYT1XKuM2{J);Usugq_-O%V
z7Qd=@p=OP)T*UXPoZFY{Z!Yc4-|AAewCYOW^#AVnu9mNxC(i$G_f^BKgHUKVJJkE%eIukBt+F6mn#F7>3AQ1Svp6SbcL{f%2G~o=3*D7YiwDMxmYMGGs
z1~2oghJN!VVJKX{#nN@PQKQhv<=$!UX=he6-K%n8V&RygrqH2r)>9k9`HW1?Ts9jY
zK6sG3X&3*}yzO^)thllaR1z$B#L6NlYVRTksz6Yqa6uGH*VVEU#T`P2I!;eN*JGU*
z7o;2eZ4PMlRFH#!p~^%yR1M%P?WR9LeAT+slRA_VT_81ql=Pp?cV8ThZDeTl5)4?g
zE6D9ou>f+UfPELT_dwUt%gLwLO?LeiIQ^+W?8HwUnZe7yZ1Xl%yj0|qsn#N}X!=oh
zCKk2M28EFVsPbfpoM$Sr(+*~oZVlc*|%+rcx=_m4+~y7h^XulRtVr`N^`k#NaHnT
zj&Zoj^6z+C^T!MScdOpA-lRJH)vHavmsknhto~(jU>V;L28}X71%s8WEP|7(DoXpn
zK1Fu-f;mj_zyF>4vH$aL)3ro1sUsab5HfJW-jELyq<;QN>78r
zqO`Uscg*^?P5T0@CR3XI^@4do#ryL*J!h?>AJyC3ueqmM|Fl{A(PjA^7We<}|8qL^
zx$O3421cf>Y6=}IwhCU4$4D!UlUQc;Z#~NVI<7yr+V5NT{*P;?d92^U6ny3B|B3SX
zbArVG|GpcZwpmf^Yxa9k{e&k$Kd=Gk+xGbGx7E9+hgz+7yftxp^NQ1-I@ZlF-fZ~q
z!~ON0+4{4M6N0Td1r!2KGc|QY$<@|kDF6Z#bdQIav}nwk+A8>Ylfa|%^{;nDY%8cr
zTwf0I!3*Vp`_DJ`V@Z%4DNHNXTvpzG^fS0sU};jOdxL{7*9^hH$%ofn##G)cx@e#7
z>W={$KCxYw&M`0d&RoXJ$i#wkKDY6fsKh3L(zlmhSTZuP90N5to-NVyKqM?^ln0z-
zQWafvjw_%%e6idv_31h@4NH`DIRrq3UY5(14-Z~jp{L0OVys?TE^~`Igtl*)GPxII
z5SzGxa#De`J2=UL1mFy{i4L!4_T8x8p}X(znR|-WQ_r_+BnE-naK~iL^(8-5Nr9%t
zr?IjKZngRK3u7p3h6|JI+}MjXTXet4<@MIKbG=`C^ZT|N)8ASbEwX)|8y+5h2<@
zx0T;Nu8I9--|XAxp?Kt0^);8|W>@#FBrA^whqK%qN?HH<85lsZft
zMPX^aW1#A=d+9FD%#({uq7!ufFZ>tbUG0BiLMw0NfeqgSxTJR3zqh|6HFxgf*WUj(
zzh1O*qu#rnk0%wrjQ(H!8&pD{R95JiVUxU49X;wA3&l}-KKI}~pPFk24($y7Ei3=V
zJIYRzmFM@S2F0^UFZiT(rJF1{zc$@%z6p<^S3(-uKvf?8~e6bi@DrSZauHLz{ByVxP5i3ow1Vc{1Ss`JIz*}=X}
zG_@_h+0$N>`}HQ5SNC(@-nL)6Zd|<+btzY5kzS{#G7}4jh^T;z$kRfMA~+zD>G4jU
zO98h2rwv896}g@-H+W?J@AT(FGj2t`6vZPq^yY``@c#aLPh@Z5#io^o7g;YSd4AiK
z;aD|a%6rpy*GLXSRc^&e5A*;1^nQN!(Tn<}9IY$Pi+-HTz{sQwS~q&;Y$TR&lz5#w
z!Rw`i)|)#;yOjIp=JbcmSFE?MH2eSOto(b;r$UvpW6v(%{QVK@BJZ6ywk-QKuRyVt
z$F|W~&Mc+T`CDz&C|zdO)eN3y%-L?UBDVzBX6a{X#&XA!yiK()6$L&HO{vzIcheM<%hobAb!5p}
zo<|=@>e+eVX5YFWVc(+v`R7E7Qo>to{Yp~?$GKTng7CtqLqtnU0?aAAA=y8MahpFQ_`
z#`mpN=63X(V>g?f?YRHkUg4YCt?Vz0tLkh1{+pEl+kd@WSH;$rm+Y$Xg%8@6o+;3n
zGqY*p{r~0Jj}8e<_t%>992C_otKuC50{l0T$a5*7)}s9Xnatp%
zcV~{hxhjyEx#Y{N>9zMOAC&yLyt@5-uHA$0@m1elHyX{3O#-!!8gB^;xLmn6=Tyh9!Ke}6sOk@ND*y_sCK&aJ|>3!T!#_!kCkU&G>jMze+MrEM#h
zW{k$0*FWccJA1OJ{mVUr)CUh#SuOVee6H_Wq`7VBq4SxU+Mtdn$CYIb3X9B+$F4`M
zFdck3=j6Sfx$uIp$dV5WK6rV{*Zx;us$c!(OZVB2U%GEza(}#sH(hcGYw@f{=f1~W
zk=09abegr-pghcMwqo^s+reZM*ux%Y6dw
zGBtI)lC$^sN38|gbSKnx+n!}uairyF_Ok=D+bZ!0c5
z7cn_A>z+XIrUeT1Ut8E(&)?o0$!=e@atp(g;O)BSyA8zG#h&{fVyvti9@<;K?9|Ig
zw?MJ_VOxX3qg?L!pkfPQ?SUnrLecC&{`&rK$7d{aoEoRiljJbZ=WuE-$Z{l|6&pCDMQo1Y`)UajuPNV6L
zUYlj#?MZ#Pqg6iiWBUPTP=a-=MH)`XP4IqTgUA>m~b?`~N>=Z>)X4($P99%kf!B
zW69n_XPUpnY3!Qw{xoyjmiK=aB(7L=rr9n=l3(QK_y3>YS=mRwdf{we{;<-~iA$Pm
z;h_Xm(Q~_R7?ee@WlBWM0^8>b>K$iU*zlkxCXM+HQC7<%I0APRb1DBj{eQEiUcA|A
z^NbgKB2`YU^Cm3(>XZI(N>_dUsk-F-)of1ReOkWk{5`dm{pR!B-O-O$3ca@bGy8V9
z&yDQAgM)w}Lsu*)oDn^f1Qn*KA=L{PFV^ncGN)5n{nq0TAB_tw
zs{j9=cPF-J`@EWkmh);BZmD8XjW6MmTBh31rRc;Z@ag=`Np7{yt%p7y`aNgOH772m
zuH4Kw+ur^1d}CFzEn>4r>-6_KDm^cnJ+;e_TvEin+YaQ#o~;cENo!nV`@zK}tO1!7
zl&~jDe@>3Aw0qz7;|ql&Ph1c-C}HQlyYTSBoOmwzzPUN}>*qPCilq3}TU;{oFkZgY
zVd3&TC&hplweROGosgv_a;W9YylHl`j8v_6@Nd2JigxCf4sb%
z)tQBBFQaq$27~M<=PTEzs|QFFG^IB9nkQ`ZwNKRiKCk!ASb1UkG^hCiiD_aQKHJtR&Mqu`uIsJ7hV4ko=PUAH
zQzx*f-M=r*S{{sOP@A;(k
zPB^vyjC?Vn@BI9$C2_W`TUxGw>i3Pg=TCnAb)no{RV3xzZyP)4!ojP$3LPunef<0d
zCGi?`9JtwcuIA+8eFvQseLzj2=GHCmkG$O69FzK|?EBok6WDn(#hk@-VkVqT@p#X@
z>AT79M3d8sOMkJgyzz
zzoz=wp@f4@vu+mrdGe!``|!%W8#3-)`7xD0ZVo&5(KP)j**nC}&6SG(^QLs-t0;{V
zF?y-jp>ssPxHy!4W&Q9$6ln~NQUV^QKZjhhcPd|2@bJpbnwyK04mw$t>2NFV+ND-D
zA;|FYPUFpyT$yc7{%>2G-ESuyo^~lq|IXKasUIKC-(BEjJu%Hqa7#@
zr_b-7|1$iEWv%_Jt7#`Tb#UH&^;(%+ym*l6LT(<9P_n$xM)KP4{Rs0;JoS2M<9c}4N8l^@C`KG(@O(QUQeJ<2Up
zY5SI#AiLtkuvHr;?A`R}?8>-azv?U#FgXIpY@h^M)U=l=nheq2opK
zLzJHEG4BMWY3^Q-HfF7V;*s}upQ2(c>Z9ZgM5cLry?-k!EUmXBeU9zohi`vz-Rx#^j@B_ZXCSA#9)q-m#|mS1}PzRlL%DZA$9+0EK2yTAU(eA8O5`3i{-5)}C*H{Ik3
z-Xz64b=S(h0V|as?*u0|hQ>}20T-Vo`>LU-92BGh#Y~H1@qsrfuZQ*QBJI-Mr=x)ZM$
zXFq%!#dCMF1X~o_s{fZkT@Gj##?pXv2<75QuUryxKJnn3Wi^#coDNLja^T;?8}~i&
z!8hgG)@xVV@eA*o?j&Us;o;~U{P?G-np;_TI(#cv$mRxxMYG(`Z$|b-DAURlpUXE}
z@h;6fpD%m+>BKhU!-*I7to*q0_Ox_ksZEmHH+|YfI+iq@ySzD)&kS66fs4e$f&wl)
z?%vS|5f%;}#R-Sn?w(z{QN8+Yo}KJ&{Qhitz-8^Ur%Rg
z=E+=mS=E(hzwu$hn;X|-pZuDnYW!%MwD?nF#TEh8;w%qXQ4-M9psP-Jq~2%I#D!sOiH1
zHbTK*g~QTT-e$XuvICzyj+V%Pn%H2O89kuAOctwtA(rMR2yyX$Sc4x+MDe
zjPDk@i$ikK4rk
z{>nA;oEvk`XIRJz8*WatIn=gLM+PzO6Tl4`3X({zMU2}Ua3RK${CTUUiUcfK@ThzK
zUcL2=1{V{Z7Y1zEka$6{7#8vl4F`5`awr|^z152d{E+1iQGF{TI09dUaw*q6?XQz7kliLn=3il2&z%jVw4&K^@jcPEm`?_ayuOo&T$9?;LeVbJ4md
z-=3T4h;+p5D~JlysH)1*Nh@v1A)C_p_@bd>mLO&<2VYXZGY=p!+
zvnxF9`>yX!Iob0=fBsIhXXo=??Y^Ck(9Dt*;UExrxOx3+xbCak1@GRp)l73XJDj*C
z-F%5a(zPvZ7KOXENDA+-_$;L8^7Y@wPfy^=Sx$kraB{EiMkHYg>Bd8E+P3q}soLG<
zylqO*s=Ef0Zt^zUhDLd19$oZuW6j4eJ1nY~e*aUwO}|wTR!*>6+upASP4Kvjx!eFp
z6*LWA2zL;;7=9SZ)xrt}^EOM1ou4hG9dzP?u*sSo2HdinHY7g0v(mMC-?w?D9}n!h
z4sPd8yk%l`MSO2xGs3+bSLQV+Ec$jVrXSvYRP$IMlxA*X+NYxd9q6fff3x=Ek+$ZI
z$@f>r7+!4wP4NHp;ZQun^7mj7QaLQDr_izD1LLO(xcSNY7wWcc&iTI}j(4-Po7SwR
zHtYPzS^M3pc%LImT!nyYrlyWt(#5v0`t!;bhtC_gF;17b^&`xC$@Ryt`JZ_6@NNyc
zxO21gy;HBu-kj=k?RS6M7IHZ8=AoB{mu~W!{$+P~4)+3wfJ8Z?Lv^XqgJ|p&_4vvQnv!4cop|JK{RTU~Iqyy!?l|=C
z;y(ZRR;pnstqZx2E}EX+*nE?BacC*H!vk%CPX&eC7r{?8h>%m8(4{kdm#lrMS@ta7
zP>E;L(#&Hl>a&*I$vvErZM6=qnPZd78Dm5rU4
zX0d0_--w)hH-na>{&&udTqdH$v+eAOH1jXK(r5A{d`{KDG=PSH(Wh+;PO=2acIfW*
zKjwYA@962)}z-i?%Y}_vPm6#Va?~E%3gHx;s@BR5P|*
z>Vc+zhXqC~e%nir9NX@fVl21mCg069?bq+y2)@1f$y+sdW#q)C(|*N0R<a0SR>s}vjzI}3nAKw@EoLQ+eCAG|)1kZ+v4HvREdS;_q!R
z0L>%D9oSW#KA&H+1yqS-sjGmz@XwEc5>#756)zW^?B3;r7>?mrfH)@z%cyG6C#15MzNAs5VEM
zJ`6Brs-ESa-gx+ap@Q_q)qur3S!
zU{Jhk|1v)AK)6wjFJ8Us+Vv$`*Nllp%kMz_;nh17KRQ5t+IULz#hW*$x~;{V+D#rm
zym4~#;i?Ckksk^^E^7O+Gh6S>q4u4HZmY@$G?i8OtdfDGz
zHhNo5=d@|lBDQ1%#uOeEExaCE{&YTjkk|9S57_NHrpHxj+UsxK`RCK=$8FMi9k=uM
z*DeSKZ7-d|)YK8kWCg3e4Q8@hZF-P+``zTq+;$N=P${ux&O3>)>C)1#lFlC8ym{%g
zXHQDyW}SQ2zbxnes?g~?udSru4K{%n+8bbtIb%1cpYO9Qes-jhnf+5Zm&UbqvC^lf
z>%Xt|Dk&>Frrd9HsrufjsoIMdE>w)G`FOPAVXJu3{e86`U;5YYx^KBpK*692bhrU;
zY$G)78Dz4YD=RtnEY|j*v)S#3Q_cO3yxjJXmH+arSIK8j-Q0V0>E-9g+H#~^&Tp&y
z+<3_SJtCakbT$+}KeyxQwCG34^1mZ=qPOYnKXlen-Ri|GK*4`@QPl
zvHvf+%b#`bXyq0^*354wAs$oUSXcA<+S-rq^Nz
z&sJ!EpF==mA7WYQqgPi~KUS9i=~44o`hLgR+2-@Z%^$5?KJV1+`e(-TU-Bwm>f18s
zvTXSs!TSH->*deeeC|p@soY}lHL3f)1X*pX{r&C6=5+rhsdIu7
z3g3ML?UUzMGRwIkkbZvNTif?{%JvB>7}PX&@hAmFWrBB#|MBUayHs27!{;aG9kz1L
zvAZmJ`}^G9wbkd3OxyeRT0`1R2@FG~xLPCB;Z(V}HLiZYXRVhvPZy$bqJ
zVD#wA$rEWC`!ha&Hc>KD7nBG&aQ?~y6FvcnZ4L96Cr-9(ba3SaErqS07haB}GsvENF~=hg9^V8d7CN~8+kR?_*DVeKiMAiPJl;cO`r}PCutbNi50i!*y4VeqR1;tL(b-(;};mKP^tW
zdFbWgea8y?K72Nj(aq)L(S4Afm7%Q5F-7aa^OYf*Z#j5$Cropg)$ta*`gYa&_5J*H
zADaKlDV{Czxc%j2^Z(lID_3gfPj2D>uMGw*;k{9Mek!P-1eKVRy%+q9h?cWiBE_$t
zcJOfYZ-4&X&8Nluy34;@Dff8j%%zlr$VjVV7r<8B-u>~y-CjyOzNT=$-q!8gpWolz
z@17KAVmT)&;4(-1ku|i*mB7P#>wMX<@AK}8LuZ`Mhk<6CK&?m6
zx}`-M7w&s;mro}1G;_PjZN*mp-Ls>+x5>YFa8%r{zh;}W|Br%$bKc$mB(-8~Es~Q0
z6!nwEl-}~2D^(*_xQc(`ww=Y#pS}Or4BDG6;L_8(
zcr~<{#d1#AW3xD@g3Y--S+w-s=G>aqs+V4W{K}s6);2ro;hpX2DsM9FWc71j&wKkJ
zNX%x5LXt)FD#hANv67hSXG?bIMW?;ob^6({JCVJIceZRpa+V)_O>fY_m*;EW6;FI+
zJ7@RVS*F_eOFyOj-#=gc)>4Dy6;?v6+wO4+NX%kofC{a$V0o?VYCnL+`$r#-%lB7)es&bJE?9$w@A)?!S^wMXVt1djol)_=LBg1h4BFuk%~7Pk1MeXX5L)-`~7}+$pTAAXs-zD70v(8_)LcBkD2t%|*U|6f_%Ki%zjg1%Vs
z2`L!VFghOjaCQ#tv;+(P1&bGJ-@8$6wEpjhU$fPdg2R{>U0J*O^;=FsL_HLqK7V$b
zMn>$b+AZ+rq=G>tOH_39a|xF=pxmO9ACse
z>hI@eWOVfP^;uMX$@ur`{-WQvcW#vnTN5F;|9ka*aen(h1)#$j%HG|X`G0Ti&reT3
z?)$!1-|ovoe%=zv-y8xGOB)oDrZo6L3sbfI2VQRLyRm7tb%Dph!`YFEFAuBV>Mq-J
zghy%ru~nj*AH9p7F1~jja-VaLu0iduFF#)I|Mz-(InU$Epq&Q?+2zkT_w23yeyoX=
zJLy=D=~O%D`xH*PVU
z{jor6HlyLB+<$M5?b+w7rB{3OljO(n`<2G`Zd9*&u~aYK$`~}We$k9i2$rh^6bvj`
z&&{)yzW?`K`D5$*KmFnsFUr^Nm$#SOUH<-Dx$UnPi$A_A-)~*_b9%j{nC_=;pW3-K
z>-ZQQT}pc5upS|E_<3{k%zV
z^1C}b3!j~tnUR_K()QaKUb!V}
zm0~O#l=yP(ZvSI9`yQ^_c%}ArYWFhNSuZCzwO_qi%_X?ZM|0n|ONVv_KL!nGAyy@?
zuP!^H>YWB#KH8I!F&8ngx8N0P(25CZPD^xIxwqf1tNwFH|Bus>r!!tvb)8#kko5W4
z*@1obuqU=^z&s;iBl7I8E{x|D=p`(-8F8q&Gka`DdOAjRX+ls};#!lqQ
zzh8d8w(#ZB>GQ6iU$$%+=(Lp2*Fh(#)JQJ>`uh5FW96{*akX*P)*K9xapeNxis>pPrJ$E#Gi{^D({+x
zGUO1j>cF|V)}NQ{|IxkQB7vjuUFo}hzu(>1kmw9L)97Bs<6ck&{G?hHG>TSPVgp_u
zAfPY-G{tk;seRhKq)VV8EN0i*y~Qq8-Ov5cPK&6rF4<9ZbWKLk;zXBeen`i+C8RKA
zo?QC(_xI=O>!Y@=TGD;x`t{?X;jvTM1+B~8XuOo^)xKq&tCi9
zG_i7j+Q!Z&qw!OQmoo%3t}Nts&=^#`Ff>Yudc0ov&ZfX>_R9%P?eA{!<-f6%oU6P-
zJ$C-p-hDp~N!lJ=vb(u`>do)JN)EVz8a&WCx{*uBv>l-#(n`O2k}*ZKs%)*O6u
zY{#odH*Hy$rXLN}PCNc3hph#?W(}5~t}1LOdV0#HTT>Y`&VN)hXqTpl#9nlk4^XsU1e9!utr`jJ^`qygBn#C69_3cQf@WJTOEF`OMBY6F3n(_jUi|5BMr8)tnz;F_kDdm=s>KGpHAx^|GxkK-->TH
z(;rWZ&O13h)9bX^QY#_%KABG6*=9$7eSQ7;{mS;0XJ1`iy?XWLdE1_Wj&1nw&Hyfh
zK>eYU*EVllxqO|ooL$QN{1AwwV{<#+a|NNrZ_Z@Xo+>D0yiwC7@7p35cq^HW)uZMM36
z_};RV*2VhKR*TEG9iEl5a_Q6V<@~>`{2+-29F+|RQUqq0=f~N6x#0Y5a}+@mp)c
zOicM?>!wuIz6E<0621xnZ<%;`c|ShnueZqC`}Nw5z18J!?(et%_V%`T=CLD>j&^?z
z*YdN?on=*d)$ZEXKYtJ_R2vgH=bU{dTl4yOwVUbgga~sP*TX6m0>5e=lD?>c2
zw*EY$A1f8TsfsW2m~&Lx%Lf;YnN8)3?r&N4D`IO>Sj=2jzE;&~VrL|GT(~ts{4!GB
zWMnc`Gbnv^WyhOMr$2@Fmd2K6J2(ggGB>a31_h`=RpVlH>qq+X)^fY~Ouz5G5wMy2
zm#N%w{Y=YcNs2BH1A}JY|9LuG>38VtL+d8p3;x`_S#|2QB^MN{mwrfm+G@PWF1qR@
za#;XQJ1?{qI$o@PXbk2^I4GRe`;p%-*L}C$n$6mM5j
zjTUyzfERz~uyft~?sOr5L*f?;XYO0&)yD%W`o7FN)U#z?hGw*u)!prx$=l-wbdq1wNzY|{c+bd%RQ}^w>m@Ba%
zRZrLKsCjuNW5%KdC8|BW=|~x1!7tW-uh#$5npgkt=N{$ykK*-$+~Rs??EfE>|Kk`p
zr%J{4&yC}DV&(U1zkB$V@-=b_3b^=i?4Av3CpnmM?g?D-;PcME7Ug9JcOF0fy86B(
zpYz?~QnSww?f=gXbv7+V8S`dwQz-cI;^Mu{eDZd8q+NPS%v^RwWM^l;H?36&;03LQ
zlu$hn9wvRPSD?0<`{Viba((arKXHg#z3@tE-?3MY%gwGG|FSYTDJr=3+bp5Wm#hEn
zeO|n6{qO2)>&`#l^Y+TGioC}YC#9z?xha4&4Gr2_)_(vrCiDLT|9^pQas7AOO)i7B
zir&~?|Gy)z>awqS?+Y7s!5JEijz?Th?gnq63|VsE*ml1s4-Zd1FW)om^4+5=+l_Z8
z9NVG^8u8n8xVg^J$$!O!x2K(3MfASd-g{omCGRF(bEo3zo{GxfogSsyUAdW(%RoC6
z)^sL=G6#6X8N@K)YMlT7=luRJR^_|DUW-0|_o;QGr?x`Jj4jTq!72k*fhJXcJoM*(
z#(3l$GqVWS=`Kt6%+mRf!|nGNz1x$TxpKQ+^zLJAzd(b|6$y7=H@69Dws_=1cDNxI
zB@PQ>n3_6@PVNHll?s7uFS@LK*IWN@$>)n6TV>g9Us{;Mc(uCLtZPnk)JG!p+QO+k(=?mn={`dtpUOq!ja^o5(A<
z8l^;kOt$|y8MM#y&+-31>uj
z&mVhk+_Aa+rfE?Va_irr!9kPByijxHy&
zq{5I}JO^fQZ<+V9qrT>6K-~9-KXs3{?fEBqI_;UUeBS9ahch#8S|t2#(=1IB=g~+;
z-38Rs?hqXvT{rt-i}>S@G4C7`K*=z`34G9+!&Q!w)K8z-Q3&Tj@tkKZ2w$#zI}aNF5`>btK1w)
ztLivP!NtutxvaObRhjo6zPryS>9f>u_SFyTvc;Zw>;HZ8>gU91Nt>W;U{Hz$oj+H^
zUGsVN{hsi+%BA1UK<5D1*FU$u-wEpf?)`oK?}dB!!)s3XuGv8%1}GL>Se9DPS;K2Kl}GD+=DdV
z4zhHkD0uk!^fcY)u_f>C?VT96G!L}3o4@7(^HQ_xeGaZ1Kc>&Bo3gPJ%84lwPW?f?AYVgC8n0_=VBBzFX!zqhRI*N>ms;!hqP_FetVb??&YT~(H-
zc0X4B0P0vzjB9=SdH(;JH+Oa#+x>m%e;jlK=%Kv#ENYg82g^|m(`u1-JG$N%TeBk!HNJ}Lxq7C24xOm3)ODXE^Z9W+hS
zxRBM#dUw*{X^THL&zAwE)q**e(KRoZ9{s#&>GVw>9)5eXwdUfNh4~9uL77=V!QsLG
z^!I)X-mE&+lDL0r<%$UcMqxrmjvh(^3JMA=69rn*CO8^){9U