File: System\Composition\Hosting\Util\SmallSparseInitonlyArray.cs
Web Access
Project: src\src\libraries\System.Composition.Hosting\src\System.Composition.Hosting.csproj (System.Composition.Hosting)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace System.Composition.Hosting.Util
{
    // Extremely performance-sensitive.
    // Always safe for reading, even under concurrent writes,
    // only one writer at a time allowed.
    internal sealed class SmallSparseInitonlyArray
    {
        private sealed class Element { public int Index; public object Value; }
 
        private const int ElementsCapacity = 128;
        private const int ElementIndexMask = 127;
        private const int LocalOffsetMax = 3;
 
        private Element[] _elements;
        private SmallSparseInitonlyArray _overflow;
 
        public void Add(int index, object value)
        {
            _elements ??= new Element[ElementsCapacity];
 
            var newElement = new Element { Index = index, Value = value };
 
            var elementIndex = index & ElementIndexMask;
            var e = _elements[elementIndex];
            if (e == null)
            {
                _elements[elementIndex] = newElement;
                return;
            }
 
            if (e.Index == index)
            {
                throw new ArgumentException(SR.Format(SR.Key_Already_Exist, index), nameof(index));
            }
 
            for (int offset = 1; offset <= LocalOffsetMax; ++offset)
            {
                var nextIndex = (index + offset) & ElementIndexMask;
                e = _elements[nextIndex];
                if (e == null)
                {
                    _elements[nextIndex] = newElement;
                    return;
                }
 
                if (e.Index == index)
                {
                    throw new ArgumentException(SR.Format(SR.Key_Already_Exist, index), nameof(index));
                }
            }
 
            _overflow ??= new SmallSparseInitonlyArray();
 
            _overflow.Add(index, value);
        }
 
        public bool TryGetValue(int index, out object value)
        {
            if (_elements == null)
            {
                value = null;
                return false;
            }
 
            var elementIndex = index & ElementIndexMask;
            var e = _elements[elementIndex];
            if (e != null && e.Index == index)
            {
                value = e.Value;
                return true;
            }
 
            for (int offset = 1; offset <= LocalOffsetMax; ++offset)
            {
                e = _elements[(index + offset) & ElementIndexMask];
                if (e == null)
                {
                    value = null;
                    return false;
                }
 
                if (e.Index == index)
                {
                    value = e.Value;
                    return true;
                }
            }
 
            if (_overflow != null)
                return _overflow.TryGetValue(index, out value);
 
            value = null;
            return false;
        }
    }
}