sync.Map中amended和Delete删除中nil和expunged的理解

news/2024/11/17 19:38:30/

结论

amended: 意思是被修改过的,为true就是表明dirty和readOnly中的map的数据不相同了
readOnly中的map数据为nil: 就是正常的Delete()操作会让readOnly中的map数据值为nil,key还在
readOnly中的map数据被标记为expunged(擦去;删掉): 就是只有在readOnly生成dirty数据时,如果遇到readOnly中标记为nil的值,则标记为expunged,并且不放在dirty中,没有对应key和值

因为一个readOnly数据被抹去分为2种情况:

  1. 情况一(dirty提升为readOnly的map):
    1. 在readOnly中标记key对应的值为nil,dirty中数据的key直接被删除
    2. 在readOnly中的miss命中率太低了,然后dirty_map提升为readOnly中的map,readOnly中的nil值key被抹去(之前之前的dirty的key已经被删除掉了)
  2. 情况二(readOnly先生成dirty,之后再被dirty替换):
    1. 在readOnly中标记key对应的值为nil,dirty中数据的key直接被删除
    2. 插入过程引发的readOnly刷新未删除的数据到dirty(此时会将已经删除标记为nil的数据标记为expunged)(expunged状态可以在Store存储的时候恢复为nil)
    3. 等到后面miss命中率太低,然后dirty_map提升为readOnly的map,去除掉相对应的key值

从上面可以看出,nil状态下,dirty中可能有对应的key值。而expunged状态下,dirty绝对没有对应的key值,除非在增(改)的时候添加对应的key到dirty中,此时也会相对应地把expunged状态转化为nil状态

sync.Map介绍与参考文章

由浅入深聊聊Golang的sync.Map

理解的hack过程

Delete()为什么没有更改amended的状态

感觉这两个状态的理解要理解全部实现,发现删除Delete()是没有更改amended的状态的!!!这样的话,就会造成dirty和readOnly数据不一致(先暂时如此假设,后面会证实为错误,其实是对先前的一些定义没有深入理解),但是可能amended还是false

那么两次删除同一个数据,第一次readOlny标记为nil删除掉数据,第二次,!ok 而且还amended为false,那就导致dirty中存在数据

之后再反复读这个数据,一直miss…然后再dirty同步到readOnly,那岂不是没删除掉???

一定是哪里理解有偏差

理解了,因为readOnly和dirty中的entry指向同一片地址,所以第一次删除一个数据后,不用修改掉amended,还是完全一致的

所以得出结论是,amended在删,查的时候都不会发生变化,只有在增(改)的时候发生变化

但是同样还有这个问题就是,如果增加一个值后,连续删除这个值两次,那么就会第一次dirty中有值,第二次dirty中没有值,当然这时候readOnly是nil,但是其实是科学的,得出的结论就是nil状态下,dirty中可能有对应的key值

看了go1.18的源码就更加清晰了,源码中确定了无论dirty中是否有对应的值,也即是证明了有可能有值,有可能没有值,然后都让miss增加,因为走的是先readOnly再dirty的最长查找路径,所以需要尽快把dirty提升到readOnly上面

// LoadAndDelete deletes the value for a key, returning the previous value if any.
// The loaded result reports whether the key was present.
func (m *Map) LoadAndDelete(key any) (value any, loaded bool) {read, _ := m.read.Load().(readOnly)e, ok := read.m[key]if !ok && read.amended {m.mu.Lock()read, _ = m.read.Load().(readOnly)e, ok = read.m[key]if !ok && read.amended {e, ok = m.dirty[key]delete(m.dirty, key)// Regardless of whether the entry was present, record a miss: this key// will take the slow path until the dirty map is promoted to the read// map.m.missLocked()}m.mu.Unlock()}if ok {return e.delete()}return nil, false
}// Delete deletes the value for a key.
func (m *Map) Delete(key any) {m.LoadAndDelete(key)
}

http://www.ppmy.cn/news/4938.html

相关文章

【现代密码学原理】——期末复习(冲刺篇)

📖 前言:快考试了,做篇期末总结,都是重点与必考点。 博主预测考点: 计算题:RSA、Diffie-Hellman密钥交换、EIGamal 密钥交换、使用SHA-512算法,计算消息的Hash值、计算消息的HMAC 应用题&#…

Java注册登录及邮箱发送账号激活(主要技术栈SpringBoot,MyBatis)

文章目录前言学习之前需要掌握的知识项目环境搭建数据库的搭建前端页面的搭建后端代码格式pojomapperControllerservice最后前言 项目流程图如下: 这里我们通过: 163邮箱来实现激活码发送qq邮箱来进行接收 学习之前需要掌握的知识 springboot的基本使…

【计算机毕业设计】79.勤工助学管理系统源码

一、系统截图(需要演示视频可以私聊) 摘 要 随着我国教育需求不断增加,高校教育资源有限,教育经费相对不足的情况下,利用现代信息技术发展高等教育,不仅充分利用了优秀的教育资源,而且为更多的…

数据安全治理笔记

数据安全治理整理概述 数据安全治理不仅局限于组织内部,而是需要一个国家、行业组织、可言机构、企业和个人共同努力完成的课题。因此,应该分别重广义和狭义的角度看待数据安全治理。 广义地说:数据安全治理是在过数据安全战略的知道下&…

【机器学习实战】基于代价敏感学习的AdaCost方法用于信用卡欺诈检测

1. 数据集 数据集地址:Credit Card Fraud Detection 数据集整体浏览: 284807个样本,30个特征,1个分类标签Class Class为0的是多数类,一共有284315个样本。 Class为1的是少数类,一共有492个样本&#xff…

【微服务】Nacos 如何做到⼀致性协议下沉的与自研 Distro 协议

目录 一、⼀致性协议下沉 1、⼀致性协议抽象 2、数据存储抽象 二、Nacos 自研 Distro 协议 1、背景 2、设计思想 2.1、数据初始化 2.2、数据校验 2.3、写操作 2.4、读操作 3、小结 一、⼀致性协议下沉 既然 Nacos 已经做到了将 AP、CP 协议下沉到了内核模块&#xff…

CentOS 8:Tomcat服务器

Tomcat 本身是一个 Java程序,必须要有 Java 的运行环境。 1 下载 Tomcat 8.5 apache-tomcat-8.5.54.tar.gz 2 上传到 CentOS, 以 root 身份执行 3 解压缩 tar -zxvf apache-tomcat-8.5.54.tar.gz mv apache-tomcat-8.5.54 /opt/tomcat8.5 4 运行 /opt/tomcat…

用 Java?试试国产框架 Solon v1.11.5(带视频)

一个更现代感的 Java 应用开发框架:更快、更小、更自由。没有 Spring,没有 Servlet,没有 JavaEE;独立的轻量生态。主框架仅 0.1 MB。 Controller public class App {public static void main(String[] args) {Solon.start(App.cl…