Skip to content

Commit

Permalink
Merge pull request #77 from dragonfruitnetwork/use-arraypool
Browse files Browse the repository at this point in the history
add arraypool support to file downloads and json deserialization
  • Loading branch information
aspriddell authored Aug 28, 2021
2 parents 2cc917a + 8782c27 commit 9f666b6
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
</ItemGroup>
</Project>
10 changes: 6 additions & 4 deletions DragonFruit.Common.Data/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. Please refer to the LICENSE file at the root of this project for details

using System;
using System.Buffers;
using System.Globalization;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -267,8 +268,8 @@ HttpResponseMessage CopyProcess(HttpResponseMessage response)
using var networkStream = response.Content.ReadAsStreamAsync().Result;
#endif

// create a buffer for progress reporting
var buffer = new byte[request.BufferSize];
// rent a buffer for progress reporting
var buffer = ArrayPool<byte>.Shared.Rent(request.BufferSize);
int count;
int iterations = 0;

Expand All @@ -282,10 +283,11 @@ HttpResponseMessage CopyProcess(HttpResponseMessage response)
progressUpdated?.Invoke(stream.Length, response.Content.Headers.ContentLength);
}

// flush, send a final update and return
// flush, return buffer and send a final update
stream.Flush();
progressUpdated?.Invoke(stream.Length, response.Content.Headers.ContentLength);
ArrayPool<byte>.Shared.Return(buffer);

progressUpdated?.Invoke(stream.Length, response.Content.Headers.ContentLength);
return response;
}

Expand Down
1 change: 1 addition & 0 deletions DragonFruit.Common.Data/DragonFruit.Common.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Buffers" Version="4.5.1" />
</ItemGroup>

<ItemGroup>
Expand Down
22 changes: 21 additions & 1 deletion DragonFruit.Common.Data/Serializers/ApiJsonSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// DragonFruit.Common Copyright 2020 DragonFruit Network
// Licensed under the MIT License. Please refer to the LICENSE file at the root of this project for details

using System.Buffers;
using System.Globalization;
using System.IO;
using System.Net.Http;
Expand Down Expand Up @@ -80,6 +81,7 @@ public HttpContent Serialize<T>(T input) where T : class
using (var streamWriter = new StreamWriter(stream, Encoding, 4096, true))
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
jsonWriter.ArrayPool = JsonArrayPool.Instance;
Serializer.Serialize(jsonWriter, input);
}

Expand All @@ -95,9 +97,27 @@ public T Deserialize<T>(Stream input) where T : class
false when Encoding is null => new StreamReader(input),
false => new StreamReader(input, Encoding)
};
using var reader = new JsonTextReader(sr);

using var reader = new JsonTextReader(sr)
{
ArrayPool = JsonArrayPool.Instance
};

return Serializer.Deserialize<T>(reader);
}
}

/// <summary>
/// A wrapper for the <see cref="T:System.Buffers.ArrayPool`1" /> that implements <see cref="T:Newtonsoft.Json.IArrayPool`1" />
/// </summary>
/// <remarks>
/// Taken from https://github.com/JamesNK/Newtonsoft.Json/blob/52e257ee57899296d81a868b32300f0b3cfeacbe/Src/Newtonsoft.Json.Tests/DemoTests.cs#L709
/// </remarks>
internal class JsonArrayPool : IArrayPool<char>
{
public static readonly JsonArrayPool Instance = new JsonArrayPool();

public char[] Rent(int minimumLength) => ArrayPool<char>.Shared.Rent(minimumLength);
public void Return(char[] array) => ArrayPool<char>.Shared.Return(array);
}
}

0 comments on commit 9f666b6

Please sign in to comment.