标签:数据 返回 code for 计算 info 种子 actor poi
//初始化: 最重要的肯定就是确定一开始要有多少个桶,初始化哈希种子等等
func makemap_small() *hmap {
h := new(hmap)
h.hash0 = fastrand()
return h
}
// makemap implements Go map creation for make(map[k]v, hint).
func makemap(t *maptype, hint int, h *hmap) *hmap {
.....
// initialize Hmap
if h == nil {
h = (*hmap)(newobject(t.hmap))
}
h.hash0 = fastrand()
// find size parameter which will hold the requested # of elements
B := uint8(0)
for overLoadFactor(hint, B) {
B++
}
h.B = B
......
return h
}
存储逻辑结构
map数据结构
// A header for a Go map.
type hmap struct {
count int // len()返回的map的大小 即有多少kv对
flags uint8
B uint8 // 表示hash table总共有2^B个buckets
hash0 uint32 // hash seed
buckets unsafe.Pointer // 按照low hash值可查找的连续分配的数组,初始时为16个Buckets. 当bucket(桶为0时)为nil
oldbuckets unsafe.Pointer
nevacuate uintptr
overflow *[2]*[]*bmap //溢出链 当初始buckets都满了之后会使用overflow
}
// A bucket for a Go map.
type bmap struct {
tophash [bucketCnt]uint8
keys [8]keytype // 第二个是8个key、8个value
values [8]valuetype
pad uintptr
overflow uintptr // 第三个是溢出时,下一个溢出桶的地址
}
// 注意: key、value、overflow字段都不显示定义,而是通过maptype计算偏移获取的。
注:
之所以把所有k1k2放一起而不是k1v1是因为key和value的数据类型内存大小可能差距很大,
比如map[int64]int8,考虑到字节对齐,kv存在一起会浪费很多空间。
标签:数据 返回 code for 计算 info 种子 actor poi
原文地址:https://www.cnblogs.com/iiiiiher/p/12190108.html