summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortest4973 <Kdo4973@hotmail.com>2018-04-05 19:40:33 (GMT)
committertest4973 <Kdo4973@hotmail.com>2018-04-05 19:40:33 (GMT)
commit6d931b6a93100fe2cb4dafc032ff486c814d1fed (patch)
treecd734c9a0d2b2b7d807ea2339de6f9e25b4ae35f /lib
parent43132af808119e71fdeb153f6e7ad53673c8f9e4 (diff)
downloadlz4-6d931b6a93100fe2cb4dafc032ff486c814d1fed.zip
lz4-6d931b6a93100fe2cb4dafc032ff486c814d1fed.tar.gz
lz4-6d931b6a93100fe2cb4dafc032ff486c814d1fed.tar.bz2
fixed lz4 compression starting at small address
when using byU32 and byU16 modes
Diffstat (limited to 'lib')
-rw-r--r--lib/lz4.c70
1 files changed, 67 insertions, 3 deletions
diff --git a/lib/lz4.c b/lib/lz4.c
index 0fdbe5e..bcebc92 100644
--- a/lib/lz4.c
+++ b/lib/lz4.c
@@ -533,6 +533,20 @@ LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_
LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
}
+/* LZ4_getIndexOnHash() :
+ * Index of match position registered in hash table.
+ * hash position must be calculated by using base+index, or dictBase+index.
+ * Assumption 1 : only valid if tableType == byU32 or byU16.
+ * Assumption 2 : h is presumed valid (within limits of hash table)
+ */
+static U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType)
+{
+ LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2);
+ if (tableType == byU32) { const U32* const hashTable = (const U32*) tableBase; assert(h < (1U << (LZ4_MEMORY_USAGE-2))); return hashTable[h]; }
+ if (tableType == byU16) { const U16* const hashTable = (const U16*) tableBase; assert(h < (1U << (LZ4_MEMORY_USAGE-1))); return hashTable[h]; }
+ assert(0); return 0; /* forbidden case */
+}
+
static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType_t tableType, const BYTE* srcBase)
{
if (tableType == byPtr) { const BYTE* const* hashTable = (const BYTE* const*) tableBase; return hashTable[h]; }
@@ -598,7 +612,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
{
const BYTE* ip = (const BYTE*) source;
- size_t currentOffset = cctx->currentOffset;
+ size_t const currentOffset = cctx->currentOffset;
const BYTE* base = (const BYTE*) source - currentOffset;
const BYTE* lowLimit;
@@ -650,7 +664,8 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
BYTE* token;
/* Find a match */
- { const BYTE* forwardIp = ip;
+ if (tableType == byPtr) {
+ const BYTE* forwardIp = ip;
unsigned step = 1;
unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
do {
@@ -687,6 +702,54 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
} while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
|| ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
|| (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
+
+ } else { /* byU32, byU16 */
+
+ const BYTE* forwardIp = ip;
+ unsigned step = 1;
+ unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
+ do {
+ U32 const h = forwardH;
+ U32 const matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType);
+ ip = forwardIp;
+ forwardIp += step;
+ step = (searchMatchNb++ >> LZ4_skipTrigger);
+
+ if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals;
+ assert(ip < mflimitPlusOne);
+
+ if (dictDirective == usingDictCtx) {
+ if (matchIndex < currentOffset) {
+ /* there was no match, try the dictionary */
+ match = LZ4_getPosition(ip, dictCtx->hashTable, byU32, dictBase);
+ refDelta = dictDelta;
+ lowLimit = dictLowLimit;
+ } else {
+ match = base + matchIndex;
+ refDelta = 0;
+ lowLimit = (const BYTE*)source;
+ }
+ } else if (dictDirective==usingExtDict) {
+ if (matchIndex < currentOffset) {
+ match = dictBase + matchIndex;
+ refDelta = dictDelta;
+ lowLimit = dictLowLimit;
+ } else {
+ match = base + matchIndex;
+ refDelta = 0;
+ lowLimit = (const BYTE*)source;
+ }
+ } else { /* single continuous memory segment */
+ match = base + matchIndex;
+ refDelta = 0;
+ lowLimit = (const BYTE*)source;
+ }
+ forwardH = LZ4_hashPosition(forwardIp, tableType);
+ LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base);
+
+ } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
+ || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
+ || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
}
/* Catch up */
@@ -718,7 +781,8 @@ _next_match:
/* Encode MatchLength */
{ unsigned matchCode;
- if ((dictDirective==usingExtDict || dictDirective==usingDictCtx) && lowLimit==dictionary) {
+ if ( (dictDirective==usingExtDict || dictDirective==usingDictCtx)
+ && (lowLimit==dictionary) ) {
const BYTE* limit;
match += refDelta;
limit = ip + (dictEnd-match);