Implement FileBasedIndex.collectScanRootRunnables as a project service

This commit is contained in:
Evgeniy.Stepanov
2017-01-25 10:49:59 +01:00
parent 2297824efc
commit 0e12feb843
5 changed files with 170 additions and 88 deletions
@@ -33,8 +33,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.impl.FileTypeManagerImpl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -73,7 +71,6 @@ import com.intellij.util.*;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.containers.ConcurrentIntObjectMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import com.intellij.util.gist.GistManager;
import com.intellij.util.gist.GistManagerImpl;
import com.intellij.util.indexing.impl.InvertedIndexValueIterator;
@@ -2217,76 +2214,8 @@ public class FileBasedIndexImpl extends FileBasedIndex {
private static List<Runnable> collectScanRootRunnables(@NotNull final ContentIterator processor,
@NotNull final Project project,
final ProgressIndicator indicator) {
if (project.isDisposed()) {
return Collections.emptyList();
}
List<Runnable> tasks = new ArrayList<>();
final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
tasks.add(() -> projectFileIndex.iterateContent(processor));
/*
Module[] modules = ModuleManager.getInstance(project).getModules();
for(final Module module: modules) {
tasks.add(new Runnable() {
@Override
public void run() {
if (module.isDisposed()) return;
ModuleRootManager.getInstance(module).getFileIndex().iterateContent(processor);
}
});
}*/
final Set<VirtualFile> visitedRoots = ContainerUtil.newConcurrentSet();
JBIterable<VirtualFile> contributedRoots = JBIterable.empty();
for (IndexableSetContributor contributor : Extensions.getExtensions(IndexableSetContributor.EP_NAME)) {
//important not to depend on project here, to support per-project background reindex
// each client gives a project to FileBasedIndex
if (project.isDisposed()) {
return tasks;
}
contributedRoots = contributedRoots.append(IndexableSetContributor.getRootsToIndex(contributor));
contributedRoots = contributedRoots.append(IndexableSetContributor.getProjectRootsToIndex(contributor, project));
}
for (AdditionalLibraryRootsProvider provider : Extensions.getExtensions(AdditionalLibraryRootsProvider.EP_NAME)) {
if (project.isDisposed()) {
return tasks;
}
contributedRoots = contributedRoots.append(provider.getAdditionalProjectLibrarySourceRoots(project));
}
for (VirtualFile root : contributedRoots) {
if (visitedRoots.add(root)) {
tasks.add(() -> {
if (project.isDisposed() || !root.isValid()) return;
iterateRecursively(root, processor, indicator, visitedRoots, null);
});
}
}
// iterate associated libraries
for (final Module module : ModuleManager.getInstance(project).getModules()) {
OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries();
for (OrderEntry orderEntry : orderEntries) {
if (orderEntry instanceof LibraryOrSdkOrderEntry) {
if (orderEntry.isValid()) {
final LibraryOrSdkOrderEntry entry = (LibraryOrSdkOrderEntry)orderEntry;
final VirtualFile[] libSources = entry.getRootFiles(OrderRootType.SOURCES);
final VirtualFile[] libClasses = entry.getRootFiles(OrderRootType.CLASSES);
for (VirtualFile[] roots : new VirtualFile[][]{libSources, libClasses}) {
for (final VirtualFile root : roots) {
if (visitedRoots.add(root)) {
tasks.add(() -> {
if (project.isDisposed() || module.isDisposed() || !root.isValid()) return;
iterateRecursively(root, processor, indicator, visitedRoots, projectFileIndex);
});
}
}
}
}
}
}
}
return tasks;
FileBasedIndexScanRunnableCollector collector = FileBasedIndexScanRunnableCollector.getInstance(project);
return collector.collectScanRootRunnables(processor, indicator);
}
private final class DocumentUpdateTask extends UpdateTask<Document> {
@@ -25,13 +25,9 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.*;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
import com.intellij.openapi.roots.impl.ProjectRootManagerComponent;
import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -46,18 +42,15 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.FileBasedIndexProjectHandler");
private final FileBasedIndex myIndex;
private final ProjectRootManagerEx myRootManager;
private final FileTypeManager myFileTypeManager;
private FileBasedIndexScanRunnableCollector myCollector;
public FileBasedIndexProjectHandler(FileBasedIndex index,
Project project,
ProjectRootManagerComponent rootManager,
FileTypeManager ftManager,
FileBasedIndexScanRunnableCollector collector,
ProjectManager projectManager) {
super(project);
myIndex = index;
myRootManager = rootManager;
myFileTypeManager = ftManager;
myCollector = collector;
if (ApplicationManager.getApplication().isInternal()) {
project.getMessageBus().connect().subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
@@ -100,11 +93,7 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
@Override
public boolean isInSet(@NotNull final VirtualFile file) {
final ProjectFileIndex index = myRootManager.getFileIndex();
if (index.isInContent(file) || index.isInLibraryClasses(file) || index.isInLibrarySource(file)) {
return !myFileTypeManager.isFileIgnored(file);
}
return false;
return myCollector.shouldCollect(file);
}
@Override
@@ -0,0 +1,35 @@
/*
* Copyright 2000-2016 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.components.ServiceManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public abstract class FileBasedIndexScanRunnableCollector {
public static FileBasedIndexScanRunnableCollector getInstance(@NotNull Project project) {
return ServiceManager.getService(project, FileBasedIndexScanRunnableCollector.class);
}
public abstract Boolean shouldCollect(@NotNull final VirtualFile file);
public abstract List<Runnable> collectScanRootRunnables(@NotNull final ContentIterator processor, final ProgressIndicator indicator);
}
@@ -0,0 +1,126 @@
/*
* Copyright 2000-2016 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.extensions.Extensions;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class FileBasedIndexScanRunnableCollectorImpl extends FileBasedIndexScanRunnableCollector {
private final Project myProject;
private final ProjectFileIndex myProjectFileIndex;
private final FileTypeManager myFileTypeManager;
public FileBasedIndexScanRunnableCollectorImpl(@NotNull Project project) {
this.myProject = project;
this.myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
this.myFileTypeManager = FileTypeManager.getInstance();
}
@Override
public Boolean shouldCollect(@NotNull VirtualFile file) {
if (myProjectFileIndex.isInContent(file) || myProjectFileIndex.isInLibraryClasses(file) || myProjectFileIndex.isInLibrarySource(file)) {
return !myFileTypeManager.isFileIgnored(file);
}
return false;
}
@Override
public List<Runnable> collectScanRootRunnables(@NotNull ContentIterator processor, ProgressIndicator indicator) {
if (myProject.isDisposed()) {
return Collections.emptyList();
}
List<Runnable> tasks = new ArrayList<>();
tasks.add(() -> myProjectFileIndex.iterateContent(processor));
/*
Module[] modules = ModuleManager.getInstance(project).getModules();
for(final Module module: modules) {
tasks.add(new Runnable() {
@Override
public void run() {
if (module.isDisposed()) return;
ModuleRootManager.getInstance(module).getFileIndex().iterateContent(processor);
}
});
}*/
final Set<VirtualFile> visitedRoots = ContainerUtil.newConcurrentSet();
JBIterable<VirtualFile> contributedRoots = JBIterable.empty();
for (IndexableSetContributor contributor : Extensions.getExtensions(IndexableSetContributor.EP_NAME)) {
//important not to depend on project here, to support per-project background reindex
// each client gives a project to FileBasedIndex
if (myProject.isDisposed()) {
return tasks;
}
contributedRoots = contributedRoots.append(IndexableSetContributor.getRootsToIndex(contributor));
contributedRoots = contributedRoots.append(IndexableSetContributor.getProjectRootsToIndex(contributor, myProject));
}
for (AdditionalLibraryRootsProvider provider : Extensions.getExtensions(AdditionalLibraryRootsProvider.EP_NAME)) {
if (myProject.isDisposed()) {
return tasks;
}
contributedRoots = contributedRoots.append(provider.getAdditionalProjectLibrarySourceRoots(myProject));
}
for (VirtualFile root : contributedRoots) {
if (visitedRoots.add(root)) {
tasks.add(() -> {
if (myProject.isDisposed() || !root.isValid()) return;
FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, null);
});
}
}
// iterate associated libraries
for (final Module module : ModuleManager.getInstance(myProject).getModules()) {
OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries();
for (OrderEntry orderEntry : orderEntries) {
if (orderEntry instanceof LibraryOrSdkOrderEntry) {
if (orderEntry.isValid()) {
final LibraryOrSdkOrderEntry entry = (LibraryOrSdkOrderEntry)orderEntry;
final VirtualFile[] libSources = entry.getRootFiles(OrderRootType.SOURCES);
final VirtualFile[] libClasses = entry.getRootFiles(OrderRootType.CLASSES);
for (VirtualFile[] roots : new VirtualFile[][]{libSources, libClasses}) {
for (final VirtualFile root : roots) {
if (visitedRoots.add(root)) {
tasks.add(() -> {
if (myProject.isDisposed() || module.isDisposed() || !root.isValid()) return;
FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, myProjectFileIndex);
});
}
}
}
}
}
}
}
return tasks;
}
}
@@ -78,6 +78,9 @@
<projectService serviceInterface="com.intellij.openapi.roots.impl.DirectoryIndex"
serviceImplementation="com.intellij.openapi.roots.impl.DirectoryIndexImpl"/>
<projectService serviceInterface="com.intellij.util.indexing.FileBasedIndexScanRunnableCollector"
serviceImplementation="com.intellij.util.indexing.FileBasedIndexScanRunnableCollectorImpl"/>
<projectService serviceInterface="com.intellij.pom.references.PomService"
serviceImplementation="com.intellij.pom.references.PomServiceImpl"/>