RainbowMango / GoExpertProgramming

《Go专家编程》Go语言快速入门,轻松进阶!
1.86k stars 306 forks source link

[勘误]反馈一个第1章第3节的内容错误 #102

Closed DaFeiL closed 2 years ago

DaFeiL commented 2 years ago

问题描述 网页版的内容有点小问题

如何找到这个错误

您认为应该如何? map扩容确实是渐进式扩容,但是每次搬迁时并不是搬迁两个键值对,而是尝试搬迁两个bucket 图片 image

其他补充信息 源代码里面,通过evacuate函数进行实际的搬迁,并且是进行线性遍历,会对与每个bucket及其链接的所有overflow bucket都会进行搬迁,所有并不仅仅是两个键值对

RainbowMango commented 2 years ago

请问你看的哪个版本的源吗?我确认一下

RainbowMango commented 2 years ago

感觉你说的是这里:

func growWork(t *maptype, h *hmap, bucket uintptr) {
    // make sure we evacuate the oldbucket corresponding
    // to the bucket we're about to use
    evacuate(t, h, bucket&h.oldbucketmask())

    // evacuate one more oldbucket to make progress on growing
    if h.growing() {
        evacuate(t, h, h.nevacuate)
    }
}

代码链接:https://github.com/golang/go/blob/0ed31eb73b13bd57aff727f4ab759c6701d45a01/src/runtime/map.go#L1126-L1135

DaFeiL commented 2 years ago

是的,这里evacute函数的实现逻辑,就是搬迁了整个buckte及相应的所有overflow bucket代码链接:https://github.com/golang/go/blob/0ed31eb73b13bd57aff727f4ab759c6701d45a01/src/runtime/map.go#L1173-L1247

------------------ 原始邮件 ------------------ 发件人: "Hongcai @.>; 发送时间: 2022年3月24日(星期四) 下午5:21 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [RainbowMango/GoExpertProgramming] [勘误]反馈一个第1章第3节的内容错误 (Issue #102)

感觉你说的是这里: func growWork(t maptype, h hmap, bucket uintptr) { // make sure we evacuate the oldbucket corresponding // to the bucket we're about to use evacuate(t, h, bucket&h.oldbucketmask()) // evacuate one more oldbucket to make progress on growing if h.growing() { evacuate(t, h, h.nevacuate) } }

代码链接:https://github.com/golang/go/blob/0ed31eb73b13bd57aff727f4ab759c6701d45a01/src/runtime/map.go#L1126-L1135

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

RainbowMango commented 2 years ago

感谢指出,

-考虑到如果map存储了数以亿计的键值对,一次性搬迁将会造成比较大的延时,Go采用逐步搬迁策略,即每次访问map时都会触发一次搬迁,每次搬迁2个键值对。
+考虑到如果map存储了数以亿计的键值对,一次性搬迁将会造成比较大的延时,Go采用逐步搬迁策略,即每次访问map时都会触发一次搬迁,每次搬迁2个bucket。

这么修改了。

PS:你看的网页版不知道是谁维护的 :(, 这个修改将在下次重印时修正。

DaFeiL commented 2 years ago

画红线部分也不准确(网页版),实际扩容条件如下:①当 B 小于 15,也就是 bucket 总数 2^B 小于 2^15 时,如果 overflow 的 bucket 数量超过 2^B;②当 B >= 15,也就是 bucket 总数 2^B 大于等于 2^15,如果 overflow 的 bucket 数量超过 2^15。代码链接:https://github.com/golang/go/blob/0ed31eb73b13bd57aff727f4ab759c6701d45a01/src/runtime/map.go#L1090-L1100

------------------ 原始邮件 ------------------ 发件人: "Hongcai @.>; 发送时间: 2022年3月24日(星期四) 晚上6:07 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [RainbowMango/GoExpertProgramming] [勘误]反馈一个第1章第3节的内容错误 (Issue #102)

感谢指出, -考虑到如果map存储了数以亿计的键值对,一次性搬迁将会造成比较大的延时,Go采用逐步搬迁策略,即每次访问map时都会触发一次搬迁,每次搬迁2个键值对。 +考虑到如果map存储了数以亿计的键值对,一次性搬迁将会造成比较大的延时,Go采用逐步搬迁策略,即每次访问map时都会触发一次搬迁,每次搬迁2个bucket。

这么修改了。

PS:你看的网页版不知道是谁维护的 :(, 这个修改将在下次重印时修正。

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

RainbowMango commented 2 years ago

纸质版目前的表述是:

触发扩容需要满足以下任一条件:
- 负载因子大于6.5时,也即平均每个bucket存储的键值对达到6.5个以上;
- overflow数量达到2^min(15,B)时;

有问题吗?

DaFeiL commented 2 years ago

没有问题,我看得到网页版,以为纸质版是一样的。祝好!

------------------ 原始邮件 ------------------ 发件人: "Hongcai @.>; 发送时间: 2022年3月24日(星期四) 晚上7:31 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [RainbowMango/GoExpertProgramming] [勘误]反馈一个第1章第3节的内容错误 (Issue #102)

纸质版目前的表述是: 触发扩容需要满足以下任一条件: - 负载因子大于6.5时,也即平均每个bucket存储的键值对达到6.5个以上; - overflow数量达到2^min(15,B)时;
有问题吗?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>

RainbowMango commented 2 years ago

再次感谢。

DaFeiL commented 2 years ago

1.18

------------------ 原始邮件 ------------------ 发件人: "Hongcai @.>; 发送时间: 2022年3月24日(星期四) 上午9:06 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [RainbowMango/GoExpertProgramming] [勘误]反馈一个第1章第3节的内容错误 (Issue #102)

请问你看的哪个版本的源吗?我确认一下

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you authored the thread.Message ID: @.***>