@@ -13,6 +13,7 @@ import (
1313 "fmt"
1414 "io"
1515 "math"
16+ "sync"
1617)
1718
1819var _ ValueReader = & valueReader {}
@@ -29,13 +30,30 @@ 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 {
34- r * bufio.Reader
35- offset int64
49+ r * bufio.Reader
50+ ra io. ReaderAt // The underlying reader
3651
37- stack []vrState
38- frame int64
52+ poolReader bool // Set if r is from bufioReaderPool
53+
54+ offset int64
55+ stack []vrState
56+ frame int64
3957}
4058
4159// NewDocumentReader returns a ValueReader using b for the underlying BSON
@@ -57,14 +75,33 @@ func newValueReader(t Type, r io.Reader) ValueReader {
5775}
5876
5977func newDocumentReader (r io.Reader ) * valueReader {
60- stack := make ([]vrState , 1 , 5 )
61- stack [0 ] = vrState {
62- mode : mTopLevel ,
63- }
64- return & valueReader {
65- r : bufio .NewReader (r ),
66- stack : stack ,
78+ vr := vrPool .Get ().(* valueReader )
79+
80+ vr .offset = 0
81+ vr .frame = 0
82+ vr .poolReader = true
83+
84+ vr .stack = vr .stack [:1 ]
85+ vr .stack [0 ].mode = mTopLevel
86+
87+ br := bufioReaderPool .Get ().(* bufio.Reader )
88+ br .Reset (r )
89+ vr .r = br
90+
91+ return vr
92+ }
93+
94+ func releaseDocumentReader (vr * valueReader ) {
95+ if ! vr .poolReader {
96+ return
6797 }
98+
99+ bufioReaderPool .Put (vr .r )
100+ vr .r = nil
101+ vr .poolReader = false
102+
103+ vr .ra = nil
104+ vrPool .Put (vr )
68105}
69106
70107func (vr * valueReader ) advanceFrame () {
@@ -253,14 +290,18 @@ func (vr *valueReader) appendNextElement(dst []byte) ([]byte, error) {
253290 return nil , err
254291 }
255292
256- buf := make ([]byte , length )
257- _ , err = io .ReadFull (vr .r , buf )
293+ buf , err := vr .r .Peek (int (length ))
258294 if err != nil {
259295 return nil , err
260296 }
297+
261298 dst = append (dst , buf ... )
262- vr .offset += int64 (len (buf ))
263- return dst , err
299+ if _ , err = vr .r .Discard (int (length )); err != nil {
300+ return nil , err
301+ }
302+
303+ vr .offset += int64 (length )
304+ return dst , nil
264305}
265306
266307func (vr * valueReader ) readValueBytes (dst []byte ) (Type , []byte , error ) {
0 commit comments