Added ZSTD_initStaticCDict()
This commit is contained in:
parent
57827f906f
commit
cdf7e82222
@ -408,8 +408,8 @@ size_t ZSTD_estimateDCtxSize(void);
|
||||
<pre><b>size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
|
||||
size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
|
||||
</b><p> Note : if streaming is init with function ZSTD_init?Stream_usingDict(),
|
||||
an internal ?Dict will be created, which size is not estimated.
|
||||
In this case, get additional size by using ZSTD_estimate?DictSize
|
||||
an internal ?Dict will be created, which size is not estimated here.
|
||||
In this case, get total size by adding ZSTD_estimate?DictSize
|
||||
</p></pre><BR>
|
||||
|
||||
<pre><b>size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference);
|
||||
@ -460,6 +460,24 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
|
||||
</b><p> Create a ZSTD_CDict using external alloc and free, and customized compression parameters
|
||||
</p></pre><BR>
|
||||
|
||||
<pre><b>ZSTD_CDict* ZSTD_initStaticCDict(
|
||||
void* workspace, size_t workspaceSize,
|
||||
const void* dict, size_t dictSize, unsigned byReference,
|
||||
ZSTD_compressionParameters cParams);
|
||||
</b><p> 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.
|
||||
|
||||
</p></pre><BR>
|
||||
|
||||
<pre><b>ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
|
||||
</b><p> @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
|
||||
`estimatedSrcSize` value is optional, select 0 if not known
|
||||
|
@ -3239,7 +3239,6 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
|
||||
* Estimate amount of memory that will be needed to create a dictionary with following arguments */
|
||||
size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference)
|
||||
{
|
||||
cParams = ZSTD_adjustCParams(cParams, 0, dictSize);
|
||||
return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize(cParams)
|
||||
+ (byReference ? 0 : dictSize);
|
||||
}
|
||||
@ -3258,6 +3257,34 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_
|
||||
return params;
|
||||
}
|
||||
|
||||
static size_t ZSTD_initCDict_internal(
|
||||
ZSTD_CDict* cdict,
|
||||
const void* dictBuffer, size_t dictSize, unsigned byReference,
|
||||
ZSTD_compressionParameters cParams)
|
||||
{
|
||||
if ((byReference) || (!dictBuffer) || (!dictSize)) {
|
||||
cdict->dictBuffer = NULL;
|
||||
cdict->dictContent = dictBuffer;
|
||||
} else {
|
||||
void* const internalBuffer = ZSTD_malloc(dictSize, cdict->refContext->customMem);
|
||||
if (!internalBuffer) return ERROR(memory_allocation);
|
||||
memcpy(internalBuffer, dictBuffer, dictSize);
|
||||
cdict->dictBuffer = internalBuffer;
|
||||
cdict->dictContent = internalBuffer;
|
||||
}
|
||||
cdict->dictContentSize = dictSize;
|
||||
|
||||
{ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
|
||||
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
|
||||
ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
|
||||
CHECK_F( ZSTD_compressBegin_advanced(cdict->refContext,
|
||||
cdict->dictContent, dictSize,
|
||||
params, 0 /* srcSize */) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
|
||||
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
|
||||
{
|
||||
@ -3269,44 +3296,19 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
|
||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
|
||||
|
||||
if (!cdict || !cctx) {
|
||||
DEBUGLOG(5, "!cdict || !cctx");
|
||||
ZSTD_free(cdict, customMem);
|
||||
ZSTD_freeCCtx(cctx);
|
||||
return NULL;
|
||||
}
|
||||
cdict->refContext = cctx;
|
||||
|
||||
if ((byReference) || (!dictBuffer) || (!dictSize)) {
|
||||
cdict->dictBuffer = NULL;
|
||||
cdict->dictContent = dictBuffer;
|
||||
} else {
|
||||
void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
|
||||
if (!internalBuffer) {
|
||||
DEBUGLOG(5, "!internalBuffer");
|
||||
ZSTD_free(cctx, customMem);
|
||||
ZSTD_free(cdict, customMem);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(internalBuffer, dictBuffer, dictSize);
|
||||
cdict->dictBuffer = internalBuffer;
|
||||
cdict->dictContent = internalBuffer;
|
||||
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
||||
dictBuffer, dictSize, byReference,
|
||||
cParams) )) {
|
||||
ZSTD_freeCDict(cdict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
{ ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
|
||||
0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
|
||||
ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
|
||||
size_t const errorCode = ZSTD_compressBegin_advanced(cctx,
|
||||
cdict->dictContent, dictSize, params, 0);
|
||||
if (ZSTD_isError(errorCode)) {
|
||||
DEBUGLOG(5, "ZSTD_compressBegin_advanced error : %s",
|
||||
ZSTD_getErrorName(errorCode));
|
||||
ZSTD_free(cdict->dictBuffer, customMem);
|
||||
ZSTD_free(cdict, customMem);
|
||||
ZSTD_freeCCtx(cctx);
|
||||
return NULL;
|
||||
} }
|
||||
|
||||
cdict->refContext = cctx;
|
||||
cdict->dictContentSize = dictSize;
|
||||
return cdict;
|
||||
}
|
||||
}
|
||||
@ -3336,6 +3338,51 @@ 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_compressionParameters cParams)
|
||||
{
|
||||
size_t const cctxSize = ZSTD_estimateCCtxSize(cParams);
|
||||
size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize)
|
||||
+ cctxSize;
|
||||
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
|
||||
void* ptr;
|
||||
DEBUGLOG(2, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
|
||||
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
||||
DEBUGLOG(2, "(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 /* by Reference */,
|
||||
cParams) ))
|
||||
return NULL;
|
||||
|
||||
return cdict;
|
||||
}
|
||||
|
||||
static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
|
||||
return ZSTD_getParamsFromCCtx(cdict->refContext);
|
||||
}
|
||||
|
@ -2053,7 +2053,8 @@ ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
|
||||
{
|
||||
size_t const neededSpace = sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize);
|
||||
ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace;
|
||||
if (workspaceSize < neededSpace) return NULL; /* minimum size */
|
||||
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
||||
if (workspaceSize < neededSpace) return NULL;
|
||||
if (!byReference) {
|
||||
memcpy(ddict+1, dict, dictSize); /* local copy */
|
||||
dict = ddict+1;
|
||||
|
23
lib/zstd.h
23
lib/zstd.h
@ -495,8 +495,8 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
|
||||
|
||||
/*! ZSTD_estimate?StreamSize() :
|
||||
* Note : if streaming is init with function ZSTD_init?Stream_usingDict(),
|
||||
* an internal ?Dict will be created, which size is not estimated.
|
||||
* In this case, get additional size by using ZSTD_estimate?DictSize */
|
||||
* an internal ?Dict will be created, which size is not estimated here.
|
||||
* In this case, get total size by adding ZSTD_estimate?DictSize */
|
||||
ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
|
||||
ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
|
||||
|
||||
@ -540,6 +540,7 @@ typedef enum {
|
||||
* @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.
|
||||
@ -551,6 +552,24 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, siz
|
||||
ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
|
||||
ZSTD_compressionParameters cParams, ZSTD_customMem customMem);
|
||||
|
||||
/*! 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.
|
||||
*/
|
||||
ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
|
||||
void* workspace, size_t workspaceSize,
|
||||
const void* dict, size_t dictSize, unsigned byReference,
|
||||
ZSTD_compressionParameters cParams);
|
||||
|
||||
/*! ZSTD_getCParams() :
|
||||
* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
|
||||
* `estimatedSrcSize` value is optional, select 0 if not known */
|
||||
|
@ -531,6 +531,29 @@ static int basicUnitTests(U32 seed, double compressibility)
|
||||
if (r != CNBuffSize) goto _output_error);
|
||||
DISPLAYLEVEL(4, "OK \n");
|
||||
|
||||
DISPLAYLEVEL(4, "test%3i : compress with static CDict : ", testNb++);
|
||||
{ ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
|
||||
size_t const cdictSize = ZSTD_estimateCDictSize(cParams, dictSize, 0);
|
||||
void* const cdictBuffer = malloc(cdictSize);
|
||||
if (cdictBuffer==NULL) goto _output_error;
|
||||
{ ZSTD_CDict* const cdict = ZSTD_initStaticCDict(cdictBuffer, cdictSize,
|
||||
dictBuffer, dictSize, 0 /* by Reference */,
|
||||
cParams);
|
||||
if (cdict == NULL) {
|
||||
DISPLAY("ZSTD_initStaticCDict failed ");
|
||||
goto _output_error;
|
||||
}
|
||||
cSize = ZSTD_compress_usingCDict(cctx,
|
||||
compressedBuffer, ZSTD_compressBound(CNBuffSize),
|
||||
CNBuffer, CNBuffSize, cdict);
|
||||
if (ZSTD_isError(cSize)) {
|
||||
DISPLAY("ZSTD_compress_usingCDict failed ");
|
||||
goto _output_error;
|
||||
} }
|
||||
free(cdictBuffer);
|
||||
}
|
||||
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user