Add and AddByte

R=rsc
DELTA=83  (83 added, 0 deleted, 0 changed)
OCL=34584
CL=34584
This commit is contained in:
Rob Pike 2009-09-13 21:35:18 -07:00
parent 61dd8363ba
commit d3013d8aa1
2 changed files with 83 additions and 0 deletions

View File

@ -260,3 +260,45 @@ func TrimSpace(s []byte) []byte {
}
return s[start:end];
}
// How big to make a byte array when growing.
// Heuristic: Scale by 50% to give n log n time.
func resize(n int) int {
if n < 16 {
n = 16
}
return n + n/2;
}
// Add appends the contents of t to the end of s and returns the result.
// If s has enough capacity, it is extended in place; otherwise a
// new array is allocated and returned.
func Add(s, t []byte) []byte {
lens := len(s);
lent := len(t);
if lens + lent <= cap(s) {
s = s[0:lens+lent];
} else {
news := make([]byte, lens+lent, resize(lens+lent));
Copy(news, s);
s = news;
}
Copy(s[lens:lens+lent], t);
return s;
}
// AddByte appends byte b to the end of s and returns the result.
// If s has enough capacity, it is extended in place; otherwise a
// new array is allocated and returned.
func AddByte(s []byte, t byte) []byte {
lens := len(s);
if lens + 1 <= cap(s) {
s = s[0:lens+1];
} else {
news := make([]byte, lens+1, resize(lens+1));
Copy(news, s);
s = news;
}
s[lens] = t;
return s;
}

View File

@ -121,6 +121,7 @@ var splittests = []SplitTest {
SplitTest{ "123", "", 2, []string{"1", "23"} },
SplitTest{ "123", "", 17, []string{"1", "2", "3"} },
}
func TestSplit(t *testing.T) {
for _, tt := range splittests {
a := Split(strings.Bytes(tt.s), strings.Bytes(tt.sep), tt.n);
@ -261,3 +262,43 @@ func TestToLower(t *testing.T) {
func TestTrimSpace(t *testing.T) {
runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests);
}
type AddTest struct {
s, t string;
cap int;
}
var addtests = []AddTest {
AddTest{ "", "", 0 },
AddTest{ "a", "", 1 },
AddTest{ "a", "b", 1 },
AddTest{ "abc", "def", 100 },
}
func TestAdd(t *testing.T) {
for i, test := range addtests {
b := make([]byte, len(test.s), test.cap);
for i := 0; i < len(test.s); i++ {
b[i] = test.s[i]
}
b = Add(b, strings.Bytes(test.t));
if string(b) != test.s+test.t {
t.Errorf("Add(%q,%q) = %q", test.s, test.t, string(b));
}
}
}
func TestAddByte(t *testing.T) {
const N = 2e5;
b := make([]byte, 0);
for i := 0; i < N; i++ {
b = AddByte(b, byte(i))
}
if len(b) != N {
t.Errorf("AddByte: too small; expected %d got %d", N, len(b));
}
for i, c := range b {
if c != byte(i) {
t.Fatalf("AddByte: b[%d] should be %d is %d", i, c, byte(i));
}
}
}