// Copyright 2009 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 bytes_test import ( . "bytes" "math/rand" "reflect" "testing" "unicode" "unicode/utf8") func eq(a, b []string) bool { if len(a) != len(b) { return false } for i := 0; i < len(a); i++ { if a[i] != b[i] { return false } } return true} func sliceOfString(s [][]byte) []string { result := make([]string, len(s)) for i, v := range s { result[i] = string(v) } return result} // For ease of reading, the test cases use strings that are converted to byte// slices before invoking the functions. var abcd = "abcd"var faces = "☺☻☹"var commas = "1,2,3,4"var dots = "1....2....3....4" type BinOpTest struct { a string b string i int} var equalTests = []struct { a, b []byte i int}{ {[]byte(""), []byte(""), 0}, {[]byte("a"), []byte(""), 1}, {[]byte(""), []byte("a"), -1}, {[]byte("abc"), []byte("abc"), 0}, {[]byte("ab"), []byte("abc"), -1}, {[]byte("abc"), []byte("ab"), 1}, {[]byte("x"), []byte("ab"), 1}, {[]byte("ab"), []byte("x"), -1}, {[]byte("x"), []byte("a"), 1}, {[]byte("b"), []byte("x"), -1}, // test runtime·memeq's chunked implementation {[]byte("abcdefgh"), []byte("abcdefgh"), 0}, {[]byte("abcdefghi"), []byte("abcdefghi"), 0}, {[]byte("abcdefghi"), []byte("abcdefghj"), -1}, // nil tests {nil, nil, 0}, {[]byte(""), nil, 0}, {nil, []byte(""), 0}, {[]byte("a"), nil, 1}, {nil, []byte("a"), -1},} func TestEqual(t *testing.T) { for _, tt := range compareTests { eql := Equal(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql) } eql = EqualPortable(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql) } }} func TestEqualExhaustive(t *testing.T) { var size = 128 if testing.Short() { size = 32 } a := make([]byte, size) b := make([]byte, size) b_init := make([]byte, size) // randomish but deterministic data for i := 0; i < size; i++ { a[i] = byte(17 * i) b_init[i] = byte(23*i + 100) } for len := 0; len <= size; len++ { for x := 0; x <= size-len; x++ { for y := 0; y <= size-len; y++ { copy(b, b_init) copy(b[y:y+len], a[x:x+len]) if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) { t.Errorf("Equal(%d, %d, %d) = false", len, x, y) } } } }} // make sure Equal returns false for minimally different strings. The data// is all zeros except for a single one in one location.func TestNotEqual(t *testing.T) { var size = 128 if testing.Short() { size = 32 } a := make([]byte, size) b := make([]byte, size) for len := 0; len <= size; len++ { for x := 0; x <= size-len; x++ { for y := 0; y <= size-len; y++ { for diffpos := x; diffpos < x+len; diffpos++ { a[diffpos] = 1 if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) { t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos) } a[diffpos] = 0 } } } }} var indexTests = []BinOpTest{ {"", "", 0}, {"", "a", -1}, {"", "foo", -1}, {"fo", "foo", -1}, {"foo", "baz", -1}, {"foo", "foo", 0}, {"oofofoofooo", "f", 2}, {"oofofoofooo", "foo", 4}, {"barfoobarfoo", "foo", 3}, {"foo", "", 0}, {"foo", "o", 1}, {"abcABCabc", "A", 3}, // cases with one byte strings - test IndexByte and special case in Index() {"", "a", -1}, {"x", "a", -1}, {"x", "x", 0}, {"abc", "a", 0}, {"abc", "b", 1}, {"abc", "c", 2}, {"abc", "x", -1}, {"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33}, {"foofyfoobarfoobar", "y", 4}, {"oooooooooooooooooooooo", "r", -1},} var lastIndexTests = []BinOpTest{ {"", "", 0}, {"", "a", -1}, {"", "foo", -1}, {"fo", "foo", -1}, {"foo", "foo", 0}, {"foo", "f", 0}, {"oofofoofooo", "f", 7}, {"oofofoofooo", "foo", 7}, {"barfoobarfoo", "foo", 9}, {"foo", "", 3}, {"foo", "o", 2}, {"abcABCabc", "A", 3}, {"abcABCabc", "a", 6},} var indexAnyTests = []BinOpTest{ {"", "", -1}, {"", "a", -1}, {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, {"aaa", "a", 0}, {"abc", "xyz", -1}, {"abc", "xcz", 2}, {"ab☺c", "x☺yz", 2}, {"aRegExp*", ".(|)*+?^$[]", 7}, {dots + dots + dots, " ", -1},} var lastIndexAnyTests = []BinOpTest{ {"", "", -1}, {"", "a", -1}, {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, {"aaa", "a", 2}, {"abc", "xyz", -1}, {"abc", "ab", 1}, {"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")}, {"a.RegExp*", ".(|)*+?^$[]", 8}, {dots + dots + dots, " ", -1},} var indexRuneTests = []BinOpTest{ {"", "a", -1}, {"", "☺", -1}, {"foo", "☹", -1}, {"foo", "o", 1}, {"foo☺bar", "☺", 3}, {"foo☺☻☹bar", "☹", 9},} // Execute f on each test case. funcName should be the name of f; it's used// in failure reports.func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) { for _, test := range testCases { a := []byte(test.a) b := []byte(test.b) actual := f(a, b) if actual != test.i { t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i) } }} func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) { for _, test := range testCases { a := []byte(test.a) actual := f(a, test.b) if actual != test.i { t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, test.b, actual, test.i) } }} func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) }func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }func TestIndexAny(t *testing.T) { runIndexAnyTests(t, IndexAny, "IndexAny", indexAnyTests) }func TestLastIndexAny(t *testing.T) { runIndexAnyTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests)} func TestIndexByte(t *testing.T) { for _, tt := range indexTests { if len(tt.b) != 1 { continue } a := []byte(tt.a) b := tt.b[0] pos := IndexByte(a, b) if pos != tt.i { t.Errorf(`IndexByte(%q, '%c') = %v`, tt.a, b, pos) } posp := IndexBytePortable(a, b) if posp != tt.i { t.Errorf(`indexBytePortable(%q, '%c') = %v`, tt.a, b, posp) } }} func TestLastIndexByte(t *testing.T) { testCases := []BinOpTest{ {"", "q", -1}, {"abcdef", "q", -1}, {"abcdefabcdef", "a", len("abcdef")}, // something in the middle {"abcdefabcdef", "f", len("abcdefabcde")}, // last byte {"zabcdefabcdef", "z", 0}, // first byte {"a☺b☻c☹d", "b", len("a☺")}, // non-ascii } for _, test := range testCases { actual := LastIndexByte([]byte(test.a), test.b[0]) if actual != test.i { t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.a, test.b[0], actual, test.i) } }} // test a larger buffer with different sizes and alignmentsfunc TestIndexByteBig(t *testing.T) { var n = 1024 if testing.Short() { n = 128 } b := make([]byte, n) for i := 0; i < n; i++ { // different start alignments b1 := b[i:] for j := 0; j < len(b1); j++ { b1[j] = 'x' pos := IndexByte(b1, 'x') if pos != j { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } b1[j] = 0 pos = IndexByte(b1, 'x') if pos != -1 { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } } // different end alignments b1 = b[:i] for j := 0; j < len(b1); j++ { b1[j] = 'x' pos := IndexByte(b1, 'x') if pos != j { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } b1[j] = 0 pos = IndexByte(b1, 'x') if pos != -1 { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } } // different start and end alignments b1 = b[i/2 : n-(i+1)/2] for j := 0; j < len(b1); j++ { b1[j] = 'x' pos := IndexByte(b1, 'x') if pos != j { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } b1[j] = 0 pos = IndexByte(b1, 'x') if pos != -1 { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } } }} func TestIndexRune(t *testing.T) { for _, tt := range indexRuneTests { a := []byte(tt.a) r, _ := utf8.DecodeRuneInString(tt.b) pos := IndexRune(a, r) if pos != tt.i { t.Errorf(`IndexRune(%q, '%c') = %v`, tt.a, r, pos) } }} var bmbuf []byte func BenchmarkIndexByte32(b *testing.B) { bmIndexByte(b, IndexByte, 32) }func BenchmarkIndexByte4K(b *testing.B) { bmIndexByte(b, IndexByte, 4<<10) }func BenchmarkIndexByte4M(b *testing.B) { bmIndexByte(b, IndexByte, 4<<20) }func BenchmarkIndexByte64M(b *testing.B) { bmIndexByte(b, IndexByte, 64<<20) }func BenchmarkIndexBytePortable32(b *testing.B) { bmIndexByte(b, IndexBytePortable, 32) }func BenchmarkIndexBytePortable4K(b *testing.B) { bmIndexByte(b, IndexBytePortable, 4<<10) }func BenchmarkIndexBytePortable4M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 4<<20) }func BenchmarkIndexBytePortable64M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 64<<20) } func bmIndexByte(b *testing.B, index func([]byte, byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' for i := 0; i < b.N; i++ { j := index(buf, 'x') if j != n-1 { b.Fatal("bad index", j) } } buf[n-1] = '\x00'} func BenchmarkEqual0(b *testing.B) { var buf [4]byte buf1 := buf[0:0] buf2 := buf[1:1] for i := 0; i < b.N; i++ { eq := Equal(buf1, buf2) if !eq { b.Fatal("bad equal") } }} func BenchmarkEqual1(b *testing.B) { bmEqual(b, Equal, 1) }func BenchmarkEqual6(b *testing.B) { bmEqual(b, Equal, 6) }func BenchmarkEqual9(b *testing.B) { bmEqual(b, Equal, 9) }func BenchmarkEqual15(b *testing.B) { bmEqual(b, Equal, 15) }func BenchmarkEqual16(b *testing.B) { bmEqual(b, Equal, 16) }func BenchmarkEqual20(b *testing.B) { bmEqual(b, Equal, 20) }func BenchmarkEqual32(b *testing.B) { bmEqual(b, Equal, 32) }func BenchmarkEqual4K(b *testing.B) { bmEqual(b, Equal, 4<<10) }func BenchmarkEqual4M(b *testing.B) { bmEqual(b, Equal, 4<<20) }func BenchmarkEqual64M(b *testing.B) { bmEqual(b, Equal, 64<<20) }func BenchmarkEqualPort1(b *testing.B) { bmEqual(b, EqualPortable, 1) }func BenchmarkEqualPort6(b *testing.B) { bmEqual(b, EqualPortable, 6) }func BenchmarkEqualPort32(b *testing.B) { bmEqual(b, EqualPortable, 32) }func BenchmarkEqualPort4K(b *testing.B) { bmEqual(b, EqualPortable, 4<<10) }func BenchmarkEqualPortable4M(b *testing.B) { bmEqual(b, EqualPortable, 4<<20) }func BenchmarkEqualPortable64M(b *testing.B) { bmEqual(b, EqualPortable, 64<<20) } func bmEqual(b *testing.B, equal func([]byte, []byte) bool, n int) { if len(bmbuf) < 2*n { bmbuf = make([]byte, 2*n) } b.SetBytes(int64(n)) buf1 := bmbuf[0:n] buf2 := bmbuf[n : 2*n] buf1[n-1] = 'x' buf2[n-1] = 'x' for i := 0; i < b.N; i++ { eq := equal(buf1, buf2) if !eq { b.Fatal("bad equal") } } buf1[n-1] = '\x00' buf2[n-1] = '\x00'} func BenchmarkIndex32(b *testing.B) { bmIndex(b, Index, 32) }func BenchmarkIndex4K(b *testing.B) { bmIndex(b, Index, 4<<10) }func BenchmarkIndex4M(b *testing.B) { bmIndex(b, Index, 4<<20) }func BenchmarkIndex64M(b *testing.B) { bmIndex(b, Index, 64<<20) } func bmIndex(b *testing.B, index func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' for i := 0; i < b.N; i++ { j := index(buf, buf[n-7:]) if j != n-7 { b.Fatal("bad index", j) } } buf[n-1] = '\x00'} func BenchmarkIndexEasy32(b *testing.B) { bmIndexEasy(b, Index, 32) }func BenchmarkIndexEasy4K(b *testing.B) { bmIndexEasy(b, Index, 4<<10) }func BenchmarkIndexEasy4M(b *testing.B) { bmIndexEasy(b, Index, 4<<20) }func BenchmarkIndexEasy64M(b *testing.B) { bmIndexEasy(b, Index, 64<<20) } func bmIndexEasy(b *testing.B, index func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' buf[n-7] = 'x' for i := 0; i < b.N; i++ { j := index(buf, buf[n-7:]) if j != n-7 { b.Fatal("bad index", j) } } buf[n-1] = '\x00' buf[n-7] = '\x00'} func BenchmarkCount32(b *testing.B) { bmCount(b, Count, 32) }func BenchmarkCount4K(b *testing.B) { bmCount(b, Count, 4<<10) }func BenchmarkCount4M(b *testing.B) { bmCount(b, Count, 4<<20) }func BenchmarkCount64M(b *testing.B) { bmCount(b, Count, 64<<20) } func bmCount(b *testing.B, count func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' for i := 0; i < b.N; i++ { j := count(buf, buf[n-7:]) if j != 1 { b.Fatal("bad count", j) } } buf[n-1] = '\x00'} func BenchmarkCountEasy32(b *testing.B) { bmCountEasy(b, Count, 32) }func BenchmarkCountEasy4K(b *testing.B) { bmCountEasy(b, Count, 4<<10) }func BenchmarkCountEasy4M(b *testing.B) { bmCountEasy(b, Count, 4<<20) }func BenchmarkCountEasy64M(b *testing.B) { bmCountEasy(b, Count, 64<<20) } func bmCountEasy(b *testing.B, count func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x'Lines 1–500 of 1288. Load more
// Copyright 2009 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 bytes_test import ( . "bytes" "math/rand" "reflect" "testing" "unicode" "unicode/utf8" ) func eq(a, b []string) bool { if len(a) != len(b) { return false } for i := 0; i < len(a); i++ { if a[i] != b[i] { return false } } return true } func sliceOfString(s [][]byte) []string { result := make([]string, len(s)) for i, v := range s { result[i] = string(v) } return result } // For ease of reading, the test cases use strings that are converted to byte // slices before invoking the functions. var abcd = "abcd" var faces = "☺☻☹" var commas = "1,2,3,4" var dots = "1....2....3....4" type BinOpTest struct { a string b string i int } var equalTests = []struct { a, b []byte i int }{ {[]byte(""), []byte(""), 0}, {[]byte("a"), []byte(""), 1}, {[]byte(""), []byte("a"), -1}, {[]byte("abc"), []byte("abc"), 0}, {[]byte("ab"), []byte("abc"), -1}, {[]byte("abc"), []byte("ab"), 1}, {[]byte("x"), []byte("ab"), 1}, {[]byte("ab"), []byte("x"), -1}, {[]byte("x"), []byte("a"), 1}, {[]byte("b"), []byte("x"), -1}, // test runtime·memeq's chunked implementation {[]byte("abcdefgh"), []byte("abcdefgh"), 0}, {[]byte("abcdefghi"), []byte("abcdefghi"), 0}, {[]byte("abcdefghi"), []byte("abcdefghj"), -1}, // nil tests {nil, nil, 0}, {[]byte(""), nil, 0}, {nil, []byte(""), 0}, {[]byte("a"), nil, 1}, {nil, []byte("a"), -1}, } func TestEqual(t *testing.T) { for _, tt := range compareTests { eql := Equal(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql) } eql = EqualPortable(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql) } } } func TestEqualExhaustive(t *testing.T) { var size = 128 if testing.Short() { size = 32 } a := make([]byte, size) b := make([]byte, size) b_init := make([]byte, size) // randomish but deterministic data for i := 0; i < size; i++ { a[i] = byte(17 * i) b_init[i] = byte(23*i + 100) } for len := 0; len <= size; len++ { for x := 0; x <= size-len; x++ { for y := 0; y <= size-len; y++ { copy(b, b_init) copy(b[y:y+len], a[x:x+len]) if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) { t.Errorf("Equal(%d, %d, %d) = false", len, x, y) } } } } } // make sure Equal returns false for minimally different strings. The data // is all zeros except for a single one in one location. func TestNotEqual(t *testing.T) { var size = 128 if testing.Short() { size = 32 } a := make([]byte, size) b := make([]byte, size) for len := 0; len <= size; len++ { for x := 0; x <= size-len; x++ { for y := 0; y <= size-len; y++ { for diffpos := x; diffpos < x+len; diffpos++ { a[diffpos] = 1 if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) { t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos) } a[diffpos] = 0 } } } } } var indexTests = []BinOpTest{ {"", "", 0}, {"", "a", -1}, {"", "foo", -1}, {"fo", "foo", -1}, {"foo", "baz", -1}, {"foo", "foo", 0}, {"oofofoofooo", "f", 2}, {"oofofoofooo", "foo", 4}, {"barfoobarfoo", "foo", 3}, {"foo", "", 0}, {"foo", "o", 1}, {"abcABCabc", "A", 3}, // cases with one byte strings - test IndexByte and special case in Index() {"", "a", -1}, {"x", "a", -1}, {"x", "x", 0}, {"abc", "a", 0}, {"abc", "b", 1}, {"abc", "c", 2}, {"abc", "x", -1}, {"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33}, {"foofyfoobarfoobar", "y", 4}, {"oooooooooooooooooooooo", "r", -1}, } var lastIndexTests = []BinOpTest{ {"", "", 0}, {"", "a", -1}, {"", "foo", -1}, {"fo", "foo", -1}, {"foo", "foo", 0}, {"foo", "f", 0}, {"oofofoofooo", "f", 7}, {"oofofoofooo", "foo", 7}, {"barfoobarfoo", "foo", 9}, {"foo", "", 3}, {"foo", "o", 2}, {"abcABCabc", "A", 3}, {"abcABCabc", "a", 6}, } var indexAnyTests = []BinOpTest{ {"", "", -1}, {"", "a", -1}, {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, {"aaa", "a", 0}, {"abc", "xyz", -1}, {"abc", "xcz", 2}, {"ab☺c", "x☺yz", 2}, {"aRegExp*", ".(|)*+?^$[]", 7}, {dots + dots + dots, " ", -1}, } var lastIndexAnyTests = []BinOpTest{ {"", "", -1}, {"", "a", -1}, {"", "abc", -1}, {"a", "", -1}, {"a", "a", 0}, {"aaa", "a", 2}, {"abc", "xyz", -1}, {"abc", "ab", 1}, {"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")}, {"a.RegExp*", ".(|)*+?^$[]", 8}, {dots + dots + dots, " ", -1}, } var indexRuneTests = []BinOpTest{ {"", "a", -1}, {"", "☺", -1}, {"foo", "☹", -1}, {"foo", "o", 1}, {"foo☺bar", "☺", 3}, {"foo☺☻☹bar", "☹", 9}, } // Execute f on each test case. funcName should be the name of f; it's used // in failure reports. func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) { for _, test := range testCases { a := []byte(test.a) b := []byte(test.b) actual := f(a, b) if actual != test.i { t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i) } } } func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) { for _, test := range testCases { a := []byte(test.a) actual := f(a, test.b) if actual != test.i { t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, test.b, actual, test.i) } } } func TestIndex(t *testing.T) { runIndexTests(t, Index, "Index", indexTests) } func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) } func TestIndexAny(t *testing.T) { runIndexAnyTests(t, IndexAny, "IndexAny", indexAnyTests) } func TestLastIndexAny(t *testing.T) { runIndexAnyTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) } func TestIndexByte(t *testing.T) { for _, tt := range indexTests { if len(tt.b) != 1 { continue } a := []byte(tt.a) b := tt.b[0] pos := IndexByte(a, b) if pos != tt.i { t.Errorf(`IndexByte(%q, '%c') = %v`, tt.a, b, pos) } posp := IndexBytePortable(a, b) if posp != tt.i { t.Errorf(`indexBytePortable(%q, '%c') = %v`, tt.a, b, posp) } } } func TestLastIndexByte(t *testing.T) { testCases := []BinOpTest{ {"", "q", -1}, {"abcdef", "q", -1}, {"abcdefabcdef", "a", len("abcdef")}, // something in the middle {"abcdefabcdef", "f", len("abcdefabcde")}, // last byte {"zabcdefabcdef", "z", 0}, // first byte {"a☺b☻c☹d", "b", len("a☺")}, // non-ascii } for _, test := range testCases { actual := LastIndexByte([]byte(test.a), test.b[0]) if actual != test.i { t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.a, test.b[0], actual, test.i) } } } // test a larger buffer with different sizes and alignments func TestIndexByteBig(t *testing.T) { var n = 1024 if testing.Short() { n = 128 } b := make([]byte, n) for i := 0; i < n; i++ { // different start alignments b1 := b[i:] for j := 0; j < len(b1); j++ { b1[j] = 'x' pos := IndexByte(b1, 'x') if pos != j { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } b1[j] = 0 pos = IndexByte(b1, 'x') if pos != -1 { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } } // different end alignments b1 = b[:i] for j := 0; j < len(b1); j++ { b1[j] = 'x' pos := IndexByte(b1, 'x') if pos != j { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } b1[j] = 0 pos = IndexByte(b1, 'x') if pos != -1 { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } } // different start and end alignments b1 = b[i/2 : n-(i+1)/2] for j := 0; j < len(b1); j++ { b1[j] = 'x' pos := IndexByte(b1, 'x') if pos != j { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } b1[j] = 0 pos = IndexByte(b1, 'x') if pos != -1 { t.Errorf("IndexByte(%q, 'x') = %v", b1, pos) } } } } func TestIndexRune(t *testing.T) { for _, tt := range indexRuneTests { a := []byte(tt.a) r, _ := utf8.DecodeRuneInString(tt.b) pos := IndexRune(a, r) if pos != tt.i { t.Errorf(`IndexRune(%q, '%c') = %v`, tt.a, r, pos) } } } var bmbuf []byte func BenchmarkIndexByte32(b *testing.B) { bmIndexByte(b, IndexByte, 32) } func BenchmarkIndexByte4K(b *testing.B) { bmIndexByte(b, IndexByte, 4<<10) } func BenchmarkIndexByte4M(b *testing.B) { bmIndexByte(b, IndexByte, 4<<20) } func BenchmarkIndexByte64M(b *testing.B) { bmIndexByte(b, IndexByte, 64<<20) } func BenchmarkIndexBytePortable32(b *testing.B) { bmIndexByte(b, IndexBytePortable, 32) } func BenchmarkIndexBytePortable4K(b *testing.B) { bmIndexByte(b, IndexBytePortable, 4<<10) } func BenchmarkIndexBytePortable4M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 4<<20) } func BenchmarkIndexBytePortable64M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 64<<20) } func bmIndexByte(b *testing.B, index func([]byte, byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' for i := 0; i < b.N; i++ { j := index(buf, 'x') if j != n-1 { b.Fatal("bad index", j) } } buf[n-1] = '\x00' } func BenchmarkEqual0(b *testing.B) { var buf [4]byte buf1 := buf[0:0] buf2 := buf[1:1] for i := 0; i < b.N; i++ { eq := Equal(buf1, buf2) if !eq { b.Fatal("bad equal") } } } func BenchmarkEqual1(b *testing.B) { bmEqual(b, Equal, 1) } func BenchmarkEqual6(b *testing.B) { bmEqual(b, Equal, 6) } func BenchmarkEqual9(b *testing.B) { bmEqual(b, Equal, 9) } func BenchmarkEqual15(b *testing.B) { bmEqual(b, Equal, 15) } func BenchmarkEqual16(b *testing.B) { bmEqual(b, Equal, 16) } func BenchmarkEqual20(b *testing.B) { bmEqual(b, Equal, 20) } func BenchmarkEqual32(b *testing.B) { bmEqual(b, Equal, 32) } func BenchmarkEqual4K(b *testing.B) { bmEqual(b, Equal, 4<<10) } func BenchmarkEqual4M(b *testing.B) { bmEqual(b, Equal, 4<<20) } func BenchmarkEqual64M(b *testing.B) { bmEqual(b, Equal, 64<<20) } func BenchmarkEqualPort1(b *testing.B) { bmEqual(b, EqualPortable, 1) } func BenchmarkEqualPort6(b *testing.B) { bmEqual(b, EqualPortable, 6) } func BenchmarkEqualPort32(b *testing.B) { bmEqual(b, EqualPortable, 32) } func BenchmarkEqualPort4K(b *testing.B) { bmEqual(b, EqualPortable, 4<<10) } func BenchmarkEqualPortable4M(b *testing.B) { bmEqual(b, EqualPortable, 4<<20) } func BenchmarkEqualPortable64M(b *testing.B) { bmEqual(b, EqualPortable, 64<<20) } func bmEqual(b *testing.B, equal func([]byte, []byte) bool, n int) { if len(bmbuf) < 2*n { bmbuf = make([]byte, 2*n) } b.SetBytes(int64(n)) buf1 := bmbuf[0:n] buf2 := bmbuf[n : 2*n] buf1[n-1] = 'x' buf2[n-1] = 'x' for i := 0; i < b.N; i++ { eq := equal(buf1, buf2) if !eq { b.Fatal("bad equal") } } buf1[n-1] = '\x00' buf2[n-1] = '\x00' } func BenchmarkIndex32(b *testing.B) { bmIndex(b, Index, 32) } func BenchmarkIndex4K(b *testing.B) { bmIndex(b, Index, 4<<10) } func BenchmarkIndex4M(b *testing.B) { bmIndex(b, Index, 4<<20) } func BenchmarkIndex64M(b *testing.B) { bmIndex(b, Index, 64<<20) } func bmIndex(b *testing.B, index func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' for i := 0; i < b.N; i++ { j := index(buf, buf[n-7:]) if j != n-7 { b.Fatal("bad index", j) } } buf[n-1] = '\x00' } func BenchmarkIndexEasy32(b *testing.B) { bmIndexEasy(b, Index, 32) } func BenchmarkIndexEasy4K(b *testing.B) { bmIndexEasy(b, Index, 4<<10) } func BenchmarkIndexEasy4M(b *testing.B) { bmIndexEasy(b, Index, 4<<20) } func BenchmarkIndexEasy64M(b *testing.B) { bmIndexEasy(b, Index, 64<<20) } func bmIndexEasy(b *testing.B, index func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' buf[n-7] = 'x' for i := 0; i < b.N; i++ { j := index(buf, buf[n-7:]) if j != n-7 { b.Fatal("bad index", j) } } buf[n-1] = '\x00' buf[n-7] = '\x00' } func BenchmarkCount32(b *testing.B) { bmCount(b, Count, 32) } func BenchmarkCount4K(b *testing.B) { bmCount(b, Count, 4<<10) } func BenchmarkCount4M(b *testing.B) { bmCount(b, Count, 4<<20) } func BenchmarkCount64M(b *testing.B) { bmCount(b, Count, 64<<20) } func bmCount(b *testing.B, count func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x' for i := 0; i < b.N; i++ { j := count(buf, buf[n-7:]) if j != 1 { b.Fatal("bad count", j) } } buf[n-1] = '\x00' } func BenchmarkCountEasy32(b *testing.B) { bmCountEasy(b, Count, 32) } func BenchmarkCountEasy4K(b *testing.B) { bmCountEasy(b, Count, 4<<10) } func BenchmarkCountEasy4M(b *testing.B) { bmCountEasy(b, Count, 4<<20) } func BenchmarkCountEasy64M(b *testing.B) { bmCountEasy(b, Count, 64<<20) } func bmCountEasy(b *testing.B, count func([]byte, []byte) int, n int) { if len(bmbuf) < n { bmbuf = make([]byte, n) } b.SetBytes(int64(n)) buf := bmbuf[0:n] buf[n-1] = 'x'