Avoid repeated file stats in the same directory.
Using readdir(), we can avoid having to stat every single
file/directory/symlink in a directory (and especially not do it 3 times as we
currently do in TreeArtifactValue.explodeDirectory).
RELNOTES: None.
PiperOrigin-RevId: 220305956
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java
index 13ff08a..386845a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java
@@ -24,11 +24,15 @@
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.cache.DigestUtils;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
+import com.google.devtools.build.lib.vfs.Dirent;
+import com.google.devtools.build.lib.vfs.Dirent.Type;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.Symlinks;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -184,12 +188,14 @@
private static void explodeDirectory(Path treeArtifactPath,
PathFragment pathToExplode, ImmutableSet.Builder<PathFragment> valuesBuilder)
throws IOException {
- for (Path subpath : treeArtifactPath.getRelative(pathToExplode).getDirectoryEntries()) {
- PathFragment canonicalSubpathFragment = pathToExplode.getChild(subpath.getBaseName());
- if (subpath.isDirectory()) {
- explodeDirectory(treeArtifactPath,
- pathToExplode.getChild(subpath.getBaseName()), valuesBuilder);
- } else if (subpath.isSymbolicLink()) {
+ Path dir = treeArtifactPath.getRelative(pathToExplode);
+ Collection<Dirent> dirents = dir.readdir(Symlinks.NOFOLLOW);
+ for (Dirent dirent : dirents) {
+ PathFragment canonicalSubpathFragment = pathToExplode.getChild(dirent.getName());
+ if (dirent.getType() == Type.DIRECTORY) {
+ explodeDirectory(treeArtifactPath, canonicalSubpathFragment, valuesBuilder);
+ } else if (dirent.getType() == Type.SYMLINK) {
+ Path subpath = dir.getRelative(dirent.getName());
PathFragment linkTarget = subpath.readSymbolicLinkUnchecked();
valuesBuilder.add(canonicalSubpathFragment);
if (linkTarget.isAbsolute()) {
@@ -214,10 +220,11 @@
throw new IOException(errorMessage);
}
}
- } else if (subpath.isFile()) {
+ } else if (dirent.getType() == Type.FILE) {
valuesBuilder.add(canonicalSubpathFragment);
} else {
// We shouldn't ever reach here.
+ Path subpath = dir.getRelative(dirent.getName());
throw new IllegalStateException("Could not determine type of file " + subpath);
}
}