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>的继承体系也 ...
随机推荐
- 【实践篇】推荐算法PaaS化探索与实践
作者:京东零售 崔宁 1. 背景说明 目前,推荐算法部支持了主站.企业业务.全渠道等20+业务线的900+推荐场景,通过梳理大促运营.各垂直业务线推荐场景的共性需求,对现有推荐算法能力进行沉淀和积累, ...
- <学习笔记> 关于错排列
1 是做排列计数的时候了解到这个东西: 一开始想的是用容斥原理,先加上全排列,再减去不满足的,再加上重复的,再减去不满足的...... 后来发现还涉及到杨辉三角,麻烦死了,时空复杂度也过不去,然后就知 ...
- ASP.NET WebForm中在TextBox输入框回车时会触发其他事件,如何处理?
一.TextBox在输入框回车时会触发其他事件,如何解决? 前台代码: <ul> <li><span>名称:</span><asp:TextBox ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-14-playwright操作iframe-番外篇
1.简介 通过前边三篇的学习,想必大家已经对iframe有了一定的认识和了解,今天这一篇主要是对iframe的一些特殊情况的介绍和讲解,主要从iframe的定位.监听事件和执行js脚本三个方面进行展开 ...
- 《SQL与数据库基础》06. 函数
目录 函数 字符串函数 数值函数 日期函数 流程函数 本文以 MySQL 为例 函数 函数是指一段可以直接被另一段程序调用的程序或代码. 要查看函数操作的结果,可以使用 SELECT 函数(参数); ...
- Spring中事务的传播行为有哪些?
Spring中事务的传播行为有哪些? 现在我们来谈一个场景,再来引出事务传播行为这个概念.现在有methodA( ) 和 methodB( ),而且两个方法都显示的开启了事务,那么methodB( ) ...
- KRPano插件一键解密大师 支持最新版KRPano XML/JS解密 ,支持分析下载静态/动态网站资源
KRPano插件一键解密大师,可以一键解密KRPano的XML/JS插件,并可以分析下载静态和动态网站的所有资源.软件下载安装即可使用,解密仅需鼠标一键点击即可,无需配置任何开发环境,方便全景开发人员 ...
- 全景VR KRPano项目打包成安卓APP快速简易教程
有时候,我们可能不想把我们制作的全景VR项目发布到网站上,而是想把它作为一个手机应用来使用或者分享.这样,我们就可以更好地保护我们的作品,也可以更方便地展示给客户或者朋友.本文将介绍一种简单的方法,让 ...
- Content Security Policy(CSP)应用及说明
什么是CSP CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源( ...
- 在线问诊 Python、FastAPI、Neo4j — 构建问题分类器
目录 构建字典数据 构建 Trie 字典树 按实体组装字典 问题分析 将问题进行分析,和系统已有的分类进行关联 构建字典数据 将构建的知识图片字典化, 用于后面对问题的解析,下图为症状的字典,其它字典 ...