mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
optimization: do not rebuild RootIndex when roots-unrelated directories changed
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
package com.intellij.java.openapi.roots.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
|
||||
@@ -988,4 +989,24 @@ public class DirectoryIndexTest extends DirectoryIndexTestCase {
|
||||
assertEquals("Invalid package name for dir " + dir + ": " + packageName, packageName, actualName);
|
||||
}
|
||||
}
|
||||
|
||||
public void testUnrelatedDirectoriesCreationMustNotLeadToDirectoryIndexRebuildToImproveCheckoutPerformance() {
|
||||
VirtualFile root = ModuleRootManager.getInstance(myModule).getContentRoots()[0];
|
||||
WriteAction.run(()->ModuleRootModificationUtil.updateModel(myModule, model -> {
|
||||
ContentEntry rootEntry = model.getContentEntries()[0];
|
||||
for (int i=0;i<10_000;i++) {
|
||||
VirtualFile src = createChildDirectory(root, "extsrc" + i);
|
||||
rootEntry.addSourceFolder(src, false);
|
||||
}
|
||||
}));
|
||||
|
||||
ProjectFileIndex fileIndex = ProjectFileIndex.getInstance(getProject());
|
||||
PlatformTestUtil.startPerformanceTest("dir creation must not lead to dirindex rebuild", 30_000, ()->{
|
||||
for (int i=0; i<5_000; i++) {
|
||||
VirtualFile xxx = createChildDirectory(root, "xxx");
|
||||
assertFalse(fileIndex.isInSource(xxx));
|
||||
delete(xxx);
|
||||
}
|
||||
}).assertTiming();
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,11 @@ public class PackageDirectoryCache {
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
myNonExistentPackages.clear();
|
||||
myDirectoriesByPackageNameCache.clear();
|
||||
}
|
||||
|
||||
public void onLowMemory() {
|
||||
myNonExistentPackages.clear();
|
||||
}
|
||||
@@ -86,7 +91,7 @@ public class PackageDirectoryCache {
|
||||
}
|
||||
|
||||
for (VirtualFile file : myRootsByPackagePrefix.get(packageName)) {
|
||||
if (file.isDirectory()) {
|
||||
if (file.isDirectory() && file.isValid()) {
|
||||
result.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileTypeEvent;
|
||||
import com.intellij.openapi.fileTypes.FileTypeListener;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -17,9 +18,12 @@ import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.LowMemoryWatcher;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -64,6 +68,11 @@ public class DirectoryIndexImpl extends DirectoryIndex {
|
||||
});
|
||||
|
||||
myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
|
||||
@Override
|
||||
public void beforeRootsChange(@NotNull ModuleRootEvent event) {
|
||||
myRootIndex = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rootsChanged(@NotNull ModuleRootEvent event) {
|
||||
myRootIndex = null;
|
||||
@@ -75,7 +84,15 @@ public class DirectoryIndexImpl extends DirectoryIndex {
|
||||
public void after(@NotNull List<? extends VFileEvent> events) {
|
||||
RootIndex rootIndex = myRootIndex;
|
||||
if (rootIndex != null && shouldResetOnEvents(events)) {
|
||||
myRootIndex = null;
|
||||
rootIndex.myPackageDirectoryCache.clear();
|
||||
for (VFileEvent event : events) {
|
||||
// TempFileSystem doesn't properly support virtual file pointers, so reset unconditionally
|
||||
if (event.getFileSystem() instanceof TempFileSystem ||
|
||||
isIgnoredFileCreated(event)) {
|
||||
myRootIndex = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -91,6 +108,12 @@ public class DirectoryIndexImpl extends DirectoryIndex {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isIgnoredFileCreated(@NotNull VFileEvent event) {
|
||||
return event instanceof VFileMoveEvent && FileTypeRegistry.getInstance().isFileIgnored(((VFileMoveEvent)event).getNewParent()) ||
|
||||
event instanceof VFilePropertyChangeEvent &&
|
||||
((VFilePropertyChangeEvent)event).getPropertyName().equals(VirtualFile.PROP_NAME) &&
|
||||
FileTypeRegistry.getInstance().isFileIgnored(((VFilePropertyChangeEvent)event).getFile());
|
||||
}
|
||||
|
||||
private void dispatchPendingEvents() {
|
||||
myConnection.deliverImmediately();
|
||||
|
||||
@@ -49,7 +49,7 @@ public class RootIndex {
|
||||
private final Map<VirtualFile, DirectoryInfo> myRootInfos = ContainerUtil.newHashMap();
|
||||
private final ConcurrentBitSet myNonInterestingIds = new ConcurrentBitSet();
|
||||
@NotNull private final Project myProject;
|
||||
private final PackageDirectoryCache myPackageDirectoryCache;
|
||||
final PackageDirectoryCache myPackageDirectoryCache;
|
||||
private OrderEntryGraph myOrderEntryGraph;
|
||||
|
||||
public RootIndex(@NotNull Project project) {
|
||||
|
||||
Reference in New Issue
Block a user