1. type Map struct {
  2. mu Mutexqwo
  3. // read是一个readOnly的指针,里面包含了一个map结构,就是我们说的只读map对该map的元素的访问
  4. // 不需要加锁,只需要通过atomic加载最新的指针即可
  5. read atomic.Value // readOnly
  6. // dirty包含部分map的键值对,如果要访问需要进行mutex获取
  7. // 最终dirty中的元素会被全部提升到read里面的map中
  8. dirty map[interface{}]*entry
  9. // misses是一个计数器用于记录从read中没有加载到数据
  10. // 尝试从dirty中进行获取的次数,从而决定将数据从dirty迁移到read的时机
  11. misses int
  12. }
  1. type readOnly struct {
  2. // m包含所有只读数据,不会进行任何的数据增加和删除操作
  3. // 但是可以修改entry的指针因为这个不会导致map的元素移动
  4. m map[interface{}]*entry
  5. // 标志位,如果为true则表明当前read只读map的数据不完整,dirty map中包含部分数据
  6. amended bool
  7. }

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的存储