Skip to content

Commit dac4668

Browse files
committed
GODRIVER-2311 Improve the BSON unmarshal buffer reuse fix to reduce memory allocations. (#891)
1 parent 97b1b72 commit dac4668

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

bson/bsonrw/value_reader.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -384,9 +384,13 @@ func (vr *valueReader) ReadBinary() (b []byte, btype byte, err error) {
384384
if err != nil {
385385
return nil, 0, err
386386
}
387+
// Make a copy of the returned byte slice because it's just a subslice from the valueReader's
388+
// buffer and is not safe to return in the unmarshaled value.
389+
cp := make([]byte, len(b))
390+
copy(cp, b)
387391

388392
vr.pop()
389-
return b, btype, nil
393+
return cp, btype, nil
390394
}
391395

392396
func (vr *valueReader) ReadBoolean() (bool, error) {
@@ -737,6 +741,9 @@ func (vr *valueReader) ReadValue() (ValueReader, error) {
737741
return vr, nil
738742
}
739743

744+
// readBytes reads length bytes from the valueReader starting at the current offset. Note that the
745+
// returned byte slice is a subslice from the valueReader buffer and must be converted or copied
746+
// before returning in an unmarshaled value.
740747
func (vr *valueReader) readBytes(length int32) ([]byte, error) {
741748
if length < 0 {
742749
return nil, fmt.Errorf("invalid length: %d", length)
@@ -749,10 +756,7 @@ func (vr *valueReader) readBytes(length int32) ([]byte, error) {
749756
start := vr.offset
750757
vr.offset += int64(length)
751758

752-
b := make([]byte, length)
753-
copy(b, vr.d[start:start+int64(length)])
754-
755-
return b, nil
759+
return vr.d[start : start+int64(length)], nil
756760
}
757761

758762
func (vr *valueReader) appendBytes(dst []byte, length int32) ([]byte, error) {

0 commit comments

Comments
 (0)