summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorYann Collet <cyan@fb.com>2017-11-07 18:53:29 (GMT)
committerYann Collet <cyan@fb.com>2017-11-07 18:53:29 (GMT)
commita004c1fbee4e5a8793f9dfc1deeafea1d59be486 (patch)
treeb1b878a8aefcba68f39d39b3566f8bb7b707bca8 /lib
parentaa99163752079890c8d75461d2b5c1fd7c426c3b (diff)
downloadlz4-a004c1fbee4e5a8793f9dfc1deeafea1d59be486.zip
lz4-a004c1fbee4e5a8793f9dfc1deeafea1d59be486.tar.gz
lz4-a004c1fbee4e5a8793f9dfc1deeafea1d59be486.tar.bz2
fixed LZ4HC_countPattern()
- works with byte values other than `0` - works for any repetitive pattern of length 1, 2 or 4 (but not 3!) - works for little and big endian systems - preserve speed of previous implementation
Diffstat (limited to 'lib')
-rw-r--r--lib/lz4hc.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/lz4hc.c b/lib/lz4hc.c
index 0cda77c..fbcec98 100644
--- a/lib/lz4hc.c
+++ b/lib/lz4hc.c
@@ -130,20 +130,34 @@ static int LZ4HC_countBack(const BYTE* const ip, const BYTE* const match,
return back;
}
-static unsigned LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, reg_t pattern)
+/* LZ4HC_countPattern() :
+ * pattern32 must be a sample of repetitive pattern of length 1, 2 or 4 (but not 3!) */
+static unsigned LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32)
{
const BYTE* const iStart = ip;
+ reg_t const pattern = (sizeof(pattern)==8) ? (reg_t)pattern32 + (((reg_t)pattern32) << 32) : pattern32;
- while (likely(ip<iEnd-(sizeof(pattern)-1))) {
+ while (likely(ip < iEnd-(sizeof(pattern)-1))) {
reg_t const diff = LZ4_read_ARCH(ip) ^ pattern;
if (!diff) { ip+=sizeof(pattern); continue; }
ip += LZ4_NbCommonBytes(diff);
return (unsigned)(ip - iStart);
}
- if ((sizeof(pattern)==8) && (ip<(iEnd-3)) && (LZ4_read32(ip)==(U32)pattern)) { ip+=4; }
- if ((ip<(iEnd-1)) && (LZ4_read16(ip)==(U16)pattern)) { ip+=2; }
- if ((ip<iEnd) && (*ip == (BYTE)pattern)) ip++;
+ if (LZ4_isLittleEndian()) {
+ reg_t patternByte = pattern;
+ while ((ip<iEnd) && (*ip == (BYTE)patternByte)) {
+ ip++; patternByte >>= 8;
+ }
+ } else { /* big endian */
+ U32 bitOffset = (sizeof(pattern)*8) - 8;
+ while (ip < iEnd) {
+ BYTE const byte = (BYTE)(pattern >> bitOffset);
+ if (*ip != byte) break;
+ ip ++; bitOffset -= 8;
+ }
+ }
+
return (unsigned)(ip - iStart);
}