mirror of
https://github.com/golang/go.git
synced 2026-02-07 02:09:55 +00:00
internal/stringslite: remove duplicate code in Index
Merge two nearly identical loops into one by selecting the fallback method (IndexString vs IndexRabinKarp) inside the loop based on whether n <= bytealg.MaxLen. Fixes #77364# Change-Id: Iefbef60922ca24e4dda3016127f54290096bcfed Reviewed-on: https://go-review.googlesource.com/c/go/+/741340 Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
f766b8da6c
commit
044fe174d7
1 changed files with 14 additions and 42 deletions
|
|
@ -28,52 +28,15 @@ func IndexByte(s string, c byte) int {
|
|||
func Index(s, substr string) int {
|
||||
n := len(substr)
|
||||
switch {
|
||||
case n == 0:
|
||||
case n == 0 || substr == s:
|
||||
return 0
|
||||
case n == 1:
|
||||
return IndexByte(s, substr[0])
|
||||
case n == len(s):
|
||||
if substr == s {
|
||||
return 0
|
||||
}
|
||||
case n >= len(s):
|
||||
return -1
|
||||
case n > len(s):
|
||||
return -1
|
||||
case n <= bytealg.MaxLen:
|
||||
case n <= bytealg.MaxLen && len(s) <= bytealg.MaxBruteForce:
|
||||
// Use brute force when s and substr both are small
|
||||
if len(s) <= bytealg.MaxBruteForce {
|
||||
return bytealg.IndexString(s, substr)
|
||||
}
|
||||
c0 := substr[0]
|
||||
c1 := substr[1]
|
||||
i := 0
|
||||
t := len(s) - n + 1
|
||||
fails := 0
|
||||
for i < t {
|
||||
if s[i] != c0 {
|
||||
// IndexByte is faster than bytealg.IndexString, so use it as long as
|
||||
// we're not getting lots of false positives.
|
||||
o := IndexByte(s[i+1:t], c0)
|
||||
if o < 0 {
|
||||
return -1
|
||||
}
|
||||
i += o + 1
|
||||
}
|
||||
if s[i+1] == c1 && s[i:i+n] == substr {
|
||||
return i
|
||||
}
|
||||
fails++
|
||||
i++
|
||||
// Switch to bytealg.IndexString when IndexByte produces too many false positives.
|
||||
if fails > bytealg.Cutover(i) {
|
||||
r := bytealg.IndexString(s[i:], substr)
|
||||
if r >= 0 {
|
||||
return r + i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
return bytealg.IndexString(s, substr)
|
||||
}
|
||||
c0 := substr[0]
|
||||
c1 := substr[1]
|
||||
|
|
@ -82,6 +45,8 @@ func Index(s, substr string) int {
|
|||
fails := 0
|
||||
for i < t {
|
||||
if s[i] != c0 {
|
||||
// IndexByte is faster than bytealg.IndexString, so use it as long as
|
||||
// we're not getting lots of false positives.
|
||||
o := IndexByte(s[i+1:t], c0)
|
||||
if o < 0 {
|
||||
return -1
|
||||
|
|
@ -93,7 +58,14 @@ func Index(s, substr string) int {
|
|||
}
|
||||
i++
|
||||
fails++
|
||||
if fails >= 4+i>>4 && i < t {
|
||||
if n <= bytealg.MaxLen && fails > bytealg.Cutover(i) {
|
||||
// Switch to bytealg.IndexString when IndexByte produces too many false positives.
|
||||
r := bytealg.IndexString(s[i:], substr)
|
||||
if r >= 0 {
|
||||
return r + i
|
||||
}
|
||||
return -1
|
||||
} else if fails >= 4+i>>4 && i < t {
|
||||
// See comment in ../bytes/bytes.go.
|
||||
j := bytealg.IndexRabinKarp(s[i:], substr)
|
||||
if j < 0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue