Procházet zdrojové kódy

Merge pull request #90 from go-sql-driver/buffer

Buffer optimizations
Julien Schmidt před 12 roky
rodič
revize
ab769a4b8a
1 změnil soubory, kde provedl 12 přidání a 22 odebrání
  1. 12 22
      buffer.go

+ 12 - 22
buffer.go

@@ -13,6 +13,8 @@ import "io"
 
 const defaultBufSize = 4096
 
+// A read buffer similar to bufio.Reader but zero-copy-ish
+// Also highly optimized for this particular use case.
 type buffer struct {
 	buf    []byte
 	rd     io.Reader
@@ -36,43 +38,31 @@ func (b *buffer) fill(need int) (err error) {
 
 	// grow buffer if necessary
 	if need > len(b.buf) {
-		b.grow(need)
+		for {
+			b.buf = append(b.buf, 0)
+			b.buf = b.buf[:cap(b.buf)]
+
+			if cap(b.buf) >= need {
+				break
+			}
+		}
 	}
 
 	b.idx = 0
 
 	var n int
-	for b.length < need {
+	for {
 		n, err = b.rd.Read(b.buf[b.length:])
 		b.length += n
 
-		if err == nil {
+		if b.length < need && err == nil {
 			continue
 		}
 		return // err
 	}
-
 	return
 }
 
-// grow the buffer to at least the given size
-// credit for this code snippet goes to Maxim Khitrov
-// https://groups.google.com/forum/#!topic/golang-nuts/ETbw1ECDgRs
-func (b *buffer) grow(size int) {
-	// If append would be too expensive, alloc a new slice
-	if size > 2*cap(b.buf) {
-		newBuf := make([]byte, size)
-		copy(newBuf, b.buf)
-		b.buf = newBuf
-		return
-	}
-
-	for cap(b.buf) < size {
-		b.buf = append(b.buf[:cap(b.buf)], 0)
-	}
-	b.buf = b.buf[:cap(b.buf)]
-}
-
 // returns next N bytes from buffer.
 // The returned slice is only guaranteed to be valid until the next read
 func (b *buffer) readNext(need int) (p []byte, err error) {