lib/zstd/decompress/zstd_decompress.c
Source file repositories/reference/linux-study-clean/lib/zstd/decompress/zstd_decompress.c
File Facts
- System
- Linux kernel
- Corpus path
lib/zstd/decompress/zstd_decompress.c- Extension
.c- Size
- 97279 bytes
- Lines
- 2304
- Domain
- Kernel Services
- Bucket
- lib
- Inferred role
- Kernel Services: implementation source
- Status
- source implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
Dependency Surface
../common/zstd_deps.h../common/allocations.h../common/error_private.h../common/zstd_internal.h../common/mem.h../common/bits.h../common/fse.h../common/huf.hlinux/xxhash.hzstd_decompress_internal.hzstd_ddict.hzstd_decompress_block.h
Detected Declarations
function ZSTD_decompressDCtxfunction ZSTD_DDictHashSet_emplaceDDictfunction ZSTD_DDictHashSet_expandfunction ZSTD_DDictHashSet_getDDictfunction ZSTD_createDDictHashSetfunction ZSTD_freeDDictHashSetfunction ZSTD_DDictHashSet_addDDictfunction ZSTD_sizeof_DCtxfunction ZSTD_estimateDCtxSizefunction ZSTD_startingInputLengthfunction ZSTD_DCtx_resetParametersfunction ZSTD_initDCtx_internalfunction ZSTD_initStaticDCtxfunction ZSTD_createDCtx_internalfunction ZSTD_createDCtx_advancedfunction ZSTD_createDCtxfunction ZSTD_clearDictfunction ZSTD_freeDCtxfunction ZSTD_copyDCtxfunction ZSTD_DCtx_selectFrameDDictfunction ZSTD_isFramefunction ZSTD_isSkippableFramefunction ZSTD_frameHeaderSize_internalfunction codefunction ZSTD_getFrameHeader_advancedfunction ZSTD_getFrameHeaderfunction ZSTD_getFrameContentSizefunction readSkippableFrameSizefunction ZSTD_readSkippableFramefunction ZSTD_findDecompressedSizefunction ZSTD_getDecompressedSizefunction ZSTD_decodeFrameHeaderfunction ZSTD_errorFrameSizeInfofunction ZSTD_findFrameSizeInfofunction ZSTD_findFrameCompressedSize_advancedfunction ZSTD_findFrameCompressedSizefunction ZSTD_decompressBoundfunction ZSTD_decompressionMarginfunction ZSTD_insertBlockfunction ZSTD_copyRawBlockfunction ZSTD_setRleBlockfunction ZSTD_DCtx_trace_endfunction ZSTD_decompressFramefunction ZSTD_decompressMultiFramefunction ZSTD_decompress_usingDictfunction ZSTD_getDDictfunction ZSTD_decompressDCtxfunction ZSTD_decompress
Annotated Snippet
static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet* hashSet, U32 dictID) {
const U64 hash = xxh64(&dictID, sizeof(U32), 0);
/* DDict ptr table size is a multiple of 2, use size - 1 as mask to get index within [0, hashSet->ddictPtrTableSize) */
return hash & (hashSet->ddictPtrTableSize - 1);
}
/* Adds DDict to a hashset without resizing it.
* If inserting a DDict with a dictID that already exists in the set, replaces the one in the set.
* Returns 0 if successful, or a zstd error code if something went wrong.
*/
static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict) {
const U32 dictID = ZSTD_getDictID_fromDDict(ddict);
size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
RETURN_ERROR_IF(hashSet->ddictPtrCount == hashSet->ddictPtrTableSize, GENERIC, "Hash set is full!");
DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
while (hashSet->ddictPtrTable[idx] != NULL) {
/* Replace existing ddict if inserting ddict with same dictID */
if (ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]) == dictID) {
DEBUGLOG(4, "DictID already exists, replacing rather than adding");
hashSet->ddictPtrTable[idx] = ddict;
return 0;
}
idx &= idxRangeMask;
idx++;
}
DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
hashSet->ddictPtrTable[idx] = ddict;
hashSet->ddictPtrCount++;
return 0;
}
/* Expands hash table by factor of DDICT_HASHSET_RESIZE_FACTOR and
* rehashes all values, allocates new table, frees old table.
* Returns 0 on success, otherwise a zstd error code.
*/
static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
size_t newTableSize = hashSet->ddictPtrTableSize * DDICT_HASHSET_RESIZE_FACTOR;
const ZSTD_DDict** newTable = (const ZSTD_DDict**)ZSTD_customCalloc(sizeof(ZSTD_DDict*) * newTableSize, customMem);
const ZSTD_DDict** oldTable = hashSet->ddictPtrTable;
size_t oldTableSize = hashSet->ddictPtrTableSize;
size_t i;
DEBUGLOG(4, "Expanding DDict hash table! Old size: %zu new size: %zu", oldTableSize, newTableSize);
RETURN_ERROR_IF(!newTable, memory_allocation, "Expanded hashset allocation failed!");
hashSet->ddictPtrTable = newTable;
hashSet->ddictPtrTableSize = newTableSize;
hashSet->ddictPtrCount = 0;
for (i = 0; i < oldTableSize; ++i) {
if (oldTable[i] != NULL) {
FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, oldTable[i]), "");
}
}
ZSTD_customFree((void*)oldTable, customMem);
DEBUGLOG(4, "Finished re-hash");
return 0;
}
/* Fetches a DDict with the given dictID
* Returns the ZSTD_DDict* with the requested dictID. If it doesn't exist, then returns NULL.
*/
static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, U32 dictID) {
size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
for (;;) {
size_t currDictID = ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]);
if (currDictID == dictID || currDictID == 0) {
/* currDictID == 0 implies a NULL ddict entry */
break;
} else {
idx &= idxRangeMask; /* Goes to start of table when we reach the end */
idx++;
}
}
DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
return hashSet->ddictPtrTable[idx];
}
/* Allocates space for and returns a ddict hash set
* The hash set's ZSTD_DDict* table has all values automatically set to NULL to begin with.
* Returns NULL if allocation failed.
*/
static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem);
DEBUGLOG(4, "Allocating new hash set");
if (!ret)
return NULL;
ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
if (!ret->ddictPtrTable) {
Annotation
- Immediate include surface: `../common/zstd_deps.h`, `../common/allocations.h`, `../common/error_private.h`, `../common/zstd_internal.h`, `../common/mem.h`, `../common/bits.h`, `../common/fse.h`, `../common/huf.h`.
- Detected declarations: `function ZSTD_decompressDCtx`, `function ZSTD_DDictHashSet_emplaceDDict`, `function ZSTD_DDictHashSet_expand`, `function ZSTD_DDictHashSet_getDDict`, `function ZSTD_createDDictHashSet`, `function ZSTD_freeDDictHashSet`, `function ZSTD_DDictHashSet_addDDict`, `function ZSTD_sizeof_DCtx`, `function ZSTD_estimateDCtxSize`, `function ZSTD_startingInputLength`.
- Atlas domain: Kernel Services / lib.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.