From: W. Felix Handte Date: Wed, 16 May 2018 18:55:20 +0000 (-0400) Subject: Refactor ZSTD_dfast to Use `goto`s X-Git-Tag: v1.3.5~3^2~37^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1850025156a2169bc0f1b022a9f3d5a6a18c9b05;p=thirdparty%2Fzstd.git Refactor ZSTD_dfast to Use `goto`s --- diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 3e1a1d3c6..de1529006 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -106,6 +106,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( /* Main Search Loop */ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ size_t mLength; + U32 offset; size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); U32 const current = (U32)(ip-base); @@ -120,6 +121,7 @@ size_t ZSTD_compressBlock_doubleFast_generic( base + repIndex; hashLong[h2] = hashSmall[h] = current; /* update hash tables */ + /* check dictMatchState repcode */ if (dictMode == ZSTD_dictMatchState && ((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */) && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { @@ -127,73 +129,93 @@ size_t ZSTD_compressBlock_doubleFast_generic( mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, istart) + 4; ip++; ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH); - } else if ( dictMode == ZSTD_noDict - && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) { + goto _match_stored; + } + + /* check noDict repcode */ + if ( dictMode == ZSTD_noDict + && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) { mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; ip++; ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH); - } else { - U32 offset; - if ( (matchIndexL > prefixLowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) { - mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; - offset = (U32)(ip-matchLong); - while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ - } else if ( (matchIndexS > prefixLowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) { + goto _match_stored; + } + + /* check prefix long match */ + if ( (matchIndexL > prefixLowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) { + mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; + offset = (U32)(ip-matchLong); + while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + goto _match_found; + } + + /* check prefix short match */ + if ( (matchIndexS > prefixLowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) { + size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + U32 const matchIndexL3 = hashLong[hl3]; + const BYTE* matchL3 = base + matchIndexL3; + hashLong[hl3] = current + 1; + + /* check prefix + 1 long match */ + if ( (matchIndexL3 > prefixLowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) { + mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + ip++; + offset = (U32)(ip-matchL3); + while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ + } else { + mLength = ZSTD_count(ip+4, match+4, iend) + 4; + offset = (U32)(ip-match); + while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + goto _match_found; + } + + /* check dictMatchState matches */ + if (dictMode == ZSTD_dictMatchState) { + U32 const dictMatchIndexL = dictHashLong[h2]; + U32 const dictMatchIndexS = dictHashSmall[h]; + const BYTE* dictMatchL = dictBase + dictMatchIndexL; + const BYTE* dictMatchS = dictBase + dictMatchIndexS; + assert(dictMatchL < dictEnd); + assert(dictMatchS < dictEnd); + + if (dictMatchL > dictLowest && MEM_read64(dictMatchL) == MEM_read64(ip)) { + mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8; + offset = (U32)(current - dictMatchIndexL - dictIndexDelta); + while (((ip>anchor) & (dictMatchL>dictLowest)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */ + goto _match_found; + } + + if (dictMatchS > dictLowest && MEM_read32(dictMatchS) == MEM_read32(ip)) { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); - U32 const matchIndexL3 = hashLong[hl3]; - const BYTE* matchL3 = base + matchIndexL3; - hashLong[hl3] = current + 1; - if ( (matchIndexL3 > prefixLowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) { - mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + U32 const dictMatchIndexL3 = dictHashLong[hl3]; + const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3; + assert(dictMatchL3 < dictEnd); + if (dictMatchL3 > dictLowest && MEM_read64(dictMatchL3) == MEM_read64(ip)) { + mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8; ip++; - offset = (U32)(ip-matchL3); - while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ - } else { - mLength = ZSTD_count(ip+4, match+4, iend) + 4; - offset = (U32)(ip-match); - while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ - } - } else if (dictMode == ZSTD_dictMatchState) { - U32 const dictMatchIndexL = dictHashLong[h2]; - U32 const dictMatchIndexS = dictHashSmall[h]; - const BYTE* dictMatchL = dictBase + dictMatchIndexL; - const BYTE* dictMatchS = dictBase + dictMatchIndexS; - assert(dictMatchL < dictEnd); - assert(dictMatchS < dictEnd); - if (dictMatchL > dictLowest && MEM_read64(dictMatchL) == MEM_read64(ip)) { - mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8; - offset = (U32)(current - dictMatchIndexL - dictIndexDelta); - while (((ip>anchor) & (dictMatchL>dictLowest)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */ - } else if (dictMatchS > dictLowest && MEM_read32(dictMatchS) == MEM_read32(ip)) { - size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); - U32 const dictMatchIndexL3 = dictHashLong[hl3]; - const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3; - assert(dictMatchL3 < dictEnd); - if (dictMatchL3 > dictLowest && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) { - mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8; - ip++; - offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta); - while (((ip>anchor) & (dictMatchL3>dictLowest)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */ - } else { - mLength = ZSTD_count_2segments(ip+4, dictMatchS+4, iend, dictEnd, istart) + 4; - offset = (U32)(current - dictMatchIndexS - dictIndexDelta); - while (((ip>anchor) & (dictMatchS>dictLowest)) && (ip[-1] == dictMatchS[-1])) { ip--; dictMatchS--; mLength++; } /* catch up */ - } + offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta); + while (((ip>anchor) & (dictMatchL3>dictLowest)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */ } else { - ip += ((ip-anchor) >> kSearchStrength) + 1; - continue; + mLength = ZSTD_count_2segments(ip+4, dictMatchS+4, iend, dictEnd, istart) + 4; + offset = (U32)(current - dictMatchIndexS - dictIndexDelta); + while (((ip>anchor) & (dictMatchS>dictLowest)) && (ip[-1] == dictMatchS[-1])) { ip--; dictMatchS--; mLength++; } /* catch up */ } - } else { - ip += ((ip-anchor) >> kSearchStrength) + 1; - continue; + + goto _match_found; } + } - offset_2 = offset_1; - offset_1 = offset; + ip += ((ip-anchor) >> kSearchStrength) + 1; + continue; - ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH); - } +_match_found: + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH); +_match_stored: /* match found */ ip += mLength; anchor = ip;