mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
UnindexedFilesUpdater -> DumbModeTask; faster refresh handling
This commit is contained in:
+6
@@ -42,6 +42,7 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.indexing.FileBasedIndexProjectHandler;
|
||||
import com.intellij.util.indexing.UnindexedFilesUpdater;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -307,7 +308,12 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl {
|
||||
if (!myStartupActivityPerformed) return;
|
||||
|
||||
if (myDoLogCachesUpdate) LOG.info(new Throwable("sync roots"));
|
||||
|
||||
DumbServiceImpl dumbService = DumbServiceImpl.getInstance(myProject);
|
||||
dumbService.queueTask(new UnindexedFilesUpdater(myProject, false));
|
||||
|
||||
if (myRootsChangeUpdaters.isEmpty()) return;
|
||||
|
||||
if (ourScheduleCacheUpdateInDumbMode) {
|
||||
dumbService.queueCacheUpdateInDumbMode(myRootsChangeUpdaters);
|
||||
} else {
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.util.indexing;
|
||||
|
||||
import com.intellij.AppTopics;
|
||||
import com.intellij.history.LocalHistory;
|
||||
import com.intellij.ide.caches.CacheUpdater;
|
||||
import com.intellij.ide.util.DelegatingProgressIndicator;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.notification.NotificationDisplayType;
|
||||
@@ -229,7 +228,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
LOG.info(e);
|
||||
}
|
||||
}
|
||||
scheduleIndexRebuild(true);
|
||||
scheduleIndexRebuild();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1327,7 +1326,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
try {
|
||||
doClearIndex(indexId);
|
||||
if (!cleanupOnly) {
|
||||
scheduleIndexRebuild(false);
|
||||
scheduleIndexRebuild();
|
||||
}
|
||||
}
|
||||
catch (StorageException e) {
|
||||
@@ -1365,16 +1364,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleIndexRebuild(boolean forceDumbMode) {
|
||||
private static void scheduleIndexRebuild() {
|
||||
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
|
||||
final Set<CacheUpdater> updatersToRun = Collections.<CacheUpdater>singleton(new UnindexedFilesUpdater(project, this));
|
||||
final DumbServiceImpl service = DumbServiceImpl.getInstance(project);
|
||||
if (forceDumbMode) {
|
||||
service.queueCacheUpdateInDumbMode(updatersToRun);
|
||||
}
|
||||
else {
|
||||
service.queueCacheUpdate(updatersToRun);
|
||||
}
|
||||
DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1671,6 +1663,10 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
return myChangedFilesCollector.getNumberOfPendingInvalidations();
|
||||
}
|
||||
|
||||
public int getChangedFileCount() {
|
||||
return myChangedFilesCollector.getAllFilesToUpdate().size();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<VirtualFile> getFilesToUpdate(final Project project) {
|
||||
return ContainerUtil.findAll(myChangedFilesCollector.getAllFilesToUpdate(), new Condition<VirtualFile>() {
|
||||
|
||||
+15
-7
@@ -37,6 +37,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.io.storage.HeavyProcessLatch;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -58,10 +59,18 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
startupManager.registerPreStartupActivity(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final UnindexedFilesUpdater unindexedFilesUpdater = new UnindexedFilesUpdater(project, index);
|
||||
// dumb mode should start before post-startup activities
|
||||
// only when queueTask is called from UI thread, we can guarantee that
|
||||
// when the method returns, the application has entered dumb mode
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!project.isDisposed()) {
|
||||
DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, true));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
startupManager.registerCacheUpdater(unindexedFilesUpdater);
|
||||
rootManager.registerRootsChangeUpdater(unindexedFilesUpdater);
|
||||
myIndex.registerIndexableSet(FileBasedIndexProjectHandler.this, project);
|
||||
projectManager.addProjectManagerListener(project, new ProjectManagerAdapter() {
|
||||
private boolean removed = false;
|
||||
@@ -69,7 +78,6 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
public void projectClosing(Project project) {
|
||||
if (!removed) {
|
||||
removed = true;
|
||||
rootManager.unregisterRootsChangeUpdater(unindexedFilesUpdater);
|
||||
myIndex.removeIndexableSet(FileBasedIndexProjectHandler.this);
|
||||
}
|
||||
}
|
||||
@@ -111,14 +119,13 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
@Nullable
|
||||
public static DumbModeTask createChangedFilesIndexingTask(final Project project) {
|
||||
final FileBasedIndexImpl index = (FileBasedIndexImpl)FileBasedIndex.getInstance();
|
||||
final Collection<VirtualFile> files = index.getFilesToUpdate(project);
|
||||
if (files.isEmpty()) return null;
|
||||
|
||||
if (files.size() + index.getNumberOfPendingInvalidations() < 20 && !DumbService.isDumb(project)) {
|
||||
if (index.getChangedFileCount() + index.getNumberOfPendingInvalidations() < 20 && !DumbService.isDumb(project)) {
|
||||
// the changed set is small, process it immediately without entering dumb mode
|
||||
// invalidation tasks are also processed and may take some time => take them into account
|
||||
try {
|
||||
HeavyProcessLatch.INSTANCE.processStarted();
|
||||
final Collection<VirtualFile> files = index.getFilesToUpdate(project);
|
||||
reindexRefreshedFiles(new EmptyProgressIndicator(), files, project, index);
|
||||
}
|
||||
finally {
|
||||
@@ -131,6 +138,7 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
return new DumbModeTask() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
final Collection<VirtualFile> files = index.getFilesToUpdate(project);
|
||||
indicator.setIndeterminate(false);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.updating"));
|
||||
reindexRefreshedFiles(indicator, files, project, index);
|
||||
|
||||
@@ -15,45 +15,43 @@
|
||||
*/
|
||||
package com.intellij.util.indexing;
|
||||
|
||||
import com.intellij.ide.caches.CacheUpdater;
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.caches.FileContent;
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.CacheUpdateRunner;
|
||||
import com.intellij.openapi.project.DumbModeTask;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.CollectingContentIterator;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* @since Jan 29, 2008
|
||||
*/
|
||||
public class UnindexedFilesUpdater implements CacheUpdater {
|
||||
public class UnindexedFilesUpdater extends DumbModeTask {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.UnindexedFilesUpdater");
|
||||
|
||||
private final FileBasedIndexImpl myIndex;
|
||||
private final FileBasedIndexImpl myIndex = (FileBasedIndexImpl)FileBasedIndex.getInstance();
|
||||
private final Project myProject;
|
||||
private final AtomicBoolean myFinishedUpdate = new AtomicBoolean();
|
||||
private long myStarted;
|
||||
private final boolean myOnStartup;
|
||||
|
||||
public UnindexedFilesUpdater(final Project project, FileBasedIndexImpl index) {
|
||||
myIndex = index;
|
||||
public UnindexedFilesUpdater(final Project project, boolean onStartup) {
|
||||
myProject = project;
|
||||
myOnStartup = onStartup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfPendingUpdateJobs() {
|
||||
return myIndex.getNumberOfPendingInvalidations();
|
||||
}
|
||||
private void updateUnindexedFiles(ProgressIndicator indicator) {
|
||||
indicator.setIndeterminate(true);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.scanning"));
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public VirtualFile[] queryNeededFiles(@NotNull ProgressIndicator indicator) {
|
||||
myIndex.filesUpdateStarted(myProject);
|
||||
CollectingContentIterator finder = myIndex.createContentIterator(indicator);
|
||||
long l = System.currentTimeMillis();
|
||||
myIndex.iterateIndexableFiles(finder, myProject, indicator);
|
||||
@@ -61,35 +59,51 @@ public class UnindexedFilesUpdater implements CacheUpdater {
|
||||
|
||||
LOG.info("Indexable files iterated in " + (System.currentTimeMillis() - l) + " ms");
|
||||
List<VirtualFile> files = finder.getFiles();
|
||||
|
||||
if (myOnStartup) {
|
||||
// full VFS refresh makes sense only after it's loaded, i.e. after scanning files to index is finished
|
||||
((StartupManagerImpl)StartupManager.getInstance(myProject)).scheduleInitialVfsRefresh();
|
||||
}
|
||||
|
||||
if (files.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long started = System.currentTimeMillis();
|
||||
LOG.info("Unindexed files update started: " + files.size() + " files to update");
|
||||
myFinishedUpdate.set(false);
|
||||
myStarted = System.currentTimeMillis();
|
||||
return VfsUtilCore.toVirtualFileArray(files);
|
||||
|
||||
indicator.setIndeterminate(false);
|
||||
indicator.setText(IdeBundle.message("progress.indexing.updating"));
|
||||
|
||||
indexFiles(indicator, files);
|
||||
LOG.info("Unindexed files update done in " + (System.currentTimeMillis() - started) + " ms");
|
||||
}
|
||||
|
||||
private void indexFiles(ProgressIndicator indicator, List<VirtualFile> files) {
|
||||
CacheUpdateRunner.processFiles(indicator, true, files, myProject, new Consumer<FileContent>() {
|
||||
@Override
|
||||
public void consume(FileContent content) {
|
||||
try {
|
||||
myIndex.indexFileContent(myProject, content);
|
||||
}
|
||||
finally {
|
||||
IndexingStamp.flushCache(content.getVirtualFile());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processFile(@NotNull FileContent fileContent) {
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
myIndex.filesUpdateStarted(myProject);
|
||||
try {
|
||||
myIndex.indexFileContent(myProject, fileContent);
|
||||
updateUnindexedFiles(indicator);
|
||||
}
|
||||
finally {
|
||||
IndexingStamp.flushCache(fileContent.getVirtualFile());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatingDone() {
|
||||
if (myFinishedUpdate.compareAndSet(false, true)) {
|
||||
myIndex.filesUpdateFinished(myProject);
|
||||
LOG.info("Unindexed files update done in " + (System.currentTimeMillis() - myStarted) + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void canceled() {
|
||||
if (myFinishedUpdate.compareAndSet(false, true)) {
|
||||
myIndex.filesUpdateFinished(myProject);
|
||||
catch (ProcessCanceledException e) {
|
||||
LOG.info("Unindexed files update canceled");
|
||||
throw e;
|
||||
} finally {
|
||||
myIndex.filesUpdateFinished(myProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,27 +187,34 @@ public class StartupManagerImpl extends StartupManagerEx {
|
||||
}
|
||||
});
|
||||
|
||||
if (!app.isUnitTestMode() && !myProject.isDisposed()) {
|
||||
if (!app.isHeadlessEnvironment()) {
|
||||
checkProjectRoots();
|
||||
final long sessionId = VirtualFileManager.getInstance().asyncRefresh(null);
|
||||
final MessageBusConnection connection = app.getMessageBus().connect();
|
||||
connection.subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener.Adapter() {
|
||||
@Override
|
||||
public void afterProjectClosed(@NotNull Project project) {
|
||||
RefreshQueue.getInstance().cancelSession(sessionId);
|
||||
connection.disconnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
VirtualFileManager.getInstance().syncRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
Registry.get("ide.firstStartup").setValue(false);
|
||||
}
|
||||
|
||||
public void scheduleInitialVfsRefresh() {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
|
||||
Application app = ApplicationManager.getApplication();
|
||||
if (!app.isHeadlessEnvironment()) {
|
||||
checkProjectRoots();
|
||||
final long sessionId = VirtualFileManager.getInstance().asyncRefresh(null);
|
||||
final MessageBusConnection connection = app.getMessageBus().connect();
|
||||
connection.subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener.Adapter() {
|
||||
@Override
|
||||
public void afterProjectClosed(@NotNull Project project) {
|
||||
RefreshQueue.getInstance().cancelSession(sessionId);
|
||||
connection.disconnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
VirtualFileManager.getInstance().syncRefresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void checkProjectRoots() {
|
||||
LocalFileSystem fs = LocalFileSystem.getInstance();
|
||||
if (!(fs instanceof LocalFileSystemImpl)) return;
|
||||
@@ -239,7 +246,27 @@ public class StartupManagerImpl extends StartupManagerEx {
|
||||
|
||||
public void startCacheUpdate() {
|
||||
try {
|
||||
DumbServiceImpl.getInstance(myProject).queueCacheUpdateInDumbMode(myCacheUpdaters);
|
||||
DumbServiceImpl dumbService = DumbServiceImpl.getInstance(myProject);
|
||||
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
// pre-startup activities have registered dumb tasks that load VFS (scanning files to index)
|
||||
// only after these tasks pass does VFS refresh make sense
|
||||
dumbService.queueTask(new DumbModeTask() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull final ProgressIndicator indicator) {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myProject.isDisposed()) {
|
||||
scheduleInitialVfsRefresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dumbService.queueCacheUpdateInDumbMode(myCacheUpdaters);
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
throw e;
|
||||
|
||||
Reference in New Issue
Block a user