/* LzFind.c -- Match finder for LZ algorithms\r
-2015-10-15 : Igor Pavlov : Public domain */\r
+2017-06-10 : Igor Pavlov : Public domain */\r
\r
#include "Precomp.h"\r
\r
\r
#define kStartMaxLen 3\r
\r
-static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)\r
+static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc)\r
{\r
if (!p->directInput)\r
{\r
- alloc->Free(alloc, p->bufferBase);\r
+ ISzAlloc_Free(alloc, p->bufferBase);\r
p->bufferBase = NULL;\r
}\r
}\r
\r
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */\r
\r
-static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)\r
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAllocPtr alloc)\r
{\r
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;\r
if (p->directInput)\r
{\r
LzInWindow_Free(p, alloc);\r
p->blockSize = blockSize;\r
- p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);\r
+ p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, (size_t)blockSize);\r
}\r
return (p->bufferBase != NULL);\r
}\r
if (size == 0)\r
return;\r
\r
- p->result = p->stream->Read(p->stream, dest, &size);\r
+ p->result = ISeqInStream_Read(p->stream, dest, &size);\r
if (p->result != SZ_OK)\r
return;\r
if (size == 0)\r
p->bufferBase = NULL;\r
p->directInput = 0;\r
p->hash = NULL;\r
+ p->expectedDataSize = (UInt64)(Int64)-1;\r
MatchFinder_SetDefaultSettings(p);\r
\r
for (i = 0; i < 256; i++)\r
UInt32 r = i;\r
unsigned j;\r
for (j = 0; j < 8; j++)\r
- r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));\r
+ r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));\r
p->crc[i] = r;\r
}\r
}\r
\r
-static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)\r
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc)\r
{\r
- alloc->Free(alloc, p->hash);\r
+ ISzAlloc_Free(alloc, p->hash);\r
p->hash = NULL;\r
}\r
\r
-void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)\r
+void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc)\r
{\r
MatchFinder_FreeThisClassMemory(p, alloc);\r
LzInWindow_Free(p, alloc);\r
}\r
\r
-static CLzRef* AllocRefs(size_t num, ISzAlloc *alloc)\r
+static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc)\r
{\r
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);\r
if (sizeInBytes / sizeof(CLzRef) != num)\r
return NULL;\r
- return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);\r
+ return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes);\r
}\r
\r
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,\r
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,\r
- ISzAlloc *alloc)\r
+ ISzAllocPtr alloc)\r
{\r
UInt32 sizeReserv;\r
\r
hs = (1 << 16) - 1;\r
else\r
{\r
- hs = historySize - 1;\r
+ hs = historySize;\r
+ if (hs > p->expectedDataSize)\r
+ hs = (UInt32)p->expectedDataSize;\r
+ if (hs != 0)\r
+ hs--;\r
hs |= (hs >> 1);\r
hs |= (hs >> 2);\r
hs |= (hs >> 4);\r
p->posLimit = p->pos + limit;\r
}\r
\r
-void MatchFinder_Init_2(CMatchFinder *p, int readData)\r
+\r
+void MatchFinder_Init_LowHash(CMatchFinder *p)\r
+{\r
+ size_t i;\r
+ CLzRef *items = p->hash;\r
+ size_t numItems = p->fixedHashSize;\r
+ for (i = 0; i < numItems; i++)\r
+ items[i] = kEmptyHashValue;\r
+}\r
+\r
+\r
+void MatchFinder_Init_HighHash(CMatchFinder *p)\r
+{\r
+ size_t i;\r
+ CLzRef *items = p->hash + p->fixedHashSize;\r
+ size_t numItems = (size_t)p->hashMask + 1;\r
+ for (i = 0; i < numItems; i++)\r
+ items[i] = kEmptyHashValue;\r
+}\r
+\r
+\r
+void MatchFinder_Init_3(CMatchFinder *p, int readData)\r
{\r
- UInt32 i;\r
- UInt32 *hash = p->hash;\r
- UInt32 num = p->hashSizeSum;\r
- for (i = 0; i < num; i++)\r
- hash[i] = kEmptyHashValue;\r
- \r
p->cyclicBufferPos = 0;\r
p->buffer = p->bufferBase;\r
- p->pos = p->streamPos = p->cyclicBufferSize;\r
+ p->pos =\r
+ p->streamPos = p->cyclicBufferSize;\r
p->result = SZ_OK;\r
p->streamEndWasReached = 0;\r
\r
MatchFinder_SetLimits(p);\r
}\r
\r
+\r
void MatchFinder_Init(CMatchFinder *p)\r
{\r
- MatchFinder_Init_2(p, True);\r
+ MatchFinder_Init_HighHash(p);\r
+ MatchFinder_Init_LowHash(p);\r
+ MatchFinder_Init_3(p, True);\r
}\r
+\r
\r
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)\r
{\r
\r
d2 = pos - hash[h2];\r
\r
- curMatch = hash[kFix3HashSize + hv];\r
+ curMatch = (hash + kFix3HashSize)[hv];\r
\r
hash[h2] = pos;\r
- hash[kFix3HashSize + hv] = pos;\r
+ (hash + kFix3HashSize)[hv] = pos;\r
\r
maxLen = 2;\r
offset = 0;\r
pos = p->pos;\r
\r
d2 = pos - hash[ h2];\r
- d3 = pos - hash[kFix3HashSize + h3];\r
+ d3 = pos - (hash + kFix3HashSize)[h3];\r
\r
- curMatch = hash[kFix4HashSize + hv];\r
+ curMatch = (hash + kFix4HashSize)[hv];\r
\r
hash[ h2] = pos;\r
- hash[kFix3HashSize + h3] = pos;\r
- hash[kFix4HashSize + hv] = pos;\r
+ (hash + kFix3HashSize)[h3] = pos;\r
+ (hash + kFix4HashSize)[hv] = pos;\r
\r
maxLen = 0;\r
offset = 0;\r
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)\r
{\r
maxLen = 3;\r
- distances[offset + 1] = d3 - 1;\r
+ distances[(size_t)offset + 1] = d3 - 1;\r
offset += 2;\r
d2 = d3;\r
}\r
if (offset != 0)\r
{\r
UPDATE_maxLen\r
- distances[offset - 2] = maxLen;\r
+ distances[(size_t)offset - 2] = maxLen;\r
if (maxLen == lenLimit)\r
{\r
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));\r
pos = p->pos;\r
\r
d2 = pos - hash[ h2];\r
- d3 = pos - hash[kFix3HashSize + h3];\r
- d4 = pos - hash[kFix4HashSize + h4];\r
+ d3 = pos - (hash + kFix3HashSize)[h3];\r
+ d4 = pos - (hash + kFix4HashSize)[h4];\r
\r
- curMatch = hash[kFix5HashSize + hv];\r
+ curMatch = (hash + kFix5HashSize)[hv];\r
\r
hash[ h2] = pos;\r
- hash[kFix3HashSize + h3] = pos;\r
- hash[kFix4HashSize + h4] = pos;\r
- hash[kFix5HashSize + hv] = pos;\r
+ (hash + kFix3HashSize)[h3] = pos;\r
+ (hash + kFix4HashSize)[h4] = pos;\r
+ (hash + kFix5HashSize)[hv] = pos;\r
\r
maxLen = 0;\r
offset = 0;\r
&& *(cur - d4 + 3) == *(cur + 3))\r
{\r
maxLen = 4;\r
- distances[offset + 1] = d4 - 1;\r
+ distances[(size_t)offset + 1] = d4 - 1;\r
offset += 2;\r
d2 = d4;\r
}\r
if (offset != 0)\r
{\r
UPDATE_maxLen\r
- distances[offset - 2] = maxLen;\r
+ distances[(size_t)offset - 2] = maxLen;\r
if (maxLen == lenLimit)\r
{\r
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));\r
pos = p->pos;\r
\r
d2 = pos - hash[ h2];\r
- d3 = pos - hash[kFix3HashSize + h3];\r
+ d3 = pos - (hash + kFix3HashSize)[h3];\r
\r
- curMatch = hash[kFix4HashSize + hv];\r
+ curMatch = (hash + kFix4HashSize)[hv];\r
\r
hash[ h2] = pos;\r
- hash[kFix3HashSize + h3] = pos;\r
- hash[kFix4HashSize + hv] = pos;\r
+ (hash + kFix3HashSize)[h3] = pos;\r
+ (hash + kFix4HashSize)[hv] = pos;\r
\r
maxLen = 0;\r
offset = 0;\r
if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur)\r
{\r
maxLen = 3;\r
- distances[offset + 1] = d3 - 1;\r
+ distances[(size_t)offset + 1] = d3 - 1;\r
offset += 2;\r
d2 = d3;\r
}\r
if (offset != 0)\r
{\r
UPDATE_maxLen\r
- distances[offset - 2] = maxLen;\r
+ distances[(size_t)offset - 2] = maxLen;\r
if (maxLen == lenLimit)\r
{\r
p->son[p->cyclicBufferPos] = curMatch;\r
pos = p->pos;\r
\r
d2 = pos - hash[ h2];\r
- d3 = pos - hash[kFix3HashSize + h3];\r
- d4 = pos - hash[kFix4HashSize + h4];\r
+ d3 = pos - (hash + kFix3HashSize)[h3];\r
+ d4 = pos - (hash + kFix4HashSize)[h4];\r
\r
- curMatch = hash[kFix5HashSize + hv];\r
+ curMatch = (hash + kFix5HashSize)[hv];\r
\r
hash[ h2] = pos;\r
- hash[kFix3HashSize + h3] = pos;\r
- hash[kFix4HashSize + h4] = pos;\r
- hash[kFix5HashSize + hv] = pos;\r
+ (hash + kFix3HashSize)[h3] = pos;\r
+ (hash + kFix4HashSize)[h4] = pos;\r
+ (hash + kFix5HashSize)[hv] = pos;\r
\r
maxLen = 0;\r
offset = 0;\r
&& *(cur - d4 + 3) == *(cur + 3))\r
{\r
maxLen = 4;\r
- distances[offset + 1] = d4 - 1;\r
+ distances[(size_t)offset + 1] = d4 - 1;\r
offset += 2;\r
d2 = d4;\r
}\r
if (offset != 0)\r
{\r
UPDATE_maxLen\r
- distances[offset - 2] = maxLen;\r
+ distances[(size_t)offset - 2] = maxLen;\r
if (maxLen == lenLimit)\r
{\r
p->son[p->cyclicBufferPos] = curMatch;\r
SKIP_HEADER(3)\r
HASH3_CALC;\r
hash = p->hash;\r
- curMatch = hash[kFix3HashSize + hv];\r
+ curMatch = (hash + kFix3HashSize)[hv];\r
hash[h2] =\r
- hash[kFix3HashSize + hv] = p->pos;\r
+ (hash + kFix3HashSize)[hv] = p->pos;\r
SKIP_FOOTER\r
}\r
while (--num != 0);\r
SKIP_HEADER(4)\r
HASH4_CALC;\r
hash = p->hash;\r
- curMatch = hash[kFix4HashSize + hv];\r
+ curMatch = (hash + kFix4HashSize)[hv];\r
hash[ h2] =\r
- hash[kFix3HashSize + h3] =\r
- hash[kFix4HashSize + hv] = p->pos;\r
+ (hash + kFix3HashSize)[h3] =\r
+ (hash + kFix4HashSize)[hv] = p->pos;\r
SKIP_FOOTER\r
}\r
while (--num != 0);\r
SKIP_HEADER(5)\r
HASH5_CALC;\r
hash = p->hash;\r
- curMatch = hash[kFix5HashSize + hv];\r
+ curMatch = (hash + kFix5HashSize)[hv];\r
hash[ h2] =\r
- hash[kFix3HashSize + h3] =\r
- hash[kFix4HashSize + h4] =\r
- hash[kFix5HashSize + hv] = p->pos;\r
+ (hash + kFix3HashSize)[h3] =\r
+ (hash + kFix4HashSize)[h4] =\r
+ (hash + kFix5HashSize)[hv] = p->pos;\r
SKIP_FOOTER\r
}\r
while (--num != 0);\r
SKIP_HEADER(4)\r
HASH4_CALC;\r
hash = p->hash;\r
- curMatch = hash[kFix4HashSize + hv];\r
+ curMatch = (hash + kFix4HashSize)[hv];\r
hash[ h2] =\r
- hash[kFix3HashSize + h3] =\r
- hash[kFix4HashSize + hv] = p->pos;\r
+ (hash + kFix3HashSize)[h3] =\r
+ (hash + kFix4HashSize)[hv] = p->pos;\r
p->son[p->cyclicBufferPos] = curMatch;\r
MOVE_POS\r
}\r
SKIP_HEADER(5)\r
HASH5_CALC;\r
hash = p->hash;\r
- curMatch = p->hash[kFix5HashSize + hv];\r
+ curMatch = hash + kFix5HashSize)[hv];\r
hash[ h2] =\r
- hash[kFix3HashSize + h3] =\r
- hash[kFix4HashSize + h4] =\r
- hash[kFix5HashSize + hv] = p->pos;\r
+ (hash + kFix3HashSize)[h3] =\r
+ (hash + kFix4HashSize)[h4] =\r
+ (hash + kFix5HashSize)[hv] = p->pos;\r
p->son[p->cyclicBufferPos] = curMatch;\r
MOVE_POS\r
}\r