Skip to content

Commit 953baaa

Browse files
Updated stream extensions.
Removed superfluous CopyTo(Stream) extension. Added dual buffer extension.
1 parent 9d0464b commit 953baaa

3 files changed

Lines changed: 25 additions & 9 deletions

File tree

benchmarking/Open.Collections.Benchmarking.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
</ItemGroup>
2323

2424
<ItemGroup>
25-
<PackageReference Include="BenchmarkDotNet" Version="0.13.0" />
25+
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
2626
<PackageReference Include="Open.Diagnostics" Version="1.4.1" />
2727
</ItemGroup>
2828

source/Extensions.Stream.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Buffers;
33
using System.IO;
4+
using System.Threading.Tasks;
45

56
namespace Open.Collections
67
{
@@ -9,24 +10,39 @@ public static partial class Extensions
910
/// <summary>
1011
/// Copies the source stream to the target.
1112
/// </summary>
12-
public static void CopyTo(this Stream source, Stream target, int bufferSize = 4096, bool clearBufferAfter = false)
13+
public static async ValueTask DualBufferCopyToAsync(this Stream source, Stream target, int bufferSize = 4096, bool clearBufferAfter = false)
1314
{
1415
if (source is null)
1516
throw new NullReferenceException();
1617
if (target is null)
1718
throw new ArgumentNullException(nameof(target));
1819

19-
var pool = bufferSize > 128 ? ArrayPool<byte>.Shared : null;
20-
var bytes = pool?.Rent(bufferSize) ?? new byte[bufferSize];
20+
var pool = ArrayPool<byte>.Shared;
21+
var cNext = pool.Rent(bufferSize);
22+
var cCurrent = pool.Rent(bufferSize);
23+
2124
try
2225
{
23-
int cnt;
24-
while ((cnt = source.Read(bytes, 0, bufferSize)) != 0)
25-
target.Write(bytes, 0, cnt);
26+
var next = source.ReadAsync(cNext, 0, bufferSize);
27+
while (true)
28+
{
29+
var n = await next.ConfigureAwait(false);
30+
if (n == 0) break;
31+
32+
// Preemptive request before yielding.
33+
var current = source.ReadAsync(cCurrent, 0, bufferSize);
34+
await target.WriteAsync(cNext, 0, n);
35+
36+
var swap = cNext;
37+
cNext = cCurrent;
38+
cCurrent = swap;
39+
next = current;
40+
}
2641
}
2742
finally
2843
{
29-
pool?.Return(bytes, clearBufferAfter);
44+
pool.Return(cNext, clearBufferAfter);
45+
pool.Return(cCurrent, clearBufferAfter);
3046
}
3147
}
3248
}

source/Open.Collections.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<PackageProjectUrl>https://github.com/Open-NET-Libraries/Open.Collections/</PackageProjectUrl>
1818
<RepositoryUrl>https://github.com/Open-NET-Libraries/Open.Collections/</RepositoryUrl>
1919
<RepositoryType>git</RepositoryType>
20-
<Version>2.12.3</Version>
20+
<Version>2.12.4</Version>
2121
<PackageReleaseNotes></PackageReleaseNotes>
2222
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2323
<PublishRepositoryUrl>true</PublishRepositoryUrl>

0 commit comments

Comments
 (0)