diff options
Diffstat (limited to 'doc/zstd_manual.html')
-rw-r--r-- | doc/zstd_manual.html | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index b4720adac2638..da11ddb2a4b23 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -1,10 +1,10 @@ <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> -<title>zstd 1.3.2 Manual</title> +<title>zstd 1.3.3 Manual</title> </head> <body> -<h1>zstd 1.3.2 Manual</h1> +<h1>zstd 1.3.3 Manual</h1> <hr> <a name="Contents"></a><h2>Contents</h2> <ol> @@ -19,16 +19,17 @@ <li><a href="#Chapter9">Streaming decompression - HowTo</a></li> <li><a href="#Chapter10">START OF ADVANCED AND EXPERIMENTAL FUNCTIONS</a></li> <li><a href="#Chapter11">Advanced types</a></li> -<li><a href="#Chapter12">Frame size functions</a></li> -<li><a href="#Chapter13">Context memory usage</a></li> -<li><a href="#Chapter14">Advanced compression functions</a></li> -<li><a href="#Chapter15">Advanced decompression functions</a></li> -<li><a href="#Chapter16">Advanced streaming functions</a></li> -<li><a href="#Chapter17">Buffer-less and synchronous inner streaming functions</a></li> -<li><a href="#Chapter18">Buffer-less streaming compression (synchronous mode)</a></li> -<li><a href="#Chapter19">Buffer-less streaming decompression (synchronous mode)</a></li> -<li><a href="#Chapter20">New advanced API (experimental)</a></li> -<li><a href="#Chapter21">Block level API</a></li> +<li><a href="#Chapter12">Custom memory allocation functions</a></li> +<li><a href="#Chapter13">Frame size functions</a></li> +<li><a href="#Chapter14">Context memory usage</a></li> +<li><a href="#Chapter15">Advanced compression functions</a></li> +<li><a href="#Chapter16">Advanced decompression functions</a></li> +<li><a href="#Chapter17">Advanced streaming functions</a></li> +<li><a href="#Chapter18">Buffer-less and synchronous inner streaming functions</a></li> +<li><a href="#Chapter19">Buffer-less streaming compression (synchronous mode)</a></li> +<li><a href="#Chapter20">Buffer-less streaming decompression (synchronous mode)</a></li> +<li><a href="#Chapter21">New advanced API (experimental)</a></li> +<li><a href="#Chapter22">Block level API</a></li> </ol> <hr> <a name="Chapter1"></a><h2>Introduction</h2><pre> @@ -111,7 +112,7 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); @return : content size to be decompressed, as a 64-bits value _if known and not empty_, 0 otherwise. </p></pre><BR> -<h3>Helper functions</h3><pre></pre><b><pre>#define ZSTD_COMPRESSBOUND(srcSize) ((srcSize) + ((srcSize)>>8) + (((srcSize) < 128 KB) ? ((128 KB - (srcSize)) >> 11) </b>/* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */<b> +<h3>Helper functions</h3><pre></pre><b><pre>#define ZSTD_COMPRESSBOUND(srcSize) ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) </b>/* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */<b> size_t ZSTD_compressBound(size_t srcSize); </b>/*!< maximum compressed size in worst case scenario */<b> unsigned ZSTD_isError(size_t code); </b>/*!< tells if a `size_t` function result is an error code */<b> const char* ZSTD_getErrorName(size_t code); </b>/*!< provides readable string from an error code */<b> @@ -346,17 +347,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB ZSTD_frameParameters fParams; } ZSTD_parameters; </b></pre><BR> -<h3>Custom memory allocation functions</h3><pre></pre><b><pre>typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); -typedef void (*ZSTD_freeFunction) (void* opaque, void* address); -typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; -</b>/* use this constant to defer to stdlib's functions */<b> -static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL }; -</pre></b><BR> -<a name="Chapter12"></a><h2>Frame size functions</h2><pre></pre> +<a name="Chapter12"></a><h2>Custom memory allocation functions</h2><pre></pre> + +<pre><b>typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; +</b></pre><BR> +<a name="Chapter13"></a><h2>Frame size functions</h2><pre></pre> <pre><b>size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); </b><p> `src` should point to the start of a ZSTD encoded frame or skippable frame - `srcSize` must be at least as large as the frame + `srcSize` must be >= first frame size @return : the compressed size of the first frame starting at `src`, suitable to pass to `ZSTD_decompress` or similar, or an error code if input is invalid @@ -391,7 +390,7 @@ static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL }; @return : size of the Frame Header </p></pre><BR> -<a name="Chapter13"></a><h2>Context memory usage</h2><pre></pre> +<a name="Chapter14"></a><h2>Context memory usage</h2><pre></pre> <pre><b>size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); @@ -450,7 +449,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet </p></pre><BR> -<a name="Chapter14"></a><h2>Advanced compression functions</h2><pre></pre> +<a name="Chapter15"></a><h2>Advanced compression functions</h2><pre></pre> <pre><b>ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); </b><p> Create a ZSTD compression context using external alloc and free functions @@ -462,7 +461,8 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet It must outlive context usage. workspaceSize: Use ZSTD_estimateCCtxSize() or ZSTD_estimateCStreamSize() to determine how large workspace must be to support scenario. - @return : pointer to ZSTD_CCtx*, or NULL if error (size too small) + @return : pointer to ZSTD_CCtx* (same address as workspace, but different type), + or NULL if error (typically size too small) Note : zstd will never resize nor malloc() when using a static cctx. If it needs more memory than available, it will simply error out. Note 2 : there is no corresponding "free" function. @@ -505,7 +505,8 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet 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) + @return : pointer to ZSTD_CDict* (same address as workspace, but different type), + or NULL if error (typically, size too small). Note : there is no corresponding "free" function. Since workspace was allocated externally, it must be freed externally. @@ -518,7 +519,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet <pre><b>ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); </b><p> same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. - All fields of `ZSTD_frameParameters` are set to default (0) + All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 </p></pre><BR> <pre><b>size_t ZSTD_checkCParams(ZSTD_compressionParameters params); @@ -545,7 +546,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet </b><p> Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters </p></pre><BR> -<a name="Chapter15"></a><h2>Advanced decompression functions</h2><pre></pre> +<a name="Chapter16"></a><h2>Advanced decompression functions</h2><pre></pre> <pre><b>unsigned ZSTD_isFrame(const void* buffer, size_t size); </b><p> Tells if the content of `buffer` starts with a valid Frame Identifier. @@ -564,7 +565,8 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet It must outlive context usage. workspaceSize: Use ZSTD_estimateDCtxSize() or ZSTD_estimateDStreamSize() to determine how large workspace must be to support scenario. - @return : pointer to ZSTD_DCtx*, or NULL if error (size too small) + @return : pointer to ZSTD_DCtx* (same address as workspace, but different type), + or NULL if error (typically size too small) Note : zstd will never resize nor malloc() when using a static dctx. If it needs more memory than available, it will simply error out. Note 2 : static dctx is incompatible with legacy support @@ -627,24 +629,26 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMet When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. </p></pre><BR> -<a name="Chapter16"></a><h2>Advanced streaming functions</h2><pre></pre> +<a name="Chapter17"></a><h2>Advanced streaming functions</h2><pre></pre> <h3>Advanced Streaming compression functions</h3><pre></pre><b><pre>ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); </b>/**< same as ZSTD_initStaticCCtx() */<b> -size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */<b> +size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize must be correct. If it is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, "0" also disables frame content size field. It may be enabled in the future. */<b> size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); </b>/**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. Note: dict is loaded with ZSTD_dm_auto (treated as a full zstd dictionary if it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.*/<b> size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, - ZSTD_parameters params, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0. dict is loaded with ZSTD_dm_auto and ZSTD_dlm_byCopy. */<b> + ZSTD_parameters params, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize must be correct. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. dict is loaded with ZSTD_dm_auto and ZSTD_dlm_byCopy. */<b> size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); </b>/**< note : cdict will just be referenced, and must outlive compression session */<b> -size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); </b>/**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */<b> +size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); </b>/**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters. pledgedSrcSize must be correct. If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN. */<b> </pre></b><BR> <pre><b>size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize); </b><p> start a new compression job, using same parameters from previous job. This is typically useful to skip dictionary loading stage, since it will re-use it in-place.. Note that zcs must be init at least once before using ZSTD_resetCStream(). - pledgedSrcSize==0 means "srcSize unknown". + If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN. If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. - @return : 0, or an error code (which can be tested using ZSTD_isError()) + For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs, + but it may change to mean "empty" in some future version, so prefer using macro ZSTD_CONTENTSIZE_UNKNOWN. + @return : 0, or an error code (which can be tested using ZSTD_isError()) </p></pre><BR> <h3>Advanced Streaming decompression functions</h3><pre></pre><b><pre>ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem); @@ -655,14 +659,14 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); </b>/**< note : ddict is referenced, it must outlive decompression session */<b> size_t ZSTD_resetDStream(ZSTD_DStream* zds); </b>/**< re-use decompression parameters from previous init; saves dictionary loading */<b> </pre></b><BR> -<a name="Chapter17"></a><h2>Buffer-less and synchronous inner streaming functions</h2><pre> +<a name="Chapter18"></a><h2>Buffer-less and synchronous inner streaming functions</h2><pre> This is an advanced API, giving full control over buffer management, for users which need direct control over memory. But it's also a complex one, with several restrictions, documented below. Prefer normal streaming API for an easier experience. <BR></pre> -<a name="Chapter18"></a><h2>Buffer-less streaming compression (synchronous mode)</h2><pre> +<a name="Chapter19"></a><h2>Buffer-less streaming compression (synchronous mode)</h2><pre> A ZSTD_CCtx object is required to track streaming operations. Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. ZSTD_CCtx object can be re-used multiple times within successive compression operations. @@ -693,12 +697,12 @@ size_t ZSTD_resetDStream(ZSTD_DStream* zds); </b>/**< re-use decompression para <h3>Buffer-less streaming compression functions</h3><pre></pre><b><pre>size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); -size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */<b> +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); </b>/**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */<b> size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); </b>/**< note: fails if cdict==NULL */<b> -size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); </b>/* compression parameters are already set within cdict. pledgedSrcSize=0 means null-size */<b> -size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); </b>/**< note: if pledgedSrcSize can be 0, indicating unknown size. if it is non-zero, it must be accurate. for 0 size frames, use compressBegin_advanced */<b> +size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); </b>/* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */<b> +size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); </b>/**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */<b> </pre></b><BR> -<a name="Chapter19"></a><h2>Buffer-less streaming decompression (synchronous mode)</h2><pre> +<a name="Chapter20"></a><h2>Buffer-less streaming decompression (synchronous mode)</h2><pre> A ZSTD_DCtx object is required to track streaming operations. Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. A ZSTD_DCtx object can be re-used multiple times. @@ -784,7 +788,7 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long </pre></b><BR> <pre><b>typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; </b></pre><BR> -<a name="Chapter20"></a><h2>New advanced API (experimental)</h2><pre></pre> +<a name="Chapter21"></a><h2>New advanced API (experimental)</h2><pre></pre> <pre><b>typedef enum { </b>/* Question : should we have a format ZSTD_f_auto ?<b> @@ -848,18 +852,19 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long * Special: value 0 means "do not change strategy". */ </b>/* frame parameters */<b> - ZSTD_p_contentSizeFlag=200, </b>/* Content size is written into frame header _whenever known_ (default:1)<b> - * note that content size must be known at the beginning, - * it is sent using ZSTD_CCtx_setPledgedSrcSize() */ + ZSTD_p_contentSizeFlag=200, </b>/* Content size will be written into frame header _whenever known_ (default:1)<b> + * Content size must be known at the beginning of compression, + * it is provided using ZSTD_CCtx_setPledgedSrcSize() */ ZSTD_p_checksumFlag, </b>/* A 32-bits checksum of content is written at end of frame (default:0) */<b> - ZSTD_p_dictIDFlag, </b>/* When applicable, dictID of dictionary is provided in frame header (default:1) */<b> + ZSTD_p_dictIDFlag, </b>/* When applicable, dictionary's ID is written into frame header (default:1) */<b> </b>/* multi-threading parameters */<b> ZSTD_p_nbThreads=400, </b>/* Select how many threads a compression job can spawn (default:1)<b> * More threads improve speed, but also increase memory usage. * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled. * Special: value 0 means "do not change nbThreads" */ - ZSTD_p_jobSize, </b>/* Size of a compression job. Each compression job is completed in parallel.<b> + ZSTD_p_jobSize, </b>/* Size of a compression job. This value is only enforced in streaming (non-blocking) mode.<b> + * Each compression job is completed in parallel, so indirectly controls the nb of active threads. * 0 means default, which is dynamically determined based on compression parameters. * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest * The minimum size is automatically and transparently enforced */ @@ -904,7 +909,8 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long <pre><b>size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value); </b><p> Set one compression parameter, selected by enum ZSTD_cParameter. Note : when `value` is an enum, cast it to unsigned for proper type checking. - @result : 0, or an error code (which can be tested with ZSTD_isError()). + @result : informational value (typically, the one being set, possibly corrected), + or an error code (which can be tested with ZSTD_isError()). </p></pre><BR> <pre><b>size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize); @@ -913,7 +919,7 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long @result : 0, or an error code (which can be tested with ZSTD_isError()). Note 1 : 0 means zero, empty. In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. - Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for new compression jobs. + ZSTD_CONTENTSIZE_UNKNOWN is default value for any new compression job. Note 2 : If all data is provided and consumed in a single round, this value is overriden by srcSize instead. </p></pre><BR> @@ -985,13 +991,19 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t - Compression parameters cannot be changed once compression is started. - outpot->pos must be <= dstCapacity, input->pos must be <= srcSize - outpot->pos and input->pos will be updated. They are guaranteed to remain below their respective limit. - - @return provides the minimum amount of data still to flush from internal buffers + - In single-thread mode (default), function is blocking : it completed its job before returning to caller. + - In multi-thread mode, function is non-blocking : it just acquires a copy of input, and distribute job to internal worker threads, + and then immediately returns, just indicating that there is some data remaining to be flushed. + The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte. + - Exception : in multi-threading mode, if the first call requests a ZSTD_e_end directive, it is blocking : it will complete compression before giving back control to caller. + - @return provides the minimum amount of data remaining to be flushed from internal buffers or an error code, which can be tested using ZSTD_isError(). - if @return != 0, flush is not fully completed, there is some data left within internal buffers. - - after a ZSTD_e_end directive, if internal buffer is not fully flushed, + if @return != 0, flush is not fully completed, there is still some data left within internal buffers. + This is useful to determine if a ZSTD_e_flush or ZSTD_e_end directive is completed. + - after a ZSTD_e_end directive, if internal buffer is not fully flushed (@return != 0), only ZSTD_e_end or ZSTD_e_flush operations are allowed. - It is necessary to fully flush internal buffers - before starting a new compression job, or changing compression parameters. + Before starting a new compression job, or changing compression parameters, + it is required to fully flush internal buffers. </p></pre><BR> @@ -1166,7 +1178,7 @@ size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t </p></pre><BR> -<a name="Chapter21"></a><h2>Block level API</h2><pre></pre> +<a name="Chapter22"></a><h2>Block level API</h2><pre></pre> <pre><b></b><p> Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes). User will have to take in charge required information to regenerate data, such as compressed and content sizes. |