@@ -136,38 +136,44 @@ func makemap(t *maptype, hint int, h *hmap) *hmap {
136136
137137``` go
138138func mapaccess2 (t *maptype , h *hmap , key unsafe .Pointer ) (unsafe .Pointer , bool ) {
139- if raceenabled && h != nil {
140- callerpc := getcallerpc ()
141- pc := funcPC (mapaccess2)
142- racereadpc (unsafe.Pointer (h), callerpc, pc)
143- raceReadObjectPC (t.key , key, callerpc, pc)
144- }
145- if msanenabled && h != nil {
146- msanread (key, t.key .size )
147- }
139+ // map 为空,或者元素数为 0,直接返回未找到
148140 if h == nil || h.count == 0 {
149141 return unsafe.Pointer (&zeroVal[0 ]), false
150142 }
151143 if h.flags &hashWriting != 0 {
152144 throw (" concurrent map read and map write" )
153145 }
154146 alg := t.key .alg
147+ // 不同类型的 key,所用的 hash 算法是不一样的
148+ // 具体可以参考 algarray
155149 hash := alg.hash (key, uintptr (h.hash0 ))
150+ // 如果 B = 3,那么结果用二进制表示就是 111
151+ // 如果 B = 4,那么结果用二进制表示就是 1111
156152 m := bucketMask (h.B )
153+ // 按位 &,可以 select 出对应的 bucket
157154 b := (*bmap)(unsafe.Pointer (uintptr (h.buckets ) + (hash&m)*uintptr (t.bucketsize )))
155+ // 会用到 h.oldbuckets 时,说明 map 发生了扩容
156+ // 这时候,新的 buckets 里可能还没有老的内容
157+ // 所以一定要在老的里面找,否则有可能发生“消失”的诡异现象
158158 if c := h.oldbuckets ; c != nil {
159159 if !h.sameSizeGrow () {
160- // There used to be half as many buckets; mask down one more power of two.
160+ // 说明之前只有一半的 bucket,需要除 2
161161 m >>= 1
162162 }
163163 oldb := (*bmap)(unsafe.Pointer (uintptr (c) + (hash&m)*uintptr (t.bucketsize )))
164164 if !evacuated (oldb) {
165165 b = oldb
166166 }
167167 }
168+ // tophash 取其高 8bit 的值
168169 top := tophash (hash)
169170 for ; b != nil ; b = b.overflow (t) {
171+ // 一个 bucket 在存储满 8 个元素后,就再也放不下了
172+ // 这时候会创建新的 bucket
173+ // 挂在原来的 bucket 的 overflow 指针成员上
170174 for i := uintptr (0 ); i < bucketCnt; i++ {
175+ // 循环对比 bucket 中的 tophash 数组
176+ // 如果找到了相等的 tophash,那说明就是这个 bucket 了
171177 if b.tophash [i] != top {
172178 continue
173179 }
@@ -184,6 +190,8 @@ func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool)
184190 }
185191 }
186192 }
193+
194+ // 所有 bucket 都没有找到,返回零值和 false
187195 return unsafe.Pointer (&zeroVal[0 ]), false
188196}
189197```
0 commit comments