Skip to content

Commit fdab470

Browse files
committed
update map
1 parent a654f77 commit fdab470

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

map.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,3 +1162,78 @@ indirectkey 变成了 true:
11621162
```
11631163

11641164
indirectvalue 也是完全一样的,超过 128 字节(不含)时,会被赋值为 true,并退化为指针。
1165+
1166+
## overflow 处理
1167+
1168+
思路,从 nextOverflow 中拿 overflow bucket,如果拿到,就放进 hmap.extra.overflow 数组,并让 bmap 的 overflow pointer 指向这个 bucket。
1169+
1170+
如果没找到,那就 new 一个。
1171+
1172+
```go
1173+
func (h *hmap) newoverflow(t *maptype, b *bmap) *bmap {
1174+
var ovf *bmap
1175+
if h.extra != nil && h.extra.nextOverflow != nil {
1176+
// We have preallocated overflow buckets available.
1177+
// See makeBucketArray for more details.
1178+
ovf = h.extra.nextOverflow
1179+
if ovf.overflow(t) == nil {
1180+
// We're not at the end of the preallocated overflow buckets. Bump the pointer.
1181+
h.extra.nextOverflow = (*bmap)(add(unsafe.Pointer(ovf), uintptr(t.bucketsize)))
1182+
} else {
1183+
// This is the last preallocated overflow bucket.
1184+
// Reset the overflow pointer on this bucket,
1185+
// which was set to a non-nil sentinel value.
1186+
ovf.setoverflow(t, nil)
1187+
h.extra.nextOverflow = nil
1188+
}
1189+
} else {
1190+
ovf = (*bmap)(newobject(t.bucket))
1191+
}
1192+
h.incrnoverflow()
1193+
if t.bucket.kind&kindNoPointers != 0 {
1194+
h.createOverflow()
1195+
*h.extra.overflow = append(*h.extra.overflow, ovf)
1196+
}
1197+
b.setoverflow(t, ovf)
1198+
return ovf
1199+
}
1200+
```
1201+
1202+
```go
1203+
func (h *hmap) createOverflow() {
1204+
if h.extra == nil {
1205+
h.extra = new(mapextra)
1206+
}
1207+
if h.extra.overflow == nil {
1208+
h.extra.overflow = new([]*bmap)
1209+
}
1210+
}
1211+
```
1212+
1213+
```go
1214+
// incrnoverflow increments h.noverflow.
1215+
// noverflow counts the number of overflow buckets.
1216+
// This is used to trigger same-size map growth.
1217+
// See also tooManyOverflowBuckets.
1218+
// To keep hmap small, noverflow is a uint16.
1219+
// When there are few buckets, noverflow is an exact count.
1220+
// When there are many buckets, noverflow is an approximate count.
1221+
func (h *hmap) incrnoverflow() {
1222+
// We trigger same-size map growth if there are
1223+
// as many overflow buckets as buckets.
1224+
// We need to be able to count to 1<<h.B.
1225+
if h.B < 16 {
1226+
h.noverflow++
1227+
return
1228+
}
1229+
// Increment with probability 1/(1<<(h.B-15)).
1230+
// When we reach 1<<15 - 1, we will have approximately
1231+
// as many overflow buckets as buckets.
1232+
mask := uint32(1)<<(h.B-15) - 1
1233+
// Example: if h.B == 18, then mask == 7,
1234+
// and fastrand & 7 == 0 with probability 1/8.
1235+
if fastrand()&mask == 0 {
1236+
h.noverflow++
1237+
}
1238+
}
1239+
```

0 commit comments

Comments
 (0)