// the slice up to the next storage class.
// This is what Grow does but we don't call Grow because
// that might copy the values twice.
- s2 := append(S(nil), make(S, n+m)...)
- copy(s2, s[:i])
+ s2 := append(s[:i], make(S, n+m-i)...)
copy(s2[i:], v)
copy(s2[i+m:], s[i:])
return s2
tot := len(s[:i]) + len(v) + len(s[j:])
if tot > cap(s) {
// Too big to fit, allocate and copy over.
- s2 := append(S(nil), make(S, tot)...) // See Insert
- copy(s2, s[:i])
+ s2 := append(s[:i], make(S, tot-i)...) // See Insert
copy(s2[i:], v)
copy(s2[i+len(v):], s[j:])
return s2
}
}
}
+
+func TestInsertGrowthRate(t *testing.T) {
+ b := make([]byte, 1)
+ maxCap := cap(b)
+ nGrow := 0
+ const N = 1e6
+ for i := 0; i < N; i++ {
+ b = Insert(b, len(b)-1, 0)
+ if cap(b) > maxCap {
+ maxCap = cap(b)
+ nGrow++
+ }
+ }
+ want := int(math.Log(N) / math.Log(1.25)) // 1.25 == growth rate for large slices
+ if nGrow > want {
+ t.Errorf("too many grows. got:%d want:%d", nGrow, want)
+ }
+}
+
+func TestReplaceGrowthRate(t *testing.T) {
+ b := make([]byte, 2)
+ maxCap := cap(b)
+ nGrow := 0
+ const N = 1e6
+ for i := 0; i < N; i++ {
+ b = Replace(b, len(b)-2, len(b)-1, 0, 0)
+ if cap(b) > maxCap {
+ maxCap = cap(b)
+ nGrow++
+ }
+ }
+ want := int(math.Log(N) / math.Log(1.25)) // 1.25 == growth rate for large slices
+ if nGrow > want {
+ t.Errorf("too many grows. got:%d want:%d", nGrow, want)
+ }
+}