JBR-3680 Cherry-pick Google's NIO patches to get faster file listing

Fix regression introduced by Google's NIO patches:
- do not attempt to get the next entry after the directory stream has
been closed already,
- fix FaultyFileSystem that is used in StreamTest.java to throw
the right exception even when getFileAttributeView() is used instead of
readAttributes(),
- removed unnecessary type cast that caused a compilation warning.

Added a test for walking a directory with a non-latin name.

(cherry picked from commit 152a4e886d)
This commit is contained in:
Maxim Kartashev
2021-09-23 18:20:32 +03:00
committed by jbrbot
parent ff867e6e11
commit 2eea7928b2
4 changed files with 121 additions and 2 deletions

View File

@@ -157,6 +157,11 @@ class WindowsDirectoryStream
// synchronize on closeLock to prevent close while reading
synchronized (closeLock) {
// Fetch next set of entries if we don't have anything available in buffer
if (!isOpen) {
atEof = true;
return null;
}
if (nextOffset < 0) {
try {
atEof = !NextNtQueryDirectoryInformation(queryDirectoryInformation, queryDirectoryInformationBuffer);

View File

@@ -40,7 +40,7 @@ class WindowsFileKey {
@Override
public int hashCode() {
return (int)(volSerialNumber ^ (volSerialNumber >>> 16)) +
return (volSerialNumber ^ (volSerialNumber >>> 16)) +
(int)(fileId ^ (fileId >>> 32));
}

View File

@@ -42,6 +42,8 @@ import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.UserPrincipalLookupService;
import java.nio.file.spi.FileSystemProvider;
import java.util.Iterator;
@@ -323,12 +325,44 @@ class FaultyFileSystem extends FileSystem {
return Files.readAttributes(unwrap(file), attributes, options);
}
private class FaultyBasicFileAttributeView implements BasicFileAttributeView {
private final Path file;
private final LinkOption[] options;
public FaultyBasicFileAttributeView(final Path file, final LinkOption... options) {
this.file = file;
this.options = options;
}
@Override
public String name() {
return "faulty";
}
@Override
public BasicFileAttributes readAttributes() throws IOException {
triggerEx(file, "readAttributes");
return Files.readAttributes(file, BasicFileAttributes.class, options);
}
@Override
public void setTimes(FileTime lastModifiedTime,
FileTime lastAccessTime,
FileTime createTime) throws IOException {
triggerEx(file, "setTimes");
}
}
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path file,
Class<V> type,
LinkOption... options)
{
return Files.getFileAttributeView(unwrap(file), type, options);
if (type != BasicFileAttributeView.class) {
return null;
}
return (V)new FaultyBasicFileAttributeView(unwrap(file), options);
}
@Override

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, JetBrains s.r.o.. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Tests that walkFileTree can find files in a directory with
* non-latin characters in the name (including ones from
* the supplementary plane)
* @library /test/lib
*/
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.FileVisitOption;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.FileVisitResult;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Vector;
import java.util.HashSet;
import jdk.test.lib.Asserts;
public class NonLatin {
// Use non-Latin characters from basic (\u1889) and supplementary (\uD844\uDDD9) Unicode planes
private static final String NON_LATIN_PATH_NAME = "ka-\u1889-supp-\uD844\uDDD9";
public static void main(String args[]) throws Exception {
final Path currentDirPath = Paths.get(".").toAbsolutePath();
Path nonLatinPath = null;
try {
nonLatinPath = currentDirPath.resolve(NON_LATIN_PATH_NAME);
Files.createDirectory(nonLatinPath);
final Path underNonLatinPath = nonLatinPath.resolve("dir");
Files.createDirectory(underNonLatinPath);
} catch (java.nio.file.InvalidPathException e) {
System.out.println("Cannot create the directory with the right name. Test is considered passed");
return;
}
final Vector<String> visitedDirs = new Vector<String>();
Files.walkFileTree(nonLatinPath, new HashSet<FileVisitOption>(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
visitedDirs.add(dir.toString());
return FileVisitResult.CONTINUE;
}
});
boolean found = false;
for (final String dirName : visitedDirs) {
System.out.println("Found: " + dirName);
found |= dirName.contains(NON_LATIN_PATH_NAME);
}
Asserts.assertTrue(found);
}
}