Skip to content

Commit ab769a4

Browse files
committed
Merge pull request #90 from go-sql-driver/buffer
Buffer optimizations
2 parents 55a708b + b494bac commit ab769a4

File tree

1 file changed

+12
-22
lines changed

1 file changed

+12
-22
lines changed

buffer.go

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import "io"
1313

1414
const defaultBufSize = 4096
1515

16+
// A read buffer similar to bufio.Reader but zero-copy-ish
17+
// Also highly optimized for this particular use case.
1618
type buffer struct {
1719
buf []byte
1820
rd io.Reader
@@ -36,43 +38,31 @@ func (b *buffer) fill(need int) (err error) {
3638

3739
// grow buffer if necessary
3840
if need > len(b.buf) {
39-
b.grow(need)
41+
for {
42+
b.buf = append(b.buf, 0)
43+
b.buf = b.buf[:cap(b.buf)]
44+
45+
if cap(b.buf) >= need {
46+
break
47+
}
48+
}
4049
}
4150

4251
b.idx = 0
4352

4453
var n int
45-
for b.length < need {
54+
for {
4655
n, err = b.rd.Read(b.buf[b.length:])
4756
b.length += n
4857

49-
if err == nil {
58+
if b.length < need && err == nil {
5059
continue
5160
}
5261
return // err
5362
}
54-
5563
return
5664
}
5765

58-
// grow the buffer to at least the given size
59-
// credit for this code snippet goes to Maxim Khitrov
60-
// https://groups.google.com/forum/#!topic/golang-nuts/ETbw1ECDgRs
61-
func (b *buffer) grow(size int) {
62-
// If append would be too expensive, alloc a new slice
63-
if size > 2*cap(b.buf) {
64-
newBuf := make([]byte, size)
65-
copy(newBuf, b.buf)
66-
b.buf = newBuf
67-
return
68-
}
69-
70-
for cap(b.buf) < size {
71-
b.buf = append(b.buf[:cap(b.buf)], 0)
72-
}
73-
b.buf = b.buf[:cap(b.buf)]
74-
}
75-
7666
// returns next N bytes from buffer.
7767
// The returned slice is only guaranteed to be valid until the next read
7868
func (b *buffer) readNext(need int) (p []byte, err error) {

0 commit comments

Comments
 (0)