diff --git a/Compression/LZMA2/C/LzFind.c b/Compression/LZMA2/C/LzFind.c index 2b29e7b..4e41a18 100644 --- a/Compression/LZMA2/C/LzFind.c +++ b/Compression/LZMA2/C/LzFind.c @@ -199,40 +199,56 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 hashSize, 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)) - { - p->matchMaxLen = matchMaxLen; - hashSize /= sizeof(CLzRef); // convert bytes to hashtable entries - p->hashMask = p->btMode==MF_HashTable? hashSize/p->cutValue-1 // every hash slot contains cutValue entries with the same hash value - : hashSize-1; - p->fixedHashSize = 0; - if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; - if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; - if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; - + p->matchMaxLen = matchMaxLen; + hashSize /= sizeof(CLzRef); // convert bytes to hashtable entries + p->hashMask = p->btMode==MF_HashTable? hashSize/p->cutValue-1 // every hash slot contains cutValue entries with the same hash value + : hashSize-1; + p->fixedHashSize = 0; + if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; + if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; + if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; + + { + UInt32 prevHashSizeSum = p->hashSizeSum; + UInt32 prevNumSons = p->numSons; + p->historySize = historySize; + p->hashSizeSum = hashSize + p->fixedHashSize; + p->cyclicBufferSize = historySize + 1; + p->numSons = p->btMode==MF_BinaryTree ? p->cyclicBufferSize * 2 + : p->btMode==MF_HashChain ? p->cyclicBufferSize + : 0; + if (p->hash != 0 && prevHashSizeSum == p->hashSizeSum && + (p->son != 0 || prevNumSons == 0) && prevNumSons == p->numSons) { - UInt32 prevHashSizeSum = p->hashSizeSum; - UInt32 prevNumSons = p->numSons; - p->historySize = historySize; - p->hashSizeSum = hashSize + p->fixedHashSize; - p->cyclicBufferSize = historySize + 1; - p->numSons = p->btMode==MF_BinaryTree ? p->cyclicBufferSize * 2 - : p->btMode==MF_HashChain ? p->cyclicBufferSize - : 0; - if (p->hash != 0 && prevHashSizeSum == p->hashSizeSum && - (p->son != 0 || prevNumSons == 0) && prevNumSons == p->numSons) - { + if (LzInWindow_Create(p, sizeReserv, alloc)) return 1; - } + } + else + { MatchFinder_FreeThisClassMemory(p, alloc); - p->hash = AllocRefs(p->hashSizeSum, alloc); - p->son = p->numSons? AllocRefs(p->numSons, alloc) : 0; - if (p->hash != 0 && (p->numSons==0 || p->son!=0)) + + // Allocate larger block first (either dictionary or hash+son) + if (historySize + sizeReserv > (p->hashSizeSum + p->numSons) * sizeof(CLzRef)) { - return 1; + if (LzInWindow_Create(p, sizeReserv, alloc)) + { + p->hash = AllocRefs(p->hashSizeSum, alloc); + p->son = p->numSons? AllocRefs(p->numSons, alloc) : 0; + if (p->hash != 0 && (p->numSons==0 || p->son!=0)) + return 1; + } + } + else + { + p->son = p->numSons? AllocRefs(p->numSons, alloc) : 0; + p->hash = AllocRefs(p->hashSizeSum, alloc); + if (p->hash != 0 && (p->numSons==0 || p->son!=0)) + if (LzInWindow_Create(p, sizeReserv, alloc)) + return 1; } } } + MatchFinder_Free(p, alloc); return 0; } diff --git a/Compression/LZMA2/readme b/Compression/LZMA2/readme index d71cba0..9a860d0 100644 --- a/Compression/LZMA2/readme +++ b/Compression/LZMA2/readme @@ -5,8 +5,8 @@ +4. Буфер рангкодера уменьшен с 1 мб до 64 кб: RC_BUF_SIZE +5. При распаковке запись производится каждые 256 кб (LARGE_BUFFER_SIZE) +6. размер хеша и выделение памяти (CalcHashSize, ReservedAreaSize) -6. разбить на 3 части (hash,son) и сначала выделять меньший блок; MatchFinder_Normalize3 -6. kMtMaxValForNormalize=(1<<30)-1, так как большие значения используются в ht4 mf ++6. разбить на 3 части (hash,son) и сначала выделять меньший блок; MatchFinder_Normalize3 ++6. kMtMaxValForNormalize=(1<<30)-1, так как большие значения используются в ht4 mf +7. kDicLogSizeMaxCompress = 31; MF_HashTable; hashSize; LzmaEncProps_Normalize 8. compress_all_at_once +9. maxDist[] = {0, 0, 128, 2048, 64<<10, 2<<20, 12<<20} (оптимизация lazy matching)