System.Collections.Immutable by Microsoft

<PackageReference Include="System.Collections.Immutable" Version="8.0.0-preview.1.23110.8" />

.NET API 249,008 bytes

 FrozenDictionary

public static class FrozenDictionary
using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; namespace System.Collections.Frozen { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public static class FrozenDictionary { public static FrozenDictionary<TKey, TValue> ToFrozenDictionary<TKey, [System.Runtime.CompilerServices.Nullable(2)] TValue>([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 1, 1 })] this IEnumerable<KeyValuePair<TKey, TValue>> source, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] IEqualityComparer<TKey> comparer = null) { FrozenDictionary<TKey, TValue> existing; Dictionary<TKey, TValue> uniqueValues; bool uniqueValues2 = GetUniqueValues(source, comparer, out existing, out uniqueValues); return existing ?? ChooseImplementationOptimizedForConstruction(uniqueValues, uniqueValues2); } public static FrozenDictionary<TKey, TValue> ToFrozenDictionary<TKey, [System.Runtime.CompilerServices.Nullable(2)] TValue>([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 1, 1 })] this IEnumerable<KeyValuePair<TKey, TValue>> source, bool optimizeForReading) { return source.ToFrozenDictionary(null, optimizeForReading); } public static FrozenDictionary<TKey, TValue> ToFrozenDictionary<TKey, [System.Runtime.CompilerServices.Nullable(2)] TValue>([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 0, 1, 1 })] this IEnumerable<KeyValuePair<TKey, TValue>> source, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] IEqualityComparer<TKey> comparer, bool optimizeForReading) { FrozenDictionary<TKey, TValue> existing; Dictionary<TKey, TValue> uniqueValues; bool uniqueValues2 = GetUniqueValues(source, comparer, out existing, out uniqueValues); object frozenDictionary = existing; if (frozenDictionary == null) { if (!optimizeForReading) return ChooseImplementationOptimizedForConstruction(uniqueValues, uniqueValues2); frozenDictionary = ChooseImplementationOptimizedForReading(uniqueValues); } return (FrozenDictionary<TKey, TValue>)frozenDictionary; } private static bool GetUniqueValues<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> source, IEqualityComparer<TKey> comparer, out FrozenDictionary<TKey, TValue> existing, out Dictionary<TKey, TValue> uniqueValues) { ThrowHelper.ThrowIfNull(source, "source"); if (comparer == null) comparer = EqualityComparer<TKey>.Default; FrozenDictionary<TKey, TValue> frozenDictionary = source as FrozenDictionary<TKey, TValue>; if (frozenDictionary != null && frozenDictionary.Comparer.Equals(comparer)) { existing = frozenDictionary; uniqueValues = null; return false; } bool result = false; uniqueValues = (source as Dictionary<TKey, TValue>); if (uniqueValues == null || (uniqueValues.Count != 0 && !uniqueValues.Comparer.Equals(comparer))) { result = true; uniqueValues = new Dictionary<TKey, TValue>(comparer); foreach (KeyValuePair<TKey, TValue> item in source) { uniqueValues[item.Key] = item.Value; } } if (uniqueValues.Count == 0) { existing = ((comparer == FrozenDictionary<TKey, TValue>.Empty.Comparer) ? FrozenDictionary<TKey, TValue>.Empty : new EmptyFrozenDictionary<TKey, TValue>(comparer)); uniqueValues = null; return false; } existing = null; return result; } public static FrozenDictionary<TKey, TSource> ToFrozenDictionary<[System.Runtime.CompilerServices.Nullable(2)] TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] IEqualityComparer<TKey> comparer = null) { return ChooseImplementationOptimizedForConstruction(source.ToDictionary(keySelector, comparer), true); } public static FrozenDictionary<TKey, TElement> ToFrozenDictionary<[System.Runtime.CompilerServices.Nullable(2)] TSource, TKey, [System.Runtime.CompilerServices.Nullable(2)] TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, [System.Runtime.CompilerServices.Nullable(new byte[] { 2, 1 })] IEqualityComparer<TKey> comparer = null) { return ChooseImplementationOptimizedForConstruction(source.ToDictionary(keySelector, elementSelector, comparer), true); } private static FrozenDictionary<TKey, TValue> ChooseImplementationOptimizedForConstruction<TKey, TValue>(Dictionary<TKey, TValue> source, bool sourceIsCopy) { return new DefaultFrozenDictionary<TKey, TValue>(source, false); } private static FrozenDictionary<TKey, TValue> ChooseImplementationOptimizedForReading<TKey, TValue>(Dictionary<TKey, TValue> source) { IEqualityComparer<TKey> comparer = source.Comparer; if (typeof(TKey).IsValueType) { if (comparer == EqualityComparer<TKey>.Default) { if (typeof(TKey) == typeof(int)) return (FrozenDictionary<TKey, TValue>)((source.Count <= 10) ? ((FrozenDictionary<int, TValue>)new SmallInt32FrozenDictionary<TValue>((Dictionary<int, TValue>)source)) : ((FrozenDictionary<int, TValue>)new Int32FrozenDictionary<TValue>((Dictionary<int, TValue>)source))); return new ValueTypeDefaultComparerFrozenDictionary<TKey, TValue>(source); } } else if (typeof(TKey) == typeof(string) && (comparer == EqualityComparer<TKey>.Default || comparer == StringComparer.Ordinal || comparer == StringComparer.OrdinalIgnoreCase)) { Dictionary<string, TValue> source2 = (Dictionary<string, TValue>)source; IEqualityComparer<string> equalityComparer = (IEqualityComparer<string>)comparer; FrozenDictionary<string, TValue> frozenDictionary = LengthBucketsFrozenDictionary<TValue>.CreateLengthBucketsFrozenDictionaryIfAppropriate(source2, equalityComparer); if (frozenDictionary != null) return (FrozenDictionary<TKey, TValue>)frozenDictionary; string[] array = (string[])source.Keys.ToArray(); KeyAnalyzer.Analyze(array, equalityComparer == StringComparer.OrdinalIgnoreCase, out KeyAnalyzer.AnalysisResults results); frozenDictionary = (results.SubstringHashing ? (results.RightJustifiedSubstring ? ((!results.IgnoreCase) ? ((results.HashCount == 1) ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedSingleChar<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedSubstring<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex, results.HashCount))) : (results.AllAscii ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveAsciiSubstring<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex, results.HashCount)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveSubstring<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex, results.HashCount)))) : ((!results.IgnoreCase) ? ((results.HashCount == 1) ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedSingleChar<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedSubstring<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex, results.HashCount))) : (results.AllAscii ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveAsciiSubstring<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex, results.HashCount)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveSubstring<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff, results.HashIndex, results.HashCount))))) : ((!results.IgnoreCase) ? new OrdinalStringFrozenDictionary_Full<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff) : (results.AllAscii ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_FullCaseInsensitiveAscii<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_FullCaseInsensitive<TValue>(source2, array, equalityComparer, results.MinimumLength, results.MaximumLengthDiff))))); return (FrozenDictionary<TKey, TValue>)frozenDictionary; } if (source.Count <= 4) return new SmallFrozenDictionary<TKey, TValue>(source); return new DefaultFrozenDictionary<TKey, TValue>(source, true); } } }