From: Олег Световидов Date: Tue, 3 Feb 2026 08:02:27 +0000 (+0300) Subject: internal/stringslite: remove duplicate code in Index X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=044fe174d7a45ab0c7872500de63e6c61b01bf27;p=gostls13.git 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 Auto-Submit: Keith Randall Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI Reviewed-by: Michael Pratt --- diff --git a/src/internal/stringslite/strings.go b/src/internal/stringslite/strings.go index 3a09e08cf4..6c825df5e4 100644 --- a/src/internal/stringslite/strings.go +++ b/src/internal/stringslite/strings.go @@ -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 {