IDEA-132217 Running FileBasedIndexImpl invalidations should be cancellable same way as plain file indexing

This commit is contained in:
Maxim.Mossienko
2014-11-03 13:08:12 +01:00
parent dc9043c92d
commit 4d6b76ad64
@@ -804,7 +804,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myReentrancyGuard.set(Boolean.TRUE);
try {
myChangedFilesCollector.ensureAllInvalidateTasksCompleted();
myChangedFilesCollector.tryToEnsureAllInvalidateTasksCompleted();
if (isUpToDateCheckEnabled()) {
try {
checkRebuild(indexId, false);
@@ -1624,7 +1624,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
void processRefreshedFile(@NotNull Project project, @NotNull final com.intellij.ide.caches.FileContent fileContent) {
myChangedFilesCollector.ensureAllInvalidateTasksCompleted();
myChangedFilesCollector.tryToEnsureAllInvalidateTasksCompleted();
myChangedFilesCollector.processFileImpl(project, fileContent); // ProcessCanceledException will cause re-adding the file to processing list
}
@@ -1639,7 +1639,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
private void doIndexFileContent(@Nullable Project project, @NotNull com.intellij.ide.caches.FileContent content) {
myChangedFilesCollector.ensureAllInvalidateTasksCompleted();
myChangedFilesCollector.tryToEnsureAllInvalidateTasksCompleted();
final VirtualFile file = content.getVirtualFile();
FileType fileType = file.getFileType();
@@ -2070,19 +2070,15 @@ public class FileBasedIndexImpl extends FileBasedIndex {
if (markForReindex) {
// only mark the file as outdated, reindex will be done lazily
if (!fileIndexedStatesToUpdate.isEmpty()) {
final List<ID<?, ?>> finalNontrivialFileIndexedStates = nontrivialFileIndexedStates;
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = finalNontrivialFileIndexedStates.size(); i < size; ++i) {
final ID<?, ?> indexId = finalNontrivialFileIndexedStates.get(i);
if (needsFileContentLoading(indexId) && IndexingStamp.isFileIndexedStateCurrent(fileId, indexId)) {
IndexingStamp.setFileIndexedStateOutdated(fileId, indexId);
}
}
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = nontrivialFileIndexedStates.size(); i < size; ++i) {
final ID<?, ?> indexId = nontrivialFileIndexedStates.get(i);
if (needsFileContentLoading(indexId) && IndexingStamp.isFileIndexedStateCurrent(fileId, indexId)) {
IndexingStamp.setFileIndexedStateOutdated(fileId, indexId);
}
});
}
// the file is for sure not a dir and it was previously indexed by at least one index AND it belongs to some update set
if (!isTooLarge(file) && getIndexableSetForFile(file) != null) scheduleForUpdate(file);
}
@@ -2092,7 +2088,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myFutureInvalidations.offer(new InvalidationTask(file) {
@Override
public void run() {
removeFileDataFromIndices(finalFileIndexedStatesToUpdate, file);
removeFileDataFromIndices(finalFileIndexedStatesToUpdate, getSubj());
}
});
}
@@ -2131,31 +2127,52 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
public void ensureAllInvalidateTasksCompleted() {
ensureAllInvalidateTasksCompleted(false);
}
public void tryToEnsureAllInvalidateTasksCompleted() {
ensureAllInvalidateTasksCompleted(true);
}
private void ensureAllInvalidateTasksCompleted(boolean doCheckCancelledBetweenInvalidations) {
final int size = getNumberOfPendingInvalidations();
if (size == 0) {
return;
}
// we must avoid PCE interruptions when removing data from indices
ProgressManager.getInstance().executeNonCancelableSection(
new Runnable() {
@Override
public void run() {
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
indicator.setText("");
int count = 0;
while (true) {
InvalidationTask task = myFutureInvalidations.poll();
if (doCheckCancelledBetweenInvalidations) {
while (true) {
InvalidationTask task = myFutureInvalidations.poll();
if (task == null) {
break;
if (task == null) {
break;
}
ProgressManager.getInstance().executeNonCancelableSection(task);
ProgressManager.checkCanceled();
}
}
else {
ProgressManager.getInstance().executeNonCancelableSection(
new Runnable() {
@Override
public void run() {
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
indicator.setText("");
int count = 0;
while (true) {
InvalidationTask task = myFutureInvalidations.poll();
if (task == null) {
break;
}
indicator.setFraction((double)count++ / size);
task.run();
}
indicator.setFraction((double)count++ / size);
task.run();
}
}
}
);
);
}
}
private void iterateIndexableFiles(@NotNull final VirtualFile file, @NotNull final Processor<VirtualFile> processor) {
@@ -2210,7 +2227,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
private void forceUpdate(@Nullable Project project, @Nullable GlobalSearchScope filter, @Nullable VirtualFile restrictedTo) {
myChangedFilesCollector.ensureAllInvalidateTasksCompleted();
myChangedFilesCollector.tryToEnsureAllInvalidateTasksCompleted();
ProjectIndexableFilesFilter indexableFilesFilter = projectIndexableFiles(project);
UpdateSemaphore updateSemaphore;