前言
本文介绍 golang 中 map 的实现方式, 希望对读者和我有所帮助
结构
mapkeyO(1)
golang 的 map 是 hashmap, 实现方式是数组+链表, 并且使用拉链法来取消 hash 的冲突
hmapbmap(bucket)
hmap
- 元素个数: int
- flags: uint8
- 扩容字段: uint8
- 溢出的 bucket 数量: uint16
- 用于扩容的指针: *mapextra
- buckets 数组指针: unsafa.Pointer
- 搬迁进度: uintptr
- 扩容时用于复制的 buckets 数组: unsafe.Pointer
- hash seed: uint32
buckets 数组指针bmapbmap
- 高位哈希: [8]uint8
- 字节数组(存储 key 和 value 的数组): []bytes
- 指向扩容 bucket 的指针: pointer
bmapkeyvalue
key
bmap
bmapbmapkeyvalue
key0, key1, key2, value0, value1, value2
keykeyvaluevalue
这是为了内存对齐, 目的是减少空间浪费
hmap
hmap
bmap0 bmap1 bmap2
| | |
bmap3 bmap4 bmap5
| | |
这种关系(我真是灵魂画手😘)
hmapbmapbmapbmapkeyvaluebmap
新增 key 时
keyvaluekey高位低位低位keybmap高位keybmap
map 扩容
bmapbmap
然后把老的数据迁移到新的数组中
bmapbmap
bmapbmap
查找 key 时
key高位低位低位bmap高位bmap