legacy contexts can be re-used

This commit is contained in:
Yann Collet 2016-08-28 08:19:47 -07:00
parent 4bf317dd00
commit 767d8f66fa
2 changed files with 36 additions and 46 deletions

View File

@ -1341,6 +1341,7 @@ struct ZSTD_DStream_s {
size_t dictSize; size_t dictSize;
const void* dictSource; const void* dictSource;
void* legacyContext; void* legacyContext;
U32 previousLegacyVersion;
U32 legacyVersion; U32 legacyVersion;
}; /* typedef'd to ZSTD_DStream within "zstd.h" */ }; /* typedef'd to ZSTD_DStream within "zstd.h" */
@ -1380,7 +1381,7 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
if (zds->dictContent) zds->customMem.customFree(zds->customMem.opaque, zds->dictContent); if (zds->dictContent) zds->customMem.customFree(zds->customMem.opaque, zds->dictContent);
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
if (zds->legacyContext) { if (zds->legacyContext) {
ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->legacyVersion); ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
zds->legacyContext = NULL; zds->legacyContext = NULL;
} }
#endif #endif
@ -1407,7 +1408,6 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
memcpy(zds->dictContent, dict, dictSize); memcpy(zds->dictContent, dict, dictSize);
zds->dictSize = dictSize; zds->dictSize = dictSize;
} }
if (zds->legacyContext) zds->customMem.customFree(zds->customMem.opaque, zds->dictContent); /* legacy restarts from scratch on each call, to detect restart */
zds->legacyVersion = 0; zds->legacyVersion = 0;
return 0; return 0;
} }
@ -1470,10 +1470,14 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
{ size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
if (ZSTD_isError(hSize)) if (ZSTD_isError(hSize))
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
{ U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart) { U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
if (legacyVersion) { if (legacyVersion) {
zds->legacyVersion = legacyVersion; size_t initResult;
return ZSTD_decompressLegacyStream(&zds->legacyContext, zds->legacyVersion, output, input); initResult = ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion,
zds->dictContent, zds->dictSize);
if (ZSTD_isError(initResult)) return initResult;
zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
} else { } else {
return hSize; /* error */ return hSize; /* error */
} } } }

View File

@ -147,22 +147,6 @@ MEM_STATIC size_t ZSTD_decompressLegacy(
} }
MEM_STATIC void* ZSTD_createLegacyStreamContext(U32 version)
{
switch(version)
{
default :
case 1 :
case 2 :
case 3 :
return NULL;
case 4 : return ZBUFFv04_createDCtx();
case 5 : return ZBUFFv05_createDCtx();
case 6 : return ZBUFFv06_createDCtx();
case 7 : return ZBUFFv07_createDCtx();
}
}
MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version) MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
{ {
switch(version) switch(version)
@ -180,56 +164,58 @@ MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
} }
MEM_STATIC void ZSTD_initLegacyStream(void* legacyContext, U32 version, MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion,
const void* dict, size_t dictSize) const void* dict, size_t dictSize)
{ {
switch(version) if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion);
switch(newVersion)
{ {
default : default :
case 1 : case 1 :
case 2 : case 2 :
case 3 : case 3 :
return; return 0;
case 4 : case 4 :
{ {
ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext; ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext;
if (dctx==NULL) return ERROR(memory_allocation);
ZBUFFv04_decompressInit(dctx); ZBUFFv04_decompressInit(dctx);
ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize); ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize);
return; *legacyContext = dctx;
return 0;
} }
case 5 : case 5 :
{ {
ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext; ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext;
if (dctx==NULL) return ERROR(memory_allocation);
ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize); ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize);
return; *legacyContext = dctx;
return 0;
} }
case 6 : case 6 :
{ {
ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext; ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext;
if (dctx==NULL) return ERROR(memory_allocation);
ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize); ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize);
return; *legacyContext = dctx;
return 0;
} }
case 7 : case 7 :
{ {
ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext; ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext;
if (dctx==NULL) return ERROR(memory_allocation);
ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize); ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize);
return; *legacyContext = dctx;
return 0;
} }
} }
} }
MEM_STATIC size_t ZSTD_decompressLegacyStream(void** legacyContext, U32 version, MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version,
ZSTD_outBuffer* output, ZSTD_inBuffer* input, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
const void* dict, size_t dictSize)
{ {
if (*legacyContext == NULL) {
*legacyContext = ZSTD_createLegacyStreamContext(version);
if (*legacyContext==NULL) return ERROR(memory_allocation);
ZSTD_initLegacyStream(*legacyContext, version, dict, dictSize);
}
switch(version) switch(version)
{ {
default : default :
@ -239,7 +225,7 @@ MEM_STATIC size_t ZSTD_decompressLegacyStream(void** legacyContext, U32 version,
return ERROR(version_unsupported); return ERROR(version_unsupported);
case 4 : case 4 :
{ {
ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) (*legacyContext); ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext;
const void* src = (const char*)input->src + input->pos; const void* src = (const char*)input->src + input->pos;
size_t readSize = input->size - input->pos; size_t readSize = input->size - input->pos;
void* dst = (char*)output->dst + output->pos; void* dst = (char*)output->dst + output->pos;
@ -251,7 +237,7 @@ MEM_STATIC size_t ZSTD_decompressLegacyStream(void** legacyContext, U32 version,
} }
case 5 : case 5 :
{ {
ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) (*legacyContext); ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext;
const void* src = (const char*)input->src + input->pos; const void* src = (const char*)input->src + input->pos;
size_t readSize = input->size - input->pos; size_t readSize = input->size - input->pos;
void* dst = (char*)output->dst + output->pos; void* dst = (char*)output->dst + output->pos;
@ -263,7 +249,7 @@ MEM_STATIC size_t ZSTD_decompressLegacyStream(void** legacyContext, U32 version,
} }
case 6 : case 6 :
{ {
ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) (*legacyContext); ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext;
const void* src = (const char*)input->src + input->pos; const void* src = (const char*)input->src + input->pos;
size_t readSize = input->size - input->pos; size_t readSize = input->size - input->pos;
void* dst = (char*)output->dst + output->pos; void* dst = (char*)output->dst + output->pos;
@ -275,7 +261,7 @@ MEM_STATIC size_t ZSTD_decompressLegacyStream(void** legacyContext, U32 version,
} }
case 7 : case 7 :
{ {
ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) (*legacyContext); ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext;
const void* src = (const char*)input->src + input->pos; const void* src = (const char*)input->src + input->pos;
size_t readSize = input->size - input->pos; size_t readSize = input->size - input->pos;
void* dst = (char*)output->dst + output->pos; void* dst = (char*)output->dst + output->pos;