forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Int32FrozenDictionary.cs
68 lines (54 loc) · 2.57 KB
/
Int32FrozenDictionary.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace System.Collections.Frozen
{
/// <summary>Provides a frozen dictionary to use when the key is an <see cref="int"/> and the default comparer is used.</summary>
/// <remarks>
/// This dictionary type is specialized as a memory optimization, as the frozen hash table already contains the array of all
/// int values, and we can thus use its array as the keys rather than maintaining a duplicate copy.
/// </remarks>
internal sealed class Int32FrozenDictionary<TValue> : FrozenDictionary<int, TValue>
{
private readonly FrozenHashTable _hashTable;
private readonly TValue[] _values;
internal Int32FrozenDictionary(Dictionary<int, TValue> source) : base(EqualityComparer<int>.Default)
{
Debug.Assert(ReferenceEquals(source.Comparer, EqualityComparer<int>.Default));
Debug.Assert(source.Count != 0);
KeyValuePair<int, TValue>[] entries = new KeyValuePair<int, TValue>[source.Count];
((ICollection<KeyValuePair<int, TValue>>)source).CopyTo(entries, 0);
_values = new TValue[entries.Length];
_hashTable = FrozenHashTable.Create(
entries.Length,
index => entries[index].Key,
(destIndex, srcIndex) => _values[destIndex] = entries[srcIndex].Value);
}
/// <inheritdoc />
private protected override int[] KeysCore => _hashTable.HashCodes;
/// <inheritdoc />
private protected override TValue[] ValuesCore => _values;
/// <inheritdoc />
private protected override Enumerator GetEnumeratorCore() => new Enumerator(_hashTable.HashCodes, _values);
/// <inheritdoc />
private protected override int CountCore => _hashTable.Count;
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private protected override ref readonly TValue GetValueRefOrNullRefCore(int key)
{
_hashTable.FindMatchingEntries(key, out int index, out int endIndex);
int[] hashCodes = _hashTable.HashCodes;
while (index <= endIndex)
{
if (key == hashCodes[index])
{
return ref _values[index];
}
index++;
}
return ref Unsafe.NullRef<TValue>();
}
}
}