// 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; } } }