Skip to content

Most visited

Recently visited

navigation
DisplayingBitmaps / src / com.example.android.displayingbitmaps / util /

DiskLruCache.java

1
/*
2
 * Copyright (C) 2011 The Android Open Source Project
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
package com.example.android.displayingbitmaps.util;
18
 
19
import java.io.BufferedInputStream;
20
import java.io.BufferedWriter;
21
import java.io.Closeable;
22
import java.io.EOFException;
23
import java.io.File;
24
import java.io.FileInputStream;
25
import java.io.FileNotFoundException;
26
import java.io.FileOutputStream;
27
import java.io.FileWriter;
28
import java.io.FilterOutputStream;
29
import java.io.IOException;
30
import java.io.InputStream;
31
import java.io.InputStreamReader;
32
import java.io.OutputStream;
33
import java.io.OutputStreamWriter;
34
import java.io.Reader;
35
import java.io.StringWriter;
36
import java.io.Writer;
37
import java.lang.reflect.Array;
38
import java.nio.charset.Charset;
39
import java.util.ArrayList;
40
import java.util.Arrays;
41
import java.util.Iterator;
42
import java.util.LinkedHashMap;
43
import java.util.Map;
44
import java.util.concurrent.Callable;
45
import java.util.concurrent.ExecutorService;
46
import java.util.concurrent.LinkedBlockingQueue;
47
import java.util.concurrent.ThreadPoolExecutor;
48
import java.util.concurrent.TimeUnit;
49
 
50
/**
51
 ******************************************************************************
52
 * Taken from the JB source code, can be found in:
53
 * libcore/luni/src/main/java/libcore/io/DiskLruCache.java
54
 * or direct link:
55
 * https://android.googlesource.com/platform/libcore/+/android-4.1.1_r1/luni/src/main/java/libcore/io/DiskLruCache.java
56
 ******************************************************************************
57
 *
58
 * A cache that uses a bounded amount of space on a filesystem. Each cache
59
 * entry has a string key and a fixed number of values. Values are byte
60
 * sequences, accessible as streams or files. Each value must be between {@code
61
 * 0} and {@code Integer.MAX_VALUE} bytes in length.
62
 *
63
 * <p>The cache stores its data in a directory on the filesystem. This
64
 * directory must be exclusive to the cache; the cache may delete or overwrite
65
 * files from its directory. It is an error for multiple processes to use the
66
 * same cache directory at the same time.
67
 *
68
 * <p>This cache limits the number of bytes that it will store on the
69
 * filesystem. When the number of stored bytes exceeds the limit, the cache will
70
 * remove entries in the background until the limit is satisfied. The limit is
71
 * not strict: the cache may temporarily exceed it while waiting for files to be
72
 * deleted. The limit does not include filesystem overhead or the cache
73
 * journal so space-sensitive applications should set a conservative limit.
74
 *
75
 * <p>Clients call {@link #edit} to create or update the values of an entry. An
76
 * entry may have only one editor at one time; if a value is not available to be
77
 * edited then {@link #edit} will return null.
78
 * <ul>
79
 *     <li>When an entry is being <strong>created</strong> it is necessary to
80
 *         supply a full set of values; the empty value should be used as a
81
 *         placeholder if necessary.
82
 *     <li>When an entry is being <strong>edited</strong>, it is not necessary
83
 *         to supply data for every value; values default to their previous
84
 *         value.
85
 * </ul>
86
 * Every {@link #edit} call must be matched by a call to {@link Editor#commit}
87
 * or {@link Editor#abort}. Committing is atomic: a read observes the full set
88
 * of values as they were before or after the commit, but never a mix of values.
89
 *
90
 * <p>Clients call {@link #get} to read a snapshot of an entry. The read will
91
 * observe the value at the time that {@link #get} was called. Updates and
92
 * removals after the call do not impact ongoing reads.
93
 *
94
 * <p>This class is tolerant of some I/O errors. If files are missing from the
95
 * filesystem, the corresponding entries will be dropped from the cache. If
96
 * an error occurs while writing a cache value, the edit will fail silently.
97
 * Callers should handle other problems by catching {@code IOException} and
98
 * responding appropriately.
99
 */
100
public final class DiskLruCache implements Closeable {
101
    static final String JOURNAL_FILE = "journal";
102
    static final String JOURNAL_FILE_TMP = "journal.tmp";
103
    static final String MAGIC = "libcore.io.DiskLruCache";
104
    static final String VERSION_1 = "1";
105
    static final long ANY_SEQUENCE_NUMBER = -1;
106
    private static final String CLEAN = "CLEAN";
107
    private static final String DIRTY = "DIRTY";
108
    private static final String REMOVE = "REMOVE";
109
    private static final String READ = "READ";
110
 
111
    private static final Charset UTF_8 = Charset.forName("UTF-8");
112
    private static final int IO_BUFFER_SIZE = 8 * 1024;
113
 
114
    /*
115
     * This cache uses a journal file named "journal". A typical journal file
116
     * looks like this:
117
     *     libcore.io.DiskLruCache
118
     *     1
119
     *     100
120
     *     2
121
     *
122
     *     CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
123
     *     DIRTY 335c4c6028171cfddfbaae1a9c313c52
124
     *     CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
125
     *     REMOVE 335c4c6028171cfddfbaae1a9c313c52
126
     *     DIRTY 1ab96a171faeeee38496d8b330771a7a
127
     *     CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
128
     *     READ 335c4c6028171cfddfbaae1a9c313c52
129
     *     READ 3400330d1dfc7f3f7f4b8d4d803dfcf6
130
     *
131
     * The first five lines of the journal form its header. They are the
132
     * constant string "libcore.io.DiskLruCache", the disk cache's version,
133
     * the application's version, the value count, and a blank line.
134
     *
135
     * Each of the subsequent lines in the file is a record of the state of a
136
     * cache entry. Each line contains space-separated values: a state, a key,
137
     * and optional state-specific values.
138
     *   o DIRTY lines track that an entry is actively being created or updated.
139
     *     Every successful DIRTY action should be followed by a CLEAN or REMOVE
140
     *     action. DIRTY lines without a matching CLEAN or REMOVE indicate that
141
     *     temporary files may need to be deleted.
142
     *   o CLEAN lines track a cache entry that has been successfully published
143
     *     and may be read. A p