From 16092d7cb19115d8e07040105619009ea0698c5a Mon Sep 17 00:00:00 2001 From: Dmitry Lomov Date: Thu, 9 Mar 2017 10:43:02 +0000 Subject: Make InMemoryFileSystem case-insensitive on Windows. This fixes PackagePathLocatorTest. -- Change-Id: I3d14a80993f6b256acfc732adf2d97b1d2dcb804 Reviewed-on: https://cr.bazel.build/9310 PiperOrigin-RevId: 149634730 MOS_MIGRATED_REVID=149634730 --- src/main/java/com/google/devtools/build/lib/BUILD | 1 + .../lib/vfs/inmemoryfs/InMemoryDirectoryInfo.java | 63 +++++++++++++++++----- .../lib/vfs/inmemoryfs/InMemoryFileSystem.java | 8 ++- 3 files changed, 55 insertions(+), 17 deletions(-) (limited to 'src/main/java/com/google') diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index 604b5128ef..b289e890ab 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD @@ -190,6 +190,7 @@ java_library( deps = [ ":clock", ":concurrent", + ":os_util", ":preconditions", ":unix", ":vfs", diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryDirectoryInfo.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryDirectoryInfo.java index 34b9c32755..35a745a7b9 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryDirectoryInfo.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryDirectoryInfo.java @@ -13,10 +13,14 @@ // limitations under the License. package com.google.devtools.build.lib.vfs.inmemoryfs; +import com.google.common.base.Function; +import com.google.common.collect.Collections2; +import com.google.devtools.build.lib.concurrent.ThreadSafety; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.util.Clock; - -import java.util.Set; +import com.google.devtools.build.lib.util.OS; +import java.util.Collection; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -25,8 +29,14 @@ import java.util.concurrent.ConcurrentMap; */ @ThreadSafe class InMemoryDirectoryInfo extends InMemoryContentInfo { - - private final ConcurrentMap directoryContent = + private static final Function FILENAME_TO_STRING = + new Function() { + @Override + public String apply(InMemoryFileName inMemoryFileName) { + return inMemoryFileName.value; + } + }; + private final ConcurrentMap directoryContent = new ConcurrentHashMap<>(); InMemoryDirectoryInfo(Clock clock) { @@ -47,7 +57,7 @@ class InMemoryDirectoryInfo extends InMemoryContentInfo { synchronized void addChild(String name, InMemoryContentInfo inode) { if (name == null) { throw new NullPointerException(); } if (inode == null) { throw new NullPointerException(); } - if (directoryContent.put(name, inode) != null) { + if (directoryContent.put(new InMemoryFileName(name), inode) != null) { throw new IllegalArgumentException("File already exists: " + name); } markModificationTime(); @@ -58,7 +68,7 @@ class InMemoryDirectoryInfo extends InMemoryContentInfo { * Returns null if the child is not found. */ synchronized InMemoryContentInfo getChild(String name) { - return directoryContent.get(name); + return directoryContent.get(new InMemoryFileName(name)); } /** @@ -66,19 +76,19 @@ class InMemoryDirectoryInfo extends InMemoryContentInfo { * object. */ synchronized void removeChild(String name) { - if (directoryContent.remove(name) == null) { + if (directoryContent.remove(new InMemoryFileName(name)) == null) { throw new IllegalArgumentException(name + " is not a member of this directory"); } markModificationTime(); } /** - * This function returns the content of a directory. For now, it returns a set - * to reflect the semantics of the value returned (ie. unordered, no - * duplicates). If thats too slow, it should be changed later. + * This function returns the content of a directory. For now, it returns a set to reflect the + * semantics of the value returned (ie. unordered, no duplicates). If thats too slow, it should be + * changed later. */ - Set getAllChildren() { - return directoryContent.keySet(); + Collection getAllChildren() { + return Collections2.transform(directoryContent.keySet(), FILENAME_TO_STRING); } @Override @@ -110,4 +120,33 @@ class InMemoryDirectoryInfo extends InMemoryContentInfo { return directoryContent.size(); } + @ThreadSafety.Immutable + private static final class InMemoryFileName { + private final String value; + + private InMemoryFileName(String value) { + this.value = value; + } + + @Override + public int hashCode() { + return OS.getCurrent() == OS.WINDOWS ? value.toLowerCase().hashCode() : value.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof InMemoryFileName)) { + return false; + } + InMemoryFileName that = (InMemoryFileName) obj; + if (OS.getCurrent() != OS.WINDOWS) { + return Objects.equals(this.value, that.value); + } else { + return Objects.equals(this.value.toLowerCase(), that.value.toLowerCase()); + } + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java index 6972ccfa17..c52fdb53ad 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/inmemoryfs/InMemoryFileSystem.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.vfs.inmemoryfs; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.util.Clock; import com.google.devtools.build.lib.util.JavaClock; +import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.FileAccessException; import com.google.devtools.build.lib.vfs.FileStatus; @@ -23,7 +24,6 @@ import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.vfs.ScopeEscapableFileSystem; import com.google.devtools.build.lib.vfs.Symlinks; - import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -32,9 +32,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Set; import java.util.Stack; - import javax.annotation.Nullable; /** @@ -661,7 +659,7 @@ public class InMemoryFileSystem extends ScopeEscapableFileSystem { @Override public boolean isFilePathCaseSensitive() { - return true; + return OS.getCurrent() != OS.WINDOWS; } /** @@ -763,7 +761,7 @@ public class InMemoryFileSystem extends ScopeEscapableFileSystem { throw new IOException("Directory is not readable"); } - Set allChildren = dirInfo.getAllChildren(); + Collection allChildren = dirInfo.getAllChildren(); List result = new ArrayList<>(allChildren.size()); for (String child : allChildren) { if (!(child.equals(".") || child.equals(".."))) { -- cgit v1.2.3