@@ -13,6 +13,7 @@ import (
13
13
"fmt"
14
14
"io"
15
15
"math"
16
+ "sync"
16
17
)
17
18
18
19
var _ ValueReader = & valueReader {}
@@ -29,6 +30,20 @@ type vrState struct {
29
30
end int64
30
31
}
31
32
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
+
32
47
// valueReader is for reading BSON values.
33
48
type valueReader struct {
34
49
r * bufio.Reader
@@ -38,6 +53,33 @@ type valueReader struct {
38
53
frame int64
39
54
}
40
55
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
+
41
83
// NewDocumentReader returns a ValueReader using b for the underlying BSON
42
84
// representation.
43
85
func NewDocumentReader (r io.Reader ) ValueReader {
@@ -253,14 +295,28 @@ func (vr *valueReader) appendNextElement(dst []byte) ([]byte, error) {
253
295
return nil , err
254
296
}
255
297
256
- buf := make ([]byte , length )
257
- _ , err = io .ReadFull (vr .r , buf )
298
+ buf , err := vr .r .Peek (int (length ))
258
299
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
+
259
310
return nil , err
260
311
}
312
+
261
313
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
264
320
}
265
321
266
322
func (vr * valueReader ) readValueBytes (dst []byte ) (Type , []byte , error ) {
0 commit comments