Skip to content

Commit 2c89e53

Browse files
authored
Reuse buffer after read (#15)
* Reuse buffer after read Instead of waiting for the next Read, send back the buffer after read if no longer used. * Test with race * Add defaults as constants.
1 parent 6fcab83 commit 2c89e53

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

.github/workflows/go.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ jobs:
2727
- name: Test
2828
run: go test ./...
2929

30-
- name: Test Noasm
31-
run: go test -tags=noasm ./...
30+
- name: Test Race
31+
run: go test -race -cpu=1,4,8 ./...
3232

3333
build-special:
3434
env:
@@ -47,4 +47,4 @@ jobs:
4747
run: diff <(gofmt -d .) <(printf "")
4848

4949
- name: Test 386
50-
run: GOOS=linux GOARCH=386 go test -short ./...
50+
run: GOOS=linux GOARCH=386 go test ./...

reader.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ import (
1919
"io"
2020
)
2121

22+
const (
23+
// DefaultBuffers is the default number of buffers used.
24+
DefaultBuffers = 4
25+
26+
// DefaultBufferSize is the default buffer size, 1 MB.
27+
DefaultBufferSize = 1 << 20
28+
)
29+
2230
type seekable struct {
2331
*reader
2432
}
@@ -57,7 +65,7 @@ func NewReader(rd io.Reader) io.ReadCloser {
5765
return nil
5866
}
5967

60-
ret, err := NewReaderSize(rd, 4, 1<<20)
68+
ret, err := NewReaderSize(rd, DefaultBuffers, DefaultBufferSize)
6169

6270
// Should not be possible to trigger from other packages.
6371
if err != nil {
@@ -82,7 +90,7 @@ func NewReadCloser(rd io.ReadCloser) io.ReadCloser {
8290
return nil
8391
}
8492

85-
ret, err := NewReadCloserSize(rd, 4, 1<<20)
93+
ret, err := NewReadCloserSize(rd, DefaultBuffers, DefaultBufferSize)
8694

8795
// Should not be possible to trigger from other packages.
8896
if err != nil {
@@ -145,6 +153,7 @@ func NewReaderSize(rd io.Reader, buffers, size int) (res io.ReadCloser, err erro
145153

146154
// NewReaderBuffer returns a reader with a custom number of buffers and size.
147155
// All buffers must be the same size.
156+
// Buffers can be reused after Close has been called.
148157
func NewReaderBuffer(rd io.Reader, buffers [][]byte) (res io.ReadCloser, err error) {
149158
if len(buffers) == 0 {
150159
return nil, fmt.Errorf("number of buffers too small")
@@ -200,6 +209,7 @@ func NewReadCloserSize(rc io.ReadCloser, buffers, size int) (res io.ReadCloser,
200209

201210
// NewReadCloserBuffer returns a reader with a custom number of buffers and size.
202211
// All buffers must be the same size.
212+
// Buffers can be reused after Close has been called.
203213
func NewReadCloserBuffer(rc io.ReadCloser, buffers [][]byte) (res io.ReadCloser, err error) {
204214
if len(buffers) == 0 {
205215
return nil, fmt.Errorf("number of buffers too small")
@@ -258,6 +268,7 @@ func NewReadSeekCloserSize(rd ReadSeekCloser, buffers, size int) (res ReadSeekCl
258268

259269
// NewReadSeekCloserBuffer returns a reader with a custom number of buffers and size.
260270
// All buffers must be the same size.
271+
// Buffers can be reused after Close has been called.
261272
func NewReadSeekCloserBuffer(rd ReadSeekCloser, buffers [][]byte) (res ReadSeekCloser, err error) {
262273
reader, err := NewReadCloserBuffer(rd, buffers)
263274
if err != nil {
@@ -293,7 +304,7 @@ func (a *reader) initBuffers(rd io.Reader, buffers [][]byte, size int) {
293304

294305
// Create buffers
295306
for _, buf := range buffers {
296-
a.reuse <- newBufferBuf(buf)
307+
a.reuse <- newBuffer(buf)
297308
}
298309

299310
// Start async reader
@@ -351,9 +362,14 @@ func (a *reader) Read(p []byte) (n int, err error) {
351362
n = copy(p, a.cur.buffer())
352363
a.cur.inc(n)
353364

354-
// If at end of buffer, return any error, if present
355365
if a.cur.isEmpty() {
356-
a.err = a.cur.err
366+
// Return current, so a fetch can start.
367+
if a.cur != nil {
368+
// If at end of buffer, return any error, if present
369+
a.err = a.cur.err
370+
a.reuse <- a.cur
371+
a.cur = nil
372+
}
357373
return n, a.err
358374
}
359375
return n, nil
@@ -446,11 +462,7 @@ type buffer struct {
446462
size int
447463
}
448464

449-
func newBuffer(size int) *buffer {
450-
return &buffer{buf: make([]byte, size), err: nil, size: size}
451-
}
452-
453-
func newBufferBuf(buf []byte) *buffer {
465+
func newBuffer(buf []byte) *buffer {
454466
return &buffer{buf: buf, err: nil, size: len(buf)}
455467
}
456468

0 commit comments

Comments
 (0)