Skip to content

Commit b46aec0

Browse files
callthingsoffgopherbot
authored andcommitted
bytes,internal/bytealg: eliminate HashStrBytes,HashStrRevBytes using …
…generics The logic of HashStrBytes, HashStrRevBytes and HashStr, HashStrRev, are exactly the same, except that the types are different. Since the bootstrap toolchain is bumped to 1.20, we can eliminate them by using generics. Change-Id: I4336b1cab494ba963f09646c169b45f6b1ee62e3 GitHub-Last-Rev: b11a2bf GitHub-Pull-Request: #63766 Reviewed-on: https://go-review.googlesource.com/c/go/+/538175 Reviewed-by: Keith Randall <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-by: Keith Randall <[email protected]> Auto-Submit: Keith Randall <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 0262ea1 commit b46aec0

File tree

2 files changed

+7
-41
lines changed

2 files changed

+7
-41
lines changed

src/bytes/bytes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func LastIndex(s, sep []byte) int {
122122
return -1
123123
}
124124
// Rabin-Karp search from the end of the string
125-
hashss, pow := bytealg.HashStrRevBytes(sep)
125+
hashss, pow := bytealg.HashStrRev(sep)
126126
last := len(s) - n
127127
var h uint32
128128
for i := len(s) - 1; i >= last; i-- {

src/internal/bytealg/bytealg.go

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,33 +24,16 @@ const (
2424
// If MaxLen is not 0, make sure MaxLen >= 4.
2525
var MaxLen int
2626

27-
// FIXME: the logic of HashStrBytes, HashStrRevBytes, IndexRabinKarpBytes and HashStr, HashStrRev,
28-
// IndexRabinKarp are exactly the same, except that the types are different. Can we eliminate
29-
// three of them without causing allocation?
27+
// FIXME: the logic of IndexRabinKarpBytes and IndexRabinKarp are exactly the same,
28+
// except that the types are different.
29+
// Can we eliminate one of them without causing allocation?
3030

3131
// PrimeRK is the prime base used in Rabin-Karp algorithm.
3232
const PrimeRK = 16777619
3333

34-
// HashStrBytes returns the hash and the appropriate multiplicative
35-
// factor for use in Rabin-Karp algorithm.
36-
func HashStrBytes(sep []byte) (uint32, uint32) {
37-
hash := uint32(0)
38-
for i := 0; i < len(sep); i++ {
39-
hash = hash*PrimeRK + uint32(sep[i])
40-
}
41-
var pow, sq uint32 = 1, PrimeRK
42-
for i := len(sep); i > 0; i >>= 1 {
43-
if i&1 != 0 {
44-
pow *= sq
45-
}
46-
sq *= sq
47-
}
48-
return hash, pow
49-
}
50-
5134
// HashStr returns the hash and the appropriate multiplicative
5235
// factor for use in Rabin-Karp algorithm.
53-
func HashStr(sep string) (uint32, uint32) {
36+
func HashStr[T string | []byte](sep T) (uint32, uint32) {
5437
hash := uint32(0)
5538
for i := 0; i < len(sep); i++ {
5639
hash = hash*PrimeRK + uint32(sep[i])
@@ -65,26 +48,9 @@ func HashStr(sep string) (uint32, uint32) {
6548
return hash, pow
6649
}
6750

68-
// HashStrRevBytes returns the hash of the reverse of sep and the
69-
// appropriate multiplicative factor for use in Rabin-Karp algorithm.
70-
func HashStrRevBytes(sep []byte) (uint32, uint32) {
71-
hash := uint32(0)
72-
for i := len(sep) - 1; i >= 0; i-- {
73-
hash = hash*PrimeRK + uint32(sep[i])
74-
}
75-
var pow, sq uint32 = 1, PrimeRK
76-
for i := len(sep); i > 0; i >>= 1 {
77-
if i&1 != 0 {
78-
pow *= sq
79-
}
80-
sq *= sq
81-
}
82-
return hash, pow
83-
}
84-
8551
// HashStrRev returns the hash of the reverse of sep and the
8652
// appropriate multiplicative factor for use in Rabin-Karp algorithm.
87-
func HashStrRev(sep string) (uint32, uint32) {
53+
func HashStrRev[T string | []byte](sep T) (uint32, uint32) {
8854
hash := uint32(0)
8955
for i := len(sep) - 1; i >= 0; i-- {
9056
hash = hash*PrimeRK + uint32(sep[i])
@@ -103,7 +69,7 @@ func HashStrRev(sep string) (uint32, uint32) {
10369
// first occurrence of substr in s, or -1 if not present.
10470
func IndexRabinKarpBytes(s, sep []byte) int {
10571
// Rabin-Karp search
106-
hashsep, pow := HashStrBytes(sep)
72+
hashsep, pow := HashStr(sep)
10773
n := len(sep)
10874
var h uint32
10975
for i := 0; i < n; i++ {

0 commit comments

Comments
 (0)