Skip to content

Commit 4889093

Browse files
Merge branch 'release/2.0' into DEVPROD-17319-cherry-pick-2.0
2 parents 0a7df3b + 8123542 commit 4889093

File tree

5 files changed

+96
-13
lines changed

5 files changed

+96
-13
lines changed

bson/marshal.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ func Marshal(val interface{}) ([]byte, error) {
7474
}
7575
}()
7676
sw.Reset()
77-
vw := NewDocumentWriter(sw)
77+
78+
vw := getDocumentWriter(sw)
79+
defer putDocumentWriter(vw)
80+
7881
enc := encPool.Get().(*Encoder)
7982
defer encPool.Put(enc)
8083
enc.Reset(vw)

bson/unmarshal.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ type ValueUnmarshaler interface {
4242
// When unmarshaling BSON, if the BSON value is null and the Go value is a
4343
// pointer, the pointer is set to nil without calling UnmarshalBSONValue.
4444
func Unmarshal(data []byte, val interface{}) error {
45-
vr := newDocumentReader(bytes.NewReader(data))
45+
vr := getDocumentReader(bytes.NewReader(data))
46+
defer putDocumentReader(vr)
47+
4648
if l, err := vr.peekLength(); err != nil {
4749
return err
4850
} else if int(l) != len(data) {

bson/value_reader.go

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"fmt"
1414
"io"
1515
"math"
16+
"sync"
1617
)
1718

1819
var _ 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.
3348
type 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.
4385
func 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

266322
func (vr *valueReader) readValueBytes(dst []byte) (Type, []byte, error) {

bson/value_writer.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,29 @@ func putValueWriter(vw *valueWriter) {
3333
}
3434
}
3535

36+
var documentWriterPool = sync.Pool{
37+
New: func() interface{} {
38+
return newDocumentWriter(nil)
39+
},
40+
}
41+
42+
func getDocumentWriter(w io.Writer) *valueWriter {
43+
vw := documentWriterPool.Get().(*valueWriter)
44+
45+
vw.reset(vw.buf)
46+
vw.buf = vw.buf[:0]
47+
vw.w = w
48+
49+
return vw
50+
}
51+
52+
func putDocumentWriter(vw *valueWriter) {
53+
if vw != nil {
54+
vw.w = nil // don't leak the writer
55+
documentWriterPool.Put(vw)
56+
}
57+
}
58+
3659
// This is here so that during testing we can change it and not require
3760
// allocating a 4GB slice.
3861
var maxSize = math.MaxInt32

internal/integration/client_side_encryption_prose_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
795795
"endpoint": "doesnotexist.invalid:443",
796796
},
797797
"kmip": {
798-
"endpoint": "doesnotexist.local:5698",
798+
"endpoint": "doesnotexist.invalid:5698",
799799
},
800800
}
801801

@@ -819,9 +819,8 @@ func TestClientSideEncryptionProse(t *testing.T) {
819819
"endpoint": "kms.us-east-1.amazonaws.com:443",
820820
}
821821
awsFailureConnectionError := map[string]interface{}{
822-
"region": "us-east-1",
823-
"key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
824-
"endpoint": "kms.us-east-1.amazonaws.com:12345",
822+
"keyId": "1",
823+
"endpoint": "localhost:12345",
825824
}
826825
awsFailureInvalidEndpoint := map[string]interface{}{
827826
"region": "us-east-1",
@@ -860,7 +859,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
860859
}
861860
kmipFailureInvalidEndpoint := map[string]interface{}{
862861
"keyId": "1",
863-
"endpoint": "doesnotexist.local:5698",
862+
"endpoint": "doesnotexist.invalid:5698",
864863
}
865864

866865
const (
@@ -906,7 +905,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
906905
},
907906
{
908907
name: "Case 4: aws failure with connection error",
909-
provider: "aws",
908+
provider: "kmip",
910909
masterKey: awsFailureConnectionError,
911910
errorSubstring: []string{errConnectionRefused, errWindowsTLSConnectionRefused},
912911
testInvalidClientEncryption: false,
@@ -1583,7 +1582,7 @@ func TestClientSideEncryptionProse(t *testing.T) {
15831582
"endpoint": "127.0.0.1:9001",
15841583
}
15851584
azureMasterKey := map[string]interface{}{
1586-
"keyVaultEndpoint": "doesnotexist.local",
1585+
"keyVaultEndpoint": "doesnotexist.invalid",
15871586
"keyName": "foo",
15881587
}
15891588
gcpMasterKey := map[string]interface{}{

0 commit comments

Comments
 (0)