杨充 4 rokov pred
rodič
commit
3a846008d1

+ 12 - 7
VideoSqlLite/read/05.DiskLruCache源码分析.md

@@ -67,13 +67,18 @@
     - ② CLEAN: 该状态表示一个缓存Entry已经被成功发布了并且可以读取,该行后面会有每个Value的大小。
     - ③ READ: 在LRU缓存中被读取了。
     - ④ REMOVE: 表示被删除的缓存Entry。
-- REMOVE 除了上述的情况,当你自己手动调用 remove(key) 方法的时候也会写入一条 REMOVE 记录。
-    - 如果你足够细心的话应该还会注意到,第七行的那条记录,除了 CLEAN 前缀和 key 之外,后面还有一个1208,这是什么意思呢?
-    - 其实,DiskLruCache 会在每一行 CLEAN 记录的最后加上该条缓存数据的大小,以字节为单位。1208 也就是我们缓存文件的字节数了。
-    - 源码中的 size() 方法可以获取到当前缓存路径下所有缓存数据的总字节数,其实它的工作原理就是把 journal 文件中所有 CLEAN 记录的字节数相加,返回求出的总和。
-- 前缀是 READ 的记录,每当我们调用 get() 方法去读取一条缓存数据时,就会向 journal 文件中写入一条 READ 记录。
-    - 因此,图片和数据量都非常大的 APP 的 journal 文件中就可能会有大量的 READ 记录。那如果我不停地频繁操作的话,就会不断地向 journal 文件中写入数据,那这样 journal 文件岂不是会越来越大?
-    - 这倒不必担心,DiskLruCache 中使用了一个 redundantOpCount 变量来记录用户操作的次数,每执行一次写入、读取或移除缓存的操作,这个变量值都会加 1,当变量值达到 2000 的时候就会触发重构 journal 的事件,这时会自动把 journal 中一些多余的、不必要的记录全部清除掉,保证 journal 文件的大小始终保持在一个合理的范围内。
+- 第六行后的分析
+    - 第六行是以一个DIRTY前缀开始的,后面紧跟着缓存图片的key。
+        - 通常我们看到DIRTY这个字样都不代表着什么好事情,意味着这是一条脏数据。没错,每当我们调用一次DiskLruCache的edit()方法时,都会向journal文件中写入一条DIRTY记录,表示我们正准备写入一条缓存数据,但不知结果如何。
+        - 然后调用commit()方法表示写入缓存成功,这时会向journal中写入一条CLEAN记录,意味着这条“脏”数据被“洗干净了”,调用abort()方法表示写入缓存失败,这时会向journal中写入一条REMOVE记录。
+        - 也就是说,每一行DIRTY的key,后面都应该有一行对应的CLEAN或者REMOVE的记录,否则这条数据就是“脏”的,会被自动删除掉。
+    - 第七行的那条记录,除了 CLEAN 前缀和 key 之外,后面还有一个1208,这是什么意思呢?
+        - 其实,DiskLruCache 会在每一行 CLEAN 记录的最后加上该条缓存数据的大小,以字节为单位。1208 也就是我们缓存文件的字节数了。
+        - 源码中的 size() 方法可以获取到当前缓存路径下所有缓存数据的总字节数,其实它的工作原理就是把 journal 文件中所有 CLEAN 记录的字节数相加,返回求出的总和。
+    - 第八行的那个前缀是 READ 的记录
+        - 每当我们调用 get() 方法去读取一条缓存数据时,就会向 journal 文件中写入一条 READ 记录。
+        - 因此,图片和数据量都非常大的 APP 的 journal 文件中就可能会有大量的 READ 记录。那如果我不停地频繁操作的话,就会不断地向 journal 文件中写入数据,那这样 journal 文件岂不是会越来越大?
+        - 这倒不必担心,DiskLruCache 中使用了一个 redundantOpCount 变量来记录用户操作的次数,每执行一次写入、读取或移除缓存的操作,这个变量值都会加 1,当变量值达到 2000 的时候就会触发重构 journal 的事件,这时会自动把 journal 中一些多余的、不必要的记录全部清除掉,保证 journal 文件的大小始终保持在一个合理的范围内。
 
 
 

+ 8 - 4
VideoSqlLite/src/main/java/com/yc/videosqllite/disk/DiskLruCache.java

@@ -84,17 +84,20 @@ public final class DiskLruCache implements Closeable {
     private Writer journalWriter;
     private final LinkedHashMap<String, Entry> lruEntries =
             new LinkedHashMap<String, Entry>(0, 0.75f, true);
+    /**
+     * 记录用户操作的次数,每执行一次写入、读取或移除缓存的操作,这个变量值都会加 1
+     * 当变量值达到 2000 时就会触发重构 journal 的事件,这时会自动把 journal 中多余的、不必要的记录全部清除掉,
+     * 保证 journal 文件的大小始终保持在一个合理的范围内。
+     */
     private int redundantOpCount;
 
     /**
-     * To differentiate between old and current snapshots, each entry is given
-     * a sequence number each time an edit is committed. A snapshot is stale if
-     * its sequence number is not equal to its entry's sequence number.
+     * 为了区分旧快照和当前快照,每次提交编辑时都给每个条目一个序号。如果快照的序列号不等于其条目的序列号,则快照失效。
      */
     private long nextSequenceNumber = 0;
 
     /**
-     * This cache uses a single background thread to evict entries.
+     * 该缓存使用单个后台线程来清除条目
      */
     final ThreadPoolExecutor executorService =
             new ThreadPoolExecutor(0, 1, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
@@ -197,6 +200,7 @@ public final class DiskLruCache implements Closeable {
     private void readJournal() throws IOException {
         StrictLineReader reader = new StrictLineReader(new FileInputStream(journalFile), DiskUtils.US_ASCII);
         try {
+            //读取journal文件的前五行
             String magic = reader.readLine();
             String version = reader.readLine();
             String appVersionString = reader.readLine();