aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/PersistentMap.java42
1 files changed, 32 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/PersistentMap.java b/src/main/java/com/google/devtools/build/lib/util/PersistentMap.java
index 56ac9a1b2b..4a7348645f 100644
--- a/src/main/java/com/google/devtools/build/lib/util/PersistentMap.java
+++ b/src/main/java/com/google/devtools/build/lib/util/PersistentMap.java
@@ -15,18 +15,22 @@
package com.google.devtools.build.lib.util;
import com.google.common.collect.ForwardingMap;
+import com.google.common.io.ByteStreams;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.logging.Logger;
/**
* A map that is backed by persistent storage. It uses two files on disk for
@@ -65,8 +69,10 @@ import java.util.Map;
public abstract class PersistentMap<K, V> extends ForwardingMap<K, V> {
private static final int MAGIC = 0x20071105;
-
private static final int ENTRY_MAGIC = 0xfe;
+ private static final int MIN_MAPFILE_SIZE = 16;
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+ private static final Logger LOG = Logger.getLogger(PersistentMap.class.getName());
private final int version;
private final Path mapFile;
@@ -334,16 +340,30 @@ public abstract class PersistentMap<K, V> extends ForwardingMap<K, V> {
if (!mapFile.exists()) {
return;
}
- DataInputStream in = new DataInputStream(new BufferedInputStream(mapFile.getInputStream()));
- try {
- long fileSize = mapFile.getFileSize();
- if (fileSize < (16)) {
- if (failFast) {
- throw new IOException(mapFile + " is too short: Only " + fileSize + " bytes");
- } else {
- return;
- }
+
+ long fileSize = mapFile.getFileSize();
+ if (fileSize < MIN_MAPFILE_SIZE) {
+ if (failFast) {
+ throw new IOException(mapFile + " is too short: Only " + fileSize + " bytes");
+ } else {
+ return;
}
+ } else if (fileSize > MAX_ARRAY_SIZE) {
+ if (failFast) {
+ throw new IOException(mapFile + " is too long: " + fileSize + " bytes");
+ } else {
+ return;
+ }
+ }
+
+ // We read the whole file up front as a performance optimization; otherwise calling available()
+ // on the stream over and over does a lot of syscalls.
+ byte[] mapBytes;
+ try (InputStream fileInput = mapFile.getInputStream()) {
+ mapBytes = ByteStreams.toByteArray(new BufferedInputStream(fileInput));
+ }
+ DataInputStream in = new DataInputStream(new ByteArrayInputStream(mapBytes));
+ try {
if (in.readLong() != MAGIC) { // not a PersistentMap
if (failFast) {
throw new IOException("Unexpected format");
@@ -360,6 +380,8 @@ public abstract class PersistentMap<K, V> extends ForwardingMap<K, V> {
} finally {
in.close();
}
+
+ LOG.info(String.format("Loaded cache '%s' [%s bytes]", mapFile, fileSize));
}
/**