Use fileKey instead of canonicalPath when deduping files

`resolveDependencies` showed up as a hotspot when profiling due to `canonicalPath` doing a lot of file system calls.
`fileKey` is more efficient and should guarantee uniqueness (`canonicalPath` may fail in the case of hardlinks).
The new code is 3x faster in our use case.
This commit is contained in:
Dave MacLachlan
2023-09-22 09:14:14 -07:00
committed by Space Team
parent 3673dff959
commit 722ddc9f91
2 changed files with 18 additions and 8 deletions
@@ -56,6 +56,18 @@ data class File constructor(internal val javaPath: Path) {
val listFilesOrEmpty: List<File>
get() = if (exists) listFiles else emptyList()
// A fileKey is an object that uniquely identifies the given file.
val fileKey: Any
get() {
// It is not guaranteed that all filesystems have fileKey. If not we fall
// back on canonicalPath which can be significantly slower to get.
var key = Files.readAttributes(javaPath, BasicFileAttributes::class.java).fileKey()
if (key == null) {
key = this.canonicalPath
}
return key
}
fun child(name: String) = File(this, name)
fun startsWith(another: File) = javaPath.startsWith(another.javaPath)