go map

go 复制代码
// A header for a Go map.
type hmap struct {
   // Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
   // Make sure this stays in sync with the compiler's definition.
   // 元素个数,len(map)
   count     int // # live cells == size of map.  Must be first (used by len() builtin)
   // 标记是否有线程正在写
   flags     uint8
   // buckets 的对数 log_2
   B         uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
   // overflow的bucket大致数量
   noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
   //  哈希的种子,它能为哈希函数的结果引入随机性,这个值在创建哈希表时确定,并在调用哈希函数时作为参数传入
   hash0     uint32 // hash seed

   // buckets 数组,大小为 2^B
   buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
   // 旧map,不为nil时表示正在扩容
   oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
   // 扩容进度,小于此地址的 buckets 是已经迁移完成的
   nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)

   extra *mapextra // optional fields
}

buckets 是一个指针,最终它指向的是一个结构体:

go 复制代码
// A bucket for a Go map.
type bmap struct {
   // tophash generally contains the top byte of the hash value
   // for each key in this bucket. If tophash[0] < minTopHash,
   // tophash[0] is a bucket evacuation state instead.
   tophash [bucketCnt]uint8
   // Followed by bucketCnt keys and then bucketCnt elems.
   // NOTE: packing all the keys together and then all the elems together makes the
   // code a bit more complicated than alternating key/elem/key/elem/... but it allows
   // us to eliminate padding which would be needed for, e.g., map[int64]int8.
   // Followed by an overflow pointer.
}

运行时:

go 复制代码
type bmap struct {
    topbits  [8]uint8
    keys     [8]keytype
    values   [8]valuetype
    pad      uintptr
    overflow uintptr
}

bmap 就是我们常说的"桶",桶里面会最多装 8 个 key,这些 key 之所以会落入同一个桶,是因为它们经过哈希计算后,哈希结果是"一类"的。在桶内,又会根据 key 计算出来的 hash 值的高 8 位来决定 key 到底落入桶内的哪个位置(一个桶内最多有8个位置)。

相关推荐
李少兄1 小时前
JavaScript 数据类型完全指南
开发语言·javascript·ecmascript
Seoyoneh1 小时前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
Tangyuewei2 小时前
Java 写 Agent:模型只是组件
java·开发语言
小玮看世界2 小时前
[Python]从合并区间到传感器融合区:合并区间在传感器区域融合的实际落地
开发语言·python
繁星蓝雨3 小时前
C++的设计与演进大纲(如何从C语言一步步成长为C++)
c语言·开发语言·c++·c++历史·c++演进
HotCoffee-GPS3 小时前
Golang性能分析pprof
golang
Evand J3 小时前
【MATLAB例程,图像降噪滤波9】自适应维纳滑动窗口滤波(Wiener)图像降噪、方法对比,有中文注释
开发语言·图像处理·计算机视觉·matlab·滑动窗口·滤波·降噪
杜大哥4 小时前
python程序:如何查看电脑【电池电量的剩余百分比】 和 【是否插入连接着充电器】?
开发语言·python
wuyk5554 小时前
Python网络爬虫入门到实战 第01章:爬虫到底是什么?原理、流程、合法性、风险全解析(零基础必看)
开发语言·爬虫·python
yurenpai(27届找实习中)4 小时前
Java 10 的 var 为什么不能随便用?从订单汇总看懂类型推断与泛型陷阱
java·开发语言·java18