Skip to content

Commit

Permalink
Merge pull request #3816 from Hannah-Sten/slow-operations
Browse files Browse the repository at this point in the history
Fill package inclusion cache in background
  • Loading branch information
PHPirates authored Dec 21, 2024
2 parents 8a46f6f + 80dc2aa commit ef60f5e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Added
* Add sections to breadcrumbs
* Improve performance when starting a run configuration and when using autocompletion directly after starting the IDE
* Change order in structure view to match source file and sectioning level
* Add command redefinitions to command definition filter in structure view
* Add support for automatic language injection on the minted environment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package nl.hannahsten.texifyidea.index.file

import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
Expand All @@ -8,6 +10,8 @@ import com.jetbrains.rd.util.concurrentMapOf
import nl.hannahsten.texifyidea.algorithm.DFS
import nl.hannahsten.texifyidea.lang.LatexPackage
import nl.hannahsten.texifyidea.util.files.removeFileExtension
import nl.hannahsten.texifyidea.util.runInBackground
import java.util.concurrent.atomic.AtomicBoolean

/**
* Compute and cache for each package style file all the other style files it includes (directly or indirectly).
Expand All @@ -18,11 +22,13 @@ object LatexExternalPackageInclusionCache {

private val cache = concurrentMapOf<LatexPackage, Set<LatexPackage>>()

private var isFillingCache = AtomicBoolean(false)

/**
* Map every LaTeX package style file to all the style files it includes, directly or indirectly.
*/
@Synchronized
fun getAllPackageInclusions(project: Project): Map<LatexPackage, Set<LatexPackage>> {
fun updateOrGetCache(project: Project): Map<LatexPackage, Set<LatexPackage>> {
if (cache.isNotEmpty() || DumbService.isDumb(project)) return cache

// Make sure the index is ready (#3754)
Expand All @@ -31,20 +37,34 @@ object LatexExternalPackageInclusionCache {
val directChildren = mutableMapOf<LatexPackage, MutableSet<LatexPackage>>()

// Get direct children from the index
FileBasedIndex.getInstance().getAllKeys(LatexExternalPackageInclusionIndex.Cache.id, project).forEach { indexKey ->
FileBasedIndex.getInstance().processValues(
LatexExternalPackageInclusionIndex.Cache.id, indexKey, null, { file, _ ->
val key = LatexPackage(file.name.removeFileExtension())
directChildren[key] = directChildren.getOrDefault(key, mutableSetOf()).also { it.add(LatexPackage((indexKey))) }
true
},
GlobalSearchScope.everythingScope(project)
)
}
if (isFillingCache.getAndSet(true)) return cache
// ???
runInEdt {
runInBackground(project, "Retrieving LaTeX package inclusions...") { indicator ->
try {
runReadAction { FileBasedIndex.getInstance().getAllKeys(LatexExternalPackageInclusionIndex.Cache.id, project) }.forEach { indexKey ->
runReadAction {
FileBasedIndex.getInstance().processValues(
LatexExternalPackageInclusionIndex.Cache.id, indexKey, null, { file, _ ->
indicator.checkCanceled()
val key = LatexPackage(file.name.removeFileExtension())
directChildren[key] = directChildren.getOrDefault(key, mutableSetOf()).also { it.add(LatexPackage((indexKey))) }
true
},
GlobalSearchScope.everythingScope(project)
)
}
}

// Do some DFS for indirect inclusions
for (latexPackage in directChildren.keys) {
cache[latexPackage] = DFS(latexPackage) { parent -> directChildren[parent] ?: emptySet() }.execute()
// Do some DFS for indirect inclusions
for (latexPackage in directChildren.keys) {
cache[latexPackage] = DFS(latexPackage) { parent -> directChildren[parent] ?: emptySet() }.execute()
}
}
finally {
isFillingCache.set(false)
}
}
}

return cache
Expand All @@ -55,7 +75,7 @@ object LatexExternalPackageInclusionCache {
*/
fun getAllIndirectlyIncludedPackages(packages: Collection<LatexPackage>, project: Project): Set<LatexPackage> {
val result = packages.toMutableSet()
val allInclusions = getAllPackageInclusions(project)
val allInclusions = updateOrGetCache(project)
for (latexPackage in packages) {
result.addAll(allInclusions[latexPackage] ?: emptySet())
}
Expand Down
4 changes: 2 additions & 2 deletions src/nl/hannahsten/texifyidea/run/compiler/LatexCompiler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,9 @@ enum class LatexCompiler(private val displayName: String, val executableName: St
*/
fun getCommand(runConfig: LatexRunConfiguration, project: Project): List<String>? {
val rootManager = ProjectRootManager.getInstance(project)
val fileIndex = rootManager.fileIndex
val mainFile = runConfig.mainFile ?: return null
val moduleRoot = fileIndex.getContentRootForFile(mainFile)
// Getting the content root is an expensive operation (See WorkspaceFileIndexDataImpl#ensureIsUpToDate), and since it probably won't change often we reuse a cached value
val moduleRoot = runConfig.outputPath.contentRoot
// For now we disable module roots with Docker
// Could be improved by mounting them to the right directory
val moduleRoots = if (runConfig.getLatexDistributionType().isDocker()) {
Expand Down
6 changes: 6 additions & 0 deletions src/nl/hannahsten/texifyidea/util/General.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,9 @@ fun runInBackground(project: Project?, description: String, function: (indicator
}
})
}

fun runInBackgroundWithoutProgress(function: () -> Unit) {
ApplicationManager.getApplication().invokeLater {
function()
}
}

0 comments on commit ef60f5e

Please sign in to comment.