Browse Source

Merge pull request #46 from klauspost/faster-matching

Faster matching
Pierre Curto 6 years ago
parent
commit
a5e15b8b85
1 changed files with 19 additions and 11 deletions
  1. 19 11
      block.go

+ 19 - 11
block.go

@@ -2,6 +2,7 @@ package lz4
 
 import (
 	"encoding/binary"
+	"math/bits"
 )
 
 // blockHash hashes 4 bytes into a value < winSize.
@@ -77,12 +78,15 @@ func CompressBlock(src, dst []byte, hashTable []int) (di int, err error) {
 		si += minMatch
 		mLen := si // Match length has minMatch already.
 		// Find the longest match, first looking by batches of 8 bytes.
-		for si < sn && binary.LittleEndian.Uint64(src[si:]) == binary.LittleEndian.Uint64(src[si-offset:]) {
-			si += 8
-		}
-		// Then byte by byte.
-		for si < sn && src[si] == src[si-offset] {
-			si++
+		for si < sn {
+			x := binary.LittleEndian.Uint64(src[si:]) ^ binary.LittleEndian.Uint64(src[si-offset:])
+			if x == 0 {
+				si += 8
+			} else {
+				// Stop is first non-zero byte.
+				si += bits.TrailingZeros64(x) >> 3
+				break
+			}
 		}
 
 		mLen = si - mLen
@@ -198,11 +202,15 @@ func CompressBlockHC(src, dst []byte, depth int) (di int, err error) {
 			}
 			ml := 0
 			// Compare the current position with a previous with the same hash.
-			for ml < sn-si && binary.LittleEndian.Uint64(src[next+ml:]) == binary.LittleEndian.Uint64(src[si+ml:]) {
-				ml += 8
-			}
-			for ml < sn-si && src[next+ml] == src[si+ml] {
-				ml++
+			for ml < sn-si {
+				x := binary.LittleEndian.Uint64(src[next+ml:]) ^ binary.LittleEndian.Uint64(src[si+ml:])
+				if x == 0 {
+					ml += 8
+				} else {
+					// Stop is first non-zero byte.
+					ml += bits.TrailingZeros64(x) >> 3
+					break
+				}
 			}
 			if ml < minMatch || ml <= mLen {
 				// Match too small (<minMath) or smaller than the current match.