go笔记——map

map的底层实现的原理

Go中的map是一个指针,占用8个字节,指向hmap结构体

源码包中src/runtime/map.go定义了hmap的数据结构:
hmap包含若干个结构为bmap的数组,每个bmap底层都采用链表结构,bmap通常叫其bucket

在这里插入图片描述


hmap结构体

// A header for a Go map.
type hmap struct{
   
count int
//代表哈希表中的元素个数,调用len(map)时,返回的就是该字段值。
flags uint8
//状态标志(是否处于正在写入的状态等跖)
B uint8
// buckets(桶)的对数
//如果B=5,则buckets数组的长度=2^B=32,意味着有32个桶
noverflow uint16
//溢出桶的数量
hash0 uint32
//生成hash的随机数种子
buckets unsafe.Pointer
//指向buckets数组的指针,数组大小为2^B,如果元素个数为0,它为nil
oldbuckets unsafe.Pointer
//如果发生扩容,oldbuckets是指向老的buckets数组的指针,老的buckets数组大小是新的buckets的1/2;非扩容状态下,它为nil。
nevacuate uintptr
//表示扩容进度,小于此地址的buckets代表已搬迁完成。
extra *mapextra
//存储溢出桶,这个字段是为了优化GC扫描而设计的,下面详细介绍
}

bmap的结构体

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

//A bucket for a Go map.
type bmap struct {
   
tophash [bucketcnt]uint8
//len为8的数组
//用来快速定位key是否在这个bmap中
//一个桶最多8个槽位,如果key所在的tophash值在tophash中,则代表该key在这个桶中
}

上面bmap结构是静态结构,在编译过程中runtime.bmap会拓展成以下结构体:

type bmap struct{
   
tophash [8]uint8
keys [8]keytype
// keytype由编译器编译时候确定
values [8]elemtype
// elemtype由编译器编译时候确定
overflow uintptr
// overflow指向下一个bmap,overflow是uintptr而不是*bmap类型,保证bmap完全不含指针,是为了减少gc,溢出桶
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值