Skip to content

CSHARP-5531: Optimize the conversion from an array index to UTF-8 byte arrays #1672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/MongoDB.Bson/IO/BsonBinaryWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

using System;
using System.Buffers.Text;
using System.Collections.Generic;
using System.IO;

Expand All @@ -29,6 +30,7 @@ public class BsonBinaryWriter : BsonWriter
private readonly Stream _baseStream;
#pragma warning restore CA2213 // Disposable never disposed
private readonly BsonStream _bsonStream;
private readonly byte[] _temp10Bytes = new byte[10];
private BsonBinaryWriterContext _context;

// constructors
Expand Down Expand Up @@ -719,8 +721,8 @@ private void WriteNameHelper()
if (_context.ContextType == ContextType.Array)
{
var index = _context.Index++;
var nameBytes = ArrayElementNameAccelerator.Default.GetElementNameBytes(index);
_bsonStream.WriteCStringBytes(nameBytes);
Utf8Formatter.TryFormat(index, _temp10Bytes.AsSpan(), out var bytesWritten);
_bsonStream.WriteCStringBytes(new ArraySegment<byte>(_temp10Bytes, 0, bytesWritten));
}
else
{
Expand Down
6 changes: 6 additions & 0 deletions src/MongoDB.Bson/IO/BsonStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ public abstract class BsonStream : Stream
/// <param name="value">The value.</param>
public abstract void WriteCStringBytes(byte[] value);

/// <summary>
/// Writes the CString bytes to the stream.
/// </summary>
/// <param name="value"></param>
public abstract void WriteCStringBytes(ArraySegment<byte> value);

/// <summary>
/// Writes a BSON Decimal128 to the stream.
/// </summary>
Expand Down
9 changes: 9 additions & 0 deletions src/MongoDB.Bson/IO/BsonStreamAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,15 @@ public override void WriteCStringBytes(byte[] value)
WriteByte(0);
}

/// <inheritdoc/>
public override void WriteCStringBytes(ArraySegment<byte> value)
{
ThrowIfDisposed();

this.WriteBytes(value.Array, value.Offset, value.Count);
WriteByte(0);
}

/// <inheritdoc/>
public override void WriteDecimal128(Decimal128 value)
{
Expand Down
17 changes: 16 additions & 1 deletion src/MongoDB.Bson/IO/ByteBufferStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ public override void WriteCString(string value)
{
// Compare to 128 to preserve original behavior
const int maxLengthToUseCStringUtf8EncodingWith = 128;

if (maxLength <= maxLengthToUseCStringUtf8EncodingWith)
{
using var rentedBuffer = ThreadStaticBuffer.RentBuffer(maxLengthToUseCStringUtf8EncodingWith);
Expand Down Expand Up @@ -623,6 +623,21 @@ public override void WriteCStringBytes(byte[] value)
SetPositionAfterWrite(_position + length + 1);
}

/// <inheritdoc/>
public override void WriteCStringBytes(ArraySegment<byte> value)
{
ThrowIfDisposed();

var length = value.Count;

PrepareToWrite(length + 1);

_buffer.SetBytes(_position, value.Array, value.Offset, length);
_buffer.SetByte(_position + length, 0);

SetPositionAfterWrite(_position + length + 1);
}

/// <inheritdoc/>
public override void WriteDecimal128(Decimal128 value)
{
Expand Down
5 changes: 5 additions & 0 deletions tests/MongoDB.Bson.TestHelpers/IO/NullBsonStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ public override void WriteCStringBytes(byte[] value)
Position += value.Length + 1;
}

public override void WriteCStringBytes(ArraySegment<byte> value)
{
Position += value.Count + 1;
}

public override void WriteDecimal128(Decimal128 value)
{
Position += 16;
Expand Down