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);
}
}
}