[K/N] Reduce file reads in cache libraries

#KT-64249 Fixed
This commit is contained in:
Mark Mann
2023-12-11 11:08:00 -08:00
committed by Space Team
parent d2b810c373
commit bef0946ab7
@@ -145,34 +145,27 @@ class CachedLibraries(
}
}
private val cacheDirsContents = mutableMapOf<String, Set<String>>()
private val librariesFileDirs = mutableMapOf<KotlinLibrary, List<File>>()
private fun selectCache(library: KotlinLibrary, cacheDir: File): Cache? {
private fun File.trySelectCacheFor(library: KotlinLibrary): Cache? {
// See Linker.renameOutput why is it ok to have an empty cache directory.
val cacheDirContents = cacheDirsContents.getOrPut(cacheDir.absolutePath) {
cacheDir.listFilesOrEmpty.map { it.absolutePath }.toSet()
}
val cacheDirContents = listFilesOrEmpty.map { it.absolutePath }.toSet()
if (cacheDirContents.isEmpty()) return null
val cacheBinaryPartDir = cacheDir.child(PER_FILE_CACHE_BINARY_LEVEL_DIR_NAME)
val cacheBinaryPartDirContents = cacheDirsContents.getOrPut(cacheBinaryPartDir.absolutePath) {
cacheBinaryPartDir.listFilesOrEmpty.map { it.absolutePath }.toSet()
}
val cacheBinaryPartDir = child(PER_FILE_CACHE_BINARY_LEVEL_DIR_NAME)
val cacheBinaryPartDirContents = cacheBinaryPartDir.listFilesOrEmpty.map { it.absolutePath }.toSet()
val baseName = getCachedLibraryName(library)
val dynamicFile = cacheBinaryPartDir.child(getArtifactName(target, baseName, CompilerOutputKind.DYNAMIC_CACHE))
val staticFile = cacheBinaryPartDir.child(getArtifactName(target, baseName, CompilerOutputKind.STATIC_CACHE))
if (dynamicFile.absolutePath in cacheBinaryPartDirContents && staticFile.absolutePath in cacheBinaryPartDirContents)
error("Both dynamic and static caches files cannot be in the same directory." +
" Library: ${library.libraryName}, path to cache: ${cacheDir.absolutePath}")
" Library: ${library.libraryName}, path to cache: $absolutePath")
return when {
dynamicFile.absolutePath in cacheBinaryPartDirContents -> Cache.Monolithic(target, Kind.DYNAMIC, dynamicFile.absolutePath)
staticFile.absolutePath in cacheBinaryPartDirContents -> Cache.Monolithic(target, Kind.STATIC, staticFile.absolutePath)
else -> {
val libraryFileDirs = librariesFileDirs.getOrPut(library) {
library.getFilesWithFqNames().map { cacheDir.child(CacheSupport.cacheFileId(it.fqName, it.filePath)) }
val libraryFileDirs = library.getFilesWithFqNames().map {
child(CacheSupport.cacheFileId(it.fqName, it.filePath))
}
Cache.PerFile(target, Kind.STATIC, cacheDir.absolutePath, libraryFileDirs,
Cache.PerFile(target, Kind.STATIC, absolutePath, libraryFileDirs,
complete = cacheDirContents.containsAll(libraryFileDirs.map { it.absolutePath }))
}
}
@@ -181,23 +174,29 @@ class CachedLibraries(
private val uniqueNameToLibrary = allLibraries.associateBy { it.uniqueName }
private val uniqueNameToHash = mutableMapOf<String, FingerprintHash>()
private val cacheNameToImplicitDirMapping: Map<String, File> =
implicitCacheDirectories.flatMap { dir -> dir.listFilesOrEmpty.map { it.name to it } }
.toMap()
private fun KotlinLibrary.trySelectCacheAt(dirBuilder: (String) -> File?) =
sequenceOf(getPerFileCachedLibraryName(this), getCachedLibraryName(this))
.map(dirBuilder)
.mapNotNull { it?.trySelectCacheFor(this) }
.firstOrNull()
private val allCaches: Map<KotlinLibrary, Cache> = allLibraries.mapNotNull { library ->
val explicitPath = explicitCaches[library]
val cache = if (explicitPath != null) {
selectCache(library, File(explicitPath))
File(explicitPath).trySelectCacheFor(library)
?: error("No cache found for library ${library.libraryName} at $explicitPath")
} else {
val libraryPath = library.libraryFile.absolutePath
implicitCacheDirectories.firstNotNullOfOrNull { dir ->
selectCache(library, dir.child(getPerFileCachedLibraryName(library)))
?: selectCache(library, dir.child(getCachedLibraryName(library)))
}
library.trySelectCacheAt { cacheNameToImplicitDirMapping[it] }
?: autoCacheDirectory.takeIf { autoCacheableFrom.any { libraryPath.startsWith(it.absolutePath) } }
?.let {
val dir = computeVersionedCacheDirectory(it, library, uniqueNameToLibrary, uniqueNameToHash)
selectCache(library, dir.child(getPerFileCachedLibraryName(library)))
?: selectCache(library, dir.child(getCachedLibraryName(library)))
library.trySelectCacheAt { cacheName -> dir.child(cacheName) }
}
}