File: src\Dependencies\PooledObjects\PooledStringBuilder.cs
Web Access
Project: src\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces)
// 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.
 
using System.Diagnostics;
using System.Text;
 
namespace Microsoft.CodeAnalysis.PooledObjects
{
    /// <summary>
    /// The usage is:
    ///        var inst = PooledStringBuilder.GetInstance();
    ///        var sb = inst.builder;
    ///        ... Do Stuff...
    ///        ... sb.ToString() ...
    ///        inst.Free();
    /// </summary>
    internal sealed partial class PooledStringBuilder
    {
        public readonly StringBuilder Builder = new();
        private readonly ObjectPool<PooledStringBuilder> _pool;
 
        private PooledStringBuilder(ObjectPool<PooledStringBuilder> pool)
        {
            Debug.Assert(pool != null);
            _pool = pool!;
        }
 
        public int Length
        {
            get { return this.Builder.Length; }
        }
 
        public void Free()
        {
            var builder = this.Builder;
 
            // do not store builders that are too large.
            if (builder.Capacity <= 1024)
            {
                builder.Clear();
                _pool.Free(this);
            }
            else
            {
                _pool.ForgetTrackedObject(this);
            }
        }
 
        [System.Obsolete("Consider calling ToStringAndFree instead.")]
        public new string ToString()
        {
            return this.Builder.ToString();
        }
 
        public string ToStringAndFree()
        {
            var result = this.Builder.ToString();
            this.Free();
 
            return result;
        }
 
        public string ToStringAndFree(int startIndex, int length)
        {
            var result = this.Builder.ToString(startIndex, length);
            this.Free();
 
            return result;
        }
 
        // global pool
        private static readonly ObjectPool<PooledStringBuilder> s_poolInstance = CreatePool();
 
        // if someone needs to create a private pool;
        /// <summary>
        /// If someone need to create a private pool
        /// </summary>
        /// <param name="size">The size of the pool.</param>
        /// <returns></returns>
        public static ObjectPool<PooledStringBuilder> CreatePool(int size = 32)
        {
            ObjectPool<PooledStringBuilder>? pool = null;
            pool = new ObjectPool<PooledStringBuilder>(() => new PooledStringBuilder(pool!), size);
            return pool;
        }
 
        public static PooledStringBuilder GetInstance()
        {
            var builder = s_poolInstance.Allocate();
            Debug.Assert(builder.Builder.Length == 0);
            return builder;
        }
 
        public static implicit operator StringBuilder(PooledStringBuilder obj)
        {
            return obj.Builder;
        }
    }
}