aboutsummaryrefslogtreecommitdiff
path: root/src/bytes
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytes')
-rw-r--r--src/bytes/buffer.go15
-rw-r--r--src/bytes/bytes.go37
-rw-r--r--src/bytes/bytes_test.go6
3 files changed, 38 insertions, 20 deletions
diff --git a/src/bytes/buffer.go b/src/bytes/buffer.go
index 14c5bc38d6..087cc0e427 100644
--- a/src/bytes/buffer.go
+++ b/src/bytes/buffer.go
@@ -12,13 +12,15 @@ import (
"unicode/utf8"
)
+// smallBufferSize is an initial allocation minimal capacity.
+const smallBufferSize = 64
+
// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
- buf []byte // contents are the bytes buf[off : len(buf)]
- off int // read at &buf[off], write at &buf[len(buf)]
- bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
- lastRead readOp // last read operation, so that Unread* can work correctly.
+ buf []byte // contents are the bytes buf[off : len(buf)]
+ off int // read at &buf[off], write at &buf[len(buf)]
+ lastRead readOp // last read operation, so that Unread* can work correctly.
// FIXME: it would be advisable to align Buffer to cachelines to avoid false
// sharing.
@@ -125,9 +127,8 @@ func (b *Buffer) grow(n int) int {
if i, ok := b.tryGrowByReslice(n); ok {
return i
}
- // Check if we can make use of bootstrap array.
- if b.buf == nil && n <= len(b.bootstrap) {
- b.buf = b.bootstrap[:n]
+ if b.buf == nil && n <= smallBufferSize {
+ b.buf = make([]byte, n, smallBufferSize)
return 0
}
c := cap(b.buf)
diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go
index 77a7ce98e0..6492db088a 100644
--- a/src/bytes/bytes.go
+++ b/src/bytes/bytes.go
@@ -774,6 +774,15 @@ func Replace(s, old, new []byte, n int) []byte {
return t[0:w]
}
+// ReplaceAll returns a copy of the slice s with all
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the slice
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune slice.
+func ReplaceAll(s, old, new []byte) []byte {
+ return Replace(s, old, new, -1)
+}
+
// EqualFold reports whether s and t, interpreted as UTF-8 strings,
// are equal under Unicode case-folding.
func EqualFold(s, t []byte) bool {
@@ -849,21 +858,22 @@ func Index(s, sep []byte) int {
if len(s) <= bytealg.MaxBruteForce {
return bytealg.Index(s, sep)
}
- c := sep[0]
+ c0 := sep[0]
+ c1 := sep[1]
i := 0
- t := s[:len(s)-n+1]
+ t := len(s) - n + 1
fails := 0
- for i < len(t) {
- if t[i] != c {
+ for i < t {
+ if s[i] != c0 {
// IndexByte is faster than bytealg.Index, so use it as long as
// we're not getting lots of false positives.
- o := IndexByte(t[i:], c)
+ o := IndexByte(s[i:t], c0)
if o < 0 {
return -1
}
i += o
}
- if Equal(s[i:i+n], sep) {
+ if s[i+1] == c1 && Equal(s[i:i+n], sep) {
return i
}
fails++
@@ -879,24 +889,25 @@ func Index(s, sep []byte) int {
}
return -1
}
- c := sep[0]
+ c0 := sep[0]
+ c1 := sep[1]
i := 0
fails := 0
- t := s[:len(s)-n+1]
- for i < len(t) {
- if t[i] != c {
- o := IndexByte(t[i:], c)
+ t := len(s) - n + 1
+ for i < t {
+ if s[i] != c0 {
+ o := IndexByte(s[i:t], c0)
if o < 0 {
break
}
i += o
}
- if Equal(s[i:i+n], sep) {
+ if s[i+1] == c1 && Equal(s[i:i+n], sep) {
return i
}
i++
fails++
- if fails >= 4+i>>4 && i < len(t) {
+ if fails >= 4+i>>4 && i < t {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go
index 55a22bae22..f4c0ffd2a9 100644
--- a/src/bytes/bytes_test.go
+++ b/src/bytes/bytes_test.go
@@ -1362,6 +1362,12 @@ func TestReplace(t *testing.T) {
if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
}
+ if tt.n == -1 {
+ out := ReplaceAll(in, []byte(tt.old), []byte(tt.new))
+ if s := string(out); s != tt.out {
+ t.Errorf("ReplaceAll(%q, %q, %q) = %q, want %q", tt.in, tt.old, tt.new, s, tt.out)
+ }
+ }
}
}