CoreFX中Dictionary<TKey, TValue>的源码解读
1 Dictionary<int, string> openWith = new Dictionary<int, string>();
2 openWith.Add(1000, "key值为1000");
3 openWith.Add(1001, "key值为1001");
1 public Dictionary(int capacity, IEqualityComparer<TKey>? comparer)
2 {
3 if (capacity > 0) Initialize(capacity);
4 if (!typeof(TKey).IsValueType)
5 {
6 _comparer = comparer ?? EqualityComparer<TKey>.Default;
7 if (typeof(TKey) == typeof(string) && NonRandomizedStringEqualityComparer.GetStringComparer(_comparer!) is IEqualityComparer<string> stringComparer)
9 {
10 _comparer = (IEqualityComparer<TKey>)stringComparer;
11 }
12 }
13 else if (comparer is not null && comparer != EqualityComparer<TKey>.Default)
14 {
15 _comparer = comparer;
16 }
17 }
1 private int Initialize(int capacity)
2 {
3 int size = HashHelpers.GetPrime(capacity);
4 int[] buckets = new int[size];
5 Entry[] entries = new Entry[size];
6 _freeList = -1;
7 #if TARGET_64BIT
8 _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)size);
9 #endif
10 _buckets = buckets;
11 _entries = entries;
12 return size;
13 }
1 public static int GetPrime(int min)
2 {
3 foreach (int prime in Primes)
4 {
5 if (prime >= min) return prime;
6 for (int i = (min | 1); i < int.MaxValue; i += 2)
7 {
8 if (IsPrime(i) && ((i - 1) % HashPrime != 0)) return i;
9 }
10 return min;
11 }
12 }
1 internal static ReadOnlySpan<int> Primes => new int[]
2 {
3 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919,
4 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591,
5 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437,
6 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263,
7 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369
8 };
public static ulong GetFastModMultiplier(uint divisor) => ulong.MaxValue / divisor + 1;
1 private struct Entry
2 {
3 public uint hashCode;
4 public int next;
5 public TKey key;
6 public TValue value;
7 }
1 private ref int GetBucket(uint hashCode)
2 {
3 int[] buckets = _buckets!;
4 #if TARGET_64BIT
5 return ref buckets[HashHelpers.FastMod(hashCode, (uint)buckets.Length, _fastModMultiplier)];
6 #else
7 return ref buckets[(uint)hashCode % buckets.Length];
8 #endif
9 }
private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
{
Entry[]? entries = _entries;
uint hashCode = (uint) key.GetHashCode() ;
uint collisionCount = 0;
ref int bucket = ref GetBucket(hashCode);
int i = bucket - 1;
int index;
if (_freeCount > 0)
{
index = _freeList;
_freeList = StartOfFreeList - entries[_freeList].next;
_freeCount--;
}
else
{
int count = _count;
if (count == entries.Length)
{
Resize();
bucket = ref GetBucket(hashCode);
}
index = count;
_count = count + 1;
entries = _entries;
} ref Entry entry = ref entries![index];
entry.hashCode = hashCode;
entry.next = bucket - 1;
entry.key = key;
entry.value = value;
bucket = index + 1;
_version++; return true;
}
1 private void Resize() => Resize(HashHelpers.ExpandPrime(_count), false);
2
3 private void Resize(int newSize, bool forceNewHashCodes)
4 {
5 Entry[] entries = new Entry[newSize];
6 int count = _count;
7 Array.Copy(_entries, entries, count);
8 _buckets = new int[newSize];
9 #if TARGET_64BIT
10 _fastModMultiplier = HashHelpers.GetFastModMultiplier((uint)newSize);
11 #endif
12 for (int i = 0; i < count; i++)
13 {
14 if (entries[i].next >= -1)
15 {
16 ref int bucket = ref GetBucket(entries[i].hashCode);
17 entries[i].next = bucket - 1;
18 bucket = i + 1;
19 }
20 }
21 _entries = entries;
22 }
1 public static int ExpandPrime(int oldSize)
2 {
3 int newSize = 2 * oldSize;
4 if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize) return MaxPrimeArrayLength;
5 return GetPrime(newSize);
6 }
1 internal ref TValue FindValue(TKey key)
2 {
3 ref Entry entry = ref Unsafe.NullRef<Entry>();
4 if (_buckets != null)
5 {
6 uint hashCode = (uint)key.GetHashCode();
7 int i = GetBucket(hashCode);
8 Entry[]? entries = _entries;
9 uint collisionCount = 0;
10 i--;
11 do
12 {
13 if ((uint)i >= (uint)entries.Length)
14 {
15 goto ReturnNotFound;
16 }
17 entry = ref entries[i];
18 if (entry.hashCode == hashCode && EqualityComparer<TKey>.Default.Equals(entry.key, key))
19 {
20 goto ReturnFound;
21 }
22 i = entry.next;
23 collisionCount++;
24 } while (collisionCount <= (uint)entries.Length);
25 goto ConcurrentOperation;
26 }
27 goto ReturnNotFound;
28 ConcurrentOperation:
29 ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
30 ReturnFound:
31 ref TValue value = ref entry.value;
32 Return:
33 return ref value;
34 ReturnNotFound:
35 value = ref Unsafe.NullRef<TValue>();
36 goto Return;
37 }
CoreFX中Dictionary<TKey, TValue>的源码解读的更多相关文章
- .NET中Dictionary<TKey, TValue>浅析
.NET中Dictionary<TKey, Tvalue>是非常常用的key-value的数据结构,也就是其实就是传说中的哈希表..NET中还有一个叫做Hashtable的类型,两个类型都 ...
- go 中 sort 如何排序,源码解读
sort 包源码解读 前言 如何使用 基本数据类型切片的排序 自定义 Less 排序比较器 自定义数据结构的排序 分析下源码 不稳定排序 稳定排序 查找 Interface 总结 参考 sort 包源 ...
- C#中Dictionary<TKey,TValue>排序方式
自定义类: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy ...
- Twitter Storm中Bolt消息传递路径之源码解读
本文初次发表于storm-cn的google groups中,现以blog的方式再次发表,表明本人徽沪一郎确实读过这些代码,:). Bolt作为task被executor执行,而executor是一个 ...
- Spark-1.6.0中的Sort Based Shuffle源码解读
从Spark-1.2.0开始,Spark的Shuffle由Hash Based Shuffle升级成了Sort Based Shuffle.即Spark.shuffle.manager从Hash换成了 ...
- springBoot 日志中关于profiles设置的源码解读
在启动SpringBoot应用是看到到如下日志,于是出于好奇查看了下源代码: 首先,StartpInfoLogger类,采用jcl-over-slf4j[即Apache Common Log]中的Lo ...
- .net源码分析 – Dictionary<TKey, TValue>
接上篇:.net源码分析 – List<T> Dictionary<TKey, TValue>源码地址:https://github.com/dotnet/corefx/blo ...
- C# .Net 中字典Dictionary<TKey,TValue>泛型类 学习浅谈
一.综述: Dictionary<TKey,TValue>是在 .NET Framework 2.0 版中是新增的.表示键值对的集合,Dictionary<TKey,TValue&g ...
- C#中数组、集合(ArrayList)、泛型集合List<T>、字典(dictionary<TKey,TValue>)全面对比
C#中数组.集合(ArrayList).泛型集合List<T>.字典(dictionary<TKey,TValue>)全面对比 为什么把这4个东西放在一起来说,因为c#中的这4 ...
- c# 图解泛型List<T>, HashTable和Dictionary<TKey,TValue>
前辈在代码中使用了HashTable,由于我用的比较少,不能理解,为什么不用Dictionary?看了源码以及查阅资料,总结如下: 首先看看它们的继承体系: 我把list<T>的继承体系也 ...
随机推荐
- 2021-3-9 excel导出
public void ExportExcel(DataTable dt) { //要添加epplus的nuget包 ExcelPackage.LicenseContext = LicenseCont ...
- html元数据
元数据就是用来描述数据的数据.HTML中也有很多元数据. <meta>标签提供关于HTML文档的元数据:描述(description)\关键词(keywords).文档的作者(author ...
- [Python]树基础
关于树 树是一种数据结构,由n个有限节点组成的一个具有层次关系的集合.二叉树则是每个节点最多有两个子树的树结构.二叉树一般有以下性质: 二叉树第k层上的节点数目最多为 \(2^{k-1}\) 深度为 ...
- quarkus依赖注入之九:bean读写锁
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<quarkus依赖注入> ...
- 3.0 Python 迭代器与生成器
当我们需要处理一个大量的数据集合时,一次性将其全部读入内存并处理可能会导致内存溢出.此时,我们可以采用迭代器Iterator和生成器Generator的方法,逐个地处理数据,从而避免内存溢出的问题. ...
- 使用 Sealos 在离线环境中光速安装 K8s 集群
作者:尹珉.Sealos 开源社区 Ambassador,云原生爱好者. 当容器化交付遇上离线环境 在当今快节奏的软件交付环境中,容器化交付已经成为许多企业选择的首选技术手段.在可以访问公网的环境下, ...
- 2.2 PE结构:文件头详细解析
PE结构是Windows系统下最常用的可执行文件格式,理解PE文件格式不仅可以理解操作系统的加载流程,还可以更好的理解操作系统对进程和内存相关的管理知识,DOS头是PE文件开头的一个固定长度的结构体, ...
- WPF学习 - 自定义窗体(二)
上一篇文章写了如何创建自定义窗体:使用 WindowChrome 或者 WindowStyle="None"这两种方式.本文将讲述如何设置窗体的效果(以阴影效果为例),以及在效果模 ...
- 面霸的自我修养:ThreadLocal专题
王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 今天是<面霸的自我修养>第5篇文章,我们一起来看看面试中会问到哪些关于ThreadLocal ...
- SQL函数union,union all整理
SQL集合函数--并集union,union all 本次整理从4个方面展示union函数,union all函数的风采: 1.集合函数使用规则 2.集合函数作用 3.数据准备及函数效果展示 首先1. ...