Add additional cache for packages' directories

It's important because even if we know the root where
the package is located we need to go through its parts,
and it's not as fast as it could be since implementation
of VirtualFile.findChild() traverse all files in the directory
to find the relevant one
This commit is contained in:
Denis Zharkov
2017-04-06 12:55:25 +03:00
parent e4cb5496b8
commit aef1ca10f7
@@ -21,6 +21,7 @@ import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.containers.IntArrayList import com.intellij.util.containers.IntArrayList
import gnu.trove.THashMap
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import java.util.* import java.util.*
@@ -63,6 +64,10 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
override val indexedRoots by lazy { roots.asSequence() } override val indexedRoots by lazy { roots.asSequence() }
private val packageCache: Array<out MutableMap<String, VirtualFile?>> by lazy {
Array(roots.size) { THashMap<String, VirtualFile?>() }
}
// findClassGivenDirectory MUST check whether the class with this classId exists in given package // findClassGivenDirectory MUST check whether the class with this classId exists in given package
override fun <T : Any> findClass( override fun <T : Any> findClass(
classId: ClassId, classId: ClassId,
@@ -159,7 +164,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
val rootIndex = cacheRootIndices[i] val rootIndex = cacheRootIndices[i]
if (rootIndex <= processedRootsUpTo) continue // roots with those indices have been processed by now if (rootIndex <= processedRootsUpTo) continue // roots with those indices have been processed by now
val directoryInRoot = travelPath(rootIndex, packagesPath, reverseCacheIndex, caches) ?: continue val directoryInRoot = travelPath(rootIndex, request.packageFqName, packagesPath, reverseCacheIndex, caches) ?: continue
val root = roots[rootIndex] val root = roots[rootIndex]
val result = handle(root, directoryInRoot) val result = handle(root, directoryInRoot)
if (result != null) { if (result != null) {
@@ -168,13 +173,19 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
} }
processedRootsUpTo = if (cacheRootIndices.isEmpty) processedRootsUpTo else cacheRootIndices.get(cacheRootIndices.size() - 1) processedRootsUpTo = if (cacheRootIndices.isEmpty) processedRootsUpTo else cacheRootIndices.get(cacheRootIndices.size() - 1)
} }
return notFound() return notFound()
} }
// try to find a target directory corresponding to package represented by packagesPath in a given root represented by index // try to find a target directory corresponding to package represented by packagesPath in a given root represented by index
// possibly filling "Cache" objects with new information // possibly filling "Cache" objects with new information
private fun travelPath(rootIndex: Int, packagesPath: List<String>, fillCachesAfter: Int, cachesPath: List<Cache>): VirtualFile? { private fun travelPath(
rootIndex: Int,
packageFqName: FqName,
packagesPath: List<String>,
fillCachesAfter: Int,
cachesPath: List<Cache>
): VirtualFile? {
if (rootIndex >= maxIndex) { if (rootIndex >= maxIndex) {
for (i in (fillCachesAfter + 1)..(cachesPath.size - 1)) { for (i in (fillCachesAfter + 1)..(cachesPath.size - 1)) {
// we all know roots that contain this package by now // we all know roots that contain this package by now
@@ -184,6 +195,12 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
return null return null
} }
return packageCache[rootIndex].getOrPut(packageFqName.asString()) {
doTravelPath(rootIndex, packagesPath, fillCachesAfter, cachesPath)
}
}
private fun doTravelPath(rootIndex: Int, packagesPath: List<String>, fillCachesAfter: Int, cachesPath: List<Cache>): VirtualFile? {
val pathRoot = roots[rootIndex] val pathRoot = roots[rootIndex]
val prefixPathSegments = pathRoot.prefixFqName?.pathSegments() val prefixPathSegments = pathRoot.prefixFqName?.pathSegments()