From bef0946ab7e5acd5b24b971eca532c43c8eba750 Mon Sep 17 00:00:00 2001 From: Mark Mann Date: Mon, 11 Dec 2023 11:08:00 -0800 Subject: [PATCH] [K/N] Reduce file reads in cache libraries #KT-64249 Fixed --- .../kotlin/backend/konan/CachedLibraries.kt | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CachedLibraries.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CachedLibraries.kt index 68fb24bf06a..c1b13abcc12 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CachedLibraries.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CachedLibraries.kt @@ -145,34 +145,27 @@ class CachedLibraries( } } - private val cacheDirsContents = mutableMapOf>() - private val librariesFileDirs = mutableMapOf>() - - 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() + private val cacheNameToImplicitDirMapping: Map = + 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 = 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) } } }