IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> sync.Map中amended和Delete删除中nil和expunged的理解 -> 正文阅读

[移动开发]sync.Map中amended和Delete删除中nil和expunged的理解

结论

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)
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-12-25 11:21:31  更:2022-12-25 11:23:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 22:25:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码