func makemapt maptype hint int h hmap hmap mem overflow = mathMulUintptruintptrhint tbucketsize if overflow mem maxAlloc hint = 0 initialize Hmap if h == nil h = newhmap hhash0 = fastrand F
func makemap(t *maptype, hint int, h *hmap) *hmap { // t表示map元素的类型,hint表示期望的map元素个数,h表示是否已经分配过内存 // 计算需要分配的内存大小,如果超出了最大可分配内存,hint就会被设为0 mem, overflow := math.MulUintptr(uintptr(hint), t.bucket.size) if overflow || mem > maxAlloc { hint = 0 }
// 初始化hmap
if h == nil {
h = new(hmap)
}
h.hash0 = fastrand() // 生成一个随机数
// 找到最小的B值,使得可以容纳所需的元素个数
B := uint8(0)
for overLoadFactor(hint, B) {
B++
}
h.B = B
// 分配初始哈希表内存
// 如果B = 0,则buckets字段会在mapassign函数被延迟分配
// 如果hint很大,清零内存可能需要一段时间
if h.B != 0 {
var nextOverflow *bmap
h.buckets, nextOverflow = makeBucketArray(t, h.B, nil)
if nextOverflow != nil {
h.extra = new(mapextra)
h.extra.nextOverflow = nextOverflow
}
}
return h
}
// overLoadFactor判断指定的元素个数是否可以放到B个桶中 // 如果元素个数小于桶的数量,则返回false // 否则,如果元素个数大于桶的数量并且超出了负载因子,则返回true func overLoadFactor(n int, B uint8) bool { if n/B > loadFactorNum { return true } if n == 0 { return false } loadFactorDen := uint8(n - 1) return B >= uint8(float64(loadFactorNum*loadFactorDen)/float64(loadFactorDen)) }
原文地址: https://www.cveoy.top/t/topic/bZOL 著作权归作者所有。请勿转载和采集!