mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-161551 IjentNioFsPath + BasicFileAttributesHolder: fetch file attributes only when it is explicitly requested
GitOrigin-RevId: 5209a3af25fe96b6c694fcb651ff5789913be9a8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d0f7bfcd07
commit
e52c7130f3
+30
@@ -6,10 +6,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
import sun.nio.fs.BasicFileAttributesHolder;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
/**
|
||||
* This interface allows not adding `--add-exports` to modules where some class implements {@link BasicFileAttributesHolder}.
|
||||
*
|
||||
* Also, this interface defines some hacks and helper methods related to {@link BasicFileAttributesHolder}.
|
||||
*/
|
||||
public interface BasicFileAttributesHolder2 extends BasicFileAttributesHolder {
|
||||
/**
|
||||
@@ -47,4 +51,30 @@ public interface BasicFileAttributesHolder2 extends BasicFileAttributesHolder {
|
||||
myCachedAttributes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
static @Nullable BasicFileAttributes getAttributesFromHolder(@NotNull Path path) {
|
||||
if (path instanceof BasicFileAttributesHolder bafh) {
|
||||
return bafh.get();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A marker interface for {@link java.nio.file.spi.FileSystemProvider#newDirectoryStream}
|
||||
* that advises the file system to fetch file attributes and fill {@link BasicFileAttributesHolder}, if it's supported.
|
||||
* <p>
|
||||
* Unlike many other methods in {@code FileSystemProvider}, {@code newDirectoryStream} doesn't accept a set of options.
|
||||
* The easiest way to provide additional information to the method is through the filter argument.
|
||||
* </p>
|
||||
* A file system provider should support this feature explicitly.
|
||||
* This interface has no effect on default filesystems from JDK:
|
||||
* <ul>
|
||||
* <li>In the default file system on Windows, file attributes are always fetched, regardless of the filter argument.</li>
|
||||
* <li>In the default file system on Posix, file attributes are never fetched.</li>
|
||||
* </ul>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
interface FetchAttributesFilter extends DirectoryStream.Filter<Path> {
|
||||
FetchAttributesFilter ACCEPT_ALL = path -> true;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-15
@@ -2,6 +2,7 @@
|
||||
package com.intellij.platform.ijent.community.impl.nio
|
||||
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.platform.core.nio.fs.BasicFileAttributesHolder2.FetchAttributesFilter
|
||||
import com.intellij.platform.ijent.community.impl.IjentFsResultImpl
|
||||
import com.intellij.platform.ijent.community.impl.nio.IjentNioFileSystemProvider.Companion.newFileSystemMap
|
||||
import com.intellij.platform.ijent.community.impl.nio.IjentNioFileSystemProvider.UnixFilePermissionBranch.*
|
||||
@@ -180,23 +181,34 @@ class IjentNioFileSystemProvider : FileSystemProvider() {
|
||||
val nioFs = dir.nioFs
|
||||
|
||||
return fsBlocking {
|
||||
val children = nioFs.ijentFs
|
||||
.listDirectoryWithAttrs(ensurePathIsAbsolute(dir.ijentPath), IjentFileSystemApi.SymlinkPolicy.DO_NOT_RESOLVE)
|
||||
.getOrThrowFileSystemException()
|
||||
|
||||
val nioPathList = children.asSequence()
|
||||
.map { (childName, childStat) ->
|
||||
val childIjentPath = dir.ijentPath.getChild(childName).getOrThrow()
|
||||
val childAttrs = when (childStat) {
|
||||
is IjentPosixFileInfo -> IjentNioPosixFileAttributes(childStat)
|
||||
is IjentWindowsFileInfo -> TODO()
|
||||
}
|
||||
IjentNioPath(childIjentPath, nioFs, childAttrs)
|
||||
val notFilteredPaths =
|
||||
if (pathFilter is FetchAttributesFilter) {
|
||||
nioFs.ijentFs
|
||||
.listDirectoryWithAttrs(ensurePathIsAbsolute(dir.ijentPath), IjentFileSystemApi.SymlinkPolicy.DO_NOT_RESOLVE)
|
||||
.getOrThrowFileSystemException()
|
||||
.asSequence()
|
||||
.map { (childName, childStat) ->
|
||||
val childIjentPath = dir.ijentPath.getChild(childName).getOrThrow()
|
||||
val childAttrs = when (childStat) {
|
||||
is IjentPosixFileInfo -> IjentNioPosixFileAttributes(childStat)
|
||||
is IjentWindowsFileInfo -> TODO()
|
||||
}
|
||||
IjentNioPath(childIjentPath, nioFs, childAttrs)
|
||||
}
|
||||
}
|
||||
.filter { nioPath ->
|
||||
pathFilter?.accept(nioPath) != false
|
||||
else {
|
||||
nioFs.ijentFs
|
||||
.listDirectory(ensurePathIsAbsolute(dir.ijentPath))
|
||||
.getOrThrowFileSystemException()
|
||||
.asSequence()
|
||||
.map { childName ->
|
||||
val childIjentPath = dir.ijentPath.getChild(childName).getOrThrow()
|
||||
IjentNioPath(childIjentPath, nioFs, null)
|
||||
}
|
||||
}
|
||||
.toMutableList()
|
||||
val nioPathList = notFilteredPaths.filterTo(mutableListOf()) { nioPath ->
|
||||
pathFilter?.accept(nioPath) != false
|
||||
}
|
||||
|
||||
object : DirectoryStream<Path> {
|
||||
// The compiler doesn't (didn't?) allow to relax types here.
|
||||
|
||||
+6
-6
@@ -6,6 +6,8 @@ import com.intellij.execution.wsl.WslPath
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.util.io.CaseSensitivityAttribute
|
||||
import com.intellij.openapi.util.io.FileAttributes
|
||||
import com.intellij.platform.core.nio.fs.BasicFileAttributesHolder2
|
||||
import com.intellij.platform.core.nio.fs.BasicFileAttributesHolder2.FetchAttributesFilter
|
||||
import com.intellij.platform.core.nio.fs.RoutingAwareFileSystemProvider
|
||||
import com.intellij.platform.ijent.IjentPosixInfo
|
||||
import com.intellij.platform.ijent.community.impl.nio.IjentNioPath
|
||||
@@ -315,11 +317,9 @@ class IjentWslNioFileSystemProvider(
|
||||
lastDirectory = lastDirectory.parent
|
||||
}
|
||||
|
||||
// TODO Add BasicFileAttributesHolder, it gives a huge speed up.
|
||||
//val stat =
|
||||
// source.asSafely<BasicFileAttributesHolder>()?.get()
|
||||
// ?: source.readAttributes(LinkOption.NOFOLLOW_LINKS)
|
||||
val stat = source.readAttributes<BasicFileAttributes>(LinkOption.NOFOLLOW_LINKS)
|
||||
val stat =
|
||||
BasicFileAttributesHolder2.getAttributesFromHolder(source)
|
||||
?: source.readAttributes(LinkOption.NOFOLLOW_LINKS)
|
||||
|
||||
// WindowsPath doesn't support resolve() from paths of different class.
|
||||
val target = source.relativeTo(sourceRoot).fold(targetRoot) { parent, file ->
|
||||
@@ -337,7 +337,7 @@ class IjentWslNioFileSystemProvider(
|
||||
throw err
|
||||
}
|
||||
}
|
||||
Files.newDirectoryStream(source).use { children ->
|
||||
source.fileSystem.provider().newDirectoryStream(source, FetchAttributesFilter.ACCEPT_ALL).use { children ->
|
||||
sourceStack.addAll(children.toList().asReversed())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.intellij.util.io;
|
||||
|
||||
import com.intellij.openapi.util.io.NioFiles;
|
||||
import com.intellij.platform.core.nio.fs.BasicFileAttributesHolder2.FetchAttributesFilter;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -40,7 +41,7 @@ public final class PlatformNioHelper {
|
||||
@SuppressWarnings({"UnnecessaryFullyQualifiedName", "InstanceofIncompatibleInterface"})
|
||||
public static void visitDirectory(@NotNull Path directory, @Nullable Set<String> filter, @NotNull BiPredicate<Path, Result<BasicFileAttributes>> consumer)
|
||||
throws IOException, SecurityException {
|
||||
try (var dirStream = Files.newDirectoryStream(directory)) {
|
||||
try (var dirStream = directory.getFileSystem().provider().newDirectoryStream(directory, FetchAttributesFilter.ACCEPT_ALL)) {
|
||||
for (var path : dirStream) {
|
||||
if (filter != null && !filter.contains(path.getFileName().toString())) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user