Skip to content
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

Query and change feed: Add serialization optimization by using array instead of by item #1516

Merged
merged 16 commits into from
May 15, 2020
Merged
55 changes: 25 additions & 30 deletions Microsoft.Azure.Cosmos/src/Serializer/CosmosElementSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,7 @@ internal static MemoryStream ToStream(

jsonWriter.WriteObjectEnd();

ReadOnlyMemory<byte> result = jsonWriter.GetResult();
if (!MemoryMarshal.TryGetArray(result, out ArraySegment<byte> resultAsArray))
{
resultAsArray = new ArraySegment<byte>(result.ToArray());
}

return new MemoryStream(resultAsArray.Array, resultAsArray.Offset, resultAsArray.Count, writable: false, publiclyVisible: true);
return GetMemoryStreamFromJsonWriter(jsonWriter);
}

internal static IReadOnlyList<T> GetResources<T>(
Expand All @@ -241,27 +235,8 @@ internal static IReadOnlyList<T> GetResources<T>(
}

private static IReadOnlyList<T> GetResourcesHelper<T>(
IReadOnlyList<CosmosElement> cosmosArray,
CosmosSerializerCore serializerCore)
{
List<T> result = new List<T>();
foreach (CosmosElement element in cosmosArray)
{
MemoryStream memory = CosmosElementSerializer.ElementToMemoryStream(element, null);
result.Add(serializerCore.FromStream<T>(memory));
}

return result;
}

/// <summary>
/// Converts a list of CosmosElements into a memory stream.
/// </summary>
/// <param name="cosmosElement">The cosmos elements</param>
/// <param name="cosmosSerializationOptions">The custom serialization options. This allows custom serialization types like BSON, JSON, or other formats</param>
/// <returns>Returns a memory stream of cosmos elements. By default the memory stream will contain JSON.</returns>
internal static MemoryStream ElementToMemoryStream(
CosmosElement cosmosElement,
IReadOnlyList<CosmosElement> cosmosElements,
CosmosSerializerCore serializerCore,
CosmosSerializationFormatOptions cosmosSerializationOptions = null)
{
IJsonWriter jsonWriter;
Expand All @@ -274,15 +249,35 @@ internal static MemoryStream ElementToMemoryStream(
jsonWriter = JsonWriter.Create(JsonSerializationFormat.Text);
}

cosmosElement.WriteTo(jsonWriter);
jsonWriter.WriteArrayStart();

foreach (CosmosElement element in cosmosElements)
{
element.WriteTo(jsonWriter);
}

jsonWriter.WriteArrayEnd();

using (MemoryStream memoryStream = GetMemoryStreamFromJsonWriter(jsonWriter))
{
return serializerCore.FromFeedStream<T>(memoryStream);
}
}

private static MemoryStream GetMemoryStreamFromJsonWriter(IJsonWriter jsonWriter)
{
ReadOnlyMemory<byte> result = jsonWriter.GetResult();
if (!MemoryMarshal.TryGetArray(result, out ArraySegment<byte> resultAsArray))
{
resultAsArray = new ArraySegment<byte>(result.ToArray());
}

return new MemoryStream(resultAsArray.Array, resultAsArray.Offset, resultAsArray.Count);
return new MemoryStream(
buffer: resultAsArray.Array,
index: resultAsArray.Offset,
count: resultAsArray.Count,
writable: false,
publiclyVisible: true);
}

private static string GetRootNodeName(ResourceType resourceType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace Microsoft.Azure.Cosmos
#nullable enable
internal static class CosmosFeedResponseSerializer
{
private static readonly byte ArrayStart = Encoding.UTF8.GetBytes("[")[0];
private static readonly byte ArrayEnd = Encoding.UTF8.GetBytes("]")[0];
private static readonly byte ArrayStart = (byte)'[';
private static readonly byte ArrayEnd = (byte)']';
j82w marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// The service returns feed responses in an envelope. This removes the envelope
Expand Down