Skip to content

Commit 6bd669f

Browse files
committed
Added custom pool to ArrayPoolBufferWriter<T>
1 parent 301b5fa commit 6bd669f

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

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

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public sealed class ArrayPoolBufferWriter<T> : IBuffer<T>, IMemoryOwner<T>
3333
/// </summary>
3434
private const int DefaultInitialBufferSize = 256;
3535

36+
/// <summary>
37+
/// The <see cref="ArrayPool{T}"/> instance used to rent <see cref="array"/>.
38+
/// </summary>
39+
private readonly ArrayPool<T> pool;
40+
3641
/// <summary>
3742
/// The underlying <typeparamref name="T"/> array.
3843
/// </summary>
@@ -49,12 +54,17 @@ public sealed class ArrayPoolBufferWriter<T> : IBuffer<T>, IMemoryOwner<T>
4954
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
5055
/// </summary>
5156
public ArrayPoolBufferWriter()
57+
: this(ArrayPool<T>.Shared, DefaultInitialBufferSize)
58+
{
59+
}
60+
61+
/// <summary>
62+
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
63+
/// </summary>
64+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance to use.</param>
65+
public ArrayPoolBufferWriter(ArrayPool<T> pool)
66+
: this(pool, DefaultInitialBufferSize)
5267
{
53-
// Since we're using pooled arrays, we can rent the buffer with the
54-
// default size immediately, we don't need to use lazy initialization
55-
// to save unnecessary memory allocations in this case.
56-
this.array = ArrayPool<T>.Shared.Rent(DefaultInitialBufferSize);
57-
this.index = 0;
5868
}
5969

6070
/// <summary>
@@ -65,20 +75,37 @@ public ArrayPoolBufferWriter()
6575
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
6676
/// </exception>
6777
public ArrayPoolBufferWriter(int initialCapacity)
78+
: this(ArrayPool<T>.Shared, initialCapacity)
79+
{
80+
}
81+
82+
/// <summary>
83+
/// Initializes a new instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
84+
/// </summary>
85+
/// <param name="pool">The <see cref="ArrayPool{T}"/> instance to use.</param>
86+
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
87+
/// <exception cref="ArgumentException">
88+
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
89+
/// </exception>
90+
public ArrayPoolBufferWriter(ArrayPool<T> pool, int initialCapacity)
6891
{
6992
if (initialCapacity <= 0)
7093
{
7194
ThrowArgumentOutOfRangeExceptionForInitialCapacity();
7295
}
7396

74-
this.array = ArrayPool<T>.Shared.Rent(initialCapacity);
97+
// Since we're using pooled arrays, we can rent the buffer with the
98+
// default size immediately, we don't need to use lazy initialization
99+
// to save unnecessary memory allocations in this case.
100+
this.pool = pool;
101+
this.array = pool.Rent(initialCapacity);
75102
this.index = 0;
76103
}
77104

78105
/// <summary>
79106
/// Finalizes an instance of the <see cref="ArrayPoolBufferWriter{T}"/> class.
80107
/// </summary>
81-
~ArrayPoolBufferWriter() => this.Dispose();
108+
~ArrayPoolBufferWriter() => Dispose();
82109

83110
/// <inheritdoc/>
84111
Memory<T> IMemoryOwner<T>.Memory
@@ -182,6 +209,7 @@ public void Clear()
182209
}
183210

184211
array.AsSpan(0, this.index).Clear();
212+
185213
this.index = 0;
186214
}
187215

@@ -250,7 +278,7 @@ private void CheckAndResizeBuffer(int sizeHint)
250278
{
251279
int minimumSize = this.index + sizeHint;
252280

253-
ArrayPool<T>.Shared.Resize(ref this.array, minimumSize);
281+
this.pool.Resize(ref this.array, minimumSize);
254282
}
255283
}
256284

@@ -268,7 +296,7 @@ public void Dispose()
268296

269297
this.array = null;
270298

271-
ArrayPool<T>.Shared.Return(array);
299+
this.pool.Return(array);
272300
}
273301

274302
/// <inheritdoc/>

0 commit comments

Comments
 (0)