File: src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Core\Serialization\ObjectWriter.WriterReferenceMap.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 Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.PooledObjects;
 
namespace Roslyn.Utilities;
 
internal sealed partial class ObjectWriter
{
    /// <summary>
    /// An object reference to reference-id map, that can share base data efficiently.
    /// </summary>
    private struct WriterReferenceMap
    {
        // PERF: Use segmented collection to avoid Large Object Heap allocations during serialization.
        // https://github.com/dotnet/roslyn/issues/43401
        private readonly SegmentedDictionary<string, int> _valueToIdMap;
        private int _nextId;
 
        private static readonly ObjectPool<SegmentedDictionary<string, int>> s_valueDictionaryPool = new(() => new(128));
 
        public WriterReferenceMap()
        {
            _valueToIdMap = s_valueDictionaryPool.Allocate();
            _nextId = 0;
        }
 
        public readonly void Dispose()
        {
            // If the map grew too big, don't return it to the pool.
            // When testing with the Roslyn solution, this dropped only 2.5% of requests.
            if (_valueToIdMap.Count > 1024)
            {
                s_valueDictionaryPool.ForgetTrackedObject(_valueToIdMap);
            }
            else
            {
                _valueToIdMap.Clear();
                s_valueDictionaryPool.Free(_valueToIdMap);
            }
        }
 
        public bool TryGetReferenceId(string value, out int referenceId)
            => _valueToIdMap.TryGetValue(value, out referenceId);
 
        public void Add(string value)
        {
            var id = _nextId++;
            _valueToIdMap.Add(value, id);
        }
    }
}