KT-41456: Incremental KAPT - optimize .class file counting
When counting .class files, stop once the required number is reached. Also, implement simple counting logic directly, it is 25% faster than using File.walk(). The way this information is used is a heuristic, so reducing computation cost makes sense. ^KT-41456 Fixed
This commit is contained in:
committed by
teamcity
parent
0074e0209c
commit
72532f6f03
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.kapt3.base.incremental
|
||||
|
||||
import java.io.*
|
||||
import java.util.ArrayDeque
|
||||
|
||||
// TODO(gavra): switch away from Java serialization
|
||||
class JavaClassCacheManager(val file: File) : Closeable {
|
||||
@@ -59,9 +60,9 @@ class JavaClassCacheManager(val file: File) : Closeable {
|
||||
*
|
||||
* However, comparing total numbers is probably good enough, and it should eliminate most of the issues. See KT-41456 for details.
|
||||
*/
|
||||
val totalCompiledClasses = compiledSources.sumOf { it.walk().filter { it.extension == "class" }.count() }
|
||||
val totalDeclaredTypes = javaCache.getSourceFileDefinedTypesCount()
|
||||
if (totalCompiledClasses < totalDeclaredTypes) {
|
||||
val compileOutputHasEnoughClassFiles = checkMinNumberOfClassFiles(compiledSources, totalDeclaredTypes)
|
||||
if (!compileOutputHasEnoughClassFiles) {
|
||||
return SourcesToReprocess.FullRebuild
|
||||
}
|
||||
|
||||
@@ -197,4 +198,32 @@ sealed class SourcesToReprocess {
|
||||
) : SourcesToReprocess()
|
||||
|
||||
object FullRebuild : SourcesToReprocess()
|
||||
}
|
||||
|
||||
/** Returns if specified root dirs have at least [required] number of class files. */
|
||||
private fun checkMinNumberOfClassFiles(roots: List<File>, required: Int): Boolean {
|
||||
var currentlyMissing = required
|
||||
roots.filter { it.isDirectory }.forEach {
|
||||
val inThisRoot = countClassFilesUpToLimit(it, currentlyMissing)
|
||||
currentlyMissing -= inThisRoot
|
||||
}
|
||||
return currentlyMissing <= 0
|
||||
}
|
||||
|
||||
private fun countClassFilesUpToLimit(root: File, limit: Int): Int {
|
||||
var cnt = 0;
|
||||
val toVisit = ArrayDeque<File>()
|
||||
toVisit.add(root)
|
||||
while (cnt < limit && toVisit.isNotEmpty()) {
|
||||
val curr = toVisit.removeFirst()
|
||||
if (curr.isFile && curr.toString().endsWith(".class")) {
|
||||
cnt++
|
||||
} else if (curr.isDirectory) {
|
||||
curr.listFiles()?.forEach {
|
||||
toVisit.addLast(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cnt
|
||||
}
|
||||
Reference in New Issue
Block a user