@@ -13,6 +13,7 @@ import (
1313 "fmt"
1414 "io"
1515 "math"
16+ "sync"
1617)
1718
1819var _ ValueReader = & valueReader {}
@@ -29,6 +30,20 @@ type vrState struct {
2930 end int64
3031}
3132
33+ var bufioReaderPool = sync.Pool {
34+ New : func () interface {} {
35+ return bufio .NewReader (nil )
36+ },
37+ }
38+
39+ var vrPool = sync.Pool {
40+ New : func () interface {} {
41+ return & valueReader {
42+ stack : make ([]vrState , 1 , 5 ),
43+ }
44+ },
45+ }
46+
3247// valueReader is for reading BSON values.
3348type valueReader struct {
3449 r * bufio.Reader
@@ -38,6 +53,33 @@ type valueReader struct {
3853 frame int64
3954}
4055
56+ func getDocumentReader (r io.Reader ) * valueReader {
57+ vr := vrPool .Get ().(* valueReader )
58+
59+ vr .offset = 0
60+ vr .frame = 0
61+
62+ vr .stack = vr .stack [:1 ]
63+ vr .stack [0 ] = vrState {mode : mTopLevel }
64+
65+ br := bufioReaderPool .Get ().(* bufio.Reader )
66+ br .Reset (r )
67+ vr .r = br
68+
69+ return vr
70+ }
71+
72+ func putDocumentReader (vr * valueReader ) {
73+ if vr == nil {
74+ return
75+ }
76+
77+ bufioReaderPool .Put (vr .r )
78+ vr .r = nil
79+
80+ vrPool .Put (vr )
81+ }
82+
4183// NewDocumentReader returns a ValueReader using b for the underlying BSON
4284// representation.
4385func NewDocumentReader (r io.Reader ) ValueReader {
@@ -253,14 +295,28 @@ func (vr *valueReader) appendNextElement(dst []byte) ([]byte, error) {
253295 return nil , err
254296 }
255297
256- buf := make ([]byte , length )
257- _ , err = io .ReadFull (vr .r , buf )
298+ buf , err := vr .r .Peek (int (length ))
258299 if err != nil {
300+ if err == bufio .ErrBufferFull {
301+ temp := make ([]byte , length )
302+ if _ , err = io .ReadFull (vr .r , temp ); err != nil {
303+ return nil , err
304+ }
305+ dst = append (dst , temp ... )
306+ vr .offset += int64 (len (temp ))
307+ return dst , nil
308+ }
309+
259310 return nil , err
260311 }
312+
261313 dst = append (dst , buf ... )
262- vr .offset += int64 (len (buf ))
263- return dst , err
314+ if _ , err = vr .r .Discard (int (length )); err != nil {
315+ return nil , err
316+ }
317+
318+ vr .offset += int64 (length )
319+ return dst , nil
264320}
265321
266322func (vr * valueReader ) readValueBytes (dst []byte ) (Type , []byte , error ) {
0 commit comments