@@ -492,65 +492,64 @@ func hashGrow(t *maptype, h *hmap) {
492492```
493493
494494``` go
495- // makeBucketArray initializes a backing array for map buckets.
496- // 1<<b is the minimum number of buckets to allocate.
497- // dirtyalloc should either be nil or a bucket array previously
498- // allocated by makeBucketArray with the same t and b parameters.
499- // If dirtyalloc is nil a new backing array will be alloced and
500- // otherwise dirtyalloc will be cleared and reused as backing array.
495+ // makeBucketArray 为 map buckets 初始化底层数组
496+ // 1<<b 是需要分配的最小数量 buckets
497+ // dirtyalloc 要么是 nil,要么就是之前由 makeBucketArray 使用同样的 t 和 b 参数
498+ // 分配的数组
499+ // 如果 dirtyalloc 是 nil,那么就会分配一个新数组,否则会清空掉原来的 dirtyalloc
500+ // 然后重用这部分内存作为新的底层数组
501501func makeBucketArray (t *maptype , b uint8 , dirtyalloc unsafe .Pointer ) (buckets unsafe .Pointer , nextOverflow *bmap ) {
502- base := bucketShift (b)
503- nbuckets := base
504- // For small b, overflow buckets are unlikely.
505- // Avoid the overhead of the calculation.
506- if b >= 4 {
507- // Add on the estimated number of overflow buckets
508- // required to insert the median number of elements
509- // used with this value of b.
510- nbuckets += bucketShift (b - 4 )
511- sz := t. bucket . size * nbuckets
512- up := roundupsize (sz)
513- if up != sz {
514- nbuckets = up / t. bucket . size
515- }
516- }
517-
518- if dirtyalloc == nil {
519- buckets = newarray (t. bucket , int (nbuckets))
520- } else {
521- // dirtyalloc was previously generated by
522- // the above newarray(t.bucket, int(nbuckets))
523- // but may not be empty.
524- buckets = dirtyalloc
525- size := t.bucket .size * nbuckets
526- if t.bucket .kind &kindNoPointers == 0 {
527- memclrHasPointers (buckets, size)
528- } else {
529- memclrNoHeapPointers (buckets, size)
530- }
531- }
532-
533- if base != nbuckets {
534- // We preallocated some overflow buckets.
535- // To keep the overhead of tracking these overflow buckets to a minimum,
536- // we use the convention that if a preallocated overflow bucket's overflow
537- // pointer is nil, then there are more available by bumping the pointer.
538- // We need a safe non-nil pointer for the last overflow bucket; just use buckets.
539- nextOverflow = (*bmap)(add (buckets, base*uintptr (t.bucketsize )))
540- last := (*bmap)(add (buckets, (nbuckets-1 )*uintptr (t.bucketsize )))
541- last.setoverflow (t, (*bmap)(buckets))
542- }
543- return buckets, nextOverflow
502+ // base = 1 << b
503+ base := bucketShift (b)
504+ nbuckets := base
505+ // 对于比较小的 b 来说,不太可能有 overflow buckets
506+ // 这里省掉一些计算消耗
507+ if b >= 4 {
508+ // Add on the estimated number of overflow buckets
509+ // required to insert the median number of elements
510+ // used with this value of b.
511+ nbuckets += bucketShift (b - 4 )
512+ sz := t. bucket . size * nbuckets
513+ up := roundupsize (sz)
514+ if up != sz {
515+ nbuckets = up / t. bucket . size
516+ }
517+ }
518+
519+ if dirtyalloc == nil {
520+ buckets = newarray (t. bucket , int (nbuckets))
521+ } else {
522+ // dirtyalloc 之前就是用上面的 newarray(t.bucket, int(nbuckets))
523+ // 生成的,所以是非空
524+ buckets = dirtyalloc
525+ size := t.bucket .size * nbuckets
526+ if t.bucket .kind &kindNoPointers == 0 {
527+ memclrHasPointers (buckets, size)
528+ } else {
529+ memclrNoHeapPointers (buckets, size)
530+ }
531+ }
532+
533+ if base != nbuckets {
534+ // 我们预分配了一些 overflow buckets
535+ // 为了让追踪这些 overflow buckets 的成本最低
536+ // 我们这里约定,如果预分配的 overflow bucket 的 overflow 指针是 nil
537+ // 那么 there are more available by bumping the pointer.
538+ // 我们需要一个安全的非空指针来作为 last overflow bucket,直接用 buckets 就行了
539+ nextOverflow = (*bmap)(add (buckets, base*uintptr (t.bucketsize )))
540+ last := (*bmap)(add (buckets, (nbuckets-1 )*uintptr (t.bucketsize )))
541+ last.setoverflow (t, (*bmap)(buckets))
542+ }
543+ return buckets, nextOverflow
544544}
545545```
546546
547547``` go
548548func growWork (t *maptype , h *hmap , bucket uintptr ) {
549- // make sure we evacuate the oldbucket corresponding
550- // to the bucket we're about to use
549+ // 确保我们移动的 oldbucket 对应的是我们马上就要用到的那一个
551550 evacuate (t, h, bucket&h.oldbucketmask ())
552551
553- // evacuate one more oldbucket to make progress on growing
552+ // 如果还在 growing 状态,再多移动一个 oldbucket
554553 if h.growing () {
555554 evacuate (t, h, h.nevacuate )
556555 }
0 commit comments