Skip to content

Commit 39571cc

Browse files
committed
Improves performance
1 parent 97bbed8 commit 39571cc

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

internal/proto/reader.go

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,10 @@ func (r *Reader) Reset(rd io.Reader) {
5555
}
5656

5757
func (r *Reader) ReadLine() ([]byte, error) {
58-
line, err := r.rd.ReadBytes('\n')
59-
if err != nil && err != io.EOF {
58+
line, err := r.readLine()
59+
if err != nil {
6060
return nil, err
6161
}
62-
if len(line) == 0 {
63-
return nil, fmt.Errorf("redis: reply is empty")
64-
}
6562
if isNilReply(line) {
6663
return nil, Nil
6764
}
@@ -72,15 +69,29 @@ func (r *Reader) ReadLine() ([]byte, error) {
7269
// - there is a pending read error;
7370
// - or line does not end with \r\n.
7471
func (r *Reader) readLine() ([]byte, error) {
75-
b, err := r.rd.ReadSlice('\n')
76-
if err != nil {
77-
return nil, err
78-
}
79-
if len(b) <= 2 || b[len(b)-1] != '\n' || b[len(b)-2] != '\r' {
80-
return nil, fmt.Errorf("redis: invalid reply: %q", b)
72+
var s []byte
73+
multi := false
74+
for {
75+
b, err := r.rd.ReadSlice('\n')
76+
if err != nil {
77+
// in case the end of the buffer is not reached
78+
if err == bufio.ErrBufferFull {
79+
s = append(s, b...)
80+
multi = true
81+
continue
82+
} else {
83+
return nil, err
84+
}
85+
}
86+
if len(b) <= 2 || b[len(b)-1] != '\n' || b[len(b)-2] != '\r' {
87+
return nil, fmt.Errorf("redis: invalid reply: %q", b)
88+
}
89+
if multi {
90+
b = append(s, b...)
91+
}
92+
b = b[:len(b)-2]
93+
return b, nil
8194
}
82-
b = b[:len(b)-2]
83-
return b, nil
8495
}
8596

8697
func (r *Reader) ReadReply(m MultiBulkParse) (interface{}, error) {

internal/proto/reader_test.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package proto_test
22

33
import (
44
"bytes"
5+
"io"
56
"testing"
67

78
"github.com/go-redis/redis/v8/internal/proto"
@@ -29,14 +30,16 @@ func BenchmarkReader_ParseReply_Slice(b *testing.B) {
2930

3031
func TestReader_ReadLine(t *testing.T) {
3132
original := bytes.Repeat([]byte("a"), 8192)
33+
original[len(original)-2] = '\r'
34+
original[len(original)-1] = '\n'
3235
r := proto.NewReader(bytes.NewReader(original))
3336
read, err := r.ReadLine()
34-
if err != nil {
37+
if err != nil && err != io.EOF {
3538
t.Errorf("Should be able to read the full buffer: %v", err)
3639
}
3740

38-
if bytes.Compare(read, original) != 0 {
39-
t.Errorf("Values must be equal: %q", read)
41+
if bytes.Compare(read, original[:len(original)-2]) != 0 {
42+
t.Errorf("Values must be equal: %d expected %d", len(read), len(original[:len(original)-2]))
4043
}
4144
}
4245

0 commit comments

Comments
 (0)