-
Notifications
You must be signed in to change notification settings - Fork 978
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tar): support for async streams (#746)
- Loading branch information
Showing
15 changed files
with
1,239 additions
and
418 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
benchmark/ICSharpCode.SharpZipLib.Benchmark/Tar/TarInputStream.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
using System; | ||
using System.IO; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using BenchmarkDotNet.Attributes; | ||
using ICSharpCode.SharpZipLib.Tar; | ||
|
||
namespace ICSharpCode.SharpZipLib.Benchmark.Tar | ||
{ | ||
[MemoryDiagnoser] | ||
[Config(typeof(MultipleRuntimes))] | ||
public class TarInputStream | ||
{ | ||
private readonly byte[] archivedData; | ||
private readonly byte[] readBuffer = new byte[1024]; | ||
|
||
public TarInputStream() | ||
{ | ||
using (var outputMemoryStream = new MemoryStream()) | ||
{ | ||
using (var zipOutputStream = | ||
new ICSharpCode.SharpZipLib.Tar.TarOutputStream(outputMemoryStream, Encoding.UTF8)) | ||
{ | ||
var tarEntry = TarEntry.CreateTarEntry("some file"); | ||
tarEntry.Size = 1024 * 1024; | ||
zipOutputStream.PutNextEntry(tarEntry); | ||
|
||
var rng = RandomNumberGenerator.Create(); | ||
var inputBuffer = new byte[1024]; | ||
rng.GetBytes(inputBuffer); | ||
|
||
for (int i = 0; i < 1024; i++) | ||
{ | ||
zipOutputStream.Write(inputBuffer, 0, inputBuffer.Length); | ||
} | ||
} | ||
|
||
archivedData = outputMemoryStream.ToArray(); | ||
} | ||
} | ||
|
||
[Benchmark] | ||
public long ReadTarInputStream() | ||
{ | ||
using (var memoryStream = new MemoryStream(archivedData)) | ||
using (var zipInputStream = new ICSharpCode.SharpZipLib.Tar.TarInputStream(memoryStream, Encoding.UTF8)) | ||
{ | ||
var entry = zipInputStream.GetNextEntry(); | ||
|
||
while (zipInputStream.Read(readBuffer, 0, readBuffer.Length) > 0) | ||
{ | ||
} | ||
|
||
return entry.Size; | ||
} | ||
} | ||
|
||
[Benchmark] | ||
public async Task<long> ReadTarInputStreamAsync() | ||
{ | ||
using (var memoryStream = new MemoryStream(archivedData)) | ||
using (var zipInputStream = new ICSharpCode.SharpZipLib.Tar.TarInputStream(memoryStream, Encoding.UTF8)) | ||
{ | ||
var entry = await zipInputStream.GetNextEntryAsync(CancellationToken.None); | ||
|
||
#if NETCOREAPP2_1_OR_GREATER | ||
while (await zipInputStream.ReadAsync(readBuffer.AsMemory()) > 0) | ||
{ | ||
} | ||
#else | ||
while (await zipInputStream.ReadAsync(readBuffer, 0, readBuffer.Length) > 0) | ||
{ | ||
} | ||
#endif | ||
|
||
return entry.Size; | ||
} | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
benchmark/ICSharpCode.SharpZipLib.Benchmark/Tar/TarOutputStream.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
using System.IO; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using BenchmarkDotNet.Attributes; | ||
using ICSharpCode.SharpZipLib.Tar; | ||
|
||
namespace ICSharpCode.SharpZipLib.Benchmark.Tar | ||
{ | ||
[MemoryDiagnoser] | ||
[Config(typeof(MultipleRuntimes))] | ||
public class TarOutputStream | ||
{ | ||
private readonly byte[] backingArray = new byte[1024 * 1024 + (6 * 1024)]; | ||
private readonly byte[] inputBuffer = new byte[1024]; | ||
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create(); | ||
|
||
[Benchmark] | ||
public void WriteTarOutputStream() | ||
{ | ||
using (var outputMemoryStream = new MemoryStream(backingArray)) | ||
{ | ||
using (var tarOutputStream = | ||
new ICSharpCode.SharpZipLib.Tar.TarOutputStream(outputMemoryStream, Encoding.UTF8)) | ||
{ | ||
var tarEntry = TarEntry.CreateTarEntry("some file"); | ||
tarEntry.Size = 1024 * 1024; | ||
tarOutputStream.PutNextEntry(tarEntry); | ||
|
||
_rng.GetBytes(inputBuffer); | ||
|
||
for (int i = 0; i < 1024; i++) | ||
{ | ||
tarOutputStream.Write(inputBuffer, 0, inputBuffer.Length); | ||
} | ||
} | ||
} | ||
} | ||
|
||
[Benchmark] | ||
public async Task WriteTarOutputStreamAsync() | ||
{ | ||
using (var outputMemoryStream = new MemoryStream(backingArray)) | ||
{ | ||
using (var tarOutputStream = | ||
new ICSharpCode.SharpZipLib.Tar.TarOutputStream(outputMemoryStream, Encoding.UTF8)) | ||
{ | ||
var tarEntry = TarEntry.CreateTarEntry("some file"); | ||
tarEntry.Size = 1024 * 1024; | ||
|
||
await tarOutputStream.PutNextEntryAsync(tarEntry, CancellationToken.None); | ||
|
||
_rng.GetBytes(inputBuffer); | ||
|
||
for (int i = 0; i < 1024; i++) | ||
{ | ||
await tarOutputStream.WriteAsync(inputBuffer, 0, inputBuffer.Length); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
using System; | ||
using System.Buffers; | ||
|
||
namespace ICSharpCode.SharpZipLib.Core | ||
{ | ||
/// <summary> | ||
/// A MemoryPool that will return a Memory which is exactly the length asked for using the bufferSize parameter. | ||
/// This is in contrast to the default ArrayMemoryPool which will return a Memory of equal size to the underlying | ||
/// array which at least as long as the minBufferSize parameter. | ||
/// Note: The underlying array may be larger than the slice of Memory | ||
/// </summary> | ||
/// <typeparam name="T"></typeparam> | ||
internal sealed class ExactMemoryPool<T> : MemoryPool<T> | ||
{ | ||
public new static readonly MemoryPool<T> Shared = new ExactMemoryPool<T>(); | ||
|
||
public override IMemoryOwner<T> Rent(int bufferSize = -1) | ||
{ | ||
if ((uint)bufferSize > int.MaxValue || bufferSize < 0) | ||
{ | ||
throw new ArgumentOutOfRangeException(nameof(bufferSize)); | ||
} | ||
|
||
return new ExactMemoryPoolBuffer(bufferSize); | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
} | ||
|
||
public override int MaxBufferSize => int.MaxValue; | ||
|
||
private sealed class ExactMemoryPoolBuffer : IMemoryOwner<T>, IDisposable | ||
{ | ||
private T[] array; | ||
private readonly int size; | ||
|
||
public ExactMemoryPoolBuffer(int size) | ||
{ | ||
this.size = size; | ||
this.array = ArrayPool<T>.Shared.Rent(size); | ||
} | ||
|
||
public Memory<T> Memory | ||
{ | ||
get | ||
{ | ||
T[] array = this.array; | ||
if (array == null) | ||
{ | ||
throw new ObjectDisposedException(nameof(ExactMemoryPoolBuffer)); | ||
} | ||
|
||
return new Memory<T>(array).Slice(0, size); | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
T[] array = this.array; | ||
if (array == null) | ||
{ | ||
return; | ||
} | ||
|
||
this.array = null; | ||
ArrayPool<T>.Shared.Return(array); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using System.Collections.Concurrent; | ||
using System.Text; | ||
|
||
namespace ICSharpCode.SharpZipLib.Core | ||
{ | ||
internal class StringBuilderPool | ||
{ | ||
public static StringBuilderPool Instance { get; } = new StringBuilderPool(); | ||
private readonly ConcurrentQueue<StringBuilder> pool = new ConcurrentQueue<StringBuilder>(); | ||
|
||
public StringBuilder Rent() | ||
{ | ||
return pool.TryDequeue(out var builder) ? builder : new StringBuilder(); | ||
} | ||
|
||
public void Return(StringBuilder builder) | ||
{ | ||
builder.Clear(); | ||
pool.Enqueue(builder); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.