Skip to content

Commit

Permalink
Merge pull request square#1495 from square/jwilson_0314_filesystem
Browse files Browse the repository at this point in the history
New file system abstraction.
  • Loading branch information
JakeWharton committed Mar 14, 2015
2 parents e73a4fa + 49e85a1 commit 0c2387c
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@
*/
package com.squareup.okhttp.internal;

import java.io.BufferedReader;
import com.squareup.okhttp.internal.io.FileSystem;
import com.squareup.okhttp.internal.io.InMemoryFileSystem;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -57,6 +53,7 @@ public final class DiskLruCacheTest {
@Rule public final TemporaryFolder tempDir = new TemporaryFolder();
@Rule public final Timeout timeout = new Timeout(30 * 1000);

private final FileSystem fileSystem = FileSystem.SYSTEM;
private final int appVersion = 100;
private File cacheDir;
private File journalFile;
Expand All @@ -71,7 +68,7 @@ private void createNewCache() throws IOException {
}

private void createNewCacheWithSize(int maxSize) throws IOException {
cache = new DiskLruCache(cacheDir, appVersion, 2, maxSize, executor);
cache = new DiskLruCache(fileSystem, cacheDir, appVersion, 2, maxSize, executor);
synchronized (cache) {
cache.initialize();
}
Expand Down Expand Up @@ -272,7 +269,7 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
File k1 = getCleanFile("k1", 0);
assertEquals("ABC", readFile(k1));
cache.remove("k1");
assertFalse(k1.exists());
assertFalse(fileSystem.exists(k1));
}

@Test public void removePreventsActiveEditFromStoringAValue() throws Exception {
Expand Down Expand Up @@ -328,10 +325,10 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
writeFile(dirtyFile1, "D");
createJournal("CLEAN k1 1 1", "DIRTY k1");
createNewCache();
assertFalse(cleanFile0.exists());
assertFalse(cleanFile1.exists());
assertFalse(dirtyFile0.exists());
assertFalse(dirtyFile1.exists());
assertFalse(fileSystem.exists(cleanFile0));
assertFalse(fileSystem.exists(cleanFile1));
assertFalse(fileSystem.exists(dirtyFile0));
assertFalse(fileSystem.exists(dirtyFile1));
assertNull(cache.get("k1"));
}

Expand Down Expand Up @@ -389,9 +386,10 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
cache.close();
writeFile(getCleanFile("k1", 0), "A");
writeFile(getCleanFile("k1", 1), "B");
Writer writer = new FileWriter(journalFile);
writer.write(MAGIC + "\n" + VERSION_1 + "\n100\n2\n\nCLEAN k1 1 1"); // no trailing newline
writer.close();

BufferedSink sink = Okio.buffer(fileSystem.sink(journalFile));
sink.writeUtf8(MAGIC + "\n" + VERSION_1 + "\n100\n2\n\nCLEAN k1 1 1"); // no trailing newline
sink.close();
createNewCache();
assertNull(cache.get("k1"));

Expand Down Expand Up @@ -453,10 +451,10 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
} catch (IllegalStateException expected) {
}

assertFalse(getCleanFile("k1", 0).exists());
assertFalse(getCleanFile("k1", 1).exists());
assertFalse(getDirtyFile("k1", 0).exists());
assertFalse(getDirtyFile("k1", 1).exists());
assertFalse(fileSystem.exists(getCleanFile("k1", 0)));
assertFalse(fileSystem.exists(getCleanFile("k1", 1)));
assertFalse(fileSystem.exists(getDirtyFile("k1", 0)));
assertFalse(fileSystem.exists(getDirtyFile("k1", 1)));
assertNull(cache.get("k1"));

DiskLruCache.Editor creator2 = cache.edit("k1");
Expand All @@ -469,10 +467,10 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
DiskLruCache.Editor creator = cache.edit("k1");
setString(creator, 1, "A");
creator.abort();
assertFalse(getCleanFile("k1", 0).exists());
assertFalse(getCleanFile("k1", 1).exists());
assertFalse(getDirtyFile("k1", 0).exists());
assertFalse(getDirtyFile("k1", 1).exists());
assertFalse(fileSystem.exists(getCleanFile("k1", 0)));
assertFalse(fileSystem.exists(getCleanFile("k1", 1)));
assertFalse(fileSystem.exists(getDirtyFile("k1", 0)));
assertFalse(fileSystem.exists(getDirtyFile("k1", 1)));
assertNull(cache.get("k1"));
}

