]> Cypherpunks.ru repositories - gostls13.git/commitdiff
bytes,internal/bytealg: eliminate IndexRabinKarpBytes using generics
authorJes Cok <xigua67damn@gmail.com>
Fri, 27 Oct 2023 16:20:44 +0000 (16:20 +0000)
committerGopher Robot <gobot@golang.org>
Tue, 31 Oct 2023 17:14:04 +0000 (17:14 +0000)
This is a follow-up to CL 538175.

Change-Id: Iec2523b36a16d7e157c17858c89fcd43c2470d58
GitHub-Last-Rev: 812d36e57c71ea3bf44d2d64bde0703ef02a1b91
GitHub-Pull-Request: golang/go#63770
Reviewed-on: https://go-review.googlesource.com/c/go/+/538195
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
src/bytes/bytes.go
src/internal/bytealg/bytealg.go

index 95afb30b40ca2d14c06a3681b195d3d006ce035d..c84accd8f5608c2c165d7bfaff5864b3691f2bb1 100644 (file)
@@ -1331,7 +1331,7 @@ func Index(s, sep []byte) int {
                        // we should cutover at even larger average skips,
                        // because Equal becomes that much more expensive.
                        // This code does not take that effect into account.
-                       j := bytealg.IndexRabinKarpBytes(s[i:], sep)
+                       j := bytealg.IndexRabinKarp(s[i:], sep)
                        if j < 0 {
                                return -1
                        }
index ae4b8b48d2eaa385e9ed4339e6ec58fc1abf4ddd..92be8ea79b7d721dee20f8a6d753c07404ed06d4 100644 (file)
@@ -24,10 +24,6 @@ const (
 // If MaxLen is not 0, make sure MaxLen >= 4.
 var MaxLen int
 
-// FIXME: the logic of IndexRabinKarpBytes and IndexRabinKarp are exactly the same,
-// except that the types are different.
-// Can we eliminate one of them without causing allocation?
-
 // PrimeRK is the prime base used in Rabin-Karp algorithm.
 const PrimeRK = 16777619
 
@@ -65,34 +61,9 @@ func HashStrRev[T string | []byte](sep T) (uint32, uint32) {
        return hash, pow
 }
 
-// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
-// first occurrence of substr in s, or -1 if not present.
-func IndexRabinKarpBytes(s, sep []byte) int {
-       // Rabin-Karp search
-       hashsep, pow := HashStr(sep)
-       n := len(sep)
-       var h uint32
-       for i := 0; i < n; i++ {
-               h = h*PrimeRK + uint32(s[i])
-       }
-       if h == hashsep && Equal(s[:n], sep) {
-               return 0
-       }
-       for i := n; i < len(s); {
-               h *= PrimeRK
-               h += uint32(s[i])
-               h -= pow * uint32(s[i-n])
-               i++
-               if h == hashsep && Equal(s[i-n:i], sep) {
-                       return i - n
-               }
-       }
-       return -1
-}
-
 // IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
 // first occurrence of substr in s, or -1 if not present.
-func IndexRabinKarp(s, substr string) int {
+func IndexRabinKarp[T string | []byte](s, substr T) int {
        // Rabin-Karp search
        hashss, pow := HashStr(substr)
        n := len(substr)
@@ -100,7 +71,7 @@ func IndexRabinKarp(s, substr string) int {
        for i := 0; i < n; i++ {
                h = h*PrimeRK + uint32(s[i])
        }
-       if h == hashss && s[:n] == substr {
+       if h == hashss && string(s[:n]) == string(substr) {
                return 0
        }
        for i := n; i < len(s); {
@@ -108,7 +79,7 @@ func IndexRabinKarp(s, substr string) int {
                h += uint32(s[i])
                h -= pow * uint32(s[i-n])
                i++
-               if h == hashss && s[i-n:i] == substr {
+               if h == hashss && string(s[i-n:i]) == string(substr) {
                        return i - n
                }
        }