Skip to content

Commit 301b5fa

Browse files
committed
Added custom ArrayPool<T> field to Memoryowner<T>
1 parent b464ce2 commit 301b5fa

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

Microsoft.Toolkit.HighPerformance/Buffers/MemoryOwner{T}.cs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public sealed class MemoryOwner<T> : IMemoryOwner<T>
3232
private readonly int length;
3333
#pragma warning restore IDE0032
3434

35+
/// <summary>
36+
/// The <see cref="ArrayPool{T}"/> instance used to rent <see cref="array"/>.
37+
/// </summary>
38+
private readonly ArrayPool<T> pool;
39+
3540
/// <summary>
3641
/// The underlying <typeparamref name="T"/> array.
3742
/// </summary>
@@ -41,12 +46,14 @@ public sealed class MemoryOwner<T> : IMemoryOwner<T>
4146
/// Initializes a new instance of the <see cref="MemoryOwner{T}"/> class with the specified parameters.
4247
/// </summary>
4348
/// <param name="length">The length of the new memory buffer to use.</param>
49+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance to use.</param>
4450
/// <param name="mode">Indicates the allocation mode to use for the new buffer to rent.</param>
45-
private MemoryOwner(int length, AllocationMode mode)
51+
private MemoryOwner(int length, ArrayPool<T> pool, AllocationMode mode)
4652
{
4753
this.start = 0;
4854
this.length = length;
49-
this.array = ArrayPool<T>.Shared.Rent(length);
55+
this.pool = pool;
56+
this.array = pool.Rent(length);
5057

5158
if (mode == AllocationMode.Clear)
5259
{
@@ -57,20 +64,22 @@ private MemoryOwner(int length, AllocationMode mode)
5764
/// <summary>
5865
/// Initializes a new instance of the <see cref="MemoryOwner{T}"/> class with the specified parameters.
5966
/// </summary>
60-
/// <param name="array">The input <typeparamref name="T"/> array to use.</param>
6167
/// <param name="start">The starting offset within <paramref name="array"/>.</param>
6268
/// <param name="length">The length of the array to use.</param>
63-
private MemoryOwner(T[] array, int start, int length)
69+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance currently in use.</param>
70+
/// <param name="array">The input <typeparamref name="T"/> array to use.</param>
71+
private MemoryOwner(int start, int length, ArrayPool<T> pool, T[] array)
6472
{
6573
this.start = start;
6674
this.length = length;
75+
this.pool = pool;
6776
this.array = array;
6877
}
6978

7079
/// <summary>
7180
/// Finalizes an instance of the <see cref="MemoryOwner{T}"/> class.
7281
/// </summary>
73-
~MemoryOwner() => this.Dispose();
82+
~MemoryOwner() => Dispose();
7483

7584
/// <summary>
7685
/// Gets an empty <see cref="MemoryOwner{T}"/> instance.
@@ -79,7 +88,7 @@ private MemoryOwner(T[] array, int start, int length)
7988
public static MemoryOwner<T> Empty
8089
{
8190
[MethodImpl(MethodImplOptions.AggressiveInlining)]
82-
get => new MemoryOwner<T>(0, AllocationMode.Default);
91+
get => new MemoryOwner<T>(0, ArrayPool<T>.Shared, AllocationMode.Default);
8392
}
8493

8594
/// <summary>
@@ -91,19 +100,44 @@ public static MemoryOwner<T> Empty
91100
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
92101
[Pure]
93102
[MethodImpl(MethodImplOptions.AggressiveInlining)]
94-
public static MemoryOwner<T> Allocate(int size) => new MemoryOwner<T>(size, AllocationMode.Default);
103+
public static MemoryOwner<T> Allocate(int size) => new MemoryOwner<T>(size, ArrayPool<T>.Shared, AllocationMode.Default);
104+
105+
/// <summary>
106+
/// Creates a new <see cref="MemoryOwner{T}"/> instance with the specified parameters.
107+
/// </summary>
108+
/// <param name="size">The length of the new memory buffer to use.</param>
109+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance currently in use.</param>
110+
/// <returns>A <see cref="MemoryOwner{T}"/> instance of the requested length.</returns>
111+
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="size"/> is not valid.</exception>
112+
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
113+
[Pure]
114+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
115+
public static MemoryOwner<T> Allocate(int size, ArrayPool<T> pool) => new MemoryOwner<T>(size, pool, AllocationMode.Default);
116+
117+
/// <summary>
118+
/// Creates a new <see cref="MemoryOwner{T}"/> instance with the specified parameters.
119+
/// </summary>
120+
/// <param name="size">The length of the new memory buffer to use.</param>
121+
/// <param name="mode">Indicates the allocation mode to use for the new buffer to rent.</param>
122+
/// <returns>A <see cref="MemoryOwner{T}"/> instance of the requested length.</returns>
123+
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="size"/> is not valid.</exception>
124+
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
125+
[Pure]
126+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
127+
public static MemoryOwner<T> Allocate(int size, AllocationMode mode) => new MemoryOwner<T>(size, ArrayPool<T>.Shared, mode);
95128

96129
/// <summary>
97130
/// Creates a new <see cref="MemoryOwner{T}"/> instance with the specified parameters.
98131
/// </summary>
99132
/// <param name="size">The length of the new memory buffer to use.</param>
133+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance currently in use.</param>
100134
/// <param name="mode">Indicates the allocation mode to use for the new buffer to rent.</param>
101135
/// <returns>A <see cref="MemoryOwner{T}"/> instance of the requested length.</returns>
102136
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="size"/> is not valid.</exception>
103137
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
104138
[Pure]
105139
[MethodImpl(MethodImplOptions.AggressiveInlining)]
106-
public static MemoryOwner<T> Allocate(int size, AllocationMode mode) => new MemoryOwner<T>(size, mode);
140+
public static MemoryOwner<T> Allocate(int size, ArrayPool<T> pool, AllocationMode mode) => new MemoryOwner<T>(size, pool, mode);
107141

108142
/// <summary>
109143
/// Gets the number of items in the current instance
@@ -210,7 +244,7 @@ public MemoryOwner<T> Slice(int start, int length)
210244
ThrowInvalidLengthException();
211245
}
212246

213-
return new MemoryOwner<T>(array!, start, length);
247+
return new MemoryOwner<T>(start, length, this.pool, array!);
214248
}
215249

216250
/// <inheritdoc/>
@@ -227,7 +261,7 @@ public void Dispose()
227261

228262
this.array = null;
229263

230-
ArrayPool<T>.Shared.Return(array);
264+
this.pool.Return(array);
231265
}
232266

233267
/// <inheritdoc/>

0 commit comments

Comments
 (0)