Expand Down Expand Up @@ -632,15 +630,15 @@ private void createNewCacheWithSize(int maxSize) throws IOException {

@Test public void constructorDoesNotAllowZeroCacheSize() throws Exception {
try {
DiskLruCache.create(cacheDir, appVersion, 2, 0);
DiskLruCache.create(fileSystem, cacheDir, appVersion, 2, 0);
fail();
} catch (IllegalArgumentException expected) {
}
}

@Test public void constructorDoesNotAllowZeroValuesPerEntry() throws Exception {
try {
DiskLruCache.create(cacheDir, appVersion, 0, 10);
DiskLruCache.create(fileSystem, cacheDir, appVersion, 0, 10);
fail();
} catch (IllegalArgumentException expected) {
}
Expand Down Expand Up @@ -707,17 +705,17 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
creator.commit();
cache.close();

assertTrue(journalFile.renameTo(journalBkpFile));
assertFalse(journalFile.exists());
fileSystem.rename(journalFile, journalBkpFile);
assertFalse(fileSystem.exists(journalFile));

createNewCache();

DiskLruCache.Snapshot snapshot = cache.get("k1");
assertSnapshotValue(snapshot, 0, "ABC");
assertSnapshotValue(snapshot, 1, "DE");

assertFalse(journalBkpFile.exists());
assertTrue(journalFile.exists());
assertFalse(fileSystem.exists(journalBkpFile));
assertTrue(fileSystem.exists(journalFile));
}

@Test public void journalFileIsPreferredOverBackupFile() throws Exception {
Expand All @@ -735,8 +733,8 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
creator.commit();
cache.close();

assertTrue(journalFile.exists());
assertTrue(journalBkpFile.exists());
assertTrue(fileSystem.exists(journalFile));
assertTrue(fileSystem.exists(journalBkpFile));

createNewCache();

Expand All @@ -748,23 +746,23 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
assertSnapshotValue(snapshotB, 0, "F");
assertSnapshotValue(snapshotB, 1, "GH");

assertFalse(journalBkpFile.exists());
assertTrue(journalFile.exists());
assertFalse(fileSystem.exists(journalBkpFile));
assertTrue(fileSystem.exists(journalFile));
}

@Test public void openCreatesDirectoryIfNecessary() throws Exception {
cache.close();
File dir = tempDir.newFolder("testOpenCreatesDirectoryIfNecessary");
cache = DiskLruCache.create(dir, appVersion, 2, Integer.MAX_VALUE);
cache = DiskLruCache.create(fileSystem, dir, appVersion, 2, Integer.MAX_VALUE);
set("a", "a", "a");
assertTrue(new File(dir, "a.0").exists());
assertTrue(new File(dir, "a.1").exists());
assertTrue(new File(dir, "journal").exists());
assertTrue(fileSystem.exists(new File(dir, "a.0")));
assertTrue(fileSystem.exists(new File(dir, "a.1")));
assertTrue(fileSystem.exists(new File(dir, "journal")));
}

@Test public void fileDeletedExternally() throws Exception {
set("a", "a", "a");
getCleanFile("a", 1).delete();
fileSystem.delete(getCleanFile("a", 1));
assertNull(cache.get("a"));
}

Expand Down Expand Up @@ -823,7 +821,7 @@ private void createNewCacheWithSize(int maxSize) throws IOException {

/** @see <a href="https://github.com/JakeWharton/DiskLruCache/issues/2">Issue #2</a> */
@Test public void aggressiveClearingHandlesWrite() throws Exception {
tempDir.delete();
fileSystem.deleteContents(tempDir.getRoot());
set("a", "a", "a");
assertValue("a", "a", "a");
}
Expand All @@ -832,7 +830,7 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
@Test public void aggressiveClearingHandlesEdit() throws Exception {
set("a", "a", "a");
DiskLruCache.Editor a = cache.get("a").edit();
tempDir.delete();
fileSystem.deleteContents(tempDir.getRoot());
setString(a, 1, "a2");
a.commit();
}
Expand All @@ -849,15 +847,15 @@ private void createNewCacheWithSize(int maxSize) throws IOException {
set("b", "b", "b");
DiskLruCache.Editor a = cache.get("a").edit();
setString(a, 0, "a1");
tempDir.delete();
fileSystem.deleteContents(tempDir.getRoot());
setString(a, 1, "a2");
a.commit();
assertNull(cache.get("a"));
}

/** @see <a href="https://github.com/JakeWharton/DiskLruCache/issues/2">Issue #2</a> */
@Test public void aggressiveClearingHandlesRead() throws Exception {
tempDir.delete();
fileSystem.deleteContents(tempDir.getRoot());
assertNull(cache.get("a"));
}

Expand Down Expand Up @@ -1064,7 +1062,7 @@ private void createNewCacheWithSize(int maxSize) throws IOException {

@Test public void isClosed_uninitializedCache() throws Exception {
// Create an uninitialized cache.
cache = new DiskLruCache(cacheDir, appVersion, 2, Integer.MAX_VALUE, executor);
cache = new DiskLruCache(fileSystem, cacheDir, appVersion, 2, Integer.MAX_VALUE, executor);
toClose.add(cache);

assertFalse(cache.isClosed());
Expand All @@ -1089,27 +1087,26 @@ private void createJournal(String... bodyLines) throws Exception {

private void createJournalWithHeader(String magic, String version, String appVersion,
String valueCount, String blank, String... bodyLines) throws Exception {
Writer writer = new FileWriter(journalFile);
writer.write(magic + "\n");
writer.write(version + "\n");
writer.write(appVersion + "\n");
writer.write(valueCount + "\n");
writer.write(blank + "\n");
BufferedSink sink = Okio.buffer(fileSystem.sink(journalFile));
sink.writeUtf8(magic + "\n");
sink.writeUtf8(version + "\n");
sink.writeUtf8(appVersion + "\n");
sink.writeUtf8(valueCount + "\n");
sink.writeUtf8(blank + "\n");
for (String line : bodyLines) {
writer.write(line);
writer.write('\n');
sink.writeUtf8(line);
sink.writeUtf8("\n");
}
writer.close();
sink.close();
}

private List<String> readJournalLines() throws Exception {
List<String> result = new ArrayList<>();
BufferedReader reader = new BufferedReader(new FileReader(journalFile));
String line;
while ((line = reader.readLine()) != null) {
BufferedSource source = Okio.buffer(fileSystem.source(journalFile));
for (String line; (line = source.readUtf8Line()) != null; ) {
result.add(line);
}
reader.close();
source.close();
return result;
}

Expand All @@ -1121,22 +1118,17 @@ private File getDirtyFile(String key, int index) {
return new File(cacheDir, key + "." + index + ".tmp");
}

private static String readFile(File file) throws Exception {
Reader reader = new FileReader(file);
StringWriter writer = new StringWriter();
char[] buffer = new char[1024];
int count;
while ((count = reader.read(buffer)) != -1) {
writer.write(buffer, 0, count);
}
reader.close();
return writer.toString();
private String readFile(File file) throws Exception {
BufferedSource source = Okio.buffer(fileSystem.source(file));
String result = source.readUtf8();
source.close();
return result;
}

public static void writeFile(File file, String content) throws Exception {
FileWriter writer = new FileWriter(file);
writer.write(content);
writer.close();
public void writeFile(File file, String content) throws Exception {
BufferedSink sink = Okio.buffer(fileSystem.sink(file));
sink.writeUtf8(content);
sink.close();
}

private static void assertInoperable(DiskLruCache.Editor editor) throws Exception {
Expand Down Expand Up @@ -1176,18 +1168,16 @@ private void generateSomeGarbageFiles() throws Exception {
writeFile(getCleanFile("g2", 1), "D");
writeFile(getCleanFile("g2", 1), "D");
writeFile(new File(cacheDir, "otherFile0"), "E");
dir1.mkdir();
dir2.mkdir();
writeFile(new File(dir2, "otherFile1"), "F");
}

private void assertGarbageFilesAllDeleted() throws Exception {
assertFalse(getCleanFile("g1", 0).exists());
assertFalse(getCleanFile("g1", 1).exists());
assertFalse(getCleanFile("g2", 0).exists());
assertFalse(getCleanFile("g2", 1).exists());
assertFalse(new File(cacheDir, "otherFile0").exists());
assertFalse(new File(cacheDir, "dir1").exists());
assertFalse(fileSystem.exists(getCleanFile("g1", 0)));
assertFalse(fileSystem.exists(getCleanFile("g1", 1)));
assertFalse(fileSystem.exists(getCleanFile("g2", 0)));
assertFalse(fileSystem.exists(getCleanFile("g2", 1)));
assertFalse(fileSystem.exists(new File(cacheDir, "otherFile0")));
assertFalse(fileSystem.exists(new File(cacheDir, "dir1")));
}

private void set(String key, String value0, String value1) throws Exception {
Expand All @@ -1209,18 +1199,18 @@ private void assertAbsent(String key) throws Exception {
snapshot.close();
fail();
}
assertFalse(getCleanFile(key, 0).exists());
assertFalse(getCleanFile(key, 1).exists());
assertFalse(getDirtyFile(key, 0).exists());
assertFalse(getDirtyFile(key, 1).exists());
assertFalse(fileSystem.exists(getCleanFile(key, 0)));
assertFalse(fileSystem.exists(getCleanFile(key, 1)));
assertFalse(fileSystem.exists(getDirtyFile(key, 0)));
assertFalse(fileSystem.exists(getDirtyFile(key, 1)));
}

private void assertValue(String key, String value0, String value1) throws Exception {
DiskLruCache.Snapshot snapshot = cache.get(key);
assertSnapshotValue(snapshot, 0, value0);
assertSnapshotValue(snapshot, 1, value1);
assertTrue(getCleanFile(key, 0).exists());
assertTrue(getCleanFile(key, 1).exists());
assertTrue(fileSystem.exists(getCleanFile(key, 0)));
assertTrue(fileSystem.exists(getCleanFile(key, 1)));
snapshot.close();
}

Expand All @@ -1235,8 +1225,8 @@ private String sourceAsString(Source source) throws IOException {
}

private void copyFile(File from, File to) throws IOException {
Source source = Okio.source(from);
BufferedSink sink = Okio.buffer(Okio.sink(to));
Source source = fileSystem.source(from);
BufferedSink sink = Okio.buffer(fileSystem.sink(to));
sink.writeAll(source);
source.close();
sink.close();
Expand Down
Loading

0 comments on commit 0c2387c

Please sign in to comment.