]> Cypherpunks repositories - gostls13.git/commitdiff
internal/stringslite: remove duplicate code in Index
authorОлег Световидов <olegsvetovidov@gmail.com>
Tue, 3 Feb 2026 08:02:27 +0000 (11:02 +0300)
committerGopher Robot <gobot@golang.org>
Wed, 4 Feb 2026 20:19:11 +0000 (12:19 -0800)
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>
src/internal/stringslite/strings.go

index 3a09e08cf4f7bd360e6e8b7435a655c83332f53c..6c825df5e4ca098b008599b7f62821c32cf60eae 100644 (file)
@@ -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
-               }
-               return -1
-       case n > len(s):
+       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 {