// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace System.Buffers
{
///
/// Provides a resource pool that enables reusing instances of type .
///
///
///
/// Renting and returning buffers with an can increase performance
/// in situations where arrays are created and destroyed frequently, resulting in significant
/// memory pressure on the garbage collector.
///
///
/// This class is thread-safe. All members may be used by multiple threads concurrently.
///
///
public abstract class ArrayPool
{
///
/// Retrieves a shared instance.
///
///
/// The shared pool provides a default implementation of
/// that's intended for general applicability. It maintains arrays of multiple sizes, and
/// may hand back a larger array than was actually requested, but will never hand back a smaller
/// array than was requested. Renting a buffer from it with will result in an
/// existing buffer being taken from the pool if an appropriate buffer is available or in a new
/// buffer being allocated if one is not available.
/// byte[] and char[] are the most commonly pooled array types. For these we use a special pool type
/// optimized for very fast access speeds, at the expense of more memory consumption.
/// The shared pool instance is created lazily on first access.
///
public static ArrayPool Shared { get; } =
typeof(T) == typeof(byte) || typeof(T) == typeof(char) ? new TlsOverPerCoreLockedStacksArrayPool() :
Create();
///
/// Creates a new instance using default configuration options.
///
/// A new instance.
public static ArrayPool Create() => new ConfigurableArrayPool();
///
/// Creates a new instance using custom configuration options.
///
/// The maximum length of array instances that may be stored in the pool.
///
/// The maximum number of array instances that may be stored in each bucket in the pool. The pool
/// groups arrays of similar lengths into buckets for faster access.
///
/// A new instance with the specified configuration options.
///
/// The created pool will group arrays into buckets, with no more than
/// in each bucket and with those arrays not exceeding in length.
///
public static ArrayPool Create(int maxArrayLength, int maxArraysPerBucket) =>
new ConfigurableArrayPool(maxArrayLength, maxArraysPerBucket);
///
/// Retrieves a buffer that is at least the requested length.
///
/// The minimum length of the array needed.
///
/// An that is at least in length.
///
///
/// This buffer is loaned to the caller and should be returned to the same pool via
/// so that it may be reused in subsequent usage of .
/// It is not a fatal error to not return a rented buffer, but failure to do so may lead to
/// decreased application performance, as the pool may need to create a new buffer to replace
/// the one lost.
///
public abstract T[] Rent(int minimumLength);
///
/// Returns to the pool an array that was previously obtained via on the same
/// instance.
///
///
/// The buffer previously obtained from to return to the pool.
///
///
/// If true and if the pool will store the buffer to enable subsequent reuse,
/// will clear of its contents so that a subsequent consumer via
/// will not see the previous consumer's content. If false or if the pool will release the buffer,
/// the array's contents are left unchanged.
///
///
/// Once a buffer has been returned to the pool, the caller gives up all ownership of the buffer
/// and must not use it. The reference returned from a given call to must only be
/// returned via once. The default
/// may hold onto the returned buffer in order to rent it again, or it may release the returned buffer
/// if it's determined that the pool already has enough buffers stored.
///
public abstract void Return(T[] array, bool clearArray = false);
}
}