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>的继承体系也 ...
随机推荐
- EasyExcel中使用表头模板示例
解决方案 在EasyExcel的官方示例中,使用模板导出Excel,其结果仍然还会重新打印表头.不满足使用表头模板的需求.在参考源码后,找到如下解决方案. String templateFileNam ...
- GSAP 基础
GreenSock Animation Platform (GSAP) 是一个业界知名的动画库,它被1100多万个网站使用,有超过50%的获奖的网站都是用了它.不管是在原生环境中,还是任意的框架中,你 ...
- Flask工厂模式蓝图使用Celery实例【亲测可用,已应用于项目中】
单一模式运行Celery在官方文档中已经贴出范例代码,这里我们不过多介绍. 在使用Flaks编写大型项目时,使用工厂模式的好处显而易见.因在Celery4.x以上版本已经抛弃了init_app方法,所 ...
- *CTF和nssctf#16的wp
*ctf2023 fcalc 分析程序 本题存在漏洞,是生活中很容易犯的错误,就是循环或者判断的时候没有注意多一还是少一,这种会发生很严重的问题.比如这个题在过滤数字的时候没有过滤掉0,所以输入0的时 ...
- [碎碎念]和ljf老师聊天得到的一些启发,希望大家一起来吹水
关于写这个小文 和ljf老师聊天得到的一些启发,希望能够总结出来方便回顾,并且我觉得这些想法有一定的普适性,可以供大家参考. 疑问 我的疑问是,我现在主要在做fuzz+pwn,能够进行漏洞挖掘,以及w ...
- 7、Spring之基于注解管理bean
本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行. 7.1.环境搭建 创建名为spring_ioc_annotation的新module,过程参考3.1 ...
- 《SQL与数据库基础》21. 分库分表(一)
目录 分库分表(一) 拆分策略 垂直拆分 垂直分库 垂直分表 水平拆分 水平分库 水平分表 技术实现 MyCat概述 概念介绍 环境准备 目录介绍 MyCat入门 配置 分片配置(schema.xml ...
- Python 创建或读取 Excel 文件
Excel是一种常用的电子表格软件,广泛应用于金融.商业和教育等领域.它提供了强大的数据处理和分析功能,可进行各种计算和公式运算,并能创建各种类型的图表和可视化数据.Excel的灵活性使其成为处理和管 ...
- 国内镜像安装Python解释器及扩展包
一.下载Python解释器 1.下载地址 官网(下载速度很慢):Welcome to Python.org 淘宝镜像(推荐):CNPM Binaries Mirror (npmmirror.com) ...
- springboot3框架搭建
Spring Boot 3.0.0已经发布一段时间了,越来越多的公司考虑将技术框架升级到最新版本,JDK也相应要求JDK17以上.对应Spring Boot 2.x的版本,建议先升级到Spring B ...