/** ZSTD_buildSuperBlockEntropy() : * Builds entropy for the super-block. * @return : 0 on success or error code */ private static nuint ZSTD_buildSuperBlockEntropy(seqStore_t *seqStorePtr, ZSTD_entropyCTables_t *prevEntropy, ZSTD_entropyCTables_t *nextEntropy, ZSTD_CCtx_params_s *cctxParams, ZSTD_entropyCTablesMetadata_t *entropyMetadata, void *workspace, nuint wkspSize) { nuint litSize = (nuint)(seqStorePtr->lit - seqStorePtr->litStart); entropyMetadata->hufMetadata.hufDesSize = ZSTD_buildSuperBlockEntropy_literal((void *)seqStorePtr->litStart, litSize, &prevEntropy->huf, &nextEntropy->huf, &entropyMetadata->hufMetadata, ZSTD_disableLiteralsCompression(cctxParams), workspace, wkspSize); { nuint err_code = (entropyMetadata->hufMetadata.hufDesSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } entropyMetadata->fseMetadata.fseTablesSize = ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr, &prevEntropy->fse, &nextEntropy->fse, cctxParams, &entropyMetadata->fseMetadata, workspace, wkspSize); { nuint err_code = (entropyMetadata->fseMetadata.fseTablesSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } return(0); }
private static nuint ZSTD_seqDecompressedSize(seqStore_t *seqStore, seqDef_s *sequences, nuint nbSeq, nuint litSize, int lastSequence) { seqDef_s *sstart = sequences; seqDef_s *send = sequences + nbSeq; seqDef_s *sp = sstart; nuint matchLengthSum = 0; nuint litLengthSum = 0; while (send - sp > 0) { ZSTD_sequenceLength seqLen = ZSTD_getSequenceLength(seqStore, sp); litLengthSum += seqLen.litLength; matchLengthSum += seqLen.matchLength; sp++; } assert(litLengthSum <= litSize); if (lastSequence == 0) { assert(litLengthSum == litSize); } return(matchLengthSum + litSize); }
public static nuint ZSTD_compressBlock_doubleFast(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize) { uint mls = ms->cParams.minMatch; switch (mls) { default: case 4: { return(ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_dictMode_e.ZSTD_noDict)); } case 5: { return(ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_dictMode_e.ZSTD_noDict)); } case 6: { return(ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_dictMode_e.ZSTD_noDict)); } case 7: { return(ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_dictMode_e.ZSTD_noDict)); } } }
public static nuint ZSTD_compressBlock_fast_extDict(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize) { uint mls = ms->cParams.minMatch; switch (mls) { default: case 4: { return(ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 4)); } case 5: { return(ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 5)); } case 6: { return(ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 6)); } case 7: { return(ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 7)); } } }
private static void ZSTD_storeSeq(seqStore_t *seqStorePtr, nuint litLength, byte *literals, byte *litLimit, uint offCode, nuint mlBase) { byte *litLimit_w = litLimit - 32; byte *litEnd = literals + litLength; assert((nuint)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); assert(seqStorePtr->maxNbLit <= (uint)(128 * (1 << 10))); assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit); assert(literals + litLength <= litLimit); if (litEnd <= litLimit_w) { assert(32 >= 16); ZSTD_copy16((void *)seqStorePtr->lit, (void *)literals); if (litLength > 16) { ZSTD_wildcopy((void *)(seqStorePtr->lit + 16), (void *)(literals + 16), (nint)(litLength) - 16, ZSTD_overlap_e.ZSTD_no_overlap); } } else { ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w); } seqStorePtr->lit += litLength; if (litLength > 0xFFFF) { assert(seqStorePtr->longLengthID == 0); seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (uint)(seqStorePtr->sequences - seqStorePtr->sequencesStart); } seqStorePtr->sequences[0].litLength = (ushort)(litLength); seqStorePtr->sequences[0].offset = offCode + 1; if (mlBase > 0xFFFF) { assert(seqStorePtr->longLengthID == 0); seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (uint)(seqStorePtr->sequences - seqStorePtr->sequencesStart); } seqStorePtr->sequences[0].matchLength = (ushort)(mlBase); seqStorePtr->sequences++; }
private static ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t *seqStore, seqDef_s *seq) { ZSTD_sequenceLength seqLen; seqLen.litLength = seq->litLength; seqLen.matchLength = (uint)(seq->matchLength + 3); if (seqStore->longLengthPos == (uint)(seq - seqStore->sequencesStart)) { if (seqStore->longLengthID == 1) { seqLen.litLength += 0xFFFF; } if (seqStore->longLengthID == 2) { seqLen.matchLength += 0xFFFF; } } return(seqLen); }
/** * ZSTD_ldm_blockCompress(): * * Compresses a block using the predefined sequences, along with a secondary * block compressor. The literals section of every sequence is passed to the * secondary block compressor, and those sequences are interspersed with the * predefined sequences. Returns the length of the last literals. * Updates `rawSeqStore.pos` to indicate how many sequences have been consumed. * `rawSeqStore.seq` may also be updated to split the last sequence between two * blocks. * @return The length of the last literals. * * NOTE: The source must be at most the maximum block size, but the predefined * sequences can be any size, and may be longer than the block. In the case that * they are longer than the block, the last sequences may need to be split into * two. We handle that case correctly, and update `rawSeqStore` appropriately. * NOTE: This function does not return any errors. */ public static nuint ZSTD_ldm_blockCompress(rawSeqStore_t *rawSeqStore, ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize) { ZSTD_compressionParameters *cParams = &ms->cParams; uint minMatch = cParams->minMatch; ZSTD_blockCompressor blockCompressor = ZSTD_selectBlockCompressor(cParams->strategy, ZSTD_matchState_dictMode(ms)); byte *istart = (byte *)(src); byte *iend = istart + srcSize; byte *ip = istart; if (cParams->strategy >= ZSTD_strategy.ZSTD_btopt) { nuint lastLLSize; ms->ldmSeqStore = rawSeqStore; lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize); ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize); return(lastLLSize); } assert(rawSeqStore->pos <= rawSeqStore->size); assert(rawSeqStore->size <= rawSeqStore->capacity); while (rawSeqStore->pos < rawSeqStore->size && ip < iend) { rawSeq sequence = maybeSplitSequence(rawSeqStore, (uint)(iend - ip), minMatch); int i; if (sequence.offset == 0) { break; } assert(ip + sequence.litLength + sequence.matchLength <= iend); ZSTD_ldm_limitTableUpdate(ms, ip); ZSTD_ldm_fillFastTables(ms, (void *)ip); { nuint newLitLength = blockCompressor(ms, seqStore, rep, (void *)ip, sequence.litLength); ip += sequence.litLength; for (i = 3 - 1; i > 0; i--) { rep[i] = rep[i - 1]; } rep[0] = sequence.offset; ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend, sequence.offset + (uint)((3 - 1)), sequence.matchLength - 3); ip += sequence.matchLength; } } ZSTD_ldm_limitTableUpdate(ms, ip); ZSTD_ldm_fillFastTables(ms, (void *)ip); return(blockCompressor(ms, seqStore, rep, (void *)ip, (nuint)(iend - ip))); }
/** ZSTD_compressSubBlock_multi() : * Breaks super-block into multiple sub-blocks and compresses them. * Entropy will be written to the first block. * The following blocks will use repeat mode to compress. * All sub-blocks are compressed blocks (no raw or rle blocks). * @return : compressed size of the super block (which is multiple ZSTD blocks) * Or 0 if it failed to compress. */ private static nuint ZSTD_compressSubBlock_multi(seqStore_t *seqStorePtr, ZSTD_compressedBlockState_t *prevCBlock, ZSTD_compressedBlockState_t *nextCBlock, ZSTD_entropyCTablesMetadata_t *entropyMetadata, ZSTD_CCtx_params_s *cctxParams, void *dst, nuint dstCapacity, void *src, nuint srcSize, int bmi2, uint lastBlock, void *workspace, nuint wkspSize) { seqDef_s *sstart = seqStorePtr->sequencesStart; seqDef_s *send = seqStorePtr->sequences; seqDef_s *sp = sstart; byte * lstart = seqStorePtr->litStart; byte * lend = seqStorePtr->lit; byte * lp = lstart; byte * ip = (byte *)(src); byte * iend = ip + srcSize; byte * ostart = (byte *)(dst); byte * oend = ostart + dstCapacity; byte * op = ostart; byte * llCodePtr = seqStorePtr->llCode; byte * mlCodePtr = seqStorePtr->mlCode; byte * ofCodePtr = seqStorePtr->ofCode; nuint targetCBlockSize = cctxParams->targetCBlockSize; nuint litSize, seqCount; int writeLitEntropy = ((entropyMetadata->hufMetadata.hType == symbolEncodingType_e.set_compressed) ? 1 : 0); int writeSeqEntropy = 1; int lastSequence = 0; litSize = 0; seqCount = 0; do { nuint cBlockSizeEstimate = 0; if (sstart == send) { lastSequence = 1; } else { seqDef_s *sequence = sp + seqCount; lastSequence = ((sequence == send - 1) ? 1 : 0); litSize += ZSTD_getSequenceLength(seqStorePtr, sequence).litLength; seqCount++; } if (lastSequence != 0) { assert(lp <= lend); assert(litSize <= (nuint)(lend - lp)); litSize = (nuint)(lend - lp); } cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount, &nextCBlock->entropy, entropyMetadata, workspace, wkspSize, writeLitEntropy, writeSeqEntropy); if (cBlockSizeEstimate > targetCBlockSize || lastSequence != 0) { int litEntropyWritten = 0; int seqEntropyWritten = 0; nuint decompressedSize = ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, lastSequence); nuint cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, sp, seqCount, lp, litSize, llCodePtr, mlCodePtr, ofCodePtr, cctxParams, (void *)op, (nuint)(oend - op), bmi2, writeLitEntropy, writeSeqEntropy, &litEntropyWritten, &seqEntropyWritten, ((lastBlock != 0 && lastSequence != 0) ? 1U : 0U)); { nuint err_code = (cSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } if (cSize > 0 && cSize < decompressedSize) { assert(ip + decompressedSize <= iend); ip += decompressedSize; sp += seqCount; lp += litSize; op += cSize; llCodePtr += seqCount; mlCodePtr += seqCount; ofCodePtr += seqCount; litSize = 0; seqCount = 0; if (litEntropyWritten != 0) { writeLitEntropy = 0; } if (seqEntropyWritten != 0) { writeSeqEntropy = 0; } } } }while (lastSequence == 0); if (writeLitEntropy != 0) { memcpy((void *)(&nextCBlock->entropy.huf), (void *)(&prevCBlock->entropy.huf), ((nuint)(sizeof(ZSTD_hufCTables_t)))); } if (writeSeqEntropy != 0 && (ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) != 0) { return(0); } if (ip < iend) { nuint cSize = ZSTD_noCompressBlock((void *)op, (nuint)(oend - op), (void *)ip, (nuint)(iend - ip), lastBlock); { nuint err_code = (cSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } assert(cSize != 0); op += cSize; if (sp < send) { seqDef_s * seq; repcodes_s rep; memcpy((void *)(&rep), (void *)(prevCBlock->rep), ((nuint)(sizeof(repcodes_s)))); for (seq = sstart; seq < sp; ++seq) { rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ((ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0) ? 1U : 0U)); } memcpy((void *)(nextCBlock->rep), (void *)(&rep), ((nuint)(sizeof(repcodes_s)))); } } return((nuint)(op - ostart)); }
/** ZSTD_buildSuperBlockEntropy_sequences() : * Builds entropy for the super-block sequences. * Stores symbol compression modes and fse table to fseMetadata. * @return : size of fse tables or error code */ private static nuint ZSTD_buildSuperBlockEntropy_sequences(seqStore_t *seqStorePtr, ZSTD_fseCTables_t *prevEntropy, ZSTD_fseCTables_t *nextEntropy, ZSTD_CCtx_params_s *cctxParams, ZSTD_fseCTablesMetadata_t *fseMetadata, void *workspace, nuint wkspSize) { byte * wkspStart = (byte *)(workspace); byte * wkspEnd = wkspStart + wkspSize; byte * countWkspStart = wkspStart; uint * countWksp = (uint *)(workspace); nuint countWkspSize = (uint)((((35) > (52) ? (35) : (52)) + 1)) * (nuint)(4); byte * cTableWksp = countWkspStart + countWkspSize; nuint cTableWkspSize = (nuint)(wkspEnd - cTableWksp); ZSTD_strategy strategy = cctxParams->cParams.strategy; uint * CTable_LitLength = (uint *)nextEntropy->litlengthCTable; uint * CTable_OffsetBits = (uint *)nextEntropy->offcodeCTable; uint * CTable_MatchLength = (uint *)nextEntropy->matchlengthCTable; byte * ofCodeTable = seqStorePtr->ofCode; byte * llCodeTable = seqStorePtr->llCode; byte * mlCodeTable = seqStorePtr->mlCode; nuint nbSeq = (nuint)(seqStorePtr->sequences - seqStorePtr->sequencesStart); byte * ostart = (byte *)fseMetadata->fseTablesBuffer; byte * oend = ostart + (nuint)(133); byte * op = ostart; assert(cTableWkspSize >= (uint)((1 << ((((9) > (9) ? (9) : (9))) > (8) ? (((9) > (9) ? (9) : (9))) : (8)))) * (nuint)(sizeof(byte))); memset((workspace), (0), (wkspSize)); fseMetadata->lastCountSize = 0; ZSTD_seqToCodes(seqStorePtr); { uint LLtype; uint max = 35; nuint mostFrequent = HIST_countFast_wksp(countWksp, &max, (void *)llCodeTable, nbSeq, workspace, wkspSize); nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode; LLtype = (uint)(ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, countWksp, max, mostFrequent, nbSeq, 9, (uint *)prevEntropy->litlengthCTable, (short *)LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultPolicy_e.ZSTD_defaultAllowed, strategy)); assert(symbolEncodingType_e.set_basic < symbolEncodingType_e.set_compressed && symbolEncodingType_e.set_rle < symbolEncodingType_e.set_compressed); assert(!(LLtype < (uint)symbolEncodingType_e.set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat.FSE_repeat_none)); { nuint countSize = ZSTD_buildCTable((void *)op, (nuint)(oend - op), CTable_LitLength, 9, (symbolEncodingType_e)(LLtype), countWksp, max, llCodeTable, nbSeq, (short *)LL_defaultNorm, LL_defaultNormLog, 35, (uint *)prevEntropy->litlengthCTable, (nuint)(1316), (void *)cTableWksp, cTableWkspSize); { nuint err_code = (countSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } if (LLtype == (uint)symbolEncodingType_e.set_compressed) { fseMetadata->lastCountSize = countSize; } op += countSize; fseMetadata->llType = (symbolEncodingType_e)(LLtype); } } { uint Offtype; uint max = 31; nuint mostFrequent = HIST_countFast_wksp(countWksp, &max, (void *)ofCodeTable, nbSeq, workspace, wkspSize); ZSTD_defaultPolicy_e defaultPolicy = (max <= 28) ? ZSTD_defaultPolicy_e.ZSTD_defaultAllowed : ZSTD_defaultPolicy_e.ZSTD_defaultDisallowed; nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode; Offtype = (uint)(ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, countWksp, max, mostFrequent, nbSeq, 8, (uint *)prevEntropy->offcodeCTable, (short *)OF_defaultNorm, OF_defaultNormLog, defaultPolicy, strategy)); assert(!(Offtype < (uint)symbolEncodingType_e.set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat.FSE_repeat_none)); { nuint countSize = ZSTD_buildCTable((void *)op, (nuint)(oend - op), CTable_OffsetBits, 8, (symbolEncodingType_e)(Offtype), countWksp, max, ofCodeTable, nbSeq, (short *)OF_defaultNorm, OF_defaultNormLog, 28, (uint *)prevEntropy->offcodeCTable, (nuint)(772), (void *)cTableWksp, cTableWkspSize); { nuint err_code = (countSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } if (Offtype == (uint)symbolEncodingType_e.set_compressed) { fseMetadata->lastCountSize = countSize; } op += countSize; fseMetadata->ofType = (symbolEncodingType_e)(Offtype); } } { uint MLtype; uint max = 52; nuint mostFrequent = HIST_countFast_wksp(countWksp, &max, (void *)mlCodeTable, nbSeq, workspace, wkspSize); nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode; MLtype = (uint)(ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, countWksp, max, mostFrequent, nbSeq, 9, (uint *)prevEntropy->matchlengthCTable, (short *)ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultPolicy_e.ZSTD_defaultAllowed, strategy)); assert(!(MLtype < (uint)symbolEncodingType_e.set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat.FSE_repeat_none)); { nuint countSize = ZSTD_buildCTable((void *)op, (nuint)(oend - op), CTable_MatchLength, 9, (symbolEncodingType_e)(MLtype), countWksp, max, mlCodeTable, nbSeq, (short *)ML_defaultNorm, ML_defaultNormLog, 52, (uint *)prevEntropy->matchlengthCTable, (nuint)(1452), (void *)cTableWksp, cTableWkspSize); { nuint err_code = (countSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } if (MLtype == (uint)symbolEncodingType_e.set_compressed) { fseMetadata->lastCountSize = countSize; } op += countSize; fseMetadata->mlType = (symbolEncodingType_e)(MLtype); } } assert((nuint)(op - ostart) <= (nuint)(sizeof(byte) * 133)); return((nuint)(op - ostart)); }
private static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters * @params, uint *countLit, uint *offsetcodeCount, uint *matchlengthCount, uint *litlengthCount, uint *repOffsets, void *src, nuint srcSize, uint notificationLevel) { nuint blockSizeMax = (nuint)((((1 << 17)) < (1 << (int)@params->cParams.windowLog) ? ((1 << 17)) : (1 << (int)@params->cParams.windowLog))); nuint cSize; if (srcSize > blockSizeMax) { srcSize = blockSizeMax; } { nuint errorCode = ZSTD_compressBegin_usingCDict(esr.zc, esr.dict); if ((ERR_isError(errorCode)) != 0) { return; } } cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, (nuint)((1 << 17)), src, srcSize); if ((ERR_isError(cSize)) != 0) { return; } if (cSize != 0) { seqStore_t *seqStorePtr = ZSTD_getSeqStore(esr.zc); { byte *bytePtr; for (bytePtr = seqStorePtr->litStart; bytePtr < seqStorePtr->lit; bytePtr++) { countLit[*bytePtr]++; } } { uint nbSeq = (uint)(seqStorePtr->sequences - seqStorePtr->sequencesStart); ZSTD_seqToCodes(seqStorePtr); { byte *codePtr = seqStorePtr->ofCode; uint u; for (u = 0; u < nbSeq; u++) { offsetcodeCount[codePtr[u]]++; } } { byte *codePtr = seqStorePtr->mlCode; uint u; for (u = 0; u < nbSeq; u++) { matchlengthCount[codePtr[u]]++; } } { byte *codePtr = seqStorePtr->llCode; uint u; for (u = 0; u < nbSeq; u++) { litlengthCount[codePtr[u]]++; } } if (nbSeq >= 2) { seqDef_s *seq = seqStorePtr->sequencesStart; uint offset1 = seq[0].offset - 3; uint offset2 = seq[1].offset - 3; if (offset1 >= 1024) { offset1 = 0; } if (offset2 >= 1024) { offset2 = 0; } repOffsets[offset1] += 3; repOffsets[offset2] += 1; } } } }
private static nuint ZSTD_compressBlock_fast_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize, uint mls) { ZSTD_compressionParameters *cParams = &ms->cParams; uint * hashTable = ms->hashTable; uint hlog = cParams->hashLog; nuint stepSize = cParams->targetLength + (uint)((cParams->targetLength) == 0 ? 1 : 0) + 1; byte * @base = ms->window.@base; byte * istart = (byte *)(src); byte * ip0 = istart; byte * ip1; byte * anchor = istart; uint endIndex = (uint)((nuint)(istart - @base) + srcSize); uint prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); byte * prefixStart = @base + prefixStartIndex; byte * iend = istart + srcSize; byte * ilimit = iend - 8; uint offset_1 = rep[0], offset_2 = rep[1]; uint offsetSaved = 0; ip0 += ((ip0 == prefixStart) ? 1 : 0); ip1 = ip0 + 1; { uint curr = (uint)(ip0 - @base); uint windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); uint maxRep = curr - windowLow; if (offset_2 > maxRep) { offsetSaved = offset_2; offset_2 = 0; } if (offset_1 > maxRep) { offsetSaved = offset_1; offset_1 = 0; } } while (ip1 < ilimit) { byte *match0; byte *match1; uint current0; { nuint h0 = ZSTD_hashPtr((void *)ip0, hlog, mls); nuint h1 = ZSTD_hashPtr((void *)ip1, hlog, mls); match0 = @base + hashTable[h0]; match1 = @base + hashTable[h1]; current0 = (uint)(ip0 - @base); hashTable[h0] = current0; hashTable[h1] = (uint)(ip1 - @base); } uint offcode; nuint mLength; assert(ip0 + 1 == ip1); { byte *ip2 = ip0 + 2; byte *repMatch = ip2 - offset_1; if (((offset_1 > 0) && (MEM_read32((void *)repMatch) == MEM_read32((void *)ip2)))) { mLength = (nuint)((ip2[-1] == repMatch[-1]) ? 1 : 0); ip0 = ip2 - mLength; match0 = repMatch - mLength; mLength += 4; offcode = 0; goto _match; } } if ((match0 > prefixStart) && MEM_read32((void *)match0) == MEM_read32((void *)ip0)) { goto _offset; } if ((match1 > prefixStart) && MEM_read32((void *)match1) == MEM_read32((void *)ip1)) { ip0 = ip1; match0 = match1; goto _offset; } { nuint step = ((nuint)(ip0 - anchor) >> (8 - 1)) + stepSize; assert(step >= 2); ip0 += step; ip1 += step; continue; } _offset: offset_2 = offset_1; offset_1 = (uint)(ip0 - match0); offcode = offset_1 + (uint)((3 - 1)); mLength = 4; while ((((ip0 > anchor) && (match0 > prefixStart))) && (ip0[-1] == match0[-1])) { ip0--; match0--; mLength++; } _match: mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend); ZSTD_storeSeq(seqStore, (nuint)(ip0 - anchor), anchor, iend, offcode, mLength - 3); ip0 += mLength; anchor = ip0; if (ip0 <= ilimit) { assert(@base + current0 + 2 > istart); hashTable[ZSTD_hashPtr((void *)(@base + current0 + 2), hlog, mls)] = current0 + 2; hashTable[ZSTD_hashPtr((void *)(ip0 - 2), hlog, mls)] = (uint)(ip0 - 2 - @base); if (offset_2 > 0) { while ((ip0 <= ilimit) && (MEM_read32((void *)ip0) == MEM_read32((void *)(ip0 - offset_2)))) { nuint rLength = ZSTD_count(ip0 + 4, ip0 + 4 - offset_2, iend) + 4; { uint tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } hashTable[ZSTD_hashPtr((void *)ip0, hlog, mls)] = (uint)(ip0 - @base); ip0 += rLength; ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength - 3); anchor = ip0; continue; } } } ip1 = ip0 + 1; } rep[0] = offset_1 != 0 ? offset_1 : offsetSaved; rep[1] = offset_2 != 0 ? offset_2 : offsetSaved; return((nuint)(iend - anchor)); }
private static nuint ZSTD_compressBlock_fast_extDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize, uint mls) { ZSTD_compressionParameters *cParams = &ms->cParams; uint * hashTable = ms->hashTable; uint hlog = cParams->hashLog; uint stepSize = cParams->targetLength + (uint)((cParams->targetLength) == 0 ? 1 : 0); byte * @base = ms->window.@base; byte * dictBase = ms->window.dictBase; byte * istart = (byte *)(src); byte * ip = istart; byte * anchor = istart; uint endIndex = (uint)((nuint)(istart - @base) + srcSize); uint lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); uint dictStartIndex = lowLimit; byte * dictStart = dictBase + dictStartIndex; uint dictLimit = ms->window.dictLimit; uint prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit; byte * prefixStart = @base + prefixStartIndex; byte * dictEnd = dictBase + prefixStartIndex; byte * iend = istart + srcSize; byte * ilimit = iend - 8; uint offset_1 = rep[0], offset_2 = rep[1]; if (prefixStartIndex == dictStartIndex) { return(ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls)); } while (ip < ilimit) { nuint h = ZSTD_hashPtr((void *)ip, hlog, mls); uint matchIndex = hashTable[h]; byte *matchBase = matchIndex < prefixStartIndex ? dictBase : @base; byte *match = matchBase + matchIndex; uint curr = (uint)(ip - @base); uint repIndex = curr + 1 - offset_1; byte *repBase = repIndex < prefixStartIndex ? dictBase : @base; byte *repMatch = repBase + repIndex; hashTable[h] = curr; assert(offset_1 <= curr + 1); if (((((uint)((prefixStartIndex - 1) - repIndex) >= 3) && (repIndex > dictStartIndex))) && (MEM_read32((void *)repMatch) == MEM_read32((void *)(ip + 1)))) { byte *repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; nuint rLength = ZSTD_count_2segments(ip + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4; ip++; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, 0, rLength - 3); ip += rLength; anchor = ip; } else { if ((matchIndex < dictStartIndex) || (MEM_read32((void *)match) != MEM_read32((void *)ip))) { assert(stepSize >= 1); ip += (ulong)((ip - anchor) >> 8) + stepSize; continue; } { byte *matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; byte *lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; uint offset = curr - matchIndex; nuint mLength = ZSTD_count_2segments(ip + 4, match + 4, iend, matchEnd, prefixStart) + 4; while ((((ip > anchor) && (match > lowMatchPtr))) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } offset_2 = offset_1; offset_1 = offset; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, offset + (uint)((3 - 1)), mLength - 3); ip += mLength; anchor = ip; } } if (ip <= ilimit) { hashTable[ZSTD_hashPtr((void *)(@base + curr + 2), hlog, mls)] = curr + 2; hashTable[ZSTD_hashPtr((void *)(ip - 2), hlog, mls)] = (uint)(ip - 2 - @base); while (ip <= ilimit) { uint current2 = (uint)(ip - @base); uint repIndex2 = current2 - offset_2; byte *repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : @base + repIndex2; if (((((uint)((prefixStartIndex - 1) - repIndex2) >= 3) && (repIndex2 > dictStartIndex))) && (MEM_read32((void *)repMatch2) == MEM_read32((void *)ip))) { byte *repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; nuint repLength2 = ZSTD_count_2segments(ip + 4, repMatch2 + 4, iend, repEnd2, prefixStart) + 4; { uint tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2 - 3); hashTable[ZSTD_hashPtr((void *)ip, hlog, mls)] = current2; ip += repLength2; anchor = ip; continue; } break; } } } rep[0] = offset_1; rep[1] = offset_2; return((nuint)(iend - anchor)); }
private static nuint ZSTD_compressBlock_fast_dictMatchState_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize, uint mls) { ZSTD_compressionParameters *cParams = &ms->cParams; uint * hashTable = ms->hashTable; uint hlog = cParams->hashLog; uint stepSize = cParams->targetLength + (uint)((cParams->targetLength) == 0 ? 1 : 0); byte * @base = ms->window.@base; byte * istart = (byte *)(src); byte * ip = istart; byte * anchor = istart; uint prefixStartIndex = ms->window.dictLimit; byte * prefixStart = @base + prefixStartIndex; byte * iend = istart + srcSize; byte * ilimit = iend - 8; uint offset_1 = rep[0], offset_2 = rep[1]; uint offsetSaved = 0; ZSTD_matchState_t * dms = ms->dictMatchState; ZSTD_compressionParameters *dictCParams = &dms->cParams; uint * dictHashTable = dms->hashTable; uint dictStartIndex = dms->window.dictLimit; byte * dictBase = dms->window.@base; byte * dictStart = dictBase + dictStartIndex; byte * dictEnd = dms->window.nextSrc; uint dictIndexDelta = prefixStartIndex - (uint)(dictEnd - dictBase); uint dictAndPrefixLength = (uint)(ip - prefixStart + dictEnd - dictStart); uint dictHLog = dictCParams->hashLog; uint maxDistance = 1U << (int)cParams->windowLog; uint endIndex = (uint)((nuint)(ip - @base) + srcSize); assert(endIndex - prefixStartIndex <= maxDistance); assert(prefixStartIndex >= (uint)(dictEnd - dictBase)); ip += ((dictAndPrefixLength == 0) ? 1 : 0); assert(offset_1 <= dictAndPrefixLength); assert(offset_2 <= dictAndPrefixLength); while (ip < ilimit) { nuint mLength; nuint h = ZSTD_hashPtr((void *)ip, hlog, mls); uint curr = (uint)(ip - @base); uint matchIndex = hashTable[h]; byte *match = @base + matchIndex; uint repIndex = curr + 1 - offset_1; byte *repMatch = (repIndex < prefixStartIndex) ? dictBase + (repIndex - dictIndexDelta) : @base + repIndex; hashTable[h] = curr; if (((uint)((prefixStartIndex - 1) - repIndex) >= 3) && (MEM_read32((void *)repMatch) == MEM_read32((void *)(ip + 1)))) { byte *repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; mLength = ZSTD_count_2segments(ip + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4; ip++; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, 0, mLength - 3); } else if ((matchIndex <= prefixStartIndex)) { nuint dictHash = ZSTD_hashPtr((void *)ip, dictHLog, mls); uint dictMatchIndex = dictHashTable[dictHash]; byte *dictMatch = dictBase + dictMatchIndex; if (dictMatchIndex <= dictStartIndex || MEM_read32((void *)dictMatch) != MEM_read32((void *)ip)) { assert(stepSize >= 1); ip += (ulong)((ip - anchor) >> 8) + stepSize; continue; } else { uint offset = (uint)(curr - dictMatchIndex - dictIndexDelta); mLength = ZSTD_count_2segments(ip + 4, dictMatch + 4, iend, dictEnd, prefixStart) + 4; while ((((ip > anchor) && (dictMatch > dictStart))) && (ip[-1] == dictMatch[-1])) { ip--; dictMatch--; mLength++; } offset_2 = offset_1; offset_1 = offset; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, offset + (uint)((3 - 1)), mLength - 3); } } else if (MEM_read32((void *)match) != MEM_read32((void *)ip)) { assert(stepSize >= 1); ip += (ulong)((ip - anchor) >> 8) + stepSize; continue; } else { uint offset = (uint)(ip - match); mLength = ZSTD_count(ip + 4, match + 4, iend) + 4; while ((((ip > anchor) && (match > prefixStart))) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } offset_2 = offset_1; offset_1 = offset; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, offset + (uint)((3 - 1)), mLength - 3); } ip += mLength; anchor = ip; if (ip <= ilimit) { assert(@base + curr + 2 > istart); hashTable[ZSTD_hashPtr((void *)(@base + curr + 2), hlog, mls)] = curr + 2; hashTable[ZSTD_hashPtr((void *)(ip - 2), hlog, mls)] = (uint)(ip - 2 - @base); while (ip <= ilimit) { uint current2 = (uint)(ip - @base); uint repIndex2 = current2 - offset_2; byte *repMatch2 = repIndex2 < prefixStartIndex ? dictBase - dictIndexDelta + repIndex2 : @base + repIndex2; if (((uint)((prefixStartIndex - 1) - (uint)(repIndex2)) >= 3) && (MEM_read32((void *)repMatch2) == MEM_read32((void *)ip))) { byte *repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; nuint repLength2 = ZSTD_count_2segments(ip + 4, repMatch2 + 4, iend, repEnd2, prefixStart) + 4; uint tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2 - 3); hashTable[ZSTD_hashPtr((void *)ip, hlog, mls)] = current2; ip += repLength2; anchor = ip; continue; } break; } } } rep[0] = offset_1 != 0 ? offset_1 : offsetSaved; rep[1] = offset_2 != 0 ? offset_2 : offsetSaved; return((nuint)(iend - anchor)); }
private static nuint ZSTD_compressBlock_doubleFast_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize, uint mls, ZSTD_dictMode_e dictMode) { ZSTD_compressionParameters *cParams = &ms->cParams; uint * hashLong = ms->hashTable; uint hBitsL = cParams->hashLog; uint * hashSmall = ms->chainTable; uint hBitsS = cParams->chainLog; byte * @base = ms->window.@base; byte * istart = (byte *)(src); byte * ip = istart; byte * anchor = istart; uint endIndex = (uint)((nuint)(istart - @base) + srcSize); uint prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); byte * prefixLowest = @base + prefixLowestIndex; byte * iend = istart + srcSize; byte * ilimit = iend - 8; uint offset_1 = rep[0], offset_2 = rep[1]; uint offsetSaved = 0; ZSTD_matchState_t * dms = ms->dictMatchState; ZSTD_compressionParameters *dictCParams = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? &dms->cParams : null; uint * dictHashLong = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dms->hashTable : null; uint * dictHashSmall = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dms->chainTable : null; uint dictStartIndex = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dms->window.dictLimit : 0; byte * dictBase = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dms->window.@base : null; byte * dictStart = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dictBase + dictStartIndex : null; byte * dictEnd = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dms->window.nextSrc : null; uint dictIndexDelta = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? prefixLowestIndex - (uint)(dictEnd - dictBase) : 0; uint dictHBitsL = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dictCParams->hashLog : hBitsL; uint dictHBitsS = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState ? dictCParams->chainLog : hBitsS; uint dictAndPrefixLength = (uint)((ip - prefixLowest) + (dictEnd - dictStart)); assert(dictMode == ZSTD_dictMode_e.ZSTD_noDict || dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState); if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState) { assert(ms->window.dictLimit + (1U << (int)cParams->windowLog) >= endIndex); } ip += ((dictAndPrefixLength == 0) ? 1 : 0); if (dictMode == ZSTD_dictMode_e.ZSTD_noDict) { uint curr = (uint)(ip - @base); uint windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); uint maxRep = curr - windowLow; if (offset_2 > maxRep) { offsetSaved = offset_2; offset_2 = 0; } if (offset_1 > maxRep) { offsetSaved = offset_1; offset_1 = 0; } } if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState) { assert(offset_1 <= dictAndPrefixLength); assert(offset_2 <= dictAndPrefixLength); } while (ip < ilimit) { nuint mLength; uint offset; nuint h2 = ZSTD_hashPtr((void *)ip, hBitsL, 8); nuint h = ZSTD_hashPtr((void *)ip, hBitsS, mls); nuint dictHL = ZSTD_hashPtr((void *)ip, dictHBitsL, 8); nuint dictHS = ZSTD_hashPtr((void *)ip, dictHBitsS, mls); uint curr = (uint)(ip - @base); uint matchIndexL = hashLong[h2]; uint matchIndexS = hashSmall[h]; byte *matchLong = @base + matchIndexL; byte *match = @base + matchIndexS; uint repIndex = curr + 1 - offset_1; byte *repMatch = (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState && repIndex < prefixLowestIndex) ? dictBase + (repIndex - dictIndexDelta) : @base + repIndex; hashLong[h2] = hashSmall[h] = curr; if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState && ((uint)((prefixLowestIndex - 1) - repIndex) >= 3) && (MEM_read32((void *)repMatch) == MEM_read32((void *)(ip + 1)))) { byte *repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; mLength = ZSTD_count_2segments(ip + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixLowest) + 4; ip++; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, 0, mLength - 3); goto _match_stored; } if (dictMode == ZSTD_dictMode_e.ZSTD_noDict && (((offset_1 > 0) && (MEM_read32((void *)(ip + 1 - offset_1)) == MEM_read32((void *)(ip + 1)))))) { mLength = ZSTD_count(ip + 1 + 4, ip + 1 + 4 - offset_1, iend) + 4; ip++; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, 0, mLength - 3); goto _match_stored; } if (matchIndexL > prefixLowestIndex) { if (MEM_read64((void *)matchLong) == MEM_read64((void *)ip)) { mLength = ZSTD_count(ip + 8, matchLong + 8, iend) + 8; offset = (uint)(ip - matchLong); while ((((ip > anchor) && (matchLong > prefixLowest))) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } goto _match_found; } } else if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState) { uint dictMatchIndexL = dictHashLong[dictHL]; byte *dictMatchL = dictBase + dictMatchIndexL; assert(dictMatchL < dictEnd); if (dictMatchL > dictStart && MEM_read64((void *)dictMatchL) == MEM_read64((void *)ip)) { mLength = ZSTD_count_2segments(ip + 8, dictMatchL + 8, iend, dictEnd, prefixLowest) + 8; offset = (uint)(curr - dictMatchIndexL - dictIndexDelta); while ((((ip > anchor) && (dictMatchL > dictStart))) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } goto _match_found; } } if (matchIndexS > prefixLowestIndex) { if (MEM_read32((void *)match) == MEM_read32((void *)ip)) { goto _search_next_long; } } else if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState) { uint dictMatchIndexS = dictHashSmall[dictHS]; match = dictBase + dictMatchIndexS; matchIndexS = dictMatchIndexS + dictIndexDelta; if (match > dictStart && MEM_read32((void *)match) == MEM_read32((void *)ip)) { goto _search_next_long; } } ip += ((ip - anchor) >> 8) + 1; continue; _search_next_long: { nuint hl3 = ZSTD_hashPtr((void *)(ip + 1), hBitsL, 8); nuint dictHLNext = ZSTD_hashPtr((void *)(ip + 1), dictHBitsL, 8); uint matchIndexL3 = hashLong[hl3]; byte *matchL3 = @base + matchIndexL3; hashLong[hl3] = curr + 1; if (matchIndexL3 > prefixLowestIndex) { if (MEM_read64((void *)matchL3) == MEM_read64((void *)(ip + 1))) { mLength = ZSTD_count(ip + 9, matchL3 + 8, iend) + 8; ip++; offset = (uint)(ip - matchL3); while ((((ip > anchor) && (matchL3 > prefixLowest))) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } goto _match_found; } } else if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState) { uint dictMatchIndexL3 = dictHashLong[dictHLNext]; byte *dictMatchL3 = dictBase + dictMatchIndexL3; assert(dictMatchL3 < dictEnd); if (dictMatchL3 > dictStart && MEM_read64((void *)dictMatchL3) == MEM_read64((void *)(ip + 1))) { mLength = ZSTD_count_2segments(ip + 1 + 8, dictMatchL3 + 8, iend, dictEnd, prefixLowest) + 8; ip++; offset = (uint)(curr + 1 - dictMatchIndexL3 - dictIndexDelta); while ((((ip > anchor) && (dictMatchL3 > dictStart))) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } goto _match_found; } } } if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) { mLength = ZSTD_count_2segments(ip + 4, match + 4, iend, dictEnd, prefixLowest) + 4; offset = (uint)(curr - matchIndexS); while ((((ip > anchor) && (match > dictStart))) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } } else { mLength = ZSTD_count(ip + 4, match + 4, iend) + 4; offset = (uint)(ip - match); while ((((ip > anchor) && (match > prefixLowest))) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } } _match_found: offset_2 = offset_1; offset_1 = offset; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, offset + (uint)((3 - 1)), mLength - 3); _match_stored: ip += mLength; anchor = ip; if (ip <= ilimit) { { uint indexToInsert = curr + 2; hashLong[ZSTD_hashPtr((void *)(@base + indexToInsert), hBitsL, 8)] = indexToInsert; hashLong[ZSTD_hashPtr((void *)(ip - 2), hBitsL, 8)] = (uint)(ip - 2 - @base); hashSmall[ZSTD_hashPtr((void *)(@base + indexToInsert), hBitsS, mls)] = indexToInsert; hashSmall[ZSTD_hashPtr((void *)(ip - 1), hBitsS, mls)] = (uint)(ip - 1 - @base); } if (dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState) { while (ip <= ilimit) { uint current2 = (uint)(ip - @base); uint repIndex2 = current2 - offset_2; byte *repMatch2 = dictMode == ZSTD_dictMode_e.ZSTD_dictMatchState && repIndex2 < prefixLowestIndex ? dictBase + repIndex2 - dictIndexDelta : @base + repIndex2; if (((uint)((prefixLowestIndex - 1) - (uint)(repIndex2)) >= 3) && (MEM_read32((void *)repMatch2) == MEM_read32((void *)ip))) { byte *repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend; nuint repLength2 = ZSTD_count_2segments(ip + 4, repMatch2 + 4, iend, repEnd2, prefixLowest) + 4; uint tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2 - 3); hashSmall[ZSTD_hashPtr((void *)ip, hBitsS, mls)] = current2; hashLong[ZSTD_hashPtr((void *)ip, hBitsL, 8)] = current2; ip += repLength2; anchor = ip; continue; } break; } } if (dictMode == ZSTD_dictMode_e.ZSTD_noDict) { while ((ip <= ilimit) && (((offset_2 > 0) && (MEM_read32((void *)ip) == MEM_read32((void *)(ip - offset_2)))))) { nuint rLength = ZSTD_count(ip + 4, ip + 4 - offset_2, iend) + 4; uint tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; hashSmall[ZSTD_hashPtr((void *)ip, hBitsS, mls)] = (uint)(ip - @base); hashLong[ZSTD_hashPtr((void *)ip, hBitsL, 8)] = (uint)(ip - @base); ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength - 3); ip += rLength; anchor = ip; continue; } } } } rep[0] = offset_1 != 0 ? offset_1 : offsetSaved; rep[1] = offset_2 != 0 ? offset_2 : offsetSaved; return((nuint)(iend - anchor)); }
private static nuint ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_matchState_t *ms, seqStore_t *seqStore, uint *rep, void *src, nuint srcSize, uint mls) { ZSTD_compressionParameters *cParams = &ms->cParams; uint * hashLong = ms->hashTable; uint hBitsL = cParams->hashLog; uint * hashSmall = ms->chainTable; uint hBitsS = cParams->chainLog; byte * istart = (byte *)(src); byte * ip = istart; byte * anchor = istart; byte * iend = istart + srcSize; byte * ilimit = iend - 8; byte * @base = ms->window.@base; uint endIndex = (uint)((nuint)(istart - @base) + srcSize); uint lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); uint dictStartIndex = lowLimit; uint dictLimit = ms->window.dictLimit; uint prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit; byte * prefixStart = @base + prefixStartIndex; byte * dictBase = ms->window.dictBase; byte * dictStart = dictBase + dictStartIndex; byte * dictEnd = dictBase + prefixStartIndex; uint offset_1 = rep[0], offset_2 = rep[1]; if (prefixStartIndex == dictStartIndex) { return(ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, mls, ZSTD_dictMode_e.ZSTD_noDict)); } while (ip < ilimit) { nuint hSmall = ZSTD_hashPtr((void *)ip, hBitsS, mls); uint matchIndex = hashSmall[hSmall]; byte *matchBase = matchIndex < prefixStartIndex ? dictBase : @base; byte *match = matchBase + matchIndex; nuint hLong = ZSTD_hashPtr((void *)ip, hBitsL, 8); uint matchLongIndex = hashLong[hLong]; byte *matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : @base; byte *matchLong = matchLongBase + matchLongIndex; uint curr = (uint)(ip - @base); uint repIndex = curr + 1 - offset_1; byte *repBase = repIndex < prefixStartIndex ? dictBase : @base; byte *repMatch = repBase + repIndex; nuint mLength; hashSmall[hSmall] = hashLong[hLong] = curr; if (((((uint)((prefixStartIndex - 1) - repIndex) >= 3) && (repIndex > dictStartIndex))) && (MEM_read32((void *)repMatch) == MEM_read32((void *)(ip + 1)))) { byte *repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; mLength = ZSTD_count_2segments(ip + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4; ip++; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, 0, mLength - 3); } else { if ((matchLongIndex > dictStartIndex) && (MEM_read64((void *)matchLong) == MEM_read64((void *)ip))) { byte *matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend; byte *lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart; uint offset; mLength = ZSTD_count_2segments(ip + 8, matchLong + 8, iend, matchEnd, prefixStart) + 8; offset = curr - matchLongIndex; while ((((ip > anchor) && (matchLong > lowMatchPtr))) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } offset_2 = offset_1; offset_1 = offset; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, offset + (uint)((3 - 1)), mLength - 3); } else if ((matchIndex > dictStartIndex) && (MEM_read32((void *)match) == MEM_read32((void *)ip))) { nuint h3 = ZSTD_hashPtr((void *)(ip + 1), hBitsL, 8); uint matchIndex3 = hashLong[h3]; byte *match3Base = matchIndex3 < prefixStartIndex ? dictBase : @base; byte *match3 = match3Base + matchIndex3; uint offset; hashLong[h3] = curr + 1; if ((matchIndex3 > dictStartIndex) && (MEM_read64((void *)match3) == MEM_read64((void *)(ip + 1)))) { byte *matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend; byte *lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart; mLength = ZSTD_count_2segments(ip + 9, match3 + 8, iend, matchEnd, prefixStart) + 8; ip++; offset = curr + 1 - matchIndex3; while ((((ip > anchor) && (match3 > lowMatchPtr))) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } } else { byte *matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; byte *lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; mLength = ZSTD_count_2segments(ip + 4, match + 4, iend, matchEnd, prefixStart) + 4; offset = curr - matchIndex; while ((((ip > anchor) && (match > lowMatchPtr))) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } } offset_2 = offset_1; offset_1 = offset; ZSTD_storeSeq(seqStore, (nuint)(ip - anchor), anchor, iend, offset + (uint)((3 - 1)), mLength - 3); } else { ip += ((ip - anchor) >> 8) + 1; continue; } } ip += mLength; anchor = ip; if (ip <= ilimit) { { uint indexToInsert = curr + 2; hashLong[ZSTD_hashPtr((void *)(@base + indexToInsert), hBitsL, 8)] = indexToInsert; hashLong[ZSTD_hashPtr((void *)(ip - 2), hBitsL, 8)] = (uint)(ip - 2 - @base); hashSmall[ZSTD_hashPtr((void *)(@base + indexToInsert), hBitsS, mls)] = indexToInsert; hashSmall[ZSTD_hashPtr((void *)(ip - 1), hBitsS, mls)] = (uint)(ip - 1 - @base); } while (ip <= ilimit) { uint current2 = (uint)(ip - @base); uint repIndex2 = current2 - offset_2; byte *repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : @base + repIndex2; if (((((uint)((prefixStartIndex - 1) - repIndex2) >= 3) && (repIndex2 > dictStartIndex))) && (MEM_read32((void *)repMatch2) == MEM_read32((void *)ip))) { byte *repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; nuint repLength2 = ZSTD_count_2segments(ip + 4, repMatch2 + 4, iend, repEnd2, prefixStart) + 4; uint tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2 - 3); hashSmall[ZSTD_hashPtr((void *)ip, hBitsS, mls)] = current2; hashLong[ZSTD_hashPtr((void *)ip, hBitsL, 8)] = current2; ip += repLength2; anchor = ip; continue; } break; } } } rep[0] = offset_1; rep[1] = offset_2; return((nuint)(iend - anchor)); }