From afa52c9b95dd1f83d80cd9a783a408822700e2d3 Mon Sep 17 00:00:00 2001 From: "W. Felix Handte" Date: Wed, 11 Apr 2018 16:04:24 -0400 Subject: Expose dictCtx Functionality in LZ4 --- lib/lz4.c | 4 ++++ lib/lz4.h | 28 ++++++++++++++++++++++++++++ lib/lz4frame.c | 3 +-- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/lz4.c b/lib/lz4.c index c2d1c32..cee85ec 100644 --- a/lib/lz4.c +++ b/lib/lz4.c @@ -1191,6 +1191,10 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) return dict->dictSize; } +void LZ4_attach_dictionary(LZ4_stream_t *working_stream, const LZ4_stream_t *dictionary_stream) { + working_stream->internal_donotuse.dictCtx = dictionary_stream != NULL ? &(dictionary_stream->internal_donotuse) : NULL; +} + static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) { diff --git a/lib/lz4.h b/lib/lz4.h index 427beaf..f90120e 100644 --- a/lib/lz4.h +++ b/lib/lz4.h @@ -386,6 +386,34 @@ LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr); */ LZ4LIB_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); +/*! LZ4_attach_dictionary() : + * This is an experimental API that allows for the efficient use of a + * static dictionary many times. + * + * Rather than re-loading the dictionary buffer into a working context before + * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a + * working LZ4_stream_t, this function introduces a no-copy setup mechanism, + * in which the working stream references the dictionary stream in-place. + * + * Several assumptions are made about the state of the dictionary stream. + * Currently, only streams which have been prepared by LZ4_loadDict() should + * be expected to work. + * + * Alternatively, the provided dictionary stream pointer may be NULL, in which + * case any existing dictionary stream is unset. + * + * If a dictionary is provided, it replaces any pre-existing stream history. + * The dictionary contents are the only history that can be referenced and + * logically immediately precede the data compressed in the first subsequent + * compression call. + * + * The dictionary will only remain attached to the working stream through the + * first compression call, at the end of which it is cleared. The dictionary + * stream (and source buffer) must remain in-place / accessible / unchanged + * through the completion of the first compression call on the stream. + */ +LZ4LIB_API void LZ4_attach_dictionary(LZ4_stream_t *working_stream, const LZ4_stream_t *dictionary_stream); + /*-************************************ * Private definitions diff --git a/lib/lz4frame.c b/lib/lz4frame.c index 5e11ba2..d973b5f 100644 --- a/lib/lz4frame.c +++ b/lib/lz4frame.c @@ -533,8 +533,7 @@ static void LZ4F_applyCDict(void* ctx, LZ4_stream_t_internal* internal_ctx = &((LZ4_stream_t *)ctx)->internal_donotuse; assert(!internal_ctx->initCheck); LZ4_resetStream_fast((LZ4_stream_t *)ctx); - /* Point to the dictionary context */ - internal_ctx->dictCtx = cdict ? &(cdict->fastCtx->internal_donotuse) : NULL; + LZ4_attach_dictionary((LZ4_stream_t *)ctx, cdict ? cdict->fastCtx : NULL); } else { if (cdict) { memcpy(ctx, cdict->HCCtx, sizeof(*cdict->HCCtx)); -- cgit v0.12