blob: c59b891292f66e2d8bb80fdf002d5fe3fe6ff23c [file] [log] [blame]
Dan Willemsenebae3022017-01-13 23:01:08 -08001// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package bytes
6
7//go:noescape
8
9// indexShortStr returns the index of the first instance of sep in s,
10// or -1 if sep is not present in s.
11// indexShortStr requires 2 <= len(sep) <= shortStringLen
12func indexShortStr(s, c []byte) int // ../runtime/asm_s390x.s
13
14// supportsVX reports whether the vector facility is available.
15// indexShortStr must not be called if the vector facility is not
16// available.
17func supportsVX() bool // ../runtime/asm_s390x.s
18
19var shortStringLen = -1
20
21func init() {
22 if supportsVX() {
23 shortStringLen = 64
24 }
25}
26
27// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
28func Index(s, sep []byte) int {
29 n := len(sep)
30 switch {
31 case n == 0:
32 return 0
33 case n == 1:
34 return IndexByte(s, sep[0])
35 case n == len(s):
36 if Equal(sep, s) {
37 return 0
38 }
39 return -1
40 case n > len(s):
41 return -1
42 case n <= shortStringLen:
43 // Use brute force when s and sep both are small
44 if len(s) <= 64 {
45 return indexShortStr(s, sep)
46 }
47 c := sep[0]
48 i := 0
49 t := s[:len(s)-n+1]
50 fails := 0
51 for i < len(t) {
52 if t[i] != c {
53 // IndexByte skips 16/32 bytes per iteration,
54 // so it's faster than indexShortStr.
55 o := IndexByte(t[i:], c)
56 if o < 0 {
57 return -1
58 }
59 i += o
60 }
61 if Equal(s[i:i+n], sep) {
62 return i
63 }
64 fails++
65 i++
66 // Switch to indexShortStr when IndexByte produces too many false positives.
67 // Too many means more that 1 error per 8 characters.
68 // Allow some errors in the beginning.
69 if fails > (i+16)/8 {
70 r := indexShortStr(s[i:], sep)
71 if r >= 0 {
72 return r + i
73 }
74 return -1
75 }
76 }
77 return -1
78 }
Dan Willemsena3223282018-02-27 19:41:43 -080079 return indexRabinKarp(s, sep)
Dan Willemsenebae3022017-01-13 23:01:08 -080080}
81
Dan Willemsend2797482017-07-26 13:13:13 -070082// Count counts the number of non-overlapping instances of sep in s.
Dan Willemsena3223282018-02-27 19:41:43 -080083// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
Dan Willemsend2797482017-07-26 13:13:13 -070084func Count(s, sep []byte) int {
85 return countGeneric(s, sep)
86}