<div dir="ltr">As per comment in <a href="https://bugs.openjdk.java.net/browse/JDK-8259873">JDK-8259873</a>, I am starting a discussion topic for the proposed change in <a href="https://github.com/openjdk/jdk/pull/2121">https://github.com/openjdk/jdk/pull/2121</a>.<div><br></div><div>Some context: The change, along with <a href="https://github.com/openjdk/jdk/pull/2122">https://github.com/openjdk/jdk/pull/2122</a>, is about improving performance of Files.walkFileTree on the Windows platform.</div><div><br></div><div>PR 2122<br></div><div>=======</div><div><br></div><div>PR 2122 is an "in place" (i.e. no behavior or public API change) implementation change in WindowsDirectoryStream: Instead of using <a href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilew">FindFirstFile</a>,<a href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextfilew">FindNextFile</a>, the new implementation uses <a href="https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntquerydirectoryfile">NtQueryDirectoryFile</a>, which is more efficient at enumerating directory entries and allows acquiring file keys for "free" with each entry.</div><div><br></div><div>With a file key available, Files.walkFileTree can implement symlink loop detection very efficiently (comparing 2 file keys in memory), as opposed to calling Files.isSameFile which incurs 2 file I/O on Windows (see code here in FileTreeWalker here: <a href="https://github.com/openjdk/jdk/blob/05a764f4ffb8030d6b768f2d362c388e5aabd92d/src/java.base/share/classes/java/nio/file/FileTreeWalker.java#L241">https://github.com/openjdk/jdk/blob/05a764f4ffb8030d6b768f2d362c388e5aabd92d/src/java.base/share/classes/java/nio/file/FileTreeWalker.java#L241</a>)<br><br></div><div><div>PR 2121<br></div><div>=======</div><div><br></div><div></div></div><div>PR 2121 (the subject of this email) is about removing one remaining call to "isSameFile" in FileTreeWalker: The initial directory (<a href="http://this.dir">this.dir</a>) is part of the stack of directories used for loop detection in the <a href="https://github.com/openjdk/jdk/blob/05a764f4ffb8030d6b768f2d362c388e5aabd92d/src/java.base/share/classes/java/nio/file/FileTreeWalker.java#L236">wouldLoop</a> method. The goal of the change is to ensure there is a file key available for that initial directory so that there is never a call made to "isSameFile".</div><div><br></div><div>With change 2122, *all* entries have a file key (in virtue of being retrieved with NtQueryDirectoryInformation), *except* for the "this.dir" entry (because that initial directory is provided by the caller of the API).<br></div><div><br></div><div>The problem is then how do we allow FileTreeWalker to retrieve the file key for the initial directory.</div><div><br></div><div>Option 1: Change Files.readAttributes(file, BasicFileAttributes.class, linkOptions) on Windows to always retrieve a file key.</div><div><br></div><div>The <a href="https://github.com/openjdk/jdk/blob/6948456dbf76bf314f17f24040c778a2d36a4431/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java#L296">current implementation</a> uses <a href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesw">GetFileAttributes</a> which does *not* provide a file key. To get a file key, the implementation would need to call <a href="https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileinformationbyhandle">GetFileInformationByHandle</a> (see <a href="https://github.com/openjdk/jdk/blob/6948456dbf76bf314f17f24040c778a2d36a4431/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java#L270">https://github.com/openjdk/jdk/blob/6948456dbf76bf314f17f24040c778a2d36a4431/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java#L270</a>). Unfortunately, GetFileInformationByHandle is at least an order of magnitude slower than GetFileAttributes, so it does not seem appropriate to slow down all callers, including those who don't need a file key.</div><div><br></div><div>Option 2: Find a way for FileTreeWalker to give a "hint" to the file system provider that its implementation would benefit from having a file key available to file equality detection purposes, even if it means using a slower implementation.</div><div><br></div><div>This is why PR 2121 introduces a new "BasicWithKeyFileAttributeView" interface. FileTreeWalker queries the file system provider using this new interface, hinting that it would like to obtain a file ket even if there is some performance penalty. The main issue with this option is that it introduces a new public type. One benefit is that it is a general purpose API that could benefit other consumers (other than FileTreeWalker). AFAIK, it is currently not possible for a consumer to ask for a file key explicitly (consumers gets them for free on Linux, and never gets them on Windows).</div><div><br></div><div>Option 3: Create a Windows specific version of FileTreeWalker that calls directly into the WindowsFileProvider to obtain the file key.</div><div><br></div><div>The pro here is that there is no new public type, with the cons that we'd have to create a windows specific version of FileTreeWalker, which is currently platform agnostic.</div><div><br></div><div>PR 2121 currently implements option 2.</div><div><div><br></div><div>Thoughts?</div><div><br></div></div></div>