// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Text;
namespace NuGet
{
///
/// Provides a resource pool that enables reusing instances of instances.
///
///
///
/// Renting and returning buffers with an can increase performance
/// in situations where instances 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.
///
///
internal class StringBuilderPool
{
private const int MaxPoolSize = 256;
private readonly SimplePool _pool = new(() => new StringBuilder(MaxPoolSize));
///
/// Retrieves a shared instance.
///
public static readonly StringBuilderPool Shared = new();
private StringBuilderPool()
{
}
///
/// Retrieves a that is at least the requested length.
///
/// The minimum capacity of the needed.
///
/// A 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 string builder, but failure to do so may lead to
/// decreased application performance, as the pool may need to create a new instance to replace
/// the one lost.
///
public StringBuilder Rent(int minimumCapacity)
{
if (minimumCapacity <= MaxPoolSize)
{
return _pool.Allocate();
}
return new StringBuilder(minimumCapacity);
}
///
/// Returns to the pool an array that was previously obtained via on the same
/// instance, returning the built string.
///
///
/// The previously obtained from to return to the pool.
///
///
/// Once a has been returned to the pool, the caller gives up all ownership
/// of the instance 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 instance in order to rent it again, or it may release the returned instance
/// if it's determined that the pool already has enough instances stored.
///
/// The string, built from .
public string ToStringAndReturn(StringBuilder builder)
{
string result = builder.ToString();
if (builder.Capacity <= MaxPoolSize)
{
builder.Clear();
_pool.Free(builder);
}
return result;
}
}
}