[API] Add ZSTD_c_stable{In,Out}Buffer parameters
This commit adds the parameters and sets the value in the CCtxParams but it does not do anything with the value.
This commit is contained in:
parent
e2581d9572
commit
e3e0775cc8
@ -336,6 +336,12 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src,
|
||||
* In which case, resize it down to free some memory */
|
||||
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
|
||||
|
||||
/* Controls whether the input/output buffer is buffered or stable. */
|
||||
typedef enum {
|
||||
ZSTD_bm_buffered = 0, /* Buffer the input/output */
|
||||
ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */
|
||||
} ZSTD_bufferMode_e;
|
||||
|
||||
|
||||
/*-*******************************************
|
||||
* Private declarations
|
||||
|
@ -452,6 +452,12 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
||||
bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_stableInBuffer:
|
||||
case ZSTD_c_stableOutBuffer:
|
||||
bounds.lowerBound = (int)ZSTD_bm_buffered;
|
||||
bounds.upperBound = (int)ZSTD_bm_stable;
|
||||
return bounds;
|
||||
|
||||
default:
|
||||
bounds.error = ERROR(parameter_unsupported);
|
||||
return bounds;
|
||||
@ -509,6 +515,8 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
||||
case ZSTD_c_literalCompressionMode:
|
||||
case ZSTD_c_targetCBlockSize:
|
||||
case ZSTD_c_srcSizeHint:
|
||||
case ZSTD_c_stableInBuffer:
|
||||
case ZSTD_c_stableOutBuffer:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -557,6 +565,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
|
||||
case ZSTD_c_ldmBucketSizeLog:
|
||||
case ZSTD_c_targetCBlockSize:
|
||||
case ZSTD_c_srcSizeHint:
|
||||
case ZSTD_c_stableInBuffer:
|
||||
case ZSTD_c_stableOutBuffer:
|
||||
break;
|
||||
|
||||
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
||||
@ -748,6 +758,16 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
||||
CCtxParams->srcSizeHint = value;
|
||||
return CCtxParams->srcSizeHint;
|
||||
|
||||
case ZSTD_c_stableInBuffer:
|
||||
BOUNDCHECK(ZSTD_c_stableInBuffer, value);
|
||||
CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value;
|
||||
return CCtxParams->inBufferMode;
|
||||
|
||||
case ZSTD_c_stableOutBuffer:
|
||||
BOUNDCHECK(ZSTD_c_stableOutBuffer, value);
|
||||
CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value;
|
||||
return CCtxParams->outBufferMode;
|
||||
|
||||
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
||||
}
|
||||
}
|
||||
@ -859,6 +879,12 @@ size_t ZSTD_CCtxParams_getParameter(
|
||||
case ZSTD_c_srcSizeHint :
|
||||
*value = (int)CCtxParams->srcSizeHint;
|
||||
break;
|
||||
case ZSTD_c_stableInBuffer :
|
||||
*value = (int)CCtxParams->inBufferMode;
|
||||
break;
|
||||
case ZSTD_c_stableOutBuffer :
|
||||
*value = (int)CCtxParams->outBufferMode;
|
||||
break;
|
||||
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
||||
}
|
||||
return 0;
|
||||
|
@ -238,6 +238,10 @@ struct ZSTD_CCtx_params_s {
|
||||
/* Dedicated dict search algorithm trigger */
|
||||
int enableDedicatedDictSearch;
|
||||
|
||||
/* Input/output buffer modes */
|
||||
ZSTD_bufferMode_e inBufferMode;
|
||||
ZSTD_bufferMode_e outBufferMode;
|
||||
|
||||
/* Internal use, for createCCtxParams() and freeCCtxParams() only */
|
||||
ZSTD_customMem customMem;
|
||||
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
|
||||
|
@ -99,7 +99,7 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
|
||||
assert(dctx->streamStage == zdss_init);
|
||||
dctx->format = ZSTD_f_zstd1;
|
||||
dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
|
||||
dctx->outBufferMode = ZSTD_obm_buffered;
|
||||
dctx->outBufferMode = ZSTD_bm_buffered;
|
||||
dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
|
||||
}
|
||||
|
||||
@ -1431,8 +1431,8 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
|
||||
ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
|
||||
return bounds;
|
||||
case ZSTD_d_stableOutBuffer:
|
||||
bounds.lowerBound = (int)ZSTD_obm_buffered;
|
||||
bounds.upperBound = (int)ZSTD_obm_stable;
|
||||
bounds.lowerBound = (int)ZSTD_bm_buffered;
|
||||
bounds.upperBound = (int)ZSTD_bm_stable;
|
||||
return bounds;
|
||||
case ZSTD_d_forceIgnoreChecksum:
|
||||
bounds.lowerBound = (int)ZSTD_d_validateChecksum;
|
||||
@ -1495,7 +1495,7 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
|
||||
return 0;
|
||||
case ZSTD_d_stableOutBuffer:
|
||||
CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value);
|
||||
dctx->outBufferMode = (ZSTD_outBufferMode_e)value;
|
||||
dctx->outBufferMode = (ZSTD_bufferMode_e)value;
|
||||
return 0;
|
||||
case ZSTD_d_forceIgnoreChecksum:
|
||||
CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value);
|
||||
@ -1585,7 +1585,7 @@ static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const*
|
||||
{
|
||||
ZSTD_outBuffer const expect = zds->expectedOutBuffer;
|
||||
/* No requirement when ZSTD_obm_stable is not enabled. */
|
||||
if (zds->outBufferMode != ZSTD_obm_stable)
|
||||
if (zds->outBufferMode != ZSTD_bm_stable)
|
||||
return 0;
|
||||
/* Any buffer is allowed in zdss_init, this must be the same for every other call until
|
||||
* the context is reset.
|
||||
@ -1595,7 +1595,7 @@ static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const*
|
||||
/* The buffer must match our expectation exactly. */
|
||||
if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size)
|
||||
return 0;
|
||||
RETURN_ERROR(dstBuffer_wrong, "ZSTD_obm_stable enabled but output differs!");
|
||||
RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!");
|
||||
}
|
||||
|
||||
/* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream()
|
||||
@ -1607,7 +1607,7 @@ static size_t ZSTD_decompressContinueStream(
|
||||
ZSTD_DStream* zds, char** op, char* oend,
|
||||
void const* src, size_t srcSize) {
|
||||
int const isSkipFrame = ZSTD_isSkipFrame(zds);
|
||||
if (zds->outBufferMode == ZSTD_obm_buffered) {
|
||||
if (zds->outBufferMode == ZSTD_bm_buffered) {
|
||||
size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart;
|
||||
size_t const decodedSize = ZSTD_decompressContinue(zds,
|
||||
zds->outBuff + zds->outStart, dstSize, src, srcSize);
|
||||
@ -1627,7 +1627,7 @@ static size_t ZSTD_decompressContinueStream(
|
||||
/* Flushing is not needed. */
|
||||
zds->streamStage = zdss_read;
|
||||
assert(*op <= oend);
|
||||
assert(zds->outBufferMode == ZSTD_obm_stable);
|
||||
assert(zds->outBufferMode == ZSTD_bm_stable);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1740,7 +1740,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||
} }
|
||||
|
||||
/* Check output buffer is large enough for ZSTD_odm_stable. */
|
||||
if (zds->outBufferMode == ZSTD_obm_stable
|
||||
if (zds->outBufferMode == ZSTD_bm_stable
|
||||
&& zds->fParams.frameType != ZSTD_skippableFrame
|
||||
&& zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
|
||||
&& (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) {
|
||||
@ -1770,7 +1770,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
||||
|
||||
/* Adapt buffer sizes to frame header instructions */
|
||||
{ size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
|
||||
size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_obm_buffered
|
||||
size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
|
||||
? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
|
||||
: 0;
|
||||
|
||||
|
@ -99,11 +99,6 @@ typedef enum {
|
||||
ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */
|
||||
} ZSTD_dictUses_e;
|
||||
|
||||
typedef enum {
|
||||
ZSTD_obm_buffered = 0, /* Buffer the output */
|
||||
ZSTD_obm_stable = 1 /* ZSTD_outBuffer is stable */
|
||||
} ZSTD_outBufferMode_e;
|
||||
|
||||
struct ZSTD_DCtx_s
|
||||
{
|
||||
const ZSTD_seqSymbol* LLTptr;
|
||||
@ -158,7 +153,7 @@ struct ZSTD_DCtx_s
|
||||
U32 legacyVersion;
|
||||
U32 hostageByte;
|
||||
int noForwardProgress;
|
||||
ZSTD_outBufferMode_e outBufferMode;
|
||||
ZSTD_bufferMode_e outBufferMode;
|
||||
ZSTD_outBuffer expectedOutBuffer;
|
||||
|
||||
/* workspace */
|
||||
|
59
lib/zstd.h
59
lib/zstd.h
@ -415,6 +415,8 @@ typedef enum {
|
||||
* ZSTD_c_targetCBlockSize
|
||||
* ZSTD_c_srcSizeHint
|
||||
* ZSTD_c_enableDedicatedDictSearch
|
||||
* ZSTD_c_stableInBuffer
|
||||
* ZSTD_c_stableOutBuffer
|
||||
* Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
|
||||
* note : never ever use experimentalParam? names directly;
|
||||
* also, the enums values themselves are unstable and can still change.
|
||||
@ -426,7 +428,9 @@ typedef enum {
|
||||
ZSTD_c_experimentalParam5=1002,
|
||||
ZSTD_c_experimentalParam6=1003,
|
||||
ZSTD_c_experimentalParam7=1004,
|
||||
ZSTD_c_experimentalParam8=1005
|
||||
ZSTD_c_experimentalParam8=1005,
|
||||
ZSTD_c_experimentalParam9=1006,
|
||||
ZSTD_c_experimentalParam10=1007
|
||||
} ZSTD_cParameter;
|
||||
|
||||
typedef struct {
|
||||
@ -1623,6 +1627,59 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
|
||||
*/
|
||||
#define ZSTD_c_enableDedicatedDictSearch ZSTD_c_experimentalParam8
|
||||
|
||||
/* ZSTD_c_stableInBuffer
|
||||
* Experimental parameter.
|
||||
* Default is 0 == disabled. Set to 1 to enable.
|
||||
*
|
||||
* Tells the compressor that the ZSTD_inBuffer will ALWAYS be the same
|
||||
* between calls, except for the modifications that zstd makes to pos (the
|
||||
* caller must not modify pos). This is checked by the compressor, and
|
||||
* compression will fail if it ever changes. This means the only flush
|
||||
* mode that makes sense is ZSTD_e_end, so zstd will error if ZSTD_e_end
|
||||
* is not used. The data in the ZSTD_inBuffer in the range [src, src + pos)
|
||||
* MUST not be modified during compression or you will get data corruption.
|
||||
*
|
||||
* When this flag is enabled zstd won't allocate an input window buffer,
|
||||
* because the user guarantees it can reference the ZSTD_inBuffer until
|
||||
* the frame is complete. But, it will still allocate an output buffer
|
||||
* large enough to fit a block (see ZSTD_c_stableOutBuffer). This will also
|
||||
* avoid the memcpy() from the input buffer to the input window buffer.
|
||||
*
|
||||
* NOTE: ZSTD_compressStream2() will error if ZSTD_e_end is not used.
|
||||
* That means this flag cannot be used with ZSTD_compressStream().
|
||||
*
|
||||
* NOTE: So long as the ZSTD_inBuffer always points to valid memory, using
|
||||
* this flag is ALWAYS memory safe, and will never access out-of-bounds
|
||||
* memory. However, compression WILL fail if you violate the preconditions.
|
||||
*
|
||||
* WARNING: The data in the ZSTD_inBuffer in the range [dst, dst + pos) MUST
|
||||
* not be modified during compression or you will get data corruption. This
|
||||
* is because zstd needs to reference data in the ZSTD_inBuffer to find
|
||||
* matches. Normally zstd maintains its own window buffer for this purpose,
|
||||
* but passing this flag tells zstd to use the user provided buffer.
|
||||
*/
|
||||
#define ZSTD_c_stableInBuffer ZSTD_c_experimentalParam9
|
||||
|
||||
/* ZSTD_c_stableOutBuffer
|
||||
* Experimental parameter.
|
||||
* Default is 0 == disabled. Set to 1 to enable.
|
||||
*
|
||||
* Tells he compressor that the ZSTD_outBuffer will not be resized between
|
||||
* calls. Specifically: (out.size - out.pos) will never grow. This gives the
|
||||
* compressor the freedom to say: If the compressed data doesn't fit in the
|
||||
* output buffer then return ZSTD_error_dstSizeTooSmall. This allows us to
|
||||
* always decompress directly into the output buffer, instead of decompressing
|
||||
* into an internal buffer and copying to the output buffer.
|
||||
*
|
||||
* When this flag is enabled zstd won't allocate an output buffer, because
|
||||
* it can write directly to the ZSTD_outBuffer. It will still allocate the
|
||||
* input window buffer (see ZSTD_c_stableInBuffer).
|
||||
*
|
||||
* Zstd will check that (out.size - out.pos) never grows and return an error
|
||||
* if it does. While not strictly necessary, this should prevent surprises.
|
||||
*/
|
||||
#define ZSTD_c_stableOutBuffer ZSTD_c_experimentalParam10
|
||||
|
||||
/*! ZSTD_CCtx_getParameter() :
|
||||
* Get the requested compression parameter value, selected by enum ZSTD_cParameter,
|
||||
* and store it into int* value.
|
||||
|
Loading…
Reference in New Issue
Block a user