FrozenDictionary
Provides a set of initialization methods for instances of the FrozenDictionary<T, U> class.
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)
{
Dictionary<TKey, TValue> newDictionary;
return GetExistingFrozenOrNewDictionary(source, comparer, out newDictionary) ?? CreateFromDictionary(newDictionary);
}
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 source.ToDictionary(keySelector, comparer).ToFrozenDictionary(comparer);
}
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 source.ToDictionary(keySelector, elementSelector, comparer).ToFrozenDictionary(comparer);
}
private static FrozenDictionary<TKey, TValue> GetExistingFrozenOrNewDictionary<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> source, IEqualityComparer<TKey> comparer, out Dictionary<TKey, TValue> newDictionary)
{
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)) {
newDictionary = null;
return frozenDictionary;
}
newDictionary = (source as Dictionary<TKey, TValue>);
if (newDictionary == null || (newDictionary.Count != 0 && !newDictionary.Comparer.Equals(comparer))) {
newDictionary = new Dictionary<TKey, TValue>(comparer);
foreach (KeyValuePair<TKey, TValue> item in source) {
newDictionary[item.Key] = item.Value;
}
}
if (newDictionary.Count == 0) {
if (comparer != FrozenDictionary<TKey, TValue>.Empty.Comparer)
return new EmptyFrozenDictionary<TKey, TValue>(comparer);
return FrozenDictionary<TKey, TValue>.Empty;
}
return null;
}
private static FrozenDictionary<TKey, TValue> CreateFromDictionary<TKey, TValue>(Dictionary<TKey, TValue> source)
{
IEqualityComparer<TKey> comparer = source.Comparer;
if (typeof(TKey).IsValueType && comparer == EqualityComparer<TKey>.Default) {
if (source.Count <= 10) {
if (Constants.IsKnownComparable<TKey>())
return (FrozenDictionary<TKey, TValue>)new SmallValueTypeComparableFrozenDictionary<TKey, TValue>(source);
return (FrozenDictionary<TKey, TValue>)new SmallValueTypeDefaultComparerFrozenDictionary<TKey, TValue>(source);
}
if (typeof(TKey) == typeof(int))
return (FrozenDictionary<TKey, TValue>)new Int32FrozenDictionary<TValue>((Dictionary<int, TValue>)source);
return new ValueTypeDefaultComparerFrozenDictionary<TKey, TValue>(source);
}
if (typeof(TKey) == typeof(string) && (comparer == EqualityComparer<TKey>.Default || comparer == StringComparer.Ordinal || comparer == StringComparer.OrdinalIgnoreCase)) {
IEqualityComparer<string> equalityComparer = (IEqualityComparer<string>)comparer;
string[] array = (string[])source.Keys.ToArray();
TValue[] values = source.Values.ToArray();
int num = 2147483647;
int num2 = 0;
string[] array2 = array;
foreach (string text in array2) {
if (text.Length < num)
num = text.Length;
if (text.Length > num2)
num2 = text.Length;
}
FrozenDictionary<string, TValue> frozenDictionary = LengthBucketsFrozenDictionary<TValue>.CreateLengthBucketsFrozenDictionaryIfAppropriate(array, values, equalityComparer, num, num2);
if (frozenDictionary != null)
return (FrozenDictionary<TKey, TValue>)frozenDictionary;
KeyAnalyzer.AnalysisResults analysisResults = KeyAnalyzer.Analyze(array, equalityComparer == StringComparer.OrdinalIgnoreCase, num, num2);
frozenDictionary = (analysisResults.SubstringHashing ? (analysisResults.RightJustifiedSubstring ? ((!analysisResults.IgnoreCase) ? ((analysisResults.HashCount == 1) ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedSingleChar<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedSubstring<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount))) : (analysisResults.AllAsciiIfIgnoreCase ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveAsciiSubstring<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_RightJustifiedCaseInsensitiveSubstring<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount)))) : ((!analysisResults.IgnoreCase) ? ((analysisResults.HashCount == 1) ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedSingleChar<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedSubstring<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount))) : (analysisResults.AllAsciiIfIgnoreCase ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveAsciiSubstring<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_LeftJustifiedCaseInsensitiveSubstring<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount))))) : ((!analysisResults.IgnoreCase) ? new OrdinalStringFrozenDictionary_Full<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff) : (analysisResults.AllAsciiIfIgnoreCase ? ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_FullCaseInsensitiveAscii<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff)) : ((OrdinalStringFrozenDictionary<TValue>)new OrdinalStringFrozenDictionary_FullCaseInsensitive<TValue>(array, values, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff)))));
return (FrozenDictionary<TKey, TValue>)frozenDictionary;
}
if (source.Count <= 4)
return new SmallFrozenDictionary<TKey, TValue>(source);
return new DefaultFrozenDictionary<TKey, TValue>(source);
}
}
}