bench
This commit is contained in:
parent
49f465619d
commit
a921d02997
@ -22,7 +22,7 @@ func TestContent(t *testing.T) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 2}
|
p := &fakePool{allocSize: 2}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -48,7 +48,7 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 2}
|
p := &fakePool{allocSize: 2}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -72,7 +72,7 @@ func TestContent(t *testing.T) {
|
|||||||
return n, errTest
|
return n, errTest
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 2}
|
p := &fakePool{allocSize: 2}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -98,7 +98,7 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, errTest
|
return 0, errTest
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 2}
|
p := &fakePool{allocSize: 2}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -122,7 +122,7 @@ func TestContent(t *testing.T) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 2,
|
allocSize: 2,
|
||||||
errAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ func TestContent(t *testing.T) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 2,
|
allocSize: 2,
|
||||||
errAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -175,7 +175,7 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 2,
|
allocSize: 2,
|
||||||
errAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 2}
|
p := &fakePool{allocSize: 2}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -232,7 +232,7 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 2}
|
p := &fakePool{allocSize: 2}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -267,7 +267,7 @@ func TestContent(t *testing.T) {
|
|||||||
return n, errTest
|
return n, errTest
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{allocSize: 3}
|
p := &fakePool{allocSize: 3}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := buffer.BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
@ -296,7 +296,7 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, errTest2
|
return 0, errTest2
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 2,
|
allocSize: 2,
|
||||||
errAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
|
|||||||
6
lib.go
6
lib.go
@ -59,7 +59,7 @@ var (
|
|||||||
// DefultPool initializes a synchronized pool that stores and returns byte slices of allocSize length. It can be
|
// DefultPool initializes a synchronized pool that stores and returns byte slices of allocSize length. It can be
|
||||||
// used with multiple readers concurrently.
|
// used with multiple readers concurrently.
|
||||||
func DefaultPool(allocSize int) Pool {
|
func DefaultPool(allocSize int) Pool {
|
||||||
if allocSize == 0 {
|
if allocSize <= 0 {
|
||||||
allocSize = 1 << 12
|
allocSize = 1 << 12
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +68,10 @@ func DefaultPool(allocSize int) Pool {
|
|||||||
|
|
||||||
// NoPool returns a noop pool.
|
// NoPool returns a noop pool.
|
||||||
func NoPool(allocSize int) Pool {
|
func NoPool(allocSize int) Pool {
|
||||||
|
if allocSize <= 0 {
|
||||||
|
allocSize = 1 << 12
|
||||||
|
}
|
||||||
|
|
||||||
return noPool{allocSize: allocSize}
|
return noPool{allocSize: allocSize}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
186
lib_test.go
186
lib_test.go
@ -6,7 +6,6 @@ import (
|
|||||||
"code.squareroundforest.org/arpio/buffer"
|
"code.squareroundforest.org/arpio/buffer"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -172,57 +171,32 @@ func (w writerOnly) Write(p []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBenchmarkThroughput(t *testing.T) {
|
func TestBenchmarkThroughput(t *testing.T) {
|
||||||
p := buffer.DefaultPool(0)
|
p := buffer.NoPool(0)
|
||||||
dst := bytes.NewBuffer(nil)
|
dst := bytes.NewBuffer(nil)
|
||||||
wo := writerOnly{dst}
|
wo := writerOnly{dst}
|
||||||
src := &gen{max: 1 << 18}
|
src := &gen{max: 1 << 18}
|
||||||
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
||||||
ro := readerOnly{r}
|
ro := readerOnly{r}
|
||||||
dst.Reset()
|
n, err := io.Copy(wo, ro)
|
||||||
if n, err := io.Copy(wo, ro); n != 1<<18 || err != nil {
|
if n != 1<<18 || err != nil {
|
||||||
t.Fatal(n, err)
|
t.Fatal(n, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBenchmarkCompare(t *testing.T) {
|
func TestBenchmarkThroughputCompare(t *testing.T) {
|
||||||
dst := bytes.NewBuffer(nil)
|
dst := bytes.NewBuffer(nil)
|
||||||
wo := writerOnly{dst}
|
wo := writerOnly{dst}
|
||||||
src := &gen{max: 1 << 18}
|
src := &gen{max: 1 << 18}
|
||||||
r := bufio.NewReader(src)
|
r := bufio.NewReader(src)
|
||||||
ro := readerOnly{r}
|
ro := readerOnly{r}
|
||||||
dst.Reset()
|
n, err := io.Copy(wo, ro)
|
||||||
if n, err := io.Copy(wo, ro); n != 1<<18 || err != nil {
|
if n != 1<<18 || err != nil {
|
||||||
t.Fatal(n, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBenchmarkThroughputSTDLib(t *testing.T) {
|
|
||||||
p := buffer.DefaultPool(0)
|
|
||||||
dst := bytes.NewBuffer(nil)
|
|
||||||
wo := writerOnly{dst}
|
|
||||||
src := bytes.NewBuffer(make([]byte, 1<<18))
|
|
||||||
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
|
||||||
ro := readerOnly{r}
|
|
||||||
dst.Reset()
|
|
||||||
if n, err := io.Copy(wo, ro); n != 1<<18 || err != nil {
|
|
||||||
t.Fatal(n, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBenchmarkCompareSTDLib(t *testing.T) {
|
|
||||||
dst := bytes.NewBuffer(nil)
|
|
||||||
wo := writerOnly{dst}
|
|
||||||
src := bytes.NewBuffer(make([]byte, 1<<18))
|
|
||||||
r := bufio.NewReader(src)
|
|
||||||
ro := readerOnly{r}
|
|
||||||
dst.Reset()
|
|
||||||
if n, err := io.Copy(wo, ro); n != 1<<18 || err != nil {
|
|
||||||
t.Fatal(n, err)
|
t.Fatal(n, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkThroughput(b *testing.B) {
|
func BenchmarkThroughput(b *testing.B) {
|
||||||
p := buffer.DefaultPool(0)
|
p := buffer.NoPool(0)
|
||||||
dst := bytes.NewBuffer(nil)
|
dst := bytes.NewBuffer(nil)
|
||||||
wo := writerOnly{dst}
|
wo := writerOnly{dst}
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@ -234,7 +208,7 @@ func BenchmarkThroughput(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCompare(b *testing.B) {
|
func BenchmarkThroughputCompare(b *testing.B) {
|
||||||
dst := bytes.NewBuffer(nil)
|
dst := bytes.NewBuffer(nil)
|
||||||
wo := writerOnly{dst}
|
wo := writerOnly{dst}
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
@ -246,58 +220,128 @@ func BenchmarkCompare(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkThroughputP(b *testing.B) {
|
func TestThroughputPooled(t *testing.T) {
|
||||||
p := buffer.DefaultPool(0)
|
p := &foreverPool{allocSize: 1 << 12}
|
||||||
b.SetParallelism(runtime.GOMAXPROCS(-1) * 64)
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
|
src := &gen{max: 1 << 18}
|
||||||
|
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
||||||
|
ro := readerOnly{r}
|
||||||
|
n, err := io.Copy(wo, ro)
|
||||||
|
if n != 1<<18 || err != nil {
|
||||||
|
t.Fatal(n, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThroughputPooledCompare(t *testing.T) {
|
||||||
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
|
r := bufio.NewReader(nil)
|
||||||
|
src := &gen{max: 1 << 18}
|
||||||
|
r.Reset(src)
|
||||||
|
ro := readerOnly{r}
|
||||||
|
n, err := io.Copy(wo, ro)
|
||||||
|
if n != 1<<18 || err != nil {
|
||||||
|
t.Fatal(n, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkThroughputPooled(b *testing.B) {
|
||||||
|
p := &foreverPool{allocSize: 1 << 12}
|
||||||
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
src := &gen{max: 1 << 18}
|
||||||
|
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
||||||
|
ro := readerOnly{r}
|
||||||
|
dst.Reset()
|
||||||
|
io.Copy(wo, ro)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkThroughputPooledCompare(b *testing.B) {
|
||||||
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
|
r := bufio.NewReader(nil)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
src := &gen{max: 1 << 18}
|
||||||
|
r.Reset(src)
|
||||||
|
ro := readerOnly{r}
|
||||||
|
dst.Reset()
|
||||||
|
io.Copy(wo, ro)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThroughputPooledParallel(t *testing.T) {
|
||||||
|
p := newSyncedForeverPool(func() []byte {
|
||||||
|
return make([]byte, 1<<12)
|
||||||
|
})
|
||||||
|
|
||||||
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
|
src := &gen{max: 1 << 18}
|
||||||
|
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
||||||
|
ro := readerOnly{r}
|
||||||
|
n, err := io.Copy(wo, ro)
|
||||||
|
if n != 1<<18 || err != nil {
|
||||||
|
t.Fatal(n, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThroughputPooledParallelCompare(t *testing.T) {
|
||||||
|
p := newSyncedForeverPool(func() *bufio.Reader {
|
||||||
|
return bufio.NewReader(nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
|
r, err := p.Get()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
src := &gen{max: 1 << 18}
|
||||||
|
r.Reset(src)
|
||||||
|
ro := readerOnly{r}
|
||||||
|
n, err := io.Copy(wo, ro)
|
||||||
|
if n != 1<<18 || err != nil {
|
||||||
|
t.Fatal(n, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkThroughputPooledParallel(b *testing.B) {
|
||||||
|
p := newSyncedForeverPool(func() []byte {
|
||||||
|
return make([]byte, 1<<12)
|
||||||
|
})
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
dst := bytes.NewBuffer(nil)
|
|
||||||
wo := writerOnly{dst}
|
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
src := &gen{max: 1 << 18}
|
src := &gen{max: 1 << 18}
|
||||||
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
||||||
ro := readerOnly{r}
|
ro := readerOnly{r}
|
||||||
dst.Reset()
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
io.Copy(wo, ro)
|
io.Copy(wo, ro)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCompareP(b *testing.B) {
|
func BenchmarkThroughputPooledParallelCompare(b *testing.B) {
|
||||||
b.SetParallelism(runtime.GOMAXPROCS(-1) * 64)
|
p := newSyncedForeverPool(func() *bufio.Reader {
|
||||||
|
return bufio.NewReader(nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
dst := bytes.NewBuffer(nil)
|
|
||||||
wo := writerOnly{dst}
|
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
r, _ := p.Get()
|
||||||
src := &gen{max: 1 << 18}
|
src := &gen{max: 1 << 18}
|
||||||
r := bufio.NewReader(src)
|
r.Reset(src)
|
||||||
ro := readerOnly{r}
|
ro := readerOnly{r}
|
||||||
dst.Reset()
|
dst := bytes.NewBuffer(nil)
|
||||||
|
wo := writerOnly{dst}
|
||||||
io.Copy(wo, ro)
|
io.Copy(wo, ro)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkThroughputSTDLib(b *testing.B) {
|
|
||||||
p := buffer.DefaultPool(0)
|
|
||||||
dst := bytes.NewBuffer(nil)
|
|
||||||
wo := writerOnly{dst}
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
src := bytes.NewBuffer(make([]byte, 1<<18))
|
|
||||||
r := buffer.BufferedReader(src, buffer.Options{Pool: p})
|
|
||||||
ro := readerOnly{r}
|
|
||||||
dst.Reset()
|
|
||||||
io.Copy(wo, ro)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkCompareSTDLib(b *testing.B) {
|
|
||||||
dst := bytes.NewBuffer(nil)
|
|
||||||
wo := writerOnly{dst}
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
src := bytes.NewBuffer(make([]byte, 1<<18))
|
|
||||||
r := bufio.NewReader(src)
|
|
||||||
ro := readerOnly{r}
|
|
||||||
dst.Reset()
|
|
||||||
io.Copy(wo, ro)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
133
pool_test.go
133
pool_test.go
@ -9,7 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pool struct {
|
type fakePool struct {
|
||||||
allocSize int
|
allocSize int
|
||||||
alloc, free int
|
alloc, free int
|
||||||
errAfter []int
|
errAfter []int
|
||||||
@ -18,7 +18,17 @@ type pool struct {
|
|||||||
rand *rand.Rand
|
rand *rand.Rand
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p pool) allocCondition(c *[]int) bool {
|
type foreverPool struct {
|
||||||
|
allocSize int
|
||||||
|
items [][]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
type syncedForeverPool[T any] struct {
|
||||||
|
create func() T
|
||||||
|
items chan []T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p fakePool) allocCondition(c *[]int) bool {
|
||||||
if len(*c) == 0 {
|
if len(*c) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -31,7 +41,7 @@ func (p pool) allocCondition(c *[]int) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) ensureRand() {
|
func (p *fakePool) ensureRand() {
|
||||||
if p.rand != nil {
|
if p.rand != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -39,7 +49,7 @@ func (p *pool) ensureRand() {
|
|||||||
p.rand = rand.New(rand.NewSource(9))
|
p.rand = rand.New(rand.NewSource(9))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) Get() ([]byte, error) {
|
func (p *fakePool) Get() ([]byte, error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
p.alloc++
|
p.alloc++
|
||||||
}()
|
}()
|
||||||
@ -66,16 +76,63 @@ func (p *pool) Get() ([]byte, error) {
|
|||||||
return make([]byte, n), nil
|
return make([]byte, n), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) Put([]byte) {
|
func (p *fakePool) Put([]byte) {
|
||||||
p.free++
|
p.free++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *foreverPool) Get() ([]byte, error) {
|
||||||
|
if len(p.items) == 0 {
|
||||||
|
return make([]byte, p.allocSize), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var i []byte
|
||||||
|
i, p.items = p.items[0], p.items[1:]
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *foreverPool) Put(i []byte) {
|
||||||
|
p.items = append(p.items, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSyncedForeverPool[T any](c func() T) *syncedForeverPool[T] {
|
||||||
|
items := make(chan []T, 1)
|
||||||
|
items <- nil
|
||||||
|
return &syncedForeverPool[T]{
|
||||||
|
create: c,
|
||||||
|
items: items,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *syncedForeverPool[T]) Get() (T, error) {
|
||||||
|
items := <-p.items
|
||||||
|
defer func() {
|
||||||
|
p.items <- items
|
||||||
|
}()
|
||||||
|
|
||||||
|
if len(items) == 0 {
|
||||||
|
return p.create(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var i T
|
||||||
|
i, items = items[0], items[1:]
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *syncedForeverPool[T]) Put(i T) {
|
||||||
|
items := <-p.items
|
||||||
|
defer func() {
|
||||||
|
p.items <- items
|
||||||
|
}()
|
||||||
|
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
|
||||||
func TestPoolUsage(t *testing.T) {
|
func TestPoolUsage(t *testing.T) {
|
||||||
for _, cr := range []createReader{buffer.BufferedReader, testContent} {
|
for _, cr := range []createReader{buffer.BufferedReader, testContent} {
|
||||||
t.Run("allocate", func(t *testing.T) {
|
t.Run("allocate", func(t *testing.T) {
|
||||||
t.Run("read", func(t *testing.T) {
|
t.Run("read", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b := make([]byte, 256)
|
b := make([]byte, 256)
|
||||||
@ -99,7 +156,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("read bytes", func(t *testing.T) {
|
t.Run("read bytes", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 9}
|
p := &fakePool{allocSize: 1 << 9}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("123"), 1<<12)
|
b, ok, err := r.ReadBytes([]byte("123"), 1<<12)
|
||||||
@ -122,7 +179,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("read utf8", func(t *testing.T) {
|
t.Run("read utf8", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
runes, n, err := r.ReadUTF8(1 << 12)
|
runes, n, err := r.ReadUTF8(1 << 12)
|
||||||
@ -145,7 +202,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("peek", func(t *testing.T) {
|
t.Run("peek", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, err := r.Peek(3 * 1 << 12)
|
b, err := r.Peek(3 * 1 << 12)
|
||||||
@ -164,7 +221,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("buffered", func(t *testing.T) {
|
t.Run("buffered", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b := r.Buffered()
|
b := r.Buffered()
|
||||||
@ -179,7 +236,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("write to", func(t *testing.T) {
|
t.Run("write to", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
|
|
||||||
@ -206,7 +263,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
t.Run("free", func(t *testing.T) {
|
t.Run("free", func(t *testing.T) {
|
||||||
t.Run("read", func(t *testing.T) {
|
t.Run("read", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b := make([]byte, 1<<9)
|
b := make([]byte, 1<<9)
|
||||||
@ -232,7 +289,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("read bytes", func(t *testing.T) {
|
t.Run("read bytes", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
_, _, err := r.ReadBytes([]byte("123"), 1<<15+3)
|
_, _, err := r.ReadBytes([]byte("123"), 1<<15+3)
|
||||||
@ -256,7 +313,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("read utf8", func(t *testing.T) {
|
t.Run("read utf8", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
for {
|
for {
|
||||||
@ -285,7 +342,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("peek", func(t *testing.T) {
|
t.Run("peek", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, err := r.Peek(3 * 1 << 12)
|
b, err := r.Peek(3 * 1 << 12)
|
||||||
@ -328,7 +385,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("buffered", func(t *testing.T) {
|
t.Run("buffered", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b := r.Buffered()
|
b := r.Buffered()
|
||||||
@ -343,7 +400,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("write to", func(t *testing.T) {
|
t.Run("write to", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1 << 12}
|
p := &fakePool{allocSize: 1 << 12}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
|
|
||||||
@ -374,7 +431,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
t.Run("null segment", func(t *testing.T) {
|
t.Run("null segment", func(t *testing.T) {
|
||||||
t.Run("read", func(t *testing.T) {
|
t.Run("read", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 12,
|
allocSize: 1 << 12,
|
||||||
zeroAfter: []int{0},
|
zeroAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -390,7 +447,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("read bytes", func(t *testing.T) {
|
t.Run("read bytes", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 9,
|
allocSize: 1 << 9,
|
||||||
zeroAfter: []int{1},
|
zeroAfter: []int{1},
|
||||||
}
|
}
|
||||||
@ -410,7 +467,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("read utf8", func(t *testing.T) {
|
t.Run("read utf8", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 12,
|
allocSize: 1 << 12,
|
||||||
zeroAfter: []int{0},
|
zeroAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -425,7 +482,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("peek", func(t *testing.T) {
|
t.Run("peek", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 12,
|
allocSize: 1 << 12,
|
||||||
zeroAfter: []int{0},
|
zeroAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -440,7 +497,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("write to", func(t *testing.T) {
|
t.Run("write to", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 12,
|
allocSize: 1 << 12,
|
||||||
zeroAfter: []int{0},
|
zeroAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -465,7 +522,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
customContent: map[int][]byte{1 << 11: []byte("123")},
|
customContent: map[int][]byte{1 << 11: []byte("123")},
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pool{varyingSize: []int{8, 256}}
|
p := &fakePool{varyingSize: []int{8, 256}}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
||||||
@ -484,7 +541,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("find not", func(t *testing.T) {
|
t.Run("find not", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{varyingSize: []int{8, 256}}
|
p := &fakePool{varyingSize: []int{8, 256}}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
||||||
@ -504,7 +561,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("peek", func(t *testing.T) {
|
t.Run("peek", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{varyingSize: []int{8, 256}}
|
p := &fakePool{varyingSize: []int{8, 256}}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, err := r.Peek(1 << 11)
|
b, err := r.Peek(1 << 11)
|
||||||
@ -521,7 +578,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
t.Run("one byte segments", func(t *testing.T) {
|
t.Run("one byte segments", func(t *testing.T) {
|
||||||
t.Run("read", func(t *testing.T) {
|
t.Run("read", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1}
|
p := &fakePool{allocSize: 1}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, err := io.ReadAll(r)
|
b, err := io.ReadAll(r)
|
||||||
@ -542,7 +599,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
customContent: map[int][]byte{1 << 11: []byte("123")},
|
customContent: map[int][]byte{1 << 11: []byte("123")},
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pool{allocSize: 1}
|
p := &fakePool{allocSize: 1}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
||||||
@ -561,7 +618,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("find not", func(t *testing.T) {
|
t.Run("find not", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1}
|
p := &fakePool{allocSize: 1}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
b, ok, err := r.ReadBytes([]byte("123"), 1<<15)
|
||||||
@ -585,7 +642,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
rng: utf8W2Range,
|
rng: utf8W2Range,
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pool{allocSize: 1}
|
p := &fakePool{allocSize: 1}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
runes, n, err := r.ReadUTF8(1 << 14)
|
runes, n, err := r.ReadUTF8(1 << 14)
|
||||||
@ -604,7 +661,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("peek", func(t *testing.T) {
|
t.Run("peek", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1}
|
p := &fakePool{allocSize: 1}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
b, err := r.Peek(1 << 14)
|
b, err := r.Peek(1 << 14)
|
||||||
@ -619,7 +676,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("write to", func(t *testing.T) {
|
t.Run("write to", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{allocSize: 1}
|
p := &fakePool{allocSize: 1}
|
||||||
o := buffer.Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := cr(g, o)
|
r := cr(g, o)
|
||||||
|
|
||||||
@ -642,7 +699,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
t.Run("pool error on allocate", func(t *testing.T) {
|
t.Run("pool error on allocate", func(t *testing.T) {
|
||||||
t.Run("read", func(t *testing.T) {
|
t.Run("read", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -662,7 +719,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
t.Run("read bytes", func(t *testing.T) {
|
t.Run("read bytes", func(t *testing.T) {
|
||||||
t.Run("immediate", func(t *testing.T) {
|
t.Run("immediate", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -685,7 +742,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("on grow", func(t *testing.T) {
|
t.Run("on grow", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
@ -726,7 +783,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
rng: utf8W2Range,
|
rng: utf8W2Range,
|
||||||
}
|
}
|
||||||
|
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -750,7 +807,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
t.Run("peek", func(t *testing.T) {
|
t.Run("peek", func(t *testing.T) {
|
||||||
t.Run("immediate", func(t *testing.T) {
|
t.Run("immediate", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
@ -769,7 +826,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("on grow", func(t *testing.T) {
|
t.Run("on grow", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
@ -811,7 +868,7 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("write to", func(t *testing.T) {
|
t.Run("write to", func(t *testing.T) {
|
||||||
g := &gen{max: 1 << 15}
|
g := &gen{max: 1 << 15}
|
||||||
p := &pool{
|
p := &fakePool{
|
||||||
allocSize: 1 << 11,
|
allocSize: 1 << 11,
|
||||||
errAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -437,6 +437,58 @@ func TestReadBytes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("single char delimiter", func(t *testing.T) {
|
||||||
|
g := &gen{
|
||||||
|
max: 1 << 15,
|
||||||
|
customContentAfter: []int{12},
|
||||||
|
customContent: map[int][]byte{12: []byte("1")},
|
||||||
|
}
|
||||||
|
|
||||||
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
||||||
|
r := cr(g, o)
|
||||||
|
b, ok, err := r.ReadBytes([]byte{'1'}, 64)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("delimiter")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(b, append(generate(12), '1')) {
|
||||||
|
t.Fatal("failed to generate right content")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("large delimiter", func(t *testing.T) {
|
||||||
|
src := &gen{
|
||||||
|
max: 1 << 18,
|
||||||
|
customContentAfter: []int{1<<17 - 3},
|
||||||
|
customContent: map[int][]byte{1<<17 - 3: []byte("123")},
|
||||||
|
}
|
||||||
|
|
||||||
|
r := buffer.BufferedReader(src, buffer.Options{Pool: buffer.NoPool(1 << 12)})
|
||||||
|
r.ReadBytes([]byte{'1'}, 1<<17+1<<16)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("delimiter longer than content", func(t *testing.T) {
|
||||||
|
g := &gen{max: 1 << 9}
|
||||||
|
o := buffer.Options{Pool: buffer.NoPool(16)}
|
||||||
|
r := cr(g, o)
|
||||||
|
b, ok, err := r.ReadBytes(generate(1<<10), 1<<11)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
t.Fatal("delimiter")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(b, generate(1<<9)) {
|
||||||
|
t.Fatal("content")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("find not none consumed", func(t *testing.T) {
|
t.Run("find not none consumed", func(t *testing.T) {
|
||||||
g := &gen{}
|
g := &gen{}
|
||||||
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
o := buffer.Options{Pool: buffer.NoPool(1 << 12)}
|
||||||
|
|||||||
@ -225,8 +225,11 @@ func (r *reader) fillToDelimiter(delimiter []byte, max int) (int, bool) {
|
|||||||
m, c := match(d, r.segments[seg][first:last])
|
m, c := match(d, r.segments[seg][first:last])
|
||||||
if !m {
|
if !m {
|
||||||
i += 1 - len(delimiter) + len(d)
|
i += 1 - len(delimiter) + len(d)
|
||||||
seg, segStart = r.findSegmentDown(i)
|
|
||||||
d = delimiter
|
d = delimiter
|
||||||
|
if i < r.len {
|
||||||
|
seg, segStart = r.findSegmentDown(i)
|
||||||
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user