RUST-10298 FileManagerImpl.removeInvalidFilesAndDirs optimization: don't check files for validity if not necessary

GitOrigin-RevId: 41fe71af759687c706d5f69b728dd24640a77d1d
This commit is contained in:
evgeny.bovykin
2024-10-05 07:56:31 +00:00
committed by intellij-monorepo-bot
parent 418edede82
commit 13bf9d21df
2 changed files with 39 additions and 1 deletions

View File

@@ -502,6 +502,20 @@ public final class FileManagerImpl implements FileManager {
myVFileToPsiDirMap.set(null);
}
@RequiresWriteLock
void removeInvalidFilesAndDirs(@NotNull Set<@NotNull VirtualFile> affectedFiles) {
Map<VirtualFile, FileViewProvider> fileToPsiFileMap = getVFileToViewProviderMap();
ConcurrentMap<VirtualFile, PsiDirectory> fileToPsiDirMap = myVFileToPsiDirMap.get();
for (VirtualFile file : affectedFiles) {
fileToPsiDirMap.remove(file);
FileViewProvider viewProvider = fileToPsiFileMap.get(file);
if (viewProvider != null) {
clearPsiCaches(viewProvider);
}
}
}
@RequiresWriteLock
void removeInvalidFilesAndDirs(boolean useFind) {
removeInvalidDirs();

View File

@@ -390,11 +390,15 @@ class PsiVFSListener internal constructor(private val project: Project) {
val oldParentDirs = ArrayList<PsiDirectory?>(events.size)
val newParentDirs = ArrayList<PsiDirectory?>(events.size)
var allMovedFilesAreRegularFiles = true
// find old directories before removing invalid ones
for (e in events) {
val event = e as VFileMoveEvent
val vFile = event.file
allMovedFilesAreRegularFiles = allMovedFilesAreRegularFiles and !vFile.isDirectory
var oldParentDir = fileManager.findDirectory(event.oldParent)
var newParentDir = fileManager.findDirectory(event.newParent)
@@ -418,7 +422,27 @@ class PsiVFSListener internal constructor(private val project: Project) {
oldParentDirs.add(oldParentDir)
newParentDirs.add(newParentDir)
}
fileManager.removeInvalidFilesAndDirs(true)
if (allMovedFilesAreRegularFiles) {
/*
Optimization:
`myFileManager.removeInvalidFilesAndDirs` can execute heavy operations for each PSI file currently stored to remove all invalid
files and directories.
If all files that were moved are regular files, and not directories,
all files that were *not* moved cannot become invalid,
so they can be skipped.
This is not the case if at least one moved file is a directory, since that also invalidates files in it.
*/
val movedFilesSet: MutableSet<VirtualFile> = HashSet()
for (e in events) {
val file = e.file ?: continue
movedFilesSet.add(file)
}
fileManager.removeInvalidFilesAndDirs(movedFilesSet)
} else {
fileManager.removeInvalidFilesAndDirs(true)
}
for ((i, event) in events.withIndex()) {
val vFile = event.file!!