type Map struct {
mu Mutexqwo
// read是一个readOnly的指针,里面包含了一个map结构,就是我们说的只读map对该map的元素的访问
// 不需要加锁,只需要通过atomic加载最新的指针即可
read atomic.Value // readOnly
// dirty包含部分map的键值对,如果要访问需要进行mutex获取
// 最终dirty中的元素会被全部提升到read里面的map中
dirty map[interface{}]*entry
// misses是一个计数器用于记录从read中没有加载到数据
// 尝试从dirty中进行获取的次数,从而决定将数据从dirty迁移到read的时机
misses int
}
type readOnly struct {
// m包含所有只读数据,不会进行任何的数据增加和删除操作
// 但是可以修改entry的指针因为这个不会导致map的元素移动
m map[interface{}]*entry
// 标志位,如果为true则表明当前read只读map的数据不完整,dirty map中包含部分数据
amended bool
}
Load方法中,会优先从read中读取,当read中不存在且dirty发生修改时,首先获取锁,然后从ditry中读取,此时misses++
当misser>= len(dirty)时,sync.map会将dirty中的元素迁移到read中
数据删除则分为两个过程,如果数据在read中,则就直接修改entry的标志位指向删除的指针即可,如果当前read中数据不全,则需要进行dirty里面的元素删除尝试,如果存在就直接从dirty中删除即可
map里面的指针
map里面存储数据都会涉及到一个问题就是存储值还是指针,存储值可以让 map作为一个大的的对象,减轻垃圾回收的压力(避免扫描所有小对象),而存储指针可以减少内存利用,而sync.Map中其实采用了指针结合惰性删除的方式,来进行 map的value的存储