summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Collet <Cyan4973@users.noreply.github.com>2018-05-03 22:37:51 (GMT)
committerGitHub <noreply@github.com>2018-05-03 22:37:51 (GMT)
commitf3e84ffd41bb3ff10756efcf3334493639e0b395 (patch)
tree8b353f3c1548c982e1e750a07a9559d96923689f
parent2b6c4f3d6367bf3f8bc38358109ab0a1b1d7340b (diff)
parent5406c2e479f5bb2b594a43e74e28719f4640450f (diff)
downloadlz4-f3e84ffd41bb3ff10756efcf3334493639e0b395.zip
lz4-f3e84ffd41bb3ff10756efcf3334493639e0b395.tar.gz
lz4-f3e84ffd41bb3ff10756efcf3334493639e0b395.tar.bz2
Merge pull request #529 from felixhandte/lz4f-fast-reset-for-streaming-only
LZ4F: Only Reset the LZ4_stream_t when Init'ing a Streaming Block
-rw-r--r--lib/lz4.h24
-rw-r--r--lib/lz4frame.c19
2 files changed, 33 insertions, 10 deletions
diff --git a/lib/lz4.h b/lib/lz4.h
index 410f480..7d13122 100644
--- a/lib/lz4.h
+++ b/lib/lz4.h
@@ -380,6 +380,15 @@ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int or
#ifdef LZ4_STATIC_LINKING_ONLY
/*! LZ4_resetStream_fast() :
+ * Use this, like LZ4_resetStream(), to prepare a context for a new chain of
+ * calls to a streaming API (e.g., LZ4_compress_fast_continue()).
+ *
+ * Note:
+ * Using this in advance of a non- streaming-compression function is redundant,
+ * and potentially bad for performance, since they all perform their own custom
+ * reset internally.
+ *
+ * Differences from LZ4_resetStream():
* When an LZ4_stream_t is known to be in a internally coherent state,
* it can often be prepared for a new compression with almost no work, only
* sometimes falling back to the full, expensive reset that is always required
@@ -389,13 +398,17 @@ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int or
* LZ4_streams are guaranteed to be in a valid state when:
* - returned from LZ4_createStream()
* - reset by LZ4_resetStream()
- * - memset(stream, 0, sizeof(LZ4_stream_t))
+ * - memset(stream, 0, sizeof(LZ4_stream_t)), though this is discouraged
* - the stream was in a valid state and was reset by LZ4_resetStream_fast()
* - the stream was in a valid state and was then used in any compression call
* that returned success
* - the stream was in an indeterminate state and was used in a compression
- * call that fully reset the state (LZ4_compress_fast_extState()) and that
- * returned success
+ * call that fully reset the state (e.g., LZ4_compress_fast_extState()) and
+ * that returned success
+ *
+ * When a stream isn't known to be in a valid state, it is not safe to pass to
+ * any fastReset or streaming function. It must first be cleansed by the full
+ * LZ4_resetStream().
*/
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
@@ -406,8 +419,9 @@ LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
* to call if the state buffer is known to be correctly initialized already
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly
* initialized"). From a high level, the difference is that this function
- * initializes the provided state with a call to LZ4_resetStream_fast() while
- * LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
+ * initializes the provided state with a call to something like
+ * LZ4_resetStream_fast() while LZ4_compress_fast_extState() starts with a
+ * call to LZ4_resetStream().
*/
LZ4LIB_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
diff --git a/lib/lz4frame.c b/lib/lz4frame.c
index f57db24..aa7889b 100644
--- a/lib/lz4frame.c
+++ b/lib/lz4frame.c
@@ -551,9 +551,18 @@ LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_comp
*/
static void LZ4F_initStream(void* ctx,
const LZ4F_CDict* cdict,
- int level) {
+ int level,
+ LZ4F_blockMode_t blockMode) {
if (level < LZ4HC_CLEVEL_MIN) {
- LZ4_resetStream_fast((LZ4_stream_t *)ctx);
+ if (cdict != NULL || blockMode == LZ4F_blockLinked) {
+ /* In these cases, we will call LZ4_compress_fast_continue(),
+ * which needs an already reset context. Otherwise, we'll call a
+ * one-shot API. The non-continued APIs internally perform their own
+ * resets at the beginning of their calls, where they know what
+ * tableType they need the context to be in. So in that case this
+ * would be misguided / wasted work. */
+ LZ4_resetStream_fast((LZ4_stream_t*)ctx);
+ }
LZ4_attach_dictionary((LZ4_stream_t *)ctx, cdict ? cdict->fastCtx : NULL);
} else {
LZ4_resetStreamHC_fast((LZ4_streamHC_t*)ctx, level);
@@ -631,7 +640,7 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
cctxPtr->cdict = cdict;
if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
/* frame init only for blockLinked : blockIndependent will be init at each block */
- LZ4F_initStream(cctxPtr->lz4CtxPtr, cdict, cctxPtr->prefs.compressionLevel);
+ LZ4F_initStream(cctxPtr->lz4CtxPtr, cdict, cctxPtr->prefs.compressionLevel, LZ4F_blockLinked);
}
if (preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN) {
LZ4_favorDecompressionSpeed((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, (int)preferencesPtr->favorDecSpeed);
@@ -729,7 +738,7 @@ static size_t LZ4F_makeBlock(void* dst, const void* src, size_t srcSize,
static int LZ4F_compressBlock(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
{
int const acceleration = (level < -1) ? -level : 1;
- LZ4F_initStream(ctx, cdict, level);
+ LZ4F_initStream(ctx, cdict, level, LZ4F_blockIndependent);
if (cdict) {
return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
} else {
@@ -746,7 +755,7 @@ static int LZ4F_compressBlock_continue(void* ctx, const char* src, char* dst, in
static int LZ4F_compressBlockHC(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
{
- LZ4F_initStream(ctx, cdict, level);
+ LZ4F_initStream(ctx, cdict, level, LZ4F_blockIndependent);
if (cdict) {
return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
}