mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-15 10:40:18 +00:00
55 lines
No EOL
2.7 KiB
C#
55 lines
No EOL
2.7 KiB
C#
using System;
|
|
using System.Buffers;
|
|
|
|
namespace Ryujinx.Common.Pools
|
|
{
|
|
/// <summary>
|
|
/// A centralized, static pool for getting multipurpose buffers of any type.
|
|
/// "But why does this exist when you have <see cref="ArrayPool{T}"/>?" This actually just wraps around
|
|
/// ArrayPool. The difference is that the rented array is hidden inside of a <see cref="PooledBuffer{T}"/>
|
|
/// handle and is only exposed as a <see cref="Span{T}"/>. This makes it harder to leak references to the
|
|
/// pooled array, which makes it a bit easier to track ownership. The PooledBuffer handle is <see cref="IDisposable"/>
|
|
/// so code analysis can enforce better practice as well. In addition, it also tracks the initial requested
|
|
/// size of the allocated buffer, so you can pass it around and users of it know how much of the data
|
|
/// is actually valid, compared to ArrayPool which just gives you an arbitrary sized array.
|
|
/// </summary>
|
|
public static class BufferPool<T>
|
|
{
|
|
public const int DEFAULT_BUFFER_SIZE = 65536;
|
|
|
|
private static readonly PooledBuffer<T> EMPTY_POOLED_BUFFER = new PooledBuffer<T>(Array.Empty<T>(), -1);
|
|
|
|
/// <summary>
|
|
/// Returns a disposable <see cref="PooledBuffer{T}" /> instance backed by a contiguous array of at least the requested number of elements.
|
|
/// The internal array is only exposed as a <see cref="Span{T}"/> to prevent user code from storing references to it outside
|
|
/// of the potential lifetime of the pooled handle.
|
|
/// </summary>
|
|
/// <param name="minimumRequestedSize">The minimum number of elements that you require</param>
|
|
/// <param name="clearArray">Whether to clear the contents of the buffer before returning. If false (by default), the buffer may initially contain garbage.</param>
|
|
/// <returns>A pooled buffer of exactly the requested size.</returns>
|
|
public static PooledBuffer<T> Rent(int minimumRequestedSize = DEFAULT_BUFFER_SIZE, bool clearArray = false)
|
|
{
|
|
if (minimumRequestedSize < 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("Requested buffer size must be a positive number");
|
|
}
|
|
|
|
if (minimumRequestedSize == 0)
|
|
{
|
|
return EMPTY_POOLED_BUFFER;
|
|
}
|
|
|
|
T[] array = ArrayPool<T>.Shared.Rent(minimumRequestedSize);
|
|
if (clearArray)
|
|
{
|
|
Array.Clear(array, 0, minimumRequestedSize);
|
|
}
|
|
|
|
PooledBuffer<T> returnVal = new PooledBuffer<T>(array, minimumRequestedSize);
|
|
#if TRACK_BUFFERPOOL_LEAKS
|
|
returnVal.MarkRented();
|
|
#endif
|
|
return returnVal;
|
|
}
|
|
}
|
|
} |