Map的随机遍历
/*
hiter 是遍历 map 时用于存放临时数据的迭代器:
(1)key:指向遍历得到 key 的指针;
(2)value:指向遍历得到 value 的指针;
(3)t:map 类型,包含了 key、value 类型大小等信息;
(4)h:map 的指针;
(5)buckets:map 的桶数组;
(6)bptr:当前遍历到的桶;
(7)overflow:新老桶数组对应的溢出桶;
(8)startBucket:遍历起始位置的桶索引;
(9)offset:遍历起始位置的 key-value 对索引;
(10)wrapped:遍历是否穿越桶数组尾端回到头部了;
(11)B:桶数组的长度指数;
(12)i:当前遍历到的 key-value 对在桶中的索引;
(13)bucket:当前遍历到的桶;
(14)checkBucket:因为扩容流程的存在,需要额外检查的桶
*/
type hiter struct {
key unsafe.Pointer
elem unsafe.Pointer
t *maptype
h *hmap
buckets unsafe.Pointer
bptr *bmap
overflow *[]*bmap
oldoverflow *[]*bmap
startBucket uintptr
offset uint8
wrapped bool
B uint8
i uint8
bucket uintptr
checkBucket uintptr
}
- 迭代器的初始化
func mapiterinit(t *maptype, h *hmap, it *hiter) {
it.t = t
if h == nil || h.count == 0 {
return
}
it.h = h
it.B = h.B
it.buckets = h.buckets
if t.bucket.ptrdata == 0 {
h.createOverflow()
it.overflow = h.extra.overflow
it.oldoverflow = h.extra.oldoverflow
}
// decide where to start
var r uintptr
r = uintptr(fastrand())
// 通过随机数,选择从哪个桶开始
it.startBucket = r & bucketMask(</