Skip to content

Commit 7bb7017

Browse files
committed
proto: adaptive reusable buffer for scanner
1 parent a1c3e8a commit 7bb7017

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

proto/scanner.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
package proto
22

3-
import "io"
3+
import (
4+
"bufio"
5+
"io"
6+
)
47

5-
type BytesReader interface {
6-
ReadBytes(byte) ([]byte, error)
8+
type ReadSlicer interface {
9+
ReadSlice(byte) ([]byte, error)
710
}
811

912
type ElasticLineScanner struct {
1013
line []byte
11-
reader BytesReader
14+
reader ReadSlicer
1215
lastErr error
1316
done bool
1417
delim byte
1518
}
1619

17-
func NewElasticLineScanner(reader BytesReader, delim byte) *ElasticLineScanner {
20+
func NewElasticLineScanner(reader ReadSlicer, delim byte) *ElasticLineScanner {
1821
return &ElasticLineScanner{
1922
reader: reader,
2023
delim: delim,
@@ -37,19 +40,28 @@ func (els *ElasticLineScanner) Scan() bool {
3740
return false
3841
}
3942

40-
data, err := els.reader.ReadBytes(els.delim)
43+
els.line = els.line[:0]
44+
var (
45+
data []byte
46+
err error
47+
)
48+
for data, err = els.reader.ReadSlice(els.delim); ; data, err = els.reader.ReadSlice(els.delim) {
49+
els.line = append(els.line, data...)
50+
if err != bufio.ErrBufferFull {
51+
break
52+
}
53+
}
4154
if err != nil {
4255
els.done = true
4356
els.lastErr = err
44-
if len(data) == 0 {
57+
if len(els.line) == 0 {
4558
return false
4659
}
4760
} else {
4861
// strip delimiter if needed
49-
if len(data) > 0 && data[len(data)-1] == els.delim {
50-
data = data[:len(data)-1]
62+
if len(els.line) > 0 && els.line[len(els.line)-1] == els.delim {
63+
els.line = els.line[:len(els.line)-1]
5164
}
5265
}
53-
els.line = data
5466
return true
5567
}

0 commit comments

Comments
 (0)