File: src\Shared\MS\Utility\ItemMap.cs
Project: wpf\PresentationFramework.csproj (PresentationFramework)
using System;
using System.Collections;
using System.Diagnostics;
 
namespace MS.Utility
{
    //
    // ItemStructMap<T>
    //
 
    // Disable warnings about fields never being assigned to
    // This struct is designed to function with its fields starting at
    // their default values and without the need of surfacing a constructor
    // other than the deafult
    #pragma warning disable 649
 
    internal struct ItemStructMap<T>
    {
        public int EnsureEntry(int key)
        {
            int index = Search(key);
            if (index < 0)
            {
                // Not found, add Entry
 
                // Create initial capacity, if necessary
                if (Entries == null)
                {
                    Entries = new Entry[SearchTypeThreshold];
                }
 
                // Convert not-found index to insertion point
                index = ~index;
 
                Entry[] destEntries = Entries;
 
                // Increase capacity, if necessary
                if ((Count + 1) > Entries.Length)
                {
                    destEntries = new Entry[Entries.Length * 2];
 
                    // Initialize start of new array
                    Array.Copy(Entries, 0, destEntries, 0, index);
                }
 
                // Shift entries to make room for new key at provided insertion point
                Array.Copy(Entries, index, destEntries, index + 1, Count - index);
 
                // Ensure Source and Destination arrays are the same
                Entries = destEntries;
 
                // Clear new entry
                Entries[index] = EmptyEntry;
 
                // Set
                Entries[index].Key = key;
 
                Count++;
            }
 
            return index;
        }
 
        public int Search(int key)
        {
            int keyPv = Int32.MaxValue;
            int iPv = 0;
 
            // Use fastest search based on size
            if (Count > SearchTypeThreshold)
            {
                // Binary Search
                int iLo = 0;
                int iHi = Count - 1;
 
                while (iLo <= iHi)
                {
                    iPv = (iHi + iLo) / 2;
                    keyPv = Entries[iPv].Key;
 
                    if (key == keyPv)
                    {
                        return iPv;
                    }
 
                    if (key < keyPv)
                    {
                        iHi = iPv - 1;
                    }
                    else
                    {
                        iLo = iPv + 1;
                    }
                }
            }
            else
            {
                // Linear search
 
                for (int i = 0; i < Count; i++)
                {
                    iPv = i;
                    keyPv = Entries[iPv].Key;
 
                    if (key == keyPv)
                    {
                        return iPv;
                    }
 
                    if (key < keyPv)
                    {
                        break;
                    }
                }
            }
 
            // iPv and keyPv will match and have the last pivot check
 
            // Return a negative value whose bitwise compliment
            // is this index of the first Entry that is greater
            // than the key passed in (sorted insertion point)
 
            if (key > keyPv)
            {
                iPv++;
            }
 
 
            return ~iPv;
        }
 
        private const int SearchTypeThreshold = 4;
 
        public Entry[] Entries;
        public int Count;
 
        public struct Entry
        {
            public int Key;
            public T Value;
        }
 
        private static Entry EmptyEntry;
    }
 
    #pragma warning restore 649
}