diff --git a/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs b/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs
index 4f80b15ecb..7c2240a574 100644
--- a/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs
+++ b/src/ImageSharp/Memory/ArrayPoolMemoryManager.cs
@@ -1,15 +1,11 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System;
using System.Buffers;
using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp.Memory
{
- using Guard = SixLabors.Guard;
-
///
/// Implements by allocating memory from .
///
@@ -27,14 +23,18 @@ namespace SixLabors.ImageSharp.Memory
private const int DefaultLargeBufferThresholdInBytes = 8 * 1024 * 1024;
///
- /// The for huge buffers, which is not kept clean.
+ /// The for small-to-medium buffers which is not kept clean.
///
- private ArrayPool largeArrayPool;
+ private ArrayPool normalArrayPool;
///
- /// The for small-to-medium buffers which is not kept clean.
+ /// The for huge buffers, which is not kept clean.
///
- private ArrayPool normalArrayPool;
+ private ArrayPool largeArrayPool;
+
+ private readonly int maxArraysPerBucketNormalPool;
+
+ private readonly int maxArraysPerBucketLargePool;
///
/// Initializes a new instance of the class.
@@ -57,14 +57,28 @@ namespace SixLabors.ImageSharp.Memory
/// Initializes a new instance of the class.
///
/// The maximum size of pooled arrays. Arrays over the thershold are gonna be always allocated.
- /// The threshold to pool arrays in which has less buckets for memory safety.
- public ArrayPoolMemoryManager(int maxPoolSizeInBytes, int largeBufferThresholdInBytes)
+ /// Arrays over this threshold will be pooled in which has less buckets for memory safety.
+ public ArrayPoolMemoryManager(int maxPoolSizeInBytes, int poolSelectorThresholdInBytes)
+ : this(maxPoolSizeInBytes, poolSelectorThresholdInBytes, 8, 24)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The maximum size of pooled arrays. Arrays over the thershold are gonna be always allocated.
+ /// The threshold to pool arrays in which has less buckets for memory safety.
+ /// Max arrays per bucket for the large array pool
+ /// Max arrays per bucket for the normal array pool
+ public ArrayPoolMemoryManager(int maxPoolSizeInBytes, int poolSelectorThresholdInBytes, int maxArraysPerBucketLargePool, int maxArraysPerBucketNormalPool)
{
Guard.MustBeGreaterThan(maxPoolSizeInBytes, 0, nameof(maxPoolSizeInBytes));
- Guard.MustBeLessThanOrEqualTo(largeBufferThresholdInBytes, maxPoolSizeInBytes, nameof(largeBufferThresholdInBytes));
+ Guard.MustBeLessThanOrEqualTo(poolSelectorThresholdInBytes, maxPoolSizeInBytes, nameof(poolSelectorThresholdInBytes));
this.MaxPoolSizeInBytes = maxPoolSizeInBytes;
- this.LargeBufferThresholdInBytes = largeBufferThresholdInBytes;
+ this.PoolSelectorThresholdInBytes = poolSelectorThresholdInBytes;
+ this.maxArraysPerBucketLargePool = maxArraysPerBucketLargePool;
+ this.maxArraysPerBucketNormalPool = maxArraysPerBucketNormalPool;
this.InitArrayPools();
}
@@ -77,7 +91,7 @@ namespace SixLabors.ImageSharp.Memory
///
/// Gets the threshold to pool arrays in which has less buckets for memory safety.
///
- public int LargeBufferThresholdInBytes { get; }
+ public int PoolSelectorThresholdInBytes { get; }
///
public override void ReleaseRetainedResources()
@@ -124,13 +138,13 @@ namespace SixLabors.ImageSharp.Memory
private ArrayPool GetArrayPool(int bufferSizeInBytes)
{
- return bufferSizeInBytes <= this.LargeBufferThresholdInBytes ? this.normalArrayPool : this.largeArrayPool;
+ return bufferSizeInBytes <= this.PoolSelectorThresholdInBytes ? this.normalArrayPool : this.largeArrayPool;
}
private void InitArrayPools()
{
- this.largeArrayPool = ArrayPool.Create(this.MaxPoolSizeInBytes, 8);
- this.normalArrayPool = ArrayPool.Create(this.LargeBufferThresholdInBytes, 24);
+ this.largeArrayPool = ArrayPool.Create(this.MaxPoolSizeInBytes, this.maxArraysPerBucketLargePool);
+ this.normalArrayPool = ArrayPool.Create(this.PoolSelectorThresholdInBytes, this.maxArraysPerBucketNormalPool);
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs b/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs
index 0bd243fda2..581e0b78d9 100644
--- a/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs
+++ b/tests/ImageSharp.Tests/Memory/ArrayPoolMemoryManagerTests.cs
@@ -17,9 +17,9 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
private const int MaxPooledBufferSizeInBytes = 2048;
- private const int LargeBufferThresholdInBytes = MaxPooledBufferSizeInBytes / 2;
+ private const int PoolSelectorThresholdInBytes = MaxPooledBufferSizeInBytes / 2;
- private MemoryManager MemoryManager { get; } = new ArrayPoolMemoryManager(MaxPooledBufferSizeInBytes, LargeBufferThresholdInBytes);
+ private MemoryManager MemoryManager { get; } = new ArrayPoolMemoryManager(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes);
///
/// Rent a buffer -> return it -> re-rent -> verify if it's span points to the previous location
@@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
public class BufferTests : BufferTestSuite
{
public BufferTests()
- : base(new ArrayPoolMemoryManager(MaxPooledBufferSizeInBytes, LargeBufferThresholdInBytes))
+ : base(new ArrayPoolMemoryManager(MaxPooledBufferSizeInBytes, PoolSelectorThresholdInBytes))
{
}
}
@@ -53,19 +53,19 @@ namespace SixLabors.ImageSharp.Tests.Memory
{
var mgr = new ArrayPoolMemoryManager(1111, 666);
Assert.Equal(1111, mgr.MaxPoolSizeInBytes);
- Assert.Equal(666, mgr.LargeBufferThresholdInBytes);
+ Assert.Equal(666, mgr.PoolSelectorThresholdInBytes);
}
[Fact]
- public void WhenPassedOnly_MaxPooledBufferSizeInBytes_SmallerThresholdIsAutoCalculated()
+ public void WhenPassedOnly_MaxPooledBufferSizeInBytes_SmallerThresholdValueIsAutoCalculated()
{
var mgr = new ArrayPoolMemoryManager(5000);
Assert.Equal(5000, mgr.MaxPoolSizeInBytes);
- Assert.True(mgr.LargeBufferThresholdInBytes < mgr.MaxPoolSizeInBytes);
+ Assert.True(mgr.PoolSelectorThresholdInBytes < mgr.MaxPoolSizeInBytes);
}
[Fact]
- public void When_LargeBufferThresholdInBytes_IsGreaterThan_MaxPooledBufferSizeInBytes_Throws()
+ public void When_PoolSelectorThresholdInBytes_IsGreaterThan_MaxPooledBufferSizeInBytes_ExceptionIsThrown()
{
Assert.ThrowsAny(() => { new ArrayPoolMemoryManager(100, 200); });
}
@@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
[Fact]
public void AllocationOverLargeArrayThreshold_UsesDifferentPool()
{
- int arrayLengthThreshold = LargeBufferThresholdInBytes / sizeof(int);
+ int arrayLengthThreshold = PoolSelectorThresholdInBytes / sizeof(int);
IBuffer small = this.MemoryManager.Allocate(arrayLengthThreshold - 1);
ref int ptr2Small = ref small.DangerousGetPinnableReference();