Refactor usage of ms->ldmSeqStore so that it is not modified during compressBlock(), and simplify skipRawSeqStoreBytes
parent
a5500cf2af
commit
0fac8e07e1
|
@ -555,6 +555,26 @@ static rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore,
|
||||||
return sequence;
|
return sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ZSTD_ldm_skipRawSeqStoreBytes():
|
||||||
|
* Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'.
|
||||||
|
*/
|
||||||
|
static void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
|
||||||
|
U32 currPos = rawSeqStore->posInSequence + nbBytes;
|
||||||
|
while (currPos && rawSeqStore->pos < rawSeqStore->size) {
|
||||||
|
rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
|
||||||
|
if (currPos >= currSeq.litLength + currSeq.matchLength) {
|
||||||
|
currPos -= currSeq.litLength + currSeq.matchLength;
|
||||||
|
rawSeqStore->pos++;
|
||||||
|
if (currPos == 0) {
|
||||||
|
rawSeqStore->posInSequence = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rawSeqStore->posInSequence = currPos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
||||||
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
||||||
void const* src, size_t srcSize)
|
void const* src, size_t srcSize)
|
||||||
|
@ -574,7 +594,11 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
||||||
size_t lastLLSize;
|
size_t lastLLSize;
|
||||||
ms->ldmSeqStore = *rawSeqStore;
|
ms->ldmSeqStore = *rawSeqStore;
|
||||||
lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize);
|
lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize);
|
||||||
*rawSeqStore = ms->ldmSeqStore;
|
ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize);
|
||||||
|
if (rawSeqStore->pos >= rawSeqStore->size) {
|
||||||
|
/* If we're done with rawSeqStore, invalidate the one in matchState as well */
|
||||||
|
ms->ldmSeqStore.pos = rawSeqStore->size;
|
||||||
|
}
|
||||||
return lastLLSize;
|
return lastLLSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -768,39 +768,30 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
||||||
* LDM helper functions *
|
* LDM helper functions *
|
||||||
*************************/
|
*************************/
|
||||||
|
|
||||||
|
/* Struct containing info needed to make decision about ldm inclusion */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
rawSeqStore_t* seqStore; /* Reference to struct containing external candidates */
|
rawSeqStore_t seqStore; /* External match candidates store for this block */
|
||||||
U32 startPosInBlock; /* Start position of the current match candidate */
|
U32 startPosInBlock; /* Start position of the current match candidate */
|
||||||
U32 endPosInBlock; /* End position of the current match candidate */
|
U32 endPosInBlock; /* End position of the current match candidate */
|
||||||
U32 offset; /* Offset of the match candidate */
|
U32 offset; /* Offset of the match candidate */
|
||||||
} ZSTD_optLdm_t;
|
} ZSTD_optLdm_t;
|
||||||
|
|
||||||
/* ZSTD_opt_skipRawSeqStoreBytes():
|
/* ZSTD_optLdm_skipRawSeqStoreBytes():
|
||||||
* Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'.
|
* Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'.
|
||||||
*/
|
*/
|
||||||
static void ZSTD_opt_skipRawSeqStoreBytes(rawSeqStore_t* ldmSeqStore, size_t nbBytes) {
|
static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
|
||||||
while (nbBytes && ldmSeqStore->pos < ldmSeqStore->size) {
|
U32 currPos = rawSeqStore->posInSequence + nbBytes;
|
||||||
rawSeq currSeq = ldmSeqStore->seq[ldmSeqStore->pos];
|
while (currPos && rawSeqStore->pos < rawSeqStore->size) {
|
||||||
/* posInSequence necessarily must never represent a value beyond the sequence */
|
rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
|
||||||
assert(ldmSeqStore->posInSequence <= currSeq.matchLength + currSeq.litLength);
|
if (currPos >= currSeq.litLength + currSeq.matchLength) {
|
||||||
|
currPos -= currSeq.litLength + currSeq.matchLength;
|
||||||
if (nbBytes <= currSeq.litLength) {
|
rawSeqStore->pos++;
|
||||||
ldmSeqStore->posInSequence += nbBytes;
|
if (currPos == 0) {
|
||||||
return;
|
rawSeqStore->posInSequence = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ldmSeqStore->posInSequence += currSeq.litLength;
|
rawSeqStore->posInSequence = currPos;
|
||||||
nbBytes -= currSeq.litLength;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (nbBytes < currSeq.matchLength) {
|
|
||||||
ldmSeqStore->posInSequence += nbBytes;
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
nbBytes -= currSeq.matchLength;
|
|
||||||
/* We have moved through this entire sequence - move the read pos
|
|
||||||
forward to the next sequence, and reset posInSequence */
|
|
||||||
ldmSeqStore->pos++;
|
|
||||||
ldmSeqStore->posInSequence = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -817,28 +808,28 @@ static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 cu
|
||||||
U32 matchBytesRemaining;
|
U32 matchBytesRemaining;
|
||||||
|
|
||||||
/* Setting match end position to MAX to ensure we never use an LDM during this block */
|
/* Setting match end position to MAX to ensure we never use an LDM during this block */
|
||||||
if (optLdm->seqStore->pos >= optLdm->seqStore->size) {
|
if (optLdm->seqStore.pos >= optLdm->seqStore.size || optLdm->seqStore.size == 0) {
|
||||||
optLdm->startPosInBlock = UINT_MAX;
|
optLdm->startPosInBlock = UINT_MAX;
|
||||||
optLdm->endPosInBlock = UINT_MAX;
|
optLdm->endPosInBlock = UINT_MAX;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Calculate appropriate bytes left in matchLength and litLength after adjusting
|
/* Calculate appropriate bytes left in matchLength and litLength after adjusting
|
||||||
based on ldmSeqStore->posInSequence */
|
based on ldmSeqStore->posInSequence */
|
||||||
currSeq = optLdm->seqStore->seq[optLdm->seqStore->pos];
|
currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
|
||||||
assert(optLdm->seqStore->posInSequence <= currSeq.litLength + currSeq.matchLength);
|
assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
|
||||||
currBlockEndPos = currPosInBlock + blockBytesRemaining;
|
currBlockEndPos = currPosInBlock + blockBytesRemaining;
|
||||||
literalsBytesRemaining = (optLdm->seqStore->posInSequence < currSeq.litLength) ?
|
literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ?
|
||||||
currSeq.litLength - (U32)optLdm->seqStore->posInSequence :
|
currSeq.litLength - (U32)optLdm->seqStore.posInSequence :
|
||||||
0;
|
0;
|
||||||
matchBytesRemaining = (literalsBytesRemaining == 0) ?
|
matchBytesRemaining = (literalsBytesRemaining == 0) ?
|
||||||
currSeq.matchLength - ((U32)optLdm->seqStore->posInSequence - currSeq.litLength) :
|
currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) :
|
||||||
currSeq.matchLength;
|
currSeq.matchLength;
|
||||||
|
|
||||||
/* If there are more literal bytes than bytes remaining in block, no ldm is possible */
|
/* If there are more literal bytes than bytes remaining in block, no ldm is possible */
|
||||||
if (literalsBytesRemaining >= blockBytesRemaining) {
|
if (literalsBytesRemaining >= blockBytesRemaining) {
|
||||||
optLdm->startPosInBlock = UINT_MAX;
|
optLdm->startPosInBlock = UINT_MAX;
|
||||||
optLdm->endPosInBlock = UINT_MAX;
|
optLdm->endPosInBlock = UINT_MAX;
|
||||||
ZSTD_opt_skipRawSeqStoreBytes(optLdm->seqStore, blockBytesRemaining);
|
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,21 +842,18 @@ static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 cu
|
||||||
if (optLdm->endPosInBlock > currBlockEndPos) {
|
if (optLdm->endPosInBlock > currBlockEndPos) {
|
||||||
/* Match ends after the block ends, we can't use the whole match */
|
/* Match ends after the block ends, we can't use the whole match */
|
||||||
optLdm->endPosInBlock = currBlockEndPos;
|
optLdm->endPosInBlock = currBlockEndPos;
|
||||||
ZSTD_opt_skipRawSeqStoreBytes(optLdm->seqStore, currBlockEndPos - currPosInBlock);
|
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock);
|
||||||
} else {
|
} else {
|
||||||
/* If we can use the whole match point the ldmSeqStore at the next match */
|
/* Consume nb of bytes equal to size of sequence left */
|
||||||
optLdm->seqStore->posInSequence = 0;
|
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining);
|
||||||
optLdm->seqStore->pos++;
|
|
||||||
}
|
}
|
||||||
DEBUGLOG(6, "ZSTD_opt_getNextMatchAndUpdateSeqStore(): got an ldm that beginning at pos: %u, end at pos: %u, with offset: %u",
|
|
||||||
optLdm->startPosInBlock, optLdm->endPosInBlock, optLdm->offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ZSTD_opt_maybeAddMatch():
|
/* ZSTD_optLdm_maybeAddMatch():
|
||||||
* Adds a match if it's long enough, based on it's 'matchStartPosInBlock'
|
* Adds a match if it's long enough, based on it's 'matchStartPosInBlock'
|
||||||
* and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches'
|
* and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches'
|
||||||
*/
|
*/
|
||||||
static void ZSTD_opt_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
|
static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
|
||||||
ZSTD_optLdm_t* optLdm, U32 currPosInBlock) {
|
ZSTD_optLdm_t* optLdm, U32 currPosInBlock) {
|
||||||
U32 posDiff = currPosInBlock - optLdm->startPosInBlock;
|
U32 posDiff = currPosInBlock - optLdm->startPosInBlock;
|
||||||
/* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */
|
/* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */
|
||||||
|
@ -879,7 +867,7 @@ static void ZSTD_opt_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGLOG(6, "ZSTD_opt_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u",
|
DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u",
|
||||||
candidateOffCode, candidateMatchLength, currPosInBlock);
|
candidateOffCode, candidateMatchLength, currPosInBlock);
|
||||||
if (*nbMatches == 0) {
|
if (*nbMatches == 0) {
|
||||||
matches[*nbMatches].len = candidateMatchLength;
|
matches[*nbMatches].len = candidateMatchLength;
|
||||||
|
@ -896,27 +884,27 @@ static void ZSTD_opt_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ZSTD_opt_processMatchCandidate():
|
/* ZSTD_optLdm_processMatchCandidate():
|
||||||
* Wrapper function to update ldm seq store and call ldm functions as necessary.
|
* Wrapper function to update ldm seq store and call ldm functions as necessary.
|
||||||
*/
|
*/
|
||||||
static void ZSTD_opt_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches,
|
static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches,
|
||||||
U32 currPosInBlock, U32 remainingBytes) {
|
U32 currPosInBlock, U32 remainingBytes) {
|
||||||
if (optLdm->seqStore->size == 0 && optLdm->seqStore->pos >= optLdm->seqStore->size) {
|
if (optLdm->seqStore.size == 0 && optLdm->seqStore.pos >= optLdm->seqStore.size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currPosInBlock >= optLdm->endPosInBlock) {
|
if (currPosInBlock >= optLdm->endPosInBlock) {
|
||||||
if (currPosInBlock > optLdm->endPosInBlock) {
|
if (currPosInBlock > optLdm->endPosInBlock) {
|
||||||
/* The position at which ZSTD_opt_processMatchCandidate() is called is not necessarily
|
/* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily
|
||||||
* at the end of a match from the ldm seq store, and will often be some bytes
|
* at the end of a match from the ldm seq store, and will often be some bytes
|
||||||
* over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
|
* over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
|
||||||
*/
|
*/
|
||||||
U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock;
|
U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock;
|
||||||
ZSTD_opt_skipRawSeqStoreBytes(optLdm->seqStore, posOvershoot);
|
ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
|
||||||
}
|
}
|
||||||
ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
|
ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
|
||||||
}
|
}
|
||||||
ZSTD_opt_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
|
ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-*******************************
|
/*-*******************************
|
||||||
|
@ -971,14 +959,10 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
||||||
ZSTD_optimal_t* const opt = optStatePtr->priceTable;
|
ZSTD_optimal_t* const opt = optStatePtr->priceTable;
|
||||||
ZSTD_match_t* const matches = optStatePtr->matchTable;
|
ZSTD_match_t* const matches = optStatePtr->matchTable;
|
||||||
ZSTD_optimal_t lastSequence;
|
ZSTD_optimal_t lastSequence;
|
||||||
|
ZSTD_optLdm_t optLdm = {ms->ldmSeqStore, 0, 0, 0}; /* ms->ldmSeqStore itself is immutable in this function */
|
||||||
/* Make a copy so that ms->ldmSeqStore stays immutable during compressBlock() */
|
|
||||||
ZSTD_optLdm_t optLdm = {&ms->ldmSeqStore, 0, 0, 0};
|
|
||||||
|
|
||||||
/* Get first match from ldm seq store if long mode is enabled */
|
/* Get first match from ldm seq store if long mode is enabled */
|
||||||
if (ms->ldmSeqStore.size > 0 && ms->ldmSeqStore.pos < ms->ldmSeqStore.size) {
|
ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
|
||||||
ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
|
DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
|
||||||
|
@ -995,7 +979,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
||||||
{ U32 const litlen = (U32)(ip - anchor);
|
{ U32 const litlen = (U32)(ip - anchor);
|
||||||
U32 const ll0 = !litlen;
|
U32 const ll0 = !litlen;
|
||||||
U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
|
U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
|
||||||
ZSTD_opt_processMatchCandidate(&optLdm, matches, &nbMatches,
|
ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
|
||||||
(U32)(ip-istart), (U32)(iend - ip));
|
(U32)(ip-istart), (U32)(iend - ip));
|
||||||
if (!nbMatches) { ip++; continue; }
|
if (!nbMatches) { ip++; continue; }
|
||||||
|
|
||||||
|
@ -1112,7 +1096,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
||||||
U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
|
U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
|
||||||
U32 matchNb;
|
U32 matchNb;
|
||||||
|
|
||||||
ZSTD_opt_processMatchCandidate(&optLdm, matches, &nbMatches,
|
ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
|
||||||
(U32)(inr-istart), (U32)(iend-inr));
|
(U32)(inr-istart), (U32)(iend-inr));
|
||||||
|
|
||||||
if (!nbMatches) {
|
if (!nbMatches) {
|
||||||
|
@ -1228,13 +1212,7 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
||||||
ZSTD_setBasePrices(optStatePtr, optLevel);
|
ZSTD_setBasePrices(optStatePtr, optLevel);
|
||||||
}
|
}
|
||||||
} /* while (ip < ilimit) */
|
} /* while (ip < ilimit) */
|
||||||
|
|
||||||
if (optLdm.endPosInBlock < srcSize) {
|
|
||||||
/* This can occur if after adding the final match in an ldm seq store within this block,
|
|
||||||
ip reaches end of the block without calling ZSTD_opt_getNextLdmAndUpdateSeqStore() */
|
|
||||||
ZSTD_opt_skipRawSeqStoreBytes(optLdm.seqStore, srcSize - optLdm.endPosInBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the last literals size */
|
/* Return the last literals size */
|
||||||
return (size_t)(iend - anchor);
|
return (size_t)(iend - anchor);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue