数据结构:
type hmap struct {
count int
flags uint8
B uint8
noverflow uint16
hash0 uint32
buckets unsafe.Pointer
oldbuckets unsafe.Pointer
nevacuate uintptr
extra *mapextra
}
type bmap struct {
tophash [8]uint8
data byte[1]
overflow *bmap
}
Set/Get 操作解析
- 用key Hash计算出64位值
- 取低B位 计算出key 在buckets数组中对应的 bmap
- 取高8位校验bmap是否存在当前的key
- 遍历bmap + overflow找到空位进行插入(Set)/ 找到对应的key返回元素值(Get)
- bmap 超过8个元素会把元素插入到overflow 溢出桶里面
扩容
条件满足其一触发扩容
- 负载因子过大 (count/2^B)>6.5,也就是说平均每个桶的元素超过了6.5个
- 溢出桶数量太多 noverflow > 2^B 当B>15时 noverflow> 2^15
扩容过程
- oldbuckets 指针指向buckets 地址
- B+1
- 创建新的 2^B 长度 bmap 数组出来,buckets 指向数组的地址
- 之后的操作会优先查oldbuckets,再查 buckets,并在操作中逐渐把oldbuckets 元素插入到新的buckets中,直到 oldbuckets 变为空