[JS IC] Support deleted files in IC cache invalidator

- support them in test too
This commit is contained in:
Roman Artemev
2021-12-17 06:38:19 +03:00
committed by teamcity
parent 2ace13a904
commit 9b49f0eb70
3 changed files with 35 additions and 9 deletions
@@ -52,7 +52,7 @@ private fun invalidateCacheForModule(
cacheConsumer: PersistentCacheConsumer, cacheConsumer: PersistentCacheConsumer,
signatureResolver: (String, Int) -> IdSignature, signatureResolver: (String, Int) -> IdSignature,
fileFingerPrints: MutableMap<String, Hash> fileFingerPrints: MutableMap<String, Hash>
): Set<String> { ): Pair<Set<String>, Collection<String>> {
val dirtyFiles = mutableSetOf<String>() val dirtyFiles = mutableSetOf<String>()
@@ -110,7 +110,14 @@ private fun invalidateCacheForModule(
cacheConsumer.invalidateForFile(dirty) cacheConsumer.invalidateForFile(dirty)
} }
return dirtyFiles val cachedFiles = cacheProvider.filePaths()
val deletedFiles = cachedFiles - libraryFiles.toSet()
for (deleted in deletedFiles) {
cacheConsumer.invalidateForFile(deleted)
}
return dirtyFiles to deletedFiles
} }
private fun KotlinLibrary.filesAndSigReaders(): List<Pair<String, IdSignatureDeserializer>> { private fun KotlinLibrary.filesAndSigReaders(): List<Pair<String, IdSignatureDeserializer>> {
@@ -149,6 +156,7 @@ private fun buildCacheForModule(
deserializer: JsIrLinker, deserializer: JsIrLinker,
dependencies: Collection<IrModuleFragment>, dependencies: Collection<IrModuleFragment>,
dirtyFiles: Collection<String>, dirtyFiles: Collection<String>,
deletedFiles: Collection<String>,
cleanInlineHashes: Map<IdSignature, Hash>, cleanInlineHashes: Map<IdSignature, Hash>,
cacheConsumer: PersistentCacheConsumer, cacheConsumer: PersistentCacheConsumer,
signatureDeserializers: Map<FilePath, Map<IdSignature, Int>>, signatureDeserializers: Map<FilePath, Map<IdSignature, Int>>,
@@ -194,7 +202,7 @@ private fun buildCacheForModule(
// TODO: actual way of building a cache could change in future // TODO: actual way of building a cache could change in future
cacheExecutor.execute(irModule, dependencies, deserializer, configuration, dirtyFiles, cacheConsumer, emptySet(), null) // TODO: main arguments? cacheExecutor.execute(irModule, dependencies, deserializer, configuration, dirtyFiles, deletedFiles, cacheConsumer, emptySet(), null) // TODO: main arguments?
cacheConsumer.commitLibraryPath(libraryInfo.libPath.toCanonicalPath(), libraryInfo.flatHash, libraryInfo.transHash) cacheConsumer.commitLibraryPath(libraryInfo.libPath.toCanonicalPath(), libraryInfo.flatHash, libraryInfo.transHash)
} }
@@ -299,6 +307,7 @@ fun interface CacheExecutor {
deserializer: JsIrLinker, deserializer: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
dirtyFiles: Collection<String>?, // if null consider the whole module dirty dirtyFiles: Collection<String>?, // if null consider the whole module dirty
deletedFiles: Collection<String>,
cacheConsumer: PersistentCacheConsumer, cacheConsumer: PersistentCacheConsumer,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
mainArguments: List<String>?, mainArguments: List<String>?,
@@ -441,7 +450,9 @@ private fun actualizeCacheForModule(
persistentCacheProviders[lib]?.let { provider -> persistentCacheProviders[lib]?.let { provider ->
val moduleReaders = depReaders[lib]!! val moduleReaders = depReaders[lib]!!
val inlineHashes = provider.allInlineHashes { f, i -> val inlineHashes = provider.allInlineHashes { f, i ->
moduleReaders[f]!!.deserializeIdSignature(i) val moduleReader = moduleReaders[f]
?: error("No module reader for file $f")
moduleReader.deserializeIdSignature(i)
} }
sigHashes.putAll(inlineHashes) sigHashes.putAll(inlineHashes)
} }
@@ -458,7 +469,7 @@ private fun actualizeCacheForModule(
currentLibraryCacheProvider.inlineHashes(filePath) { s -> sigReader.deserializeIdSignature(s) } currentLibraryCacheProvider.inlineHashes(filePath) { s -> sigReader.deserializeIdSignature(s) }
} }
val dirtySet = invalidateCacheForModule( val (dirtySet, deletedFiles) = invalidateCacheForModule(
library, library,
libraryFiles, libraryFiles,
sigHashes, sigHashes,
@@ -513,6 +524,7 @@ private fun actualizeCacheForModule(
jsIrLinker, jsIrLinker,
irModules.map { it.first }, irModules.map { it.first },
dirtySet, dirtySet,
deletedFiles,
sigHashes, sigHashes,
persistentCacheConsumer, persistentCacheConsumer,
deserializers, deserializers,
@@ -565,6 +577,7 @@ fun rebuildCacheForDirtyFiles(
jsIrLinker, jsIrLinker,
configuration, configuration,
dirtyFiles, dirtyFiles,
emptyList(),
cacheConsumer, cacheConsumer,
exportedDeclarations, exportedDeclarations,
mainArguments mainArguments
@@ -578,6 +591,7 @@ fun buildCacheForModuleFiles(
deserializer: JsIrLinker, deserializer: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
dirtyFiles: Collection<String>?, // if null consider the whole module dirty dirtyFiles: Collection<String>?, // if null consider the whole module dirty
deletedFiles: Collection<String>,
cacheConsumer: PersistentCacheConsumer, cacheConsumer: PersistentCacheConsumer,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
mainArguments: List<String>?, mainArguments: List<String>?,
@@ -184,7 +184,8 @@ class PersistentCacheProviderImpl(private val cachePath: String) : PersistentCac
} }
override fun filePaths(): Iterable<String> { override fun filePaths(): Iterable<String> {
return File(cachePath).listFiles()!!.filter { it.isDirectory }.mapNotNull { f -> val files = File(cachePath).listFiles() ?: return emptyList()
return files.filter { it.isDirectory }.mapNotNull { f ->
val fileInfo = File(f, fileInfoFile) val fileInfo = File(f, fileInfoFile)
if (fileInfo.exists()) { if (fileInfo.exists()) {
fileInfo.readLines()[0] fileInfo.readLines()[0]
@@ -53,6 +53,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
deserializer: JsIrLinker, deserializer: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
dirtyFiles: Collection<String>?, // if null consider the whole module dirty dirtyFiles: Collection<String>?, // if null consider the whole module dirty
deletedFiles: Collection<String>,
cacheConsumer: PersistentCacheConsumer, cacheConsumer: PersistentCacheConsumer,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
mainArguments: List<String>?, mainArguments: List<String>?,
@@ -147,7 +148,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
val moduleCacheDir = resolveModuleCache(module, buildDir) val moduleCacheDir = resolveModuleCache(module, buildDir)
buildCachesAndCheck(moduleStep, configuration, moduleSourceDir, outputKlibFile, moduleCacheDir, dependencies, icCaches, dirtyFiles) buildCachesAndCheck(moduleStep, configuration, moduleSourceDir, outputKlibFile, moduleCacheDir, dependencies, icCaches, dirtyFiles, deletedFiles)
} }
} }
} }
@@ -165,7 +166,8 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
moduleCacheDir: File, moduleCacheDir: File,
dependencies: List<File>, dependencies: List<File>,
icCaches: List<File>, icCaches: List<File>,
expectedDirtyFiles: List<File> expectedDirtyFiles: List<File>,
expectedDeletedFiles: List<File>
) { ) {
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
fun dirtyFilesChecker( fun dirtyFilesChecker(
@@ -174,6 +176,7 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
deserializer: JsIrLinker, deserializer: JsIrLinker,
configuration: CompilerConfiguration, configuration: CompilerConfiguration,
invalidatedDirtyFiles: Collection<String>?, // if null consider the whole module dirty invalidatedDirtyFiles: Collection<String>?, // if null consider the whole module dirty
deletedFiles: Collection<String>,
cacheConsumer: PersistentCacheConsumer, cacheConsumer: PersistentCacheConsumer,
exportedDeclarations: Set<FqName>, exportedDeclarations: Set<FqName>,
mainArguments: List<String>?, mainArguments: List<String>?,
@@ -183,7 +186,15 @@ abstract class AbstractInvalidationTest : KotlinTestWithEnvironment() {
val expectedDirtyFilesCanonical = expectedDirtyFiles.map { it.canonicalPath } val expectedDirtyFilesCanonical = expectedDirtyFiles.map { it.canonicalPath }
JUnit4Assertions.assertSameElements(expectedDirtyFilesCanonical, actualDirtyFiles) { JUnit4Assertions.assertSameElements(expectedDirtyFilesCanonical, actualDirtyFiles) {
"For module $moduleKlibFile at step ${moduleStep.id}" "Mismatched DIRTY files for module $moduleKlibFile at step ${moduleStep.id}"
}
val actualDeletedFiles =
deletedFiles.map { File(it).canonicalPath }
val expectedDeletedFilesCanonical = expectedDeletedFiles.map { it.canonicalPath }
JUnit4Assertions.assertSameElements(expectedDeletedFilesCanonical, actualDeletedFiles) {
"Mismatched DELETED files for module $moduleKlibFile at step ${moduleStep.id}"
} }
} }