277 字
1 分钟
map 的删除过程是怎样的
写操作底层的执行函数是 mapdelete:
func mapdelete(t *maptype, h *hmap, key unsafe.Pointer)根据 key 类型的不同,删除操作会被优化成更具体的函数:
| key 类型 | 删除 |
|---|---|
| uint32 | mapdelete_fast32(t *maptype, h *hmap, key uint32) |
| uint64 | mapdelete_fast64(t *maptype, h *hmap, key uint64) |
| string | mapdelete_faststr(t *maptype, h *hmap, ky string) |
当然,我们只关心 mapdelete 函数。它首先会检查 h.flags 标志,如果发现写标位是 1,直接 panic,因为这表明有其他协程同时在进行写操作。
计算 key 的哈希,找到落入的 bucket。检查此 map 如果正在扩容的过程中,直接触发一次搬迁操作。
删除操作同样是两层循环,核心还是找到 key 的具体位置。寻找过程都是类似的,在 bucket 中挨个 cell 寻找。
找到对应位置后,对 key 或者 value 进行“清零”操作:
// 对 key 清零if t.indirectkey { *(*unsafe.Pointer)(k) = nil} else { typedmemclr(t.key, k)}
// 对 value 清零if t.indirectvalue { *(*unsafe.Pointer)(v) = nil} else { typedmemclr(t.elem, v)}最后,将 count 值减 1,将对应位置的 tophash 值置成 Empty。
这块源码同样比较简单,感兴起直接去看代码。
相关阅读
本主题其他内容
Go 原理与面试问答
本主题共 67 篇 ·
Go 语言 专题 →
深入 Go runtime 源码:GMP 调度器工作机制、map 扩容与渐进式迁移、channel 收发与阻塞唤醒、interface 底层结构与类型断言、反射原理与 GC 三色标记,逐一拆解高频面试考点。