FrozenSet
Provides a set of initialization methods for instances of the FrozenSet<T> class.
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace System.Collections.Frozen
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class FrozenSet
{
public static FrozenSet<T> Create<[System.Runtime.CompilerServices.Nullable(2)] T>([ParamCollection] [ScopedRef] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> source)
{
return Create(null, source);
}
public static FrozenSet<T> Create<[System.Runtime.CompilerServices.Nullable(2)] T>([System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] IEqualityComparer<T> equalityComparer, [ParamCollection] [ScopedRef] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> source)
{
if (source.Length == 0) {
if (equalityComparer != null && equalityComparer != FrozenSet<T>.Empty.Comparer)
return new EmptyFrozenSet<T>(equalityComparer);
return FrozenSet<T>.Empty;
}
HashSet<T> hashSet = new HashSet<T>(equalityComparer);
ReadOnlySpan<T> readOnlySpan = source;
foreach (T item in readOnlySpan) {
hashSet.Add(item);
}
return hashSet.ToFrozenSet(equalityComparer);
}
public static FrozenSet<T> ToFrozenSet<[System.Runtime.CompilerServices.Nullable(2)] T>(this IEnumerable<T> source, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] IEqualityComparer<T> comparer = null)
{
HashSet<T> newSet;
return GetExistingFrozenOrNewSet(source, comparer, out newSet) ?? CreateFromSet(newSet);
}
private static FrozenSet<T> GetExistingFrozenOrNewSet<T>(IEnumerable<T> source, IEqualityComparer<T> comparer, out HashSet<T> newSet)
{
ThrowHelper.ThrowIfNull(source, "source");
if (comparer == null)
comparer = EqualityComparer<T>.Default;
FrozenSet<T> frozenSet = source as FrozenSet<T>;
if (frozenSet != null && frozenSet.Comparer.Equals(comparer)) {
newSet = null;
return frozenSet;
}
newSet = (source as HashSet<T>);
if (newSet == null || (newSet.Count != 0 && !newSet.Comparer.Equals(comparer)))
newSet = new HashSet<T>(source, comparer);
if (newSet.Count == 0) {
if (comparer != FrozenSet<T>.Empty.Comparer)
return new EmptyFrozenSet<T>(comparer);
return FrozenSet<T>.Empty;
}
return null;
}
private static FrozenSet<T> CreateFromSet<T>(HashSet<T> source)
{
IEqualityComparer<T> comparer = source.Comparer;
if (typeof(T).IsValueType && comparer == EqualityComparer<T>.Default) {
if (source.Count <= 10) {
if (Constants.IsKnownComparable<T>())
return (FrozenSet<T>)new SmallValueTypeComparableFrozenSet<T>(source);
return (FrozenSet<T>)new SmallValueTypeDefaultComparerFrozenSet<T>(source);
}
if (typeof(T) == typeof(int))
return (FrozenSet<T>)new Int32FrozenSet((HashSet<int>)source);
return new ValueTypeDefaultComparerFrozenSet<T>(source);
}
if (typeof(T) == typeof(string) && !source.Contains(default(T)) && (comparer == EqualityComparer<T>.Default || comparer == StringComparer.Ordinal || comparer == StringComparer.OrdinalIgnoreCase)) {
IEqualityComparer<string> equalityComparer = (IEqualityComparer<string>)comparer;
HashSet<string> obj = (HashSet<string>)source;
string[] array = new string[obj.Count];
obj.CopyTo(array);
int num = 2147483647;
int num2 = 0;
ulong num3 = 0;
string[] array2 = array;
foreach (string text in array2) {
if (text.Length < num)
num = text.Length;
if (text.Length > num2)
num2 = text.Length;
num3 = (ulong)((long)num3 | (1 << text.Length % 64));
}
FrozenSet<string> frozenSet = LengthBucketsFrozenSet.CreateLengthBucketsFrozenSetIfAppropriate(array, equalityComparer, num, num2);
if (frozenSet != null)
return (FrozenSet<T>)frozenSet;
KeyAnalyzer.AnalysisResults analysisResults = KeyAnalyzer.Analyze(array, equalityComparer == StringComparer.OrdinalIgnoreCase, num, num2);
frozenSet = (analysisResults.SubstringHashing ? (analysisResults.RightJustifiedSubstring ? ((!analysisResults.IgnoreCase) ? ((analysisResults.HashCount == 1) ? ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_RightJustifiedSingleChar(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex)) : ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_RightJustifiedSubstring(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount))) : (analysisResults.AllAsciiIfIgnoreCase ? ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_RightJustifiedCaseInsensitiveAsciiSubstring(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount)) : ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_RightJustifiedCaseInsensitiveSubstring(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount)))) : ((!analysisResults.IgnoreCase) ? ((analysisResults.HashCount == 1) ? ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_LeftJustifiedSingleChar(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex)) : ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_LeftJustifiedSubstring(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount))) : (analysisResults.AllAsciiIfIgnoreCase ? ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_LeftJustifiedCaseInsensitiveAsciiSubstring(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount)) : ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_LeftJustifiedCaseInsensitiveSubstring(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, analysisResults.HashIndex, analysisResults.HashCount))))) : ((!analysisResults.IgnoreCase) ? new OrdinalStringFrozenSet_Full(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, num3) : (analysisResults.AllAsciiIfIgnoreCase ? ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_FullCaseInsensitiveAscii(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, num3)) : ((OrdinalStringFrozenSet)new OrdinalStringFrozenSet_FullCaseInsensitive(array, equalityComparer, analysisResults.MinimumLength, analysisResults.MaximumLengthDiff, num3)))));
return (FrozenSet<T>)frozenSet;
}
if (source.Count <= 4)
return new SmallFrozenSet<T>(source);
return new DefaultFrozenSet<T>(source);
}
}
}