| File: SharedStringBuilder.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Versioning\NuGet.Versioning.csproj (NuGet.Versioning) |
// 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; using System.Text; namespace NuGet { /// <summary> /// Provides a resource pool that enables reusing instances of <see cref="StringBuilder" /> instances. /// </summary> /// <remarks> /// <para> /// Renting and returning buffers with an <see cref="StringBuilderPool" /> can increase performance /// in situations where <see cref="StringBuilder" /> instances are created and destroyed frequently, /// resulting in significant memory pressure on the garbage collector. /// </para> /// <para> /// This class is thread-safe. All members may be used by multiple threads concurrently. The string /// builder must be returned, even if an exception is thrown while it is in use. Failure to do results /// in other callers not being able to rent the string builder. /// </para> /// </remarks> internal class SharedStringBuilder { public static readonly SharedStringBuilder Instance = new SharedStringBuilder(); private const int MaxSize = 256; [ThreadStatic] private static StringBuilder? BuilderInstance = null; [ThreadStatic] private static bool InUse = false; private SharedStringBuilder() { } /// <summary> /// Retrieves a <see cref="StringBuilder" /> that is at least the requested length. /// </summary> /// <param name="minimumCapacity">The minimum capacity of the <see cref="StringBuilder" /> needed.</param> /// <returns> /// A <see cref="StringBuilder" /> that is at least <paramref name="minimumCapacity" /> in length. /// </returns> /// <remarks> /// This buffer is loaned to the caller and should be returned to the same pool via /// <see cref="ToStringAndReturn" /> so that it may be reused in subsequent usage of <see cref="Rent" />. /// 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. /// </remarks> #pragma warning disable CA1822 // Mark members as static. Callers are supposed to access this method via SharedStringBuilder.Instance public StringBuilder Rent(int minimumCapacity) #pragma warning restore CA1822 // Mark members as static { if (!InUse) { if (minimumCapacity <= MaxSize) { InUse = true; if (BuilderInstance is null) { BuilderInstance = new StringBuilder(MaxSize); } return BuilderInstance; } } return new StringBuilder(minimumCapacity); } /// <summary> /// Returns to the pool an array that was previously obtained via <see cref="Rent" /> on the same /// <see cref="StringBuilderPool" /> instance, returning the built string. /// </summary> /// <param name="builder"> /// The <see cref="StringBuilder" /> previously obtained from <see cref="Rent" /> to return to the pool. /// </param> /// <remarks> /// Once a <see cref="StringBuilder" /> 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 <see cref="Rent" /> /// must only be returned via <see cref="ToStringAndReturn" /> once. The default <see cref="StringBuilderPool" /> /// 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. /// </remarks> /// <returns>The string, built from <paramref name="builder" />.</returns> #pragma warning disable CA1822 // Mark members as static. Callers are supposed to access this method via SharedStringBuilder.Instance public string ToStringAndReturn(StringBuilder builder) #pragma warning restore CA1822 // Mark members as static { string result = builder.ToString(); if (ReferenceEquals(BuilderInstance, builder)) { InUse = false; builder.Clear(); } return result; } } }