fix regress: invalidateIndices shouldn't schedule indexing for nonindexed files, many thanks for Peter.Gromov for help of finding the problem in review sessions

This commit is contained in:
Maxim.Mossienko
2014-02-07 21:35:41 +01:00
parent d516dd3b1c
commit 83758fecf1
@@ -1698,8 +1698,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = affectedIndexCandidates.size(); i < size; ++i) {
final ID<?, ?> indexId = affectedIndexCandidates.get(i);
if (myRequiringContentIndices.contains(indexId) && shouldIndexFile(file, indexId)) {
if (shouldIndexFile(file, indexId)) {
if (fc == null) {
byte[] currentBytes;
try {
@@ -2066,9 +2065,9 @@ public class FileBasedIndexImpl extends FileBasedIndex {
IndexingStamp.removeAllIndexedState(file);
}
});
// the file is for sure not a dir and it was previously indexed by at least one index
if (!isTooLarge(file)) scheduleForUpdate(file);
}
// the file is for sure not a dir and it was previously indexed by at least one index
if (!isTooLarge(file)) scheduleForUpdate(file);
}
else {
myFilesToUpdate.remove(file);
@@ -2170,7 +2169,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
}
}
public List<VirtualFile> getAllFilesToUpdate() {
public Collection<VirtualFile> getAllFilesToUpdate() {
if (myFilesToUpdate.isEmpty()) {
return Collections.emptyList();
}
@@ -2200,50 +2199,34 @@ public class FileBasedIndexImpl extends FileBasedIndex {
myUpdateSemaphoreRef.compareAndSet(semaphore, null);
}
private static final int MAX_FILES_TO_PROCESS_OUTSIDE_SCOPE = 5;
private void forceUpdate(@Nullable Project project, @Nullable GlobalSearchScope filter, @Nullable VirtualFile restrictedTo, boolean onlyRemoveOutdatedData) {
myChangedFilesCollector.ensureAllInvalidateTasksCompleted();
ProjectIndexableFilesFilter indexableFilesFilter = projectIndexableFiles(project);
int filesProcessedOutsideScope = 0;
UpdateSemaphore updateSemaphore;
do{
updateSemaphore = obtainForceUpdateSemaphore();
try {
List<VirtualFile> filesToUpdate = getAllFilesToUpdate();
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = filesToUpdate.size(); i < size; ++i) {
VirtualFile file = filesToUpdate.get(i);
if ((indexableFilesFilter != null && // project files filtering
file instanceof VirtualFileWithId &&
!indexableFilesFilter.containsFileId(((VirtualFileWithId)file).getId())
) ||
filter != null && !filter.accept(file) ||
restrictedTo != null && restrictedTo != file
) {
if (filesProcessedOutsideScope >= MAX_FILES_TO_PROCESS_OUTSIDE_SCOPE) continue;
// In order to have myFilesToUpdate empty for avoiding contention on scanning large concurrent set
// we need eventually to process all files in it including the ones that do not belong to any project or current scope
// e.g. the files that have vfs built but avoided due to project / scope exclusion: workspace.xml / files under .git / user home / etc
++filesProcessedOutsideScope;
for (VirtualFile file : getAllFilesToUpdate()) {
if (indexableFilesFilter != null && file instanceof VirtualFileWithId && !indexableFilesFilter.containsFileId(
((VirtualFileWithId)file).getId())) {
continue;
}
try {
updateSemaphore.down();
// process only files that can affect result
processFileImpl(project, new com.intellij.ide.caches.FileContent(file), onlyRemoveOutdatedData);
if (filter == null || filter.accept(file) || Comparing.equal(file, restrictedTo)) {
try {
updateSemaphore.down();
// process only files that can affect result
processFileImpl(project, new com.intellij.ide.caches.FileContent(file), onlyRemoveOutdatedData);
}
catch (ProcessCanceledException e) {
updateSemaphore.reportUpdateCanceled();
throw e;
}
finally {
updateSemaphore.up();
}
}
catch (ProcessCanceledException e) {
updateSemaphore.reportUpdateCanceled();
throw e;
}
finally {
updateSemaphore.up();
}
}
// If several threads entered the method at the same time and there were files to update,
@@ -2464,11 +2447,17 @@ public class FileBasedIndexImpl extends FileBasedIndex {
if (file != null) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile instanceof VirtualFileWithId) {
boolean wasIndexed = false;
for(ID<?,?> psiBackedIndex:myPsiDependentIndices) {
IndexingStamp.update(virtualFile, psiBackedIndex, IndexInfrastructure.INVALID_STAMP2);
if (isFileIndexed(virtualFile, psiBackedIndex)) {
IndexingStamp.update(virtualFile, psiBackedIndex, IndexInfrastructure.INVALID_STAMP2);
wasIndexed = true;
}
}
if (wasIndexed) {
myChangedFilesCollector.scheduleForUpdate(virtualFile);
IndexingStamp.flushCache(virtualFile);
}
myChangedFilesCollector.scheduleForUpdate(virtualFile);
IndexingStamp.flushCache(virtualFile);
}
}
}