provide default pool
This commit is contained in:
parent
83801867f4
commit
40e4c067d0
137
content_test.go
137
content_test.go
@ -1,40 +1,15 @@
|
|||||||
package buffer
|
package buffer_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"code.squareroundforest.org/arpio/buffer"
|
||||||
"io"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type testPool struct {
|
|
||||||
size int
|
|
||||||
failAfter []int
|
|
||||||
count int
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
errTest = errors.New("test error")
|
|
||||||
errTest2 = errors.New("test error 2")
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *testPool) Get() ([]byte, error) {
|
|
||||||
defer func() {
|
|
||||||
p.count++
|
|
||||||
}()
|
|
||||||
|
|
||||||
if len(p.failAfter) > 0 && p.count == p.failAfter[0] {
|
|
||||||
p.failAfter = p.failAfter[1:]
|
|
||||||
return nil, errTest
|
|
||||||
}
|
|
||||||
|
|
||||||
return make([]byte, p.size), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *testPool) Put([]byte) {}
|
|
||||||
|
|
||||||
func TestContent(t *testing.T) {
|
func TestContent(t *testing.T) {
|
||||||
t.Run("eof", func(t *testing.T) {
|
t.Run("eof", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
var n int64
|
var n int64
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
||||||
@ -47,9 +22,9 @@ func TestContent(t *testing.T) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 2}
|
p := &pool{allocSize: 2}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
@ -69,13 +44,13 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("eof right away", func(t *testing.T) {
|
t.Run("eof right away", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 2}
|
p := &pool{allocSize: 2}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
if n != 0 || !errors.Is(err, io.EOF) {
|
if n != 0 || !errors.Is(err, io.EOF) {
|
||||||
@ -84,7 +59,7 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("writer error", func(t *testing.T) {
|
t.Run("writer error", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
var n int64
|
var n int64
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
||||||
@ -97,9 +72,9 @@ func TestContent(t *testing.T) {
|
|||||||
return n, errTest
|
return n, errTest
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 2}
|
p := &pool{allocSize: 2}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
@ -119,13 +94,13 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("writer error right away", func(t *testing.T) {
|
t.Run("writer error right away", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
return 0, errTest
|
return 0, errTest
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 2}
|
p := &pool{allocSize: 2}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
if n != 0 || !errors.Is(err, errTest) {
|
if n != 0 || !errors.Is(err, errTest) {
|
||||||
@ -134,7 +109,7 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("abort", func(t *testing.T) {
|
t.Run("abort", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
var n int64
|
var n int64
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
||||||
@ -147,13 +122,13 @@ func TestContent(t *testing.T) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{
|
p := &pool{
|
||||||
size: 2,
|
allocSize: 2,
|
||||||
failAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
|
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
||||||
if string(b) != "12" /* segment size og 2 by the pool */ || ok || err != nil {
|
if string(b) != "12" /* segment size og 2 by the pool */ || ok || err != nil {
|
||||||
t.Fatal(string(b), ok, err)
|
t.Fatal(string(b), ok, err)
|
||||||
@ -166,7 +141,7 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("abort right away", func(t *testing.T) {
|
t.Run("abort right away", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
var n int64
|
var n int64
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
||||||
@ -179,13 +154,13 @@ func TestContent(t *testing.T) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{
|
p := &pool{
|
||||||
size: 2,
|
allocSize: 2,
|
||||||
failAfter: []int{0},
|
errAfter: []int{0},
|
||||||
}
|
}
|
||||||
|
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
||||||
if len(b) != 0 || ok || !errors.Is(err, errTest) {
|
if len(b) != 0 || ok || !errors.Is(err, errTest) {
|
||||||
t.Fatal(string(b), ok, err)
|
t.Fatal(string(b), ok, err)
|
||||||
@ -193,20 +168,20 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("close when implementation ignores writer errors", func(t *testing.T) {
|
t.Run("close when implementation ignores writer errors", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
w.Write([]byte("123"))
|
w.Write([]byte("123"))
|
||||||
w.Write([]byte("456"))
|
w.Write([]byte("456"))
|
||||||
w.Write([]byte("123"))
|
w.Write([]byte("123"))
|
||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{
|
p := &pool{
|
||||||
size: 2,
|
allocSize: 2,
|
||||||
failAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
|
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
||||||
if string(b) != "12" /* segment size og 2 by the pool */ || ok || err != nil {
|
if string(b) != "12" /* segment size og 2 by the pool */ || ok || err != nil {
|
||||||
t.Fatal(string(b), ok, err)
|
t.Fatal(string(b), ok, err)
|
||||||
@ -219,7 +194,7 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("zero write", func(t *testing.T) {
|
t.Run("zero write", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
w.Write([]byte("123"))
|
w.Write([]byte("123"))
|
||||||
w.Write(nil)
|
w.Write(nil)
|
||||||
w.Write([]byte("456"))
|
w.Write([]byte("456"))
|
||||||
@ -227,9 +202,9 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 2}
|
p := &pool{allocSize: 2}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
@ -249,7 +224,7 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("zero write right away", func(t *testing.T) {
|
t.Run("zero write right away", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
w.Write(nil)
|
w.Write(nil)
|
||||||
w.Write([]byte("123"))
|
w.Write([]byte("123"))
|
||||||
w.Write([]byte("456"))
|
w.Write([]byte("456"))
|
||||||
@ -257,9 +232,9 @@ func TestContent(t *testing.T) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 2}
|
p := &pool{allocSize: 2}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
@ -279,7 +254,7 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("custom error", func(t *testing.T) {
|
t.Run("custom error", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
var n int64
|
var n int64
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
ni, err := w.Write([]byte("123456789")[i*3 : i*3+3])
|
||||||
@ -292,9 +267,9 @@ func TestContent(t *testing.T) {
|
|||||||
return n, errTest
|
return n, errTest
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{size: 3}
|
p := &pool{allocSize: 3}
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b := make([]byte, 3)
|
b := make([]byte, 3)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
n, err := r.Read(b)
|
n, err := r.Read(b)
|
||||||
@ -314,20 +289,20 @@ func TestContent(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("custom error with pool error", func(t *testing.T) {
|
t.Run("custom error with pool error", func(t *testing.T) {
|
||||||
c := ContentFunc(func(w io.Writer) (int64, error) {
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
w.Write([]byte("123"))
|
w.Write([]byte("123"))
|
||||||
w.Write([]byte("456"))
|
w.Write([]byte("456"))
|
||||||
w.Write([]byte("123"))
|
w.Write([]byte("123"))
|
||||||
return 0, errTest2
|
return 0, errTest2
|
||||||
})
|
})
|
||||||
|
|
||||||
p := &testPool{
|
p := &pool{
|
||||||
size: 2,
|
allocSize: 2,
|
||||||
failAfter: []int{1},
|
errAfter: []int{1},
|
||||||
}
|
}
|
||||||
|
|
||||||
o := Options{Pool: p}
|
o := buffer.Options{Pool: p}
|
||||||
r := BufferedContent(c, o)
|
r := buffer.BufferedContent(c, o)
|
||||||
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
b, ok, err := r.ReadBytes([]byte("67"), 12)
|
||||||
if string(b) != "12" /* segment size og 2 by the pool */ || ok || err != nil {
|
if string(b) != "12" /* segment size og 2 by the pool */ || ok || err != nil {
|
||||||
t.Fatal(string(b), ok, err)
|
t.Fatal(string(b), ok, err)
|
||||||
|
|||||||
@ -30,6 +30,7 @@ var (
|
|||||||
utf8Range = []byte("aábéícóöődúüeű")
|
utf8Range = []byte("aábéícóöődúüeű")
|
||||||
utf8W2Range = []byte("áéíóöőúüű")
|
utf8W2Range = []byte("áéíóöőúüű")
|
||||||
errTest = errors.New("test error")
|
errTest = errors.New("test error")
|
||||||
|
errTest2 = errors.New("test error 2")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *gen) Read(p []byte) (int, error) {
|
func (g *gen) Read(p []byte) (int, error) {
|
||||||
|
|||||||
8
lib.go
8
lib.go
@ -33,8 +33,8 @@ var (
|
|||||||
ErrContentAbort = errors.New("content pipe aborted")
|
ErrContentAbort = errors.New("content pipe aborted")
|
||||||
)
|
)
|
||||||
|
|
||||||
func DefaultPool() Pool {
|
func DefaultPool(allocSize int) Pool {
|
||||||
return newPool()
|
return newPool(allocSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NoPool(allocSize int) Pool {
|
func NoPool(allocSize int) Pool {
|
||||||
@ -52,7 +52,7 @@ func BufferedReader(in io.Reader, o Options) Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.Pool == nil {
|
if o.Pool == nil {
|
||||||
o.Pool = DefaultPool()
|
o.Pool = DefaultPool(1 << 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Reader{reader: &reader{options: o, in: in}}
|
return Reader{reader: &reader{options: o, in: in}}
|
||||||
@ -70,7 +70,7 @@ func BufferedContent(c io.WriterTo, o Options) Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if o.Pool == nil {
|
if o.Pool == nil {
|
||||||
o.Pool = DefaultPool()
|
o.Pool = DefaultPool(1 << 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Reader{reader: &reader{options: o, in: mkcontent(c)}}
|
return Reader{reader: &reader{options: o, in: mkcontent(c)}}
|
||||||
|
|||||||
152
lib_test.go
Normal file
152
lib_test.go
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package buffer_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"code.squareroundforest.org/arpio/buffer"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLib(t *testing.T) {
|
||||||
|
t.Run("default pool", func(t *testing.T) {
|
||||||
|
t.Run("buffered reader", func(t *testing.T) {
|
||||||
|
g := &gen{max: 1 << 18}
|
||||||
|
r := buffer.BufferedReader(g, buffer.Options{})
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(b, generate(1<<18)) {
|
||||||
|
t.Fatal("output does not match", len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("buffered content", func(t *testing.T) {
|
||||||
|
c := buffer.ContentFunc(func(w io.Writer) (int64, error) {
|
||||||
|
g := &gen{max: 1 << 18}
|
||||||
|
return io.Copy(w, g)
|
||||||
|
})
|
||||||
|
|
||||||
|
r := buffer.BufferedContent(c, buffer.Options{})
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(b, generate(1<<18)) {
|
||||||
|
t.Fatal("output does not match", len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("zero reader", func(t *testing.T) {
|
||||||
|
t.Run("buffered reader", func(t *testing.T) {
|
||||||
|
r := buffer.BufferedReader(nil, buffer.Options{})
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b) != 0 {
|
||||||
|
t.Fatal("output does not match", len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("buffered content", func(t *testing.T) {
|
||||||
|
r := buffer.BufferedContent(nil, buffer.Options{})
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b) != 0 {
|
||||||
|
t.Fatal("output does not match", len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("uninitialized reader", func(t *testing.T) {
|
||||||
|
t.Run("read", func(t *testing.T) {
|
||||||
|
var r buffer.Reader
|
||||||
|
p := make([]byte, 512)
|
||||||
|
n, err := r.Read(p)
|
||||||
|
if !errors.Is(err, io.EOF) {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != 0 {
|
||||||
|
t.Fatal(n)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("read bytes", func(t *testing.T) {
|
||||||
|
var r buffer.Reader
|
||||||
|
b, ok, err := r.ReadBytes([]byte("123"), 512)
|
||||||
|
if !errors.Is(err, io.EOF) {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
t.Fatal(ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b) != 0 {
|
||||||
|
t.Fatal(len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("read utf8", func(t *testing.T) {
|
||||||
|
var r buffer.Reader
|
||||||
|
runes, n, err := r.ReadUTF8(512)
|
||||||
|
if !errors.Is(err, io.EOF) {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != 0 {
|
||||||
|
t.Fatal(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(runes) != 0 {
|
||||||
|
t.Fatal(len(runes))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("peek", func(t *testing.T) {
|
||||||
|
var r buffer.Reader
|
||||||
|
b, err := r.Peek(512)
|
||||||
|
if !errors.Is(err, io.EOF) {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(b) != 0 {
|
||||||
|
t.Fatal(len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("buffered", func(t *testing.T) {
|
||||||
|
var r buffer.Reader
|
||||||
|
b := r.Buffered()
|
||||||
|
if len(b) != 0 {
|
||||||
|
t.Fatal(len(b))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("write to", func(t *testing.T) {
|
||||||
|
var (
|
||||||
|
r buffer.Reader
|
||||||
|
b bytes.Buffer
|
||||||
|
)
|
||||||
|
|
||||||
|
n, err := r.WriteTo(&b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if n != 0 {
|
||||||
|
t.Fatal(n)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
19
pool.go
19
pool.go
@ -1,13 +1,23 @@
|
|||||||
package buffer
|
package buffer
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
type noPool struct {
|
type noPool struct {
|
||||||
allocSize int
|
allocSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
type pool struct{}
|
type pool struct {
|
||||||
|
sp *sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
func newPool() *pool {
|
func newPool(allocSize int) *pool {
|
||||||
return &pool{}
|
sp := &sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return make([]byte, allocSize)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pool{sp: sp}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p noPool) Get() ([]byte, error) {
|
func (p noPool) Get() ([]byte, error) {
|
||||||
@ -18,8 +28,9 @@ func (noPool) Put([]byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) Get() ([]byte, error) {
|
func (p *pool) Get() ([]byte, error) {
|
||||||
return nil, nil
|
return p.sp.Get().([]byte), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pool) Put(b []byte) {
|
func (p *pool) Put(b []byte) {
|
||||||
|
p.sp.Put(b)
|
||||||
}
|
}
|
||||||
|
|||||||
13
pool_test.go
13
pool_test.go
@ -836,3 +836,16 @@ func TestPoolUsage(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultPool(t *testing.T) {
|
||||||
|
g := &gen{max: 1 << 18}
|
||||||
|
r := buffer.BufferedReader(g, buffer.Options{})
|
||||||
|
b, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(b, generate(1<<18)) {
|
||||||
|
t.Fatal("output does not match", len(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user