[FUS] revert Directory Index collector due to unexpected issues

GitOrigin-RevId: e6b58244f4d07849241eb968c896ef385a23a65d
This commit is contained in:
Anton Makeev
2022-07-01 10:57:21 +00:00
committed by intellij-monorepo-bot
parent e1d9d71dea
commit 326ca85654
8 changed files with 41 additions and 248 deletions
@@ -28,7 +28,7 @@ public class AdditionalLibraryRootsListenerHelperImpl implements AdditionalLibra
@NotNull String libraryNameForDebug) {
DirectoryIndex directoryIndex = DirectoryIndex.getInstance(project);
if (directoryIndex instanceof DirectoryIndexImpl) {
((DirectoryIndexImpl)directoryIndex).reset(DirectoryIndexAnalyticsReporter.ResetReason.ADDITIONAL_LIBRARIES_PROVIDER);
((DirectoryIndexImpl)directoryIndex).reset();
}
additionalLibraryRootsChanged(project, presentableLibraryName, oldRoots, newRoots, libraryNameForDebug);
}
@@ -172,7 +172,7 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
try {
DirectoryIndex directoryIndex = DirectoryIndex.getInstance(myProject);
if (directoryIndex instanceof DirectoryIndexImpl) {
((DirectoryIndexImpl)directoryIndex).reset(DirectoryIndexAnalyticsReporter.ResetReason.ROOT_MODEL);
((DirectoryIndexImpl)directoryIndex).reset();
}
myProject.getMessageBus().syncPublisher(ProjectTopics.PROJECT_ROOTS).beforeRootsChange(new ModuleRootEventImpl(myProject, fileTypes));
}
@@ -187,7 +187,7 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen
try {
DirectoryIndex directoryIndex = DirectoryIndex.getInstance(myProject);
if (directoryIndex instanceof DirectoryIndexImpl) {
((DirectoryIndexImpl)directoryIndex).reset(DirectoryIndexAnalyticsReporter.ResetReason.ROOT_MODEL);
((DirectoryIndexImpl)directoryIndex).reset();
}
ThreeState isFromWorkspaceOnly = ThreeState.UNSURE;
for (RootsChangeRescanningInfo info : indexingInfos) {
@@ -1,108 +0,0 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.roots.impl
import com.intellij.internal.statistic.StructuredIdeActivity
import com.intellij.internal.statistic.eventLog.EventLogGroup
import com.intellij.internal.statistic.eventLog.events.EventFields
import com.intellij.internal.statistic.eventLog.events.VarargEventId
import com.intellij.internal.statistic.service.fus.collectors.CounterUsagesCollector
import com.intellij.openapi.project.Project
class DirectoryIndexCollector : CounterUsagesCollector() {
companion object {
val GROUP = EventLogGroup("directoryIndex", 2)
@JvmField
val RESET_REASON = EventFields.Enum("reason", DirectoryIndexAnalyticsReporter.ResetReason::class.java)
@JvmField
val RESET = GROUP.registerEvent("reset", RESET_REASON)
@JvmField
val BUILD_REQUEST = EventFields.Enum("buildRequest", DirectoryIndexAnalyticsReporter.BuildRequestKind::class.java)
@JvmField
val BUILD_PART = EventFields.Enum("part", DirectoryIndexAnalyticsReporter.BuildPart::class.java)
@JvmField
val BUILDING_ACTIVITY = GROUP.registerIdeActivity("building", startEventAdditionalFields = arrayOf(BUILD_REQUEST, BUILD_PART))
@JvmField
val DURATION_MS_FIELD = EventFields.Long("duration_ms")
@JvmField
val WORKSPACE_MODEL_STAGE_FINISHED = BUILDING_ACTIVITY.registerStage("workspaceModel.finished", arrayOf(DURATION_MS_FIELD))
@JvmField
val SDK_STAGE_FINISHED = BUILDING_ACTIVITY.registerStage("sdk.finished", arrayOf(DURATION_MS_FIELD))
@JvmField
val ADDITIONAL_LIBRARIES_STAGE_FINISHED = BUILDING_ACTIVITY.registerStage("additionalLibraryRootsProvider.finished",
arrayOf(DURATION_MS_FIELD))
@JvmField
val EXCLUSION_POLICY_STAGE_FINISHED = BUILDING_ACTIVITY.registerStage("exclusionPolicy.finished", arrayOf(DURATION_MS_FIELD))
@JvmField
val FINALIZING_STAGE_FINISHED = BUILDING_ACTIVITY.registerStage("finalizing.finished", arrayOf(DURATION_MS_FIELD))
}
override fun getGroup(): EventLogGroup {
return GROUP
}
}
class DirectoryIndexAnalyticsReporterImpl(private val project: Project) : DirectoryIndexAnalyticsReporter {
override fun reportResetImpl(reason: DirectoryIndexAnalyticsReporter.ResetReason) {
DirectoryIndexCollector.RESET.log(reason)
}
override fun reportStartedImpl(requestKind: DirectoryIndexAnalyticsReporter.BuildRequestKind,
buildPart: DirectoryIndexAnalyticsReporter.BuildPart): DirectoryIndexAnalyticsReporter.ActivityReporter {
val impl = DirectoryIndexCollector.BUILDING_ACTIVITY.started(project) {
listOf(DirectoryIndexCollector.BUILD_REQUEST.with(requestKind),
DirectoryIndexCollector.BUILD_PART.with(buildPart))
}
return ActivityReporter(impl)
}
private class ActivityReporter(private val impl: StructuredIdeActivity) : DirectoryIndexAnalyticsReporter.ActivityReporter {
override fun reportWorkspacePhaseStarted(): DirectoryIndexAnalyticsReporter.PhaseReporter {
return PhaseReporter(impl, DirectoryIndexCollector.WORKSPACE_MODEL_STAGE_FINISHED)
}
override fun reportSdkPhaseStarted(): DirectoryIndexAnalyticsReporter.PhaseReporter {
return PhaseReporter(impl, DirectoryIndexCollector.SDK_STAGE_FINISHED)
}
override fun reportAdditionalLibrariesPhaseStarted(): DirectoryIndexAnalyticsReporter.PhaseReporter {
return PhaseReporter(impl, DirectoryIndexCollector.ADDITIONAL_LIBRARIES_STAGE_FINISHED)
}
override fun reportExclusionPolicyPhaseStarted(): DirectoryIndexAnalyticsReporter.PhaseReporter {
return PhaseReporter(impl, DirectoryIndexCollector.EXCLUSION_POLICY_STAGE_FINISHED)
}
override fun reportFinalizingPhaseStarted(): DirectoryIndexAnalyticsReporter.PhaseReporter {
return PhaseReporter(impl, DirectoryIndexCollector.FINALIZING_STAGE_FINISHED)
}
override fun reportFinished() {
impl.finished()
}
private class PhaseReporter(private val impl: StructuredIdeActivity,
private val event: VarargEventId) : DirectoryIndexAnalyticsReporter.PhaseReporter {
private val started = System.currentTimeMillis()
override fun reportPhaseFinished() {
impl.stageStarted(event) {
listOf(DirectoryIndexCollector.DURATION_MS_FIELD.with(System.currentTimeMillis() - started))
}
}
}
}
}
@@ -398,8 +398,6 @@
<applicationService serviceInterface="com.intellij.openapi.roots.ui.SdkAppearanceService"
serviceImplementation="com.intellij.openapi.roots.ui.SdkAppearanceServiceImpl"/>
<statistics.counterUsagesCollector implementationClass="com.intellij.openapi.roots.impl.DirectoryIndexCollector"/>
<directoryIndexAnalyticsReporter implementation="com.intellij.openapi.roots.impl.DirectoryIndexAnalyticsReporterImpl"/>
<statistics.projectUsagesCollector implementation="com.intellij.openapi.roots.impl.BundledResourceUsageCollector"/>
<statistics.validation.customValidationRule implementation="com.intellij.openapi.roots.impl.BundledResourcePathValidationRule"/>
@@ -10,8 +10,6 @@
dynamic="true"/>
<extensionPoint name="projectPathMacroContributor" interface="com.intellij.openapi.components.impl.ProjectWidePathMacroContributor"
dynamic="true"/>
<extensionPoint name="directoryIndexAnalyticsReporter" interface="com.intellij.openapi.roots.impl.DirectoryIndexAnalyticsReporter"
area="IDEA_PROJECT" dynamic="true"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<projectService serviceInterface="com.intellij.openapi.roots.impl.DirectoryIndex"
@@ -1,57 +0,0 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.roots.impl
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
interface DirectoryIndexAnalyticsReporter {
enum class ResetReason { ROOT_MODEL, VFS_CHANGE, ADDITIONAL_LIBRARIES_PROVIDER }
enum class BuildRequestKind { INITIAL, BRANCH_BUILD, FULL_REBUILD, INCREMENTAL_UPDATE }
enum class BuildPart { MAIN, ORDER_ENTRY_GRAPH }
interface ActivityReporter {
fun reportWorkspacePhaseStarted(): PhaseReporter
fun reportSdkPhaseStarted(): PhaseReporter
fun reportAdditionalLibrariesPhaseStarted(): PhaseReporter
fun reportExclusionPolicyPhaseStarted(): PhaseReporter
fun reportFinalizingPhaseStarted(): PhaseReporter
fun reportFinished()
}
interface PhaseReporter {
fun reportPhaseFinished()
}
fun reportResetImpl(reason: ResetReason)
fun reportStartedImpl(requestKind: BuildRequestKind, buildPart: BuildPart): ActivityReporter
companion object {
val EP_NAME = ExtensionPointName.create<DirectoryIndexAnalyticsReporter>("com.intellij.directoryIndexAnalyticsReporter")
@JvmStatic
fun reportReset(project: Project, reason: ResetReason) {
EP_NAME.getExtensions(project).firstOrNull()?.reportResetImpl(reason)
}
@JvmStatic
fun reportStarted(project: Project, requestKind: BuildRequestKind, buildPart: BuildPart): ActivityReporter {
return EP_NAME.getExtensions(project).firstOrNull()?.reportStartedImpl(requestKind, buildPart)
?: object : ActivityReporter {
val phaseReporter = object : PhaseReporter {
override fun reportPhaseFinished() {}
}
override fun reportWorkspacePhaseStarted(): PhaseReporter = phaseReporter
override fun reportSdkPhaseStarted(): PhaseReporter = phaseReporter
override fun reportAdditionalLibrariesPhaseStarted(): PhaseReporter = phaseReporter
override fun reportExclusionPolicyPhaseStarted(): PhaseReporter = phaseReporter
override fun reportFinalizingPhaseStarted(): PhaseReporter = phaseReporter
override fun reportFinished() {}
}
}
}
}
@@ -78,7 +78,7 @@ public final class DirectoryIndexImpl extends DirectoryIndex implements Disposab
rootIndex.myPackageDirectoryCache.clear();
for (VFileEvent event : events) {
if (isIgnoredFileCreated(event)) {
reset(DirectoryIndexAnalyticsReporter.ResetReason.VFS_CHANGE);
reset();
break;
}
}
@@ -150,8 +150,8 @@ public final class DirectoryIndexImpl extends DirectoryIndex implements Disposab
Pair<Long, RootIndex> pair = branch.getUserData(BRANCH_ROOT_INDEX);
long modCount = branch.getBranchedVfsStructureModificationCount();
if (pair == null || pair.first != modCount) {
pair = Pair.create(modCount, new RootIndex(branch.getProject(), RootFileSupplier.forBranch(branch),
DirectoryIndexAnalyticsReporter.BuildRequestKind.BRANCH_BUILD));
pair = Pair.create(modCount, new RootIndex(branch.getProject(), RootFileSupplier.forBranch(branch)
));
}
return pair.second;
}
@@ -159,8 +159,7 @@ public final class DirectoryIndexImpl extends DirectoryIndex implements Disposab
RootIndex getRootIndex() {
RootIndex rootIndex = myRootIndex;
if (rootIndex == null) {
myRootIndex = rootIndex = new RootIndex(myProject, myInInitialState ? DirectoryIndexAnalyticsReporter.BuildRequestKind.INITIAL
: DirectoryIndexAnalyticsReporter.BuildRequestKind.FULL_REBUILD);
myRootIndex = rootIndex = new RootIndex(myProject);
myInInitialState = false;
}
return rootIndex;
@@ -230,12 +229,7 @@ public final class DirectoryIndexImpl extends DirectoryIndex implements Disposab
}
}
void reset(DirectoryIndexAnalyticsReporter.ResetReason reason) {
boolean report = myRootIndex != null;
void reset() {
myRootIndex = null;
if (report) {
DirectoryIndexAnalyticsReporter.reportReset(myProject, reason);
}
}
}
@@ -51,18 +51,15 @@ class RootIndex {
private final RootFileSupplier myRootSupplier;
final PackageDirectoryCache myPackageDirectoryCache;
private OrderEntryGraph myOrderEntryGraph;
private final DirectoryIndexAnalyticsReporter.BuildRequestKind myBuildRequestKind;
RootIndex(@NotNull Project project, DirectoryIndexAnalyticsReporter.BuildRequestKind buildRequestKind) {
this(project, RootFileSupplier.INSTANCE, buildRequestKind);
RootIndex(@NotNull Project project) {
this(project, RootFileSupplier.INSTANCE);
}
RootIndex(@NotNull Project project,
@NotNull RootFileSupplier rootSupplier,
DirectoryIndexAnalyticsReporter.BuildRequestKind buildRequestKind) {
@NotNull RootFileSupplier rootSupplier) {
myProject = project;
myRootSupplier = rootSupplier;
myBuildRequestKind = buildRequestKind;
ApplicationManager.getApplication().assertReadAccessAllowed();
if (project.isDefault()) {
@@ -73,46 +70,34 @@ class RootIndex {
LOG.assertTrue(((ModuleManagerEx)manager).areModulesLoaded(), "Directory index can only be queried after project initialization");
}
DirectoryIndexAnalyticsReporter.ActivityReporter activityReporter = logActivityStarted(DirectoryIndexAnalyticsReporter.BuildPart.MAIN);
try {
final RootInfo info = buildRootInfo(project, activityReporter);
final RootInfo info = buildRootInfo(project);
DirectoryIndexAnalyticsReporter.PhaseReporter phase = activityReporter.reportFinalizingPhaseStarted();
Set<VirtualFile> allRoots = info.getAllRoots();
MultiMap<String, VirtualFile> rootsByPackagePrefix = MultiMap.create(allRoots.size(), 0.75f);
myRootInfos = new HashMap<>(allRoots.size());
myHasNonDirectoryRoots = ContainerUtil.exists(allRoots, r -> !r.isDirectory());
myPackagePrefixByRoot = new HashMap<>(allRoots.size());
List<List<VirtualFile>> hierarchies = new ArrayList<>(allRoots.size());
for (VirtualFile root : allRoots) {
List<VirtualFile> hierarchy = getHierarchy(root, allRoots, info);
hierarchies.add(hierarchy);
Pair<DirectoryInfo, String> pair = hierarchy != null
? calcDirectoryInfoAndPackagePrefix(root, hierarchy, info)
: new Pair<>(NonProjectDirectoryInfo.IGNORED, null);
myRootInfos.put(root, pair.first);
String packagePrefix = pair.second;
rootsByPackagePrefix.putValue(packagePrefix, root);
myPackagePrefixByRoot.put(root, packagePrefix);
Set<VirtualFile> allRoots = info.getAllRoots();
MultiMap<String, VirtualFile> rootsByPackagePrefix = MultiMap.create(allRoots.size(), 0.75f);
myRootInfos = new HashMap<>(allRoots.size());
myHasNonDirectoryRoots = ContainerUtil.exists(allRoots, r -> !r.isDirectory());
myPackagePrefixByRoot = new HashMap<>(allRoots.size());
List<List<VirtualFile>> hierarchies = new ArrayList<>(allRoots.size());
for (VirtualFile root : allRoots) {
List<VirtualFile> hierarchy = getHierarchy(root, allRoots, info);
hierarchies.add(hierarchy);
Pair<DirectoryInfo, String> pair = hierarchy != null
? calcDirectoryInfoAndPackagePrefix(root, hierarchy, info)
: new Pair<>(NonProjectDirectoryInfo.IGNORED, null);
myRootInfos.put(root, pair.first);
String packagePrefix = pair.second;
rootsByPackagePrefix.putValue(packagePrefix, root);
myPackagePrefixByRoot.put(root, packagePrefix);
}
storeContentsBeneathExcluded(allRoots, hierarchies);
storeOutsideProjectRootsButHasContentInside();
myPackageDirectoryCache = new PackageDirectoryCache(rootsByPackagePrefix) {
@Override
protected boolean isPackageDirectory(@NotNull VirtualFile dir, @NotNull String packageName) {
return getInfoForFile(dir).isInProject(dir) && packageName.equals(getPackageName(dir));
}
storeContentsBeneathExcluded(allRoots, hierarchies);
storeOutsideProjectRootsButHasContentInside();
myPackageDirectoryCache = new PackageDirectoryCache(rootsByPackagePrefix) {
@Override
protected boolean isPackageDirectory(@NotNull VirtualFile dir, @NotNull String packageName) {
return getInfoForFile(dir).isInProject(dir) && packageName.equals(getPackageName(dir));
}
};
phase.reportPhaseFinished();
}
finally {
activityReporter.reportFinished();
}
}
private DirectoryIndexAnalyticsReporter.ActivityReporter logActivityStarted(DirectoryIndexAnalyticsReporter.BuildPart part) {
return DirectoryIndexAnalyticsReporter.reportStarted(myProject, myBuildRequestKind, part);
};
}
private void storeOutsideProjectRootsButHasContentInside() {
@@ -190,12 +175,11 @@ class RootIndex {
}
@NotNull
private RootInfo buildRootInfo(@NotNull Project project, DirectoryIndexAnalyticsReporter.ActivityReporter activity) {
private RootInfo buildRootInfo(@NotNull Project project) {
final RootInfo info = new RootInfo();
ModuleManager moduleManager = ModuleManager.getInstance(project);
boolean includeProjectJdk = true;
DirectoryIndexAnalyticsReporter.PhaseReporter phase = activity.reportWorkspacePhaseStarted();
for (final Module module : moduleManager.getModules()) {
final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
@@ -266,19 +250,15 @@ class RootIndex {
}
}
}
phase.reportPhaseFinished();
if (includeProjectJdk) {
phase = activity.reportSdkPhaseStarted();
Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk();
if (sdk != null) {
fillIndexWithLibraryRoots(info, sdk, myRootSupplier.getSdkRoots(sdk, OrderRootType.SOURCES),
myRootSupplier.getSdkRoots(sdk, OrderRootType.CLASSES));
}
phase.reportPhaseFinished();
}
phase = activity.reportAdditionalLibrariesPhaseStarted();
for (AdditionalLibraryRootsProvider provider : AdditionalLibraryRootsProvider.EP_NAME.getExtensionList()) {
Collection<SyntheticLibrary> libraries = provider.getAdditionalProjectLibraries(project);
for (SyntheticLibrary library : libraries) {
@@ -312,9 +292,7 @@ class RootIndex {
}
}
}
phase.reportPhaseFinished();
phase = activity.reportExclusionPolicyPhaseStarted();
for (DirectoryIndexExcludePolicy policy : DirectoryIndexExcludePolicy.EP_NAME.getExtensions(project)) {
List<VirtualFile> files = ContainerUtil.mapNotNull(policy.getExcludeUrlsForProject(), myRootSupplier::findFileByUrl);
info.excludedFromProject.addAll(ContainerUtil.filter(files, file -> RootFileSupplier.ensureValid(file, project, policy)));
@@ -353,7 +331,6 @@ class RootIndex {
}
}
}
phase.reportPhaseFinished();
return info;
}
@@ -385,18 +362,9 @@ class RootIndex {
@NotNull
private synchronized OrderEntryGraph getOrderEntryGraph() {
if (myOrderEntryGraph == null) {
DirectoryIndexAnalyticsReporter.ActivityReporter activityReporter =
logActivityStarted(DirectoryIndexAnalyticsReporter.BuildPart.ORDER_ENTRY_GRAPH);
try {
RootInfo rootInfo = buildRootInfo(myProject, activityReporter);
DirectoryIndexAnalyticsReporter.PhaseReporter phase = activityReporter.reportFinalizingPhaseStarted();
Couple<MultiMap<VirtualFile, OrderEntry>> pair = initLibraryClassSourceRoots();
myOrderEntryGraph = new OrderEntryGraph(myProject, rootInfo, pair.first, pair.second);
phase.reportPhaseFinished();
}
finally {
activityReporter.reportFinished();
}
RootInfo rootInfo = buildRootInfo(myProject);
Couple<MultiMap<VirtualFile, OrderEntry>> pair = initLibraryClassSourceRoots();
myOrderEntryGraph = new OrderEntryGraph(myProject, rootInfo, pair.first, pair.second);
}
return myOrderEntryGraph;
}