diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java index c36da1c69d49..bd7b78ac2702 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/PushedFilePropertiesUpdaterImpl.java @@ -38,7 +38,6 @@ import com.intellij.openapi.roots.*; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.EmptyRunnable; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; @@ -279,8 +278,7 @@ public class PushedFilePropertiesUpdaterImpl extends PushedFilePropertiesUpdater public static void invokeConcurrentlyIfPossible(final List tasks) { if (tasks.size() == 1 || - ApplicationManager.getApplication().isWriteAccessAllowed() || - !Registry.is("idea.concurrent.scanning.files.to.index")) { + ApplicationManager.getApplication().isWriteAccessAllowed()) { for(Runnable r:tasks) r.run(); return; } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index c4c694801847..a3b63dbb8cfd 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -644,7 +644,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { @Nullable GlobalSearchScope filter, @Nullable VirtualFile restrictedFile) { ProgressManager.checkCanceled(); - myContentlessIndicesUpdateQueue.ensureUpToDate(); // some contentful indices depends on contentless ones ApplicationManager.getApplication().assertReadAccessAllowed(); if (!needsFileContentLoading(indexId)) { return; //indexed eagerly in foreground while building unindexed file list @@ -921,8 +920,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { private static final Key> ourProjectFilesSetKey = Key.create("projectFiles"); void filesUpdateEnumerationFinished() { - myContentlessIndicesUpdateQueue.ensureUpToDate(); - myContentlessIndicesUpdateQueue.signalUpdateEnd(); } @TestOnly @@ -971,8 +968,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { } void filesUpdateStarted(Project project) { - myContentlessIndicesUpdateQueue.signalUpdateStart(); - myContentlessIndicesUpdateQueue.ensureUpToDate(); myProjectsBeingUpdated.add(project); ++myFilesModCount; } @@ -1353,8 +1348,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { return true; } - private final TaskQueue myContentlessIndicesUpdateQueue = new TaskQueue(10000); - private final StorageGuard myStorageLock = new StorageGuard(); private volatile boolean myPreviousDataBufferingState; private final Object myBufferingStateUpdateLock = new Object(); @@ -1444,7 +1437,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } int getChangedFileCount() { - return myChangedFilesCollector.getAllFilesToUpdate().size(); + return myChangedFilesCollector.getChangedFileCount(); } @NotNull @@ -1467,14 +1460,14 @@ public class FileBasedIndexImpl extends FileBasedIndex { } public boolean isFileUpToDate(VirtualFile file) { - return !myChangedFilesCollector.myFilesToUpdate.containsKey(Math.abs(getIdMaskingNonIdBasedFile(file))); + return !myChangedFilesCollector.isScheduledForUpdate(file); } // caller is responsible to ensure no concurrent same document processing void processRefreshedFile(@Nullable Project project, @NotNull final com.intellij.ide.caches.FileContent fileContent) { // ProcessCanceledException will cause re-adding the file to processing list final VirtualFile file = fileContent.getVirtualFile(); - if (myChangedFilesCollector.myFilesToUpdate.containsKey(Math.abs(getIdMaskingNonIdBasedFile(file)))) { + if (myChangedFilesCollector.isScheduledForUpdate(file)) { indexFileContent(project, fileContent); } } @@ -1503,7 +1496,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { IndexingStamp.flushCache(fileId); } - myChangedFilesCollector.myFilesToUpdate.remove(fileId); + myChangedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId); } private void doIndexFileContent(@Nullable Project project, @NotNull final com.intellij.ide.caches.FileContent content) { @@ -1657,12 +1650,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } private void scheduleUpdate(@NotNull final ID indexId, final Computable update, VirtualFile file, final int inputId, final boolean hasContent) { - if (myNotRequiringContentIndices.contains(indexId) && !Registry.is("idea.concurrent.scanning.files.to.index")) { - myContentlessIndicesUpdateQueue.submit( - () -> updateWithBufferingEnabled(update), - () -> indexedStampUpdate(indexId, file, inputId, hasContent)); - } - else if (updateWithBufferingEnabled(update)) { + if (updateWithBufferingEnabled(update)) { AccessToken accessToken = ReadAction.start(); try { indexedStampUpdate(indexId, file, inputId, hasContent); @@ -1873,6 +1861,10 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } + private void removeFileIdFromFilesScheduledForUpdate(int fileId) { + myFilesToUpdate.remove(fileId); + } + Collection getAllFilesToUpdate() { if (myFilesToUpdate.isEmpty()) { return Collections.emptyList(); @@ -1882,9 +1874,6 @@ public class FileBasedIndexImpl extends FileBasedIndex { @Override public void before(@NotNull List events) { - myContentlessIndicesUpdateQueue.signalUpdateStart(); - myContentlessIndicesUpdateQueue.ensureUpToDate(); - for (VFileEvent event : events) { if (memoryStorageCleaningNeeded(event)) { cleanupMemoryStorage(); @@ -1903,10 +1892,15 @@ public class FileBasedIndexImpl extends FileBasedIndex { @Override public void after(@NotNull List events) { - myContentlessIndicesUpdateQueue.ensureUpToDate(); - super.after(events); - myContentlessIndicesUpdateQueue.signalUpdateEnd(); + } + + public boolean isScheduledForUpdate(VirtualFile file) { + return myFilesToUpdate.containsKey(Math.abs(getIdMaskingNonIdBasedFile(file))); + } + + public int getChangedFileCount() { + return myFilesToUpdate.size(); } } @@ -2113,9 +2107,9 @@ public class FileBasedIndexImpl extends FileBasedIndex { final int fileId = Math.abs(getIdMaskingNonIdBasedFile(file)); if (!file.isValid()) { removeDataFromIndicesForFile(fileId); - myChangedFilesCollector.myFilesToUpdate.remove(fileId); + myChangedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId); } else if (getIndexableSetForFile(file) == null) { // todo remove data from indices for removed - myChangedFilesCollector.myFilesToUpdate.remove(fileId); + myChangedFilesCollector.removeFileIdFromFilesScheduledForUpdate(fileId); } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/TaskQueue.java b/platform/lang-impl/src/com/intellij/util/indexing/TaskQueue.java deleted file mode 100644 index 680a940e5c71..000000000000 --- a/platform/lang-impl/src/com/intellij/util/indexing/TaskQueue.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.indexing; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.registry.Registry; -import org.jetbrains.annotations.NotNull; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** -* Created by Maxim.Mossienko on 7/18/13. -*/ -class TaskQueue { - private final AtomicInteger myDoWorkRequest = new AtomicInteger(); - private final AtomicInteger myUpdatesCount = new AtomicInteger(); - private final BlockingQueue myPendingWriteRequestsQueue = new LinkedBlockingQueue<>(); - private final BlockingQueue myTimestampUpdates = new LinkedBlockingQueue<>(); - private final int myLimit; - private final int myStealLimit; - private final int myTimeStampUpdateSizeLimit; - - public TaskQueue(int limit) { - myLimit = limit; - myStealLimit = Math.max(1, (int)(limit * 0.01)); - myTimeStampUpdateSizeLimit = 32; - } - - void submit(@NotNull final Computable update, @NotNull final Runnable successRunnable) { - int currentTasksCount = myUpdatesCount.incrementAndGet(); - - myPendingWriteRequestsQueue.add(() -> { - try { - Boolean result = update.compute(); - if (result == Boolean.TRUE) { - myTimestampUpdates.add(successRunnable); - } - } - finally { - myUpdatesCount.decrementAndGet(); - } - }); - - if (currentTasksCount > myLimit) { - Runnable runnable = myPendingWriteRequestsQueue.poll(); - int processed = 0; - while (runnable != null) { - runnable.run(); - if (++processed == myStealLimit) break; - runnable = myPendingWriteRequestsQueue.poll(); - } - } - - int size = myTimestampUpdates.size(); - if (size > myTimeStampUpdateSizeLimit) { - applyTimeStamps(size); - } - } - - private void applyTimeStamps(final int max) { - final Runnable runnable = myTimestampUpdates.poll(); - if (runnable == null) return; - ApplicationManager.getApplication().runReadAction(() -> { - int updates = 0; - for (Runnable r = runnable; r != null; r = myTimestampUpdates.poll()) { - r.run(); - if (++updates == max) break; - } - }); - } - - public void ensureUpToDate() { - try { - if (Registry.is("idea.concurrent.scanning.files.to.index")) return; - while(myUpdatesCount.get() > 0) { - Runnable runnable = myPendingWriteRequestsQueue.poll(10, TimeUnit.MILLISECONDS); - if (runnable != null) runnable.run(); - } - applyTimeStamps(Integer.MAX_VALUE); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - public void signalUpdateEnd() { - myDoWorkRequest.decrementAndGet(); - } - - public void signalUpdateStart() { - int workRequests = myDoWorkRequest.getAndIncrement(); - - if (workRequests == 0) { - if(Registry.is("idea.concurrent.scanning.files.to.index")) return; - myDoWorkRequest.incrementAndGet(); - // we have 3 content independent indices but only one of them is heavy IO bound so there is no need in more than one thread - ApplicationManager.getApplication().executeOnPooledThread(() -> { - try { - while(true) { - Runnable runnable = myPendingWriteRequestsQueue.poll(2000, TimeUnit.MILLISECONDS); - if (runnable != null) { - runnable.run(); - } else { - // we have no work for 2s and there is no currently running updates - if(myDoWorkRequest.compareAndSet(1, 0)) { - break; - } - } - } - } - catch (InterruptedException ignore) {} - }); - } - } -} diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index f38c24229ddf..39e25478e40b 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -790,7 +790,6 @@ rubymine.rails.console.use.spring=false ruby.chef.foodcritic.timeout=150 search.everywhere.pattern.checking=true search.everywhere.pattern.checking.description=Avoid searching classes and symbols if pattern contains only one dot -idea.concurrent.scanning.files.to.index=true welcome.screen.project.grouping.enabled=true welcome.screen.project.grouping.enabled.description=Allows to group recent projects