Index: third_party/lzma_sdk/LzFind.c |
diff --git a/third_party/lzma_sdk/LzFind.c b/third_party/lzma_sdk/LzFind.c |
index e3ecb05420ebd280fad24e6be650461c2bbd5c2c..2d05fa39534d261c6b4a9784bf37830e7c71a289 100644 |
--- a/third_party/lzma_sdk/LzFind.c |
+++ b/third_party/lzma_sdk/LzFind.c |
@@ -1,5 +1,7 @@ |
/* LzFind.c -- Match finder for LZ algorithms |
-2009-04-22 : Igor Pavlov : Public domain */ |
+2015-10-15 : Igor Pavlov : Public domain */ |
+ |
+#include "Precomp.h" |
#include <string.h> |
@@ -9,8 +11,8 @@ |
#define kEmptyHashValue 0 |
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) |
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ |
-#define kNormalizeMask (~(kNormalizeStepMin - 1)) |
-#define kMaxHistorySize ((UInt32)3 << 30) |
+#define kNormalizeMask (~(UInt32)(kNormalizeStepMin - 1)) |
+#define kMaxHistorySize ((UInt32)7 << 29) |
#define kStartMaxLen 3 |
@@ -19,7 +21,7 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) |
if (!p->directInput) |
{ |
alloc->Free(alloc, p->bufferBase); |
- p->bufferBase = 0; |
+ p->bufferBase = NULL; |
} |
} |
@@ -33,17 +35,16 @@ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *a |
p->blockSize = blockSize; |
return 1; |
} |
- if (p->bufferBase == 0 || p->blockSize != blockSize) |
+ if (!p->bufferBase || p->blockSize != blockSize) |
{ |
LzInWindow_Free(p, alloc); |
p->blockSize = blockSize; |
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); |
} |
- return (p->bufferBase != 0); |
+ return (p->bufferBase != NULL); |
} |
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } |
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } |
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } |
@@ -58,9 +59,12 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) |
{ |
if (p->streamEndWasReached || p->result != SZ_OK) |
return; |
+ |
+ /* We use (p->streamPos - p->pos) value. (p->streamPos < p->pos) is allowed. */ |
+ |
if (p->directInput) |
{ |
- UInt32 curSize = 0xFFFFFFFF - p->streamPos; |
+ UInt32 curSize = 0xFFFFFFFF - (p->streamPos - p->pos); |
if (curSize > p->directInputRem) |
curSize = (UInt32)p->directInputRem; |
p->directInputRem -= curSize; |
@@ -69,12 +73,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) |
p->streamEndWasReached = 1; |
return; |
} |
+ |
for (;;) |
{ |
Byte *dest = p->buffer + (p->streamPos - p->pos); |
size_t size = (p->bufferBase + p->blockSize - dest); |
if (size == 0) |
return; |
+ |
p->result = p->stream->Read(p->stream, dest, &size); |
if (p->result != SZ_OK) |
return; |
@@ -92,8 +98,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) |
void MatchFinder_MoveBlock(CMatchFinder *p) |
{ |
memmove(p->bufferBase, |
- p->buffer - p->keepSizeBefore, |
- (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); |
+ p->buffer - p->keepSizeBefore, |
+ (size_t)(p->streamPos - p->pos) + p->keepSizeBefore); |
p->buffer = p->bufferBase + p->keepSizeBefore; |
} |
@@ -133,15 +139,15 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p) |
void MatchFinder_Construct(CMatchFinder *p) |
{ |
UInt32 i; |
- p->bufferBase = 0; |
+ p->bufferBase = NULL; |
p->directInput = 0; |
- p->hash = 0; |
+ p->hash = NULL; |
MatchFinder_SetDefaultSettings(p); |
for (i = 0; i < 256; i++) |
{ |
UInt32 r = i; |
- int j; |
+ unsigned j; |
for (j = 0; j < 8; j++) |
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); |
p->crc[i] = r; |
@@ -151,7 +157,7 @@ void MatchFinder_Construct(CMatchFinder *p) |
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) |
{ |
alloc->Free(alloc, p->hash); |
- p->hash = 0; |
+ p->hash = NULL; |
} |
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) |
@@ -160,11 +166,11 @@ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) |
LzInWindow_Free(p, alloc); |
} |
-static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) |
+static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc) |
{ |
size_t sizeInBytes = (size_t)num * sizeof(CLzRef); |
if (sizeInBytes / sizeof(CLzRef) != num) |
- return 0; |
+ return NULL; |
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); |
} |
@@ -173,19 +179,24 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, |
ISzAlloc *alloc) |
{ |
UInt32 sizeReserv; |
+ |
if (historySize > kMaxHistorySize) |
{ |
MatchFinder_Free(p, alloc); |
return 0; |
} |
+ |
sizeReserv = historySize >> 1; |
- if (historySize > ((UInt32)2 << 30)) |
- sizeReserv = historySize >> 2; |
+ if (historySize >= ((UInt32)3 << 30)) sizeReserv = historySize >> 3; |
+ else if (historySize >= ((UInt32)2 << 30)) sizeReserv = historySize >> 2; |
+ |
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); |
p->keepSizeBefore = historySize + keepAddBufferBefore + 1; |
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; |
+ |
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ |
+ |
if (LzInWindow_Create(p, sizeReserv, alloc)) |
{ |
UInt32 newCyclicBufferSize = historySize + 1; |
@@ -210,6 +221,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, |
hs = (1 << 24) - 1; |
else |
hs >>= 1; |
+ /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ |
} |
} |
p->hashMask = hs; |
@@ -221,24 +233,32 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, |
} |
{ |
- UInt32 prevSize = p->hashSizeSum + p->numSons; |
- UInt32 newSize; |
+ size_t newSize; |
+ size_t numSons; |
p->historySize = historySize; |
p->hashSizeSum = hs; |
p->cyclicBufferSize = newCyclicBufferSize; |
- p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); |
- newSize = p->hashSizeSum + p->numSons; |
- if (p->hash != 0 && prevSize == newSize) |
+ |
+ numSons = newCyclicBufferSize; |
+ if (p->btMode) |
+ numSons <<= 1; |
+ newSize = hs + numSons; |
+ |
+ if (p->hash && p->numRefs == newSize) |
return 1; |
+ |
MatchFinder_FreeThisClassMemory(p, alloc); |
+ p->numRefs = newSize; |
p->hash = AllocRefs(newSize, alloc); |
- if (p->hash != 0) |
+ |
+ if (p->hash) |
{ |
p->son = p->hash + p->hashSizeSum; |
return 1; |
} |
} |
} |
+ |
MatchFinder_Free(p, alloc); |
return 0; |
} |
@@ -247,9 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p) |
{ |
UInt32 limit = kMaxValForNormalize - p->pos; |
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; |
+ |
if (limit2 < limit) |
limit = limit2; |
limit2 = p->streamPos - p->pos; |
+ |
if (limit2 <= p->keepSizeAfter) |
{ |
if (limit2 > 0) |
@@ -257,8 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p) |
} |
else |
limit2 -= p->keepSizeAfter; |
+ |
if (limit2 < limit) |
limit = limit2; |
+ |
{ |
UInt32 lenLimit = p->streamPos - p->pos; |
if (lenLimit > p->matchMaxLen) |
@@ -268,28 +292,39 @@ static void MatchFinder_SetLimits(CMatchFinder *p) |
p->posLimit = p->pos + limit; |
} |
-void MatchFinder_Init(CMatchFinder *p) |
+void MatchFinder_Init_2(CMatchFinder *p, int readData) |
{ |
UInt32 i; |
- for (i = 0; i < p->hashSizeSum; i++) |
- p->hash[i] = kEmptyHashValue; |
+ UInt32 *hash = p->hash; |
+ UInt32 num = p->hashSizeSum; |
+ for (i = 0; i < num; i++) |
+ hash[i] = kEmptyHashValue; |
+ |
p->cyclicBufferPos = 0; |
p->buffer = p->bufferBase; |
p->pos = p->streamPos = p->cyclicBufferSize; |
p->result = SZ_OK; |
p->streamEndWasReached = 0; |
- MatchFinder_ReadBlock(p); |
+ |
+ if (readData) |
+ MatchFinder_ReadBlock(p); |
+ |
MatchFinder_SetLimits(p); |
} |
+void MatchFinder_Init(CMatchFinder *p) |
+{ |
+ MatchFinder_Init_2(p, True); |
+} |
+ |
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) |
{ |
return (p->pos - p->historySize - 1) & kNormalizeMask; |
} |
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) |
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) |
{ |
- UInt32 i; |
+ size_t i; |
for (i = 0; i < numItems; i++) |
{ |
UInt32 value = items[i]; |
@@ -304,7 +339,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) |
static void MatchFinder_Normalize(CMatchFinder *p) |
{ |
UInt32 subValue = MatchFinder_GetSubValue(p); |
- MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); |
+ MatchFinder_Normalize3(subValue, p->hash, p->numRefs); |
MatchFinder_ReduceOffsets(p, subValue); |
} |
@@ -465,7 +500,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const |
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } |
#define GET_MATCHES_HEADER2(minLen, ret_op) \ |
- UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ |
+ UInt32 lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \ |
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ |
cur = p->buffer; |
@@ -481,13 +516,20 @@ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } |
#define SKIP_FOOTER \ |
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; |
+#define UPDATE_maxLen { \ |
+ ptrdiff_t diff = (ptrdiff_t)0 - d2; \ |
+ const Byte *c = cur + maxLen; \ |
+ const Byte *lim = cur + lenLimit; \ |
+ for (; c != lim; c++) if (*(c + diff) != *c) break; \ |
+ maxLen = (UInt32)(c - cur); } |
+ |
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
{ |
UInt32 offset; |
GET_MATCHES_HEADER(2) |
HASH2_CALC; |
- curMatch = p->hash[hashValue]; |
- p->hash[hashValue] = p->pos; |
+ curMatch = p->hash[hv]; |
+ p->hash[hv] = p->pos; |
offset = 0; |
GET_MATCHES_FOOTER(offset, 1) |
} |
@@ -497,35 +539,38 @@ UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
UInt32 offset; |
GET_MATCHES_HEADER(3) |
HASH_ZIP_CALC; |
- curMatch = p->hash[hashValue]; |
- p->hash[hashValue] = p->pos; |
+ curMatch = p->hash[hv]; |
+ p->hash[hv] = p->pos; |
offset = 0; |
GET_MATCHES_FOOTER(offset, 2) |
} |
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
{ |
- UInt32 hash2Value, delta2, maxLen, offset; |
+ UInt32 h2, d2, maxLen, offset, pos; |
+ UInt32 *hash; |
GET_MATCHES_HEADER(3) |
HASH3_CALC; |
- delta2 = p->pos - p->hash[hash2Value]; |
- curMatch = p->hash[kFix3HashSize + hashValue]; |
- |
- p->hash[hash2Value] = |
- p->hash[kFix3HashSize + hashValue] = p->pos; |
+ hash = p->hash; |
+ pos = p->pos; |
+ |
+ d2 = pos - hash[h2]; |
+ curMatch = hash[kFix3HashSize + hv]; |
+ |
+ hash[h2] = pos; |
+ hash[kFix3HashSize + hv] = pos; |
maxLen = 2; |
offset = 0; |
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) |
+ |
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) |
{ |
- for (; maxLen != lenLimit; maxLen++) |
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) |
- break; |
+ UPDATE_maxLen |
distances[0] = maxLen; |
- distances[1] = delta2 - 1; |
+ distances[1] = d2 - 1; |
offset = 2; |
if (maxLen == lenLimit) |
{ |
@@ -533,44 +578,51 @@ static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
MOVE_POS_RET; |
} |
} |
+ |
GET_MATCHES_FOOTER(offset, maxLen) |
} |
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
{ |
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; |
+ UInt32 h2, h3, d2, d3, maxLen, offset, pos; |
+ UInt32 *hash; |
GET_MATCHES_HEADER(4) |
HASH4_CALC; |
- delta2 = p->pos - p->hash[ hash2Value]; |
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; |
- curMatch = p->hash[kFix4HashSize + hashValue]; |
- |
- p->hash[ hash2Value] = |
- p->hash[kFix3HashSize + hash3Value] = |
- p->hash[kFix4HashSize + hashValue] = p->pos; |
+ hash = p->hash; |
+ pos = p->pos; |
+ |
+ d2 = pos - hash[ h2]; |
+ d3 = pos - hash[kFix3HashSize + h3]; |
+ |
+ curMatch = hash[kFix4HashSize + hv]; |
+ |
+ hash[ h2] = pos; |
+ hash[kFix3HashSize + h3] = pos; |
+ hash[kFix4HashSize + hv] = pos; |
- maxLen = 1; |
+ maxLen = 0; |
offset = 0; |
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) |
+ |
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) |
{ |
distances[0] = maxLen = 2; |
- distances[1] = delta2 - 1; |
+ distances[1] = d2 - 1; |
offset = 2; |
} |
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) |
+ |
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) |
{ |
maxLen = 3; |
- distances[offset + 1] = delta3 - 1; |
+ distances[offset + 1] = d3 - 1; |
offset += 2; |
- delta2 = delta3; |
+ d2 = d3; |
} |
+ |
if (offset != 0) |
{ |
- for (; maxLen != lenLimit; maxLen++) |
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) |
- break; |
+ UPDATE_maxLen |
distances[offset - 2] = maxLen; |
if (maxLen == lenLimit) |
{ |
@@ -578,46 +630,131 @@ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
MOVE_POS_RET; |
} |
} |
+ |
if (maxLen < 3) |
maxLen = 3; |
+ |
GET_MATCHES_FOOTER(offset, maxLen) |
} |
+/* |
+static UInt32 Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
+{ |
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos; |
+ UInt32 *hash; |
+ GET_MATCHES_HEADER(5) |
+ |
+ HASH5_CALC; |
+ |
+ hash = p->hash; |
+ pos = p->pos; |
+ |
+ d2 = pos - hash[ h2]; |
+ d3 = pos - hash[kFix3HashSize + h3]; |
+ d4 = pos - hash[kFix4HashSize + h4]; |
+ |
+ curMatch = hash[kFix5HashSize + hv]; |
+ |
+ hash[ h2] = pos; |
+ hash[kFix3HashSize + h3] = pos; |
+ hash[kFix4HashSize + h4] = pos; |
+ hash[kFix5HashSize + hv] = pos; |
+ |
+ maxLen = 0; |
+ offset = 0; |
+ |
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) |
+ { |
+ distances[0] = maxLen = 2; |
+ distances[1] = d2 - 1; |
+ offset = 2; |
+ if (*(cur - d2 + 2) == cur[2]) |
+ distances[0] = maxLen = 3; |
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) |
+ { |
+ distances[2] = maxLen = 3; |
+ distances[3] = d3 - 1; |
+ offset = 4; |
+ d2 = d3; |
+ } |
+ } |
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) |
+ { |
+ distances[0] = maxLen = 3; |
+ distances[1] = d3 - 1; |
+ offset = 2; |
+ d2 = d3; |
+ } |
+ |
+ if (d2 != d4 && d4 < p->cyclicBufferSize |
+ && *(cur - d4) == *cur |
+ && *(cur - d4 + 3) == *(cur + 3)) |
+ { |
+ maxLen = 4; |
+ distances[offset + 1] = d4 - 1; |
+ offset += 2; |
+ d2 = d4; |
+ } |
+ |
+ if (offset != 0) |
+ { |
+ UPDATE_maxLen |
+ distances[offset - 2] = maxLen; |
+ if (maxLen == lenLimit) |
+ { |
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); |
+ MOVE_POS_RET; |
+ } |
+ } |
+ |
+ if (maxLen < 4) |
+ maxLen = 4; |
+ |
+ GET_MATCHES_FOOTER(offset, maxLen) |
+} |
+*/ |
+ |
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
{ |
- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; |
+ UInt32 h2, h3, d2, d3, maxLen, offset, pos; |
+ UInt32 *hash; |
GET_MATCHES_HEADER(4) |
HASH4_CALC; |
- delta2 = p->pos - p->hash[ hash2Value]; |
- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; |
- curMatch = p->hash[kFix4HashSize + hashValue]; |
+ hash = p->hash; |
+ pos = p->pos; |
+ |
+ d2 = pos - hash[ h2]; |
+ d3 = pos - hash[kFix3HashSize + h3]; |
+ |
+ curMatch = hash[kFix4HashSize + hv]; |
- p->hash[ hash2Value] = |
- p->hash[kFix3HashSize + hash3Value] = |
- p->hash[kFix4HashSize + hashValue] = p->pos; |
+ hash[ h2] = pos; |
+ hash[kFix3HashSize + h3] = pos; |
+ hash[kFix4HashSize + hv] = pos; |
- maxLen = 1; |
+ maxLen = 0; |
offset = 0; |
- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) |
+ |
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) |
{ |
distances[0] = maxLen = 2; |
- distances[1] = delta2 - 1; |
+ distances[1] = d2 - 1; |
offset = 2; |
} |
- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) |
+ |
+ if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) |
{ |
maxLen = 3; |
- distances[offset + 1] = delta3 - 1; |
+ distances[offset + 1] = d3 - 1; |
offset += 2; |
- delta2 = delta3; |
+ d2 = d3; |
} |
+ |
if (offset != 0) |
{ |
- for (; maxLen != lenLimit; maxLen++) |
- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) |
- break; |
+ UPDATE_maxLen |
distances[offset - 2] = maxLen; |
if (maxLen == lenLimit) |
{ |
@@ -625,22 +762,103 @@ static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
MOVE_POS_RET; |
} |
} |
+ |
if (maxLen < 3) |
maxLen = 3; |
+ |
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), |
- distances + offset, maxLen) - (distances)); |
+ distances + offset, maxLen) - (distances)); |
MOVE_POS_RET |
} |
+/* |
+static UInt32 Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
+{ |
+ UInt32 h2, h3, h4, d2, d3, d4, maxLen, offset, pos |
+ UInt32 *hash; |
+ GET_MATCHES_HEADER(5) |
+ |
+ HASH5_CALC; |
+ |
+ hash = p->hash; |
+ pos = p->pos; |
+ |
+ d2 = pos - hash[ h2]; |
+ d3 = pos - hash[kFix3HashSize + h3]; |
+ d4 = pos - hash[kFix4HashSize + h4]; |
+ |
+ curMatch = hash[kFix5HashSize + hv]; |
+ |
+ hash[ h2] = pos; |
+ hash[kFix3HashSize + h3] = pos; |
+ hash[kFix4HashSize + h4] = pos; |
+ hash[kFix5HashSize + hv] = pos; |
+ |
+ maxLen = 0; |
+ offset = 0; |
+ |
+ if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) |
+ { |
+ distances[0] = maxLen = 2; |
+ distances[1] = d2 - 1; |
+ offset = 2; |
+ if (*(cur - d2 + 2) == cur[2]) |
+ distances[0] = maxLen = 3; |
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) |
+ { |
+ distances[2] = maxLen = 3; |
+ distances[3] = d3 - 1; |
+ offset = 4; |
+ d2 = d3; |
+ } |
+ } |
+ else if (d3 < p->cyclicBufferSize && *(cur - d3) == *cur) |
+ { |
+ distances[0] = maxLen = 3; |
+ distances[1] = d3 - 1; |
+ offset = 2; |
+ d2 = d3; |
+ } |
+ |
+ if (d2 != d4 && d4 < p->cyclicBufferSize |
+ && *(cur - d4) == *cur |
+ && *(cur - d4 + 3) == *(cur + 3)) |
+ { |
+ maxLen = 4; |
+ distances[offset + 1] = d4 - 1; |
+ offset += 2; |
+ d2 = d4; |
+ } |
+ |
+ if (offset != 0) |
+ { |
+ UPDATE_maxLen |
+ distances[offset - 2] = maxLen; |
+ if (maxLen == lenLimit) |
+ { |
+ p->son[p->cyclicBufferPos] = curMatch; |
+ MOVE_POS_RET; |
+ } |
+ } |
+ |
+ if (maxLen < 4) |
+ maxLen = 4; |
+ |
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), |
+ distances + offset, maxLen) - (distances)); |
+ MOVE_POS_RET |
+} |
+*/ |
+ |
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) |
{ |
UInt32 offset; |
GET_MATCHES_HEADER(3) |
HASH_ZIP_CALC; |
- curMatch = p->hash[hashValue]; |
- p->hash[hashValue] = p->pos; |
+ curMatch = p->hash[hv]; |
+ p->hash[hv] = p->pos; |
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), |
- distances, 2) - (distances)); |
+ distances, 2) - (distances)); |
MOVE_POS_RET |
} |
@@ -650,8 +868,8 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
{ |
SKIP_HEADER(2) |
HASH2_CALC; |
- curMatch = p->hash[hashValue]; |
- p->hash[hashValue] = p->pos; |
+ curMatch = p->hash[hv]; |
+ p->hash[hv] = p->pos; |
SKIP_FOOTER |
} |
while (--num != 0); |
@@ -663,8 +881,8 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
{ |
SKIP_HEADER(3) |
HASH_ZIP_CALC; |
- curMatch = p->hash[hashValue]; |
- p->hash[hashValue] = p->pos; |
+ curMatch = p->hash[hv]; |
+ p->hash[hv] = p->pos; |
SKIP_FOOTER |
} |
while (--num != 0); |
@@ -674,12 +892,14 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
{ |
do |
{ |
- UInt32 hash2Value; |
+ UInt32 h2; |
+ UInt32 *hash; |
SKIP_HEADER(3) |
HASH3_CALC; |
- curMatch = p->hash[kFix3HashSize + hashValue]; |
- p->hash[hash2Value] = |
- p->hash[kFix3HashSize + hashValue] = p->pos; |
+ hash = p->hash; |
+ curMatch = hash[kFix3HashSize + hv]; |
+ hash[h2] = |
+ hash[kFix3HashSize + hv] = p->pos; |
SKIP_FOOTER |
} |
while (--num != 0); |
@@ -689,43 +909,90 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
{ |
do |
{ |
- UInt32 hash2Value, hash3Value; |
+ UInt32 h2, h3; |
+ UInt32 *hash; |
SKIP_HEADER(4) |
HASH4_CALC; |
- curMatch = p->hash[kFix4HashSize + hashValue]; |
- p->hash[ hash2Value] = |
- p->hash[kFix3HashSize + hash3Value] = p->pos; |
- p->hash[kFix4HashSize + hashValue] = p->pos; |
+ hash = p->hash; |
+ curMatch = hash[kFix4HashSize + hv]; |
+ hash[ h2] = |
+ hash[kFix3HashSize + h3] = |
+ hash[kFix4HashSize + hv] = p->pos; |
+ SKIP_FOOTER |
+ } |
+ while (--num != 0); |
+} |
+ |
+/* |
+static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
+{ |
+ do |
+ { |
+ UInt32 h2, h3, h4; |
+ UInt32 *hash; |
+ SKIP_HEADER(5) |
+ HASH5_CALC; |
+ hash = p->hash; |
+ curMatch = hash[kFix5HashSize + hv]; |
+ hash[ h2] = |
+ hash[kFix3HashSize + h3] = |
+ hash[kFix4HashSize + h4] = |
+ hash[kFix5HashSize + hv] = p->pos; |
SKIP_FOOTER |
} |
while (--num != 0); |
} |
+*/ |
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
{ |
do |
{ |
- UInt32 hash2Value, hash3Value; |
+ UInt32 h2, h3; |
+ UInt32 *hash; |
SKIP_HEADER(4) |
HASH4_CALC; |
- curMatch = p->hash[kFix4HashSize + hashValue]; |
- p->hash[ hash2Value] = |
- p->hash[kFix3HashSize + hash3Value] = |
- p->hash[kFix4HashSize + hashValue] = p->pos; |
+ hash = p->hash; |
+ curMatch = hash[kFix4HashSize + hv]; |
+ hash[ h2] = |
+ hash[kFix3HashSize + h3] = |
+ hash[kFix4HashSize + hv] = p->pos; |
p->son[p->cyclicBufferPos] = curMatch; |
MOVE_POS |
} |
while (--num != 0); |
} |
+/* |
+static void Hc5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
+{ |
+ do |
+ { |
+ UInt32 h2, h3, h4; |
+ UInt32 *hash; |
+ SKIP_HEADER(5) |
+ HASH5_CALC; |
+ hash = p->hash; |
+ curMatch = p->hash[kFix5HashSize + hv]; |
+ hash[ h2] = |
+ hash[kFix3HashSize + h3] = |
+ hash[kFix4HashSize + h4] = |
+ hash[kFix5HashSize + hv] = p->pos; |
+ p->son[p->cyclicBufferPos] = curMatch; |
+ MOVE_POS |
+ } |
+ while (--num != 0); |
+} |
+*/ |
+ |
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
{ |
do |
{ |
SKIP_HEADER(3) |
HASH_ZIP_CALC; |
- curMatch = p->hash[hashValue]; |
- p->hash[hashValue] = p->pos; |
+ curMatch = p->hash[hv]; |
+ p->hash[hv] = p->pos; |
p->son[p->cyclicBufferPos] = curMatch; |
MOVE_POS |
} |
@@ -735,13 +1002,22 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) |
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) |
{ |
vTable->Init = (Mf_Init_Func)MatchFinder_Init; |
- vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; |
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; |
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; |
if (!p->btMode) |
{ |
- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; |
- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; |
+ /* if (p->numHashBytes <= 4) */ |
+ { |
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; |
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; |
+ } |
+ /* |
+ else |
+ { |
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc5_MatchFinder_GetMatches; |
+ vTable->Skip = (Mf_Skip_Func)Hc5_MatchFinder_Skip; |
+ } |
+ */ |
} |
else if (p->numHashBytes == 2) |
{ |
@@ -753,9 +1029,16 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) |
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; |
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; |
} |
- else |
+ else /* if (p->numHashBytes == 4) */ |
{ |
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; |
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; |
} |
+ /* |
+ else |
+ { |
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt5_MatchFinder_GetMatches; |
+ vTable->Skip = (Mf_Skip_Func)Bt5_MatchFinder_Skip; |
+ } |
+ */ |
} |