1 先看源码
// overLoadFactor reports whether count items placed in 1<<B buckets is over loadFactor. func overLoadFactor(count int, B uint8) bool { return count > bucketCnt && uintptr(count) > loadFactorNum*(bucketShift(B)/loadFactorDen) }
// bucketShift returns 1<<b, optimized for code generation. func bucketShift(b uint8) uintptr { // Masking the shift amount allows overflow checks to be elided. return uintptr(1) << (b & (sys.PtrSize*8 - 1)) }
// Maximum average load of a bucket that triggers growth is 6.5. // Represent as loadFactorNum/loadFactorDen, to allow integer math. loadFactorNum = 13 loadFactorDen = 2
// Maximum number of key/elem pairs a bucket can hold. bucketCntBits = 3 bucketCnt = 1 << bucketCntBits
通过上面源码可知负载因子为6.5,即当 count > 8 并且 b=b++ 直到(1<<b )* 6.5 >= count 为止,其中(1<<b ) 为桶的个数;
例如cap=9,则b=1,即桶个数为2^1= 2;
2 验证
通过dlv工具设置断点:
b runtime.makemap
func makemap(t *maptype, hint int, h *hmap) *hmap { mem, overflow := math.MulUintptr(uintptr(hint), t.bucket.size) if overflow || mem > maxAlloc { hint = 0 } .... }
函数参数 hint = 9,得出B=1
3 小结
make 函数的cap参数,作为count值 通过函数overLoadFactor reports whether count items placed in 1<<B buckets is over loadFactor.计算得到负载范围内的桶个数;