DiskLruCache 源碼解析 (三)—— 寫入緩存

上一篇我們看了 DiskLruCache open 方法
這篇我們看看寫入緩存的過程

image.png

首先我們指定一個 cacheName 就是緩存的 key 來獲取一個 editor
點進去看一下實現(xiàn)過程

edit 方法

再點進 edit 中

image.png

首先看 checkNotClosed

image.png

通過判斷 journalWriter (Writer 類)是否為空來判斷是否完成寫入操作
在看 validateKey

image.png

這里用正則表達式檢查 key 是否符合要求的格式 必須為數(shù)字或字母格式長度在1~64位之間

image.png

繼續(xù)向下 sequenceNumber 在 edit 方法中傳入了固定的 ANY_SEQUENCE_NUMBER 我們暫且跳過
接下來判斷 entry 是否為空 entry 是在 linkedHashMap 中通過 key 來獲取的對象實體,如果不存在創(chuàng)建一個新的并存入 map
如果存在 并且 正在編輯中(外部已經(jīng)持有一個 edit 對象) 返回空

image.png

接下來,在 entry 可用的情況下,創(chuàng)建一個新的 Editor 對象并將 entry 的編輯器 賦值
接下來在 journalFile 文件中寫入 dirty 記錄
返回 editor

image.png

接下來看看寫入數(shù)據(jù)過程
首先我將 bitmap 轉(zhuǎn)入 editor 的輸出流中,然后調(diào)用了 editor.commit()方法

commit 方法

判斷是否存在錯誤
如果存在錯誤 執(zhí)行 completeEdit(editor,false) 并刪除當前 entry
如果不存在錯誤 直接執(zhí)行 completeEdit(editor,true)
設(shè)置 commited 為 true

completeEdit

image.png

首先進行判斷 傳入的 editor 對應(yīng)的 entry 是否與傳入的 editor 匹配
不匹配拋出異常
接下來判斷 傳入的boolean 如果是成功 并且 entry.readable 是不可讀的
循環(huán) entry 內(nèi)的所有 value 判斷 written 標志為 false
執(zhí)行 editor.abort() 方法并拋出異常 entry 沒有 value 值
在判斷 entry 的 dirtyFile 是否存在 不存在執(zhí)行 abort

image.png

再向下,遍歷 entry 內(nèi)的所有 value
如果執(zhí)行成功的 completeEdit
將 entry 的 value 中 dirty 文件 轉(zhuǎn)為 clean 文件 更改entry 長度、尺寸。
如果執(zhí)行的失敗的 completeEdit 刪除 dirty 文件

image.png

繼續(xù)向下 redundantOpCount 計數(shù)+1
置空當前 entry 的 editor
如果是成功的操作 在 journalFile 中寫入 CLEAN 操作行
entry.sequenceNumber=nextSequenceNumber++ 這個還不清楚 稍后再看。
如果是失敗的的操作 在 journalFile 中寫入 REMOVE 操作行
寫入文件
判斷 當前緩存容量 與 用戶設(shè)置的最大容量,或者是 rebuild 請求操作

image.png

如果需要 rebuild journalFile

callable 線程
trimToSize 方法

循環(huán)刪除 lru 條件的 map entry
直到尺寸小于最大緩存容量
結(jié)束寫入流程

總結(jié)一下:
1、獲取 editor 時 會在 journal 中寫入一條 dirty 記錄
并在 lruMap 中創(chuàng)建/復用一個 entry
2、commit 方法 調(diào)用 completeEdit 方法 獲取 dirtyfile 并轉(zhuǎn)成 cleanfile
3、檢查容量是否超出限制,如果超出執(zhí)行整理操作,根據(jù) lru 刪除數(shù)據(jù)

我們還需要看一下 Entry類 這是一個 DiskLruCache 的內(nèi)部類

Entry類

屬性的注釋很清楚

image.png

我們看方法列表中有兩個熟悉的身影,getCleanFile() 和 getDirtyFile()

image.png

我們看到 cleanFile 是一個以 key 與 value 索引命名的文件
而 dirtyFile 是一個 tmp 文件 說明
當我們緩存數(shù)據(jù)時 是先將 editor 中流的數(shù)據(jù)寫入 dirty.tmp 中
確定后再轉(zhuǎn)到 cleanFile 中
我們回過頭在看一次 completeEdit()方法中的一段代碼

image.png

寫入數(shù)據(jù) commit 時 先判斷 dirty 是否存在,也就是判斷一下之前是否有

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容