]> Cypherpunks repositories - gostls13.git/commitdiff
internal/bytealg: add generic LastIndexByte{,String}
authorTobias Klauser <tklauser@distanz.ch>
Thu, 24 Aug 2023 13:10:39 +0000 (15:10 +0200)
committerGopher Robot <gobot@golang.org>
Fri, 25 Aug 2023 15:08:28 +0000 (15:08 +0000)
To avoid duplicating them in net/netip and os and to allow these
packages automatically benefiting from future performance improvements
when optimized native LastIndexByte{,String} implementations are added.

For #36891

Change-Id: I4905a4742273570c2c36b867df57762c5bfbe1e4
Reviewed-on: https://go-review.googlesource.com/c/go/+/522475
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/bytes/bytes.go
src/internal/bytealg/lastindexbyte_generic.go [new file with mode: 0644]
src/net/netip/leaf_alts.go
src/net/netip/netip.go
src/os/file_plan9.go
src/os/tempfile.go
src/strings/strings.go

index c54e52e4fc15e14d34a6d6abf7ce4151e69ac0d1..7ecf3b59f6ef1dddae69d9bcb09920b02735256f 100644 (file)
@@ -112,7 +112,7 @@ func LastIndex(s, sep []byte) int {
        case n == 0:
                return len(s)
        case n == 1:
-               return LastIndexByte(s, sep[0])
+               return bytealg.LastIndexByte(s, sep[0])
        case n == len(s):
                if Equal(s, sep) {
                        return 0
@@ -144,12 +144,7 @@ func LastIndex(s, sep []byte) int {
 
 // LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
 func LastIndexByte(s []byte, c byte) int {
-       for i := len(s) - 1; i >= 0; i-- {
-               if s[i] == c {
-                       return i
-               }
-       }
-       return -1
+       return bytealg.LastIndexByte(s, c)
 }
 
 // IndexRune interprets s as a sequence of UTF-8-encoded code points.
diff --git a/src/internal/bytealg/lastindexbyte_generic.go b/src/internal/bytealg/lastindexbyte_generic.go
new file mode 100644 (file)
index 0000000..b905f53
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bytealg
+
+func LastIndexByte(s []byte, c byte) int {
+       for i := len(s) - 1; i >= 0; i-- {
+               if s[i] == c {
+                       return i
+               }
+       }
+       return -1
+}
+
+func LastIndexByteString(s string, c byte) int {
+       for i := len(s) - 1; i >= 0; i-- {
+               if s[i] == c {
+                       return i
+               }
+       }
+       return -1
+}
index 70513abfd920cec4780e4f55818b268e146a50ef..d887bed627332c98363f58e59d2a0b0022ee5ec6 100644 (file)
@@ -7,15 +7,6 @@
 
 package netip
 
-func stringsLastIndexByte(s string, b byte) int {
-       for i := len(s) - 1; i >= 0; i-- {
-               if s[i] == b {
-                       return i
-               }
-       }
-       return -1
-}
-
 func beUint64(b []byte) uint64 {
        _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
        return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
index d640c264927dc463c8b70a05cf76b29bd59edc98..0c9dc3246ccfd493378715d368e6f9cdfb1163af 100644 (file)
@@ -1038,7 +1038,7 @@ func (p AddrPort) Port() uint16 { return p.port }
 // ip string should parse as an IPv6 address or an IPv4 address, in
 // order for s to be a valid ip:port string.
 func splitAddrPort(s string) (ip, port string, v6 bool, err error) {
-       i := stringsLastIndexByte(s, ':')
+       i := bytealg.LastIndexByteString(s, ':')
        if i == -1 {
                return "", "", false, errors.New("not an ip:port")
        }
@@ -1269,7 +1269,7 @@ func (p Prefix) IsSingleIP() bool { return p.IsValid() && p.Bits() == p.ip.BitLe
 //
 // Note that masked address bits are not zeroed. Use Masked for that.
 func ParsePrefix(s string) (Prefix, error) {
-       i := stringsLastIndexByte(s, '/')
+       i := bytealg.LastIndexByteString(s, '/')
        if i < 0 {
                return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): no '/'")
        }
index 8336487c147f856f07ec7a35721b3c7eb05a3f66..03cdb5be4acbe0b7e2c65a675f91cd3f03dc8818 100644 (file)
@@ -5,6 +5,7 @@
 package os
 
 import (
+       "internal/bytealg"
        "internal/poll"
        "io"
        "runtime"
@@ -387,7 +388,7 @@ func hasPrefix(s, prefix string) bool {
 }
 
 func rename(oldname, newname string) error {
-       dirname := oldname[:lastIndex(oldname, '/')+1]
+       dirname := oldname[:bytealg.LastIndexByteString(oldname, '/')+1]
        if hasPrefix(newname, dirname) {
                newname = newname[len(dirname):]
        } else {
@@ -396,7 +397,7 @@ func rename(oldname, newname string) error {
 
        // If newname still contains slashes after removing the oldname
        // prefix, the rename is cross-directory and must be rejected.
-       if lastIndex(newname, '/') >= 0 {
+       if bytealg.LastIndexByteString(newname, '/') >= 0 {
                return &LinkError{"rename", oldname, newname, ErrInvalid}
        }
 
index 99f65c625ae20d50fe3c33db18064b7be03e3b51..315f65ad9ceed84e76c092edcbb8fd8967c64afa 100644 (file)
@@ -6,6 +6,7 @@ package os
 
 import (
        "errors"
+       "internal/bytealg"
        "internal/itoa"
 )
 
@@ -62,7 +63,7 @@ func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
                        return "", "", errPatternHasSeparator
                }
        }
-       if pos := lastIndex(pattern, '*'); pos != -1 {
+       if pos := bytealg.LastIndexByteString(pattern, '*'); pos != -1 {
                prefix, suffix = pattern[:pos], pattern[pos+1:]
        } else {
                prefix = pattern
@@ -116,13 +117,3 @@ func joinPath(dir, name string) string {
        }
        return dir + string(PathSeparator) + name
 }
-
-// lastIndex from the strings package.
-func lastIndex(s string, sep byte) int {
-       for i := len(s) - 1; i >= 0; i-- {
-               if s[i] == sep {
-                       return i
-               }
-       }
-       return -1
-}
index 2dd4321142ef465fb6445b9a9d4f68edacf941f8..301cd8667eda278c069388f0318f1180ca201dd9 100644 (file)
@@ -83,7 +83,7 @@ func LastIndex(s, substr string) int {
        case n == 0:
                return len(s)
        case n == 1:
-               return LastIndexByte(s, substr[0])
+               return bytealg.LastIndexByteString(s, substr[0])
        case n == len(s):
                if substr == s {
                        return 0
@@ -227,12 +227,7 @@ func LastIndexAny(s, chars string) int {
 
 // LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
 func LastIndexByte(s string, c byte) int {
-       for i := len(s) - 1; i >= 0; i-- {
-               if s[i] == c {
-                       return i
-               }
-       }
-       return -1
+       return bytealg.LastIndexByteString(s, c)
 }
 
 // Generic split: splits after each instance of sep,