Skip to content

Commit 8d08cbc

Browse files
committed
update map
1 parent 4d1cca2 commit 8d08cbc

File tree

1 file changed

+18
-10
lines changed

1 file changed

+18
-10
lines changed

map.md

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,38 +136,44 @@ func makemap(t *maptype, hint int, h *hmap) *hmap {
136136

137137
```go
138138
func 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

Comments
 (0)