Skip to content

Commit

Permalink
Review fixes
Browse files Browse the repository at this point in the history
* Make InflaterPool size configurable via SharpZipLibOptions.InflaterPoolSize
  • Loading branch information
lahma committed Aug 12, 2023
1 parent 1ceca9c commit 82be257
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
2 changes: 2 additions & 0 deletions benchmark/ICSharpCode.SharpZipLib.Benchmark/Zip/ZipFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class ZipFile
[GlobalSetup]
public async Task GlobalSetup()
{
SharpZipLibOptions.InflaterPoolSize = 4;

// large real-world test file from test262 repository
string commitSha = "2e4e0e6b8ebe3348a207144204cb6d7a5571c863";
zipFileWithLargeAmountOfEntriesPath = Path.Combine(Path.GetTempPath(), $"{commitSha}.zip");
Expand Down
35 changes: 28 additions & 7 deletions src/ICSharpCode.SharpZipLib/Core/InflaterPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,56 @@
namespace ICSharpCode.SharpZipLib.Core
{
/// <summary>
/// Pool Inflator instances as they can be costly due to byte array allocations.
/// Pool for <see cref="Inflater"/> instances as they can be costly due to byte array allocations.
/// </summary>
internal sealed class InflaterPool
{
public static InflaterPool Instance { get; } = new InflaterPool();
private readonly ConcurrentQueue<PooledInflater> noHeaderPool = new ConcurrentQueue<PooledInflater>();
private readonly ConcurrentQueue<PooledInflater> headerPool = new ConcurrentQueue<PooledInflater>();

internal static InflaterPool Instance { get; } = new InflaterPool();

private InflaterPool()
{
}

public Inflater Rent(bool noHeader = false)
internal Inflater Rent(bool noHeader = false)
{
if (SharpZipLibOptions.InflaterPoolSize <= 0)
{
return new Inflater(noHeader);
}

var pool = GetPool(noHeader);
var inf = pool.TryDequeue(out var inflater) ? inflater : new PooledInflater(noHeader);
inf.Reset();

PooledInflater inf;
if (pool.TryDequeue(out var inflater))
{
inf = inflater;
inf.Reset();
}
else
{
inf = new PooledInflater(noHeader);
}

return inf;
}

public void Return(Inflater inflater)
internal void Return(Inflater inflater)
{
if (SharpZipLibOptions.InflaterPoolSize <= 0)
{
return;
}

if (!(inflater is PooledInflater pooledInflater))
{
throw new ArgumentException("Returned inflater was not a pooled one");
}

var pool = GetPool(inflater.noHeader);
if (pool.Count < 10)
if (pool.Count < SharpZipLibOptions.InflaterPoolSize)
{
pooledInflater.Reset();
pool.Enqueue(pooledInflater);
Expand Down
15 changes: 15 additions & 0 deletions src/ICSharpCode.SharpZipLib/SharpZipLibOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using ICSharpCode.SharpZipLib.Zip.Compression;

namespace ICSharpCode.SharpZipLib
{
/// <summary>
/// Global options to alter behavior.
/// </summary>
public static class SharpZipLibOptions
{
/// <summary>
/// The max pool size allowed for reusing <see cref="Inflater"/> instances, defaults to 0 (disabled).
/// </summary>
public static int InflaterPoolSize { get; set; } = 0;
}
}

0 comments on commit 82be257

Please sign in to comment.