move caching from FacetIndex to ProjectFacetManager (IDEA-CR-21856)

This commit is contained in:
peter
2017-06-14 16:39:11 +02:00
parent 0f9222c345
commit fddb3a20fe
2 changed files with 45 additions and 98 deletions
@@ -1,61 +0,0 @@
/*
* Copyright 2000-2017 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.facet;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootModificationTracker;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows to find modules with facets of specified types in amortized O(1) time, without iterating over all modules.
*
* @see FacetManager
* @since 173.*
*/
public class FacetIndex {
private final MultiMap<FacetTypeId<?>, Module> myMap = MultiMap.createLinked();
private FacetIndex(Project project) {
for (Module module : ModuleManager.getInstance(project).getModules()) {
for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
myMap.putValue(facet.getTypeId(), module);
}
}
}
public boolean hasAnyModuleWithFacet(@NotNull FacetTypeId<?> type) {
return myMap.containsKey(type);
}
@Nullable
public Module findModuleWithFacet(@NotNull FacetTypeId<?> type) {
return ContainerUtil.getFirstItem(myMap.get(type));
}
@NotNull
public static FacetIndex getIndex(@NotNull Project project) {
return CachedValuesManager.getManager(project).getCachedValue(project, () -> CachedValueProvider.Result.create(
new FacetIndex(project),
ProjectRootModificationTracker.getInstance(project)));
}
}
@@ -16,31 +16,26 @@
package com.intellij.facet.impl;
import com.intellij.ProjectTopics;
import com.intellij.facet.*;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.ModuleListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.ParameterizedCachedValue;
import com.intellij.psi.util.ParameterizedCachedValueProvider;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.xmlb.annotations.MapAnnotation;
import com.intellij.util.xmlb.annotations.Tag;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.*;
/**
* @author nik
@@ -51,25 +46,33 @@ public class ProjectFacetManagerImpl extends ProjectFacetManagerEx implements Pe
private static final Logger LOG = Logger.getInstance("#com.intellij.facet.impl.ProjectFacetManagerImpl");
private ProjectFacetManagerState myState = new ProjectFacetManagerState();
private final Project myProject;
private final ConcurrentMap<FacetTypeId<?>, ParameterizedCachedValue<Boolean, FacetTypeId<?>>> myCachedHasFacets =
ContainerUtil.newConcurrentMap();
private final ParameterizedCachedValueProvider<Boolean,FacetTypeId<?>> myCachedValueProvider;
private volatile MultiMap<FacetTypeId<?>, Module> myIndex;
public ProjectFacetManagerImpl(Project project) {
myProject = project;
myCachedValueProvider = new ParameterizedCachedValueProvider<Boolean, FacetTypeId<?>>() {
ProjectWideFacetListenersRegistry.getInstance(project).registerListener(new ProjectWideFacetAdapter<Facet>() {
@Override
public CachedValueProvider.Result<Boolean> compute(FacetTypeId<?> param) {
boolean result = false;
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
if (!FacetManager.getInstance(module).getFacetsByType(param).isEmpty()) {
result = true;
break;
}
}
return CachedValueProvider.Result.create(result, FacetFinder.getInstance(myProject).getAllFacetsOfTypeModificationTracker(param));
public void facetAdded(Facet facet) {
myIndex = null;
}
};
@Override
public void facetRemoved(Facet facet) {
myIndex = null;
}
}, project);
project.getMessageBus().connect(project).subscribe(ProjectTopics.MODULES, new ModuleListener() {
@Override
public void moduleAdded(@NotNull Project project, @NotNull Module module) {
myIndex = null;
}
@Override
public void moduleRemoved(@NotNull Project project, @NotNull Module module) {
myIndex = null;
}
});
}
@Override
@@ -82,32 +85,37 @@ public class ProjectFacetManagerImpl extends ProjectFacetManagerEx implements Pe
myState = state;
}
@NotNull
private MultiMap<FacetTypeId<?>, Module> getIndex() {
MultiMap<FacetTypeId<?>, Module> index = myIndex;
if (index == null) {
index = MultiMap.createLinked();
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
index.putValue(facet.getTypeId(), module);
}
}
myIndex = index;
}
return index;
}
@NotNull
@Override
public <F extends Facet> List<F> getFacets(@NotNull FacetTypeId<F> typeId) {
return getFacets(typeId, ModuleManager.getInstance(myProject).getModules());
return ContainerUtil.concat(getIndex().get(typeId), module -> FacetManager.getInstance(module).getFacetsByType(typeId));
}
@NotNull
@Override
public List<Module> getModulesWithFacet(@NotNull FacetTypeId<?> typeId) {
List<Module> result = new ArrayList<>();
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
if (!FacetManager.getInstance(module).getFacetsByType(typeId).isEmpty()) {
result.add(module);
}
}
return result;
//noinspection unchecked
return Collections.unmodifiableList((List)getIndex().get(typeId));
}
@Override
public boolean hasFacets(@NotNull FacetTypeId<?> typeId) {
ParameterizedCachedValue<Boolean, FacetTypeId<?>> value = myCachedHasFacets.get(typeId);
if (value == null) {
value = CachedValuesManager.getManager(myProject).createParameterizedCachedValue(myCachedValueProvider, false);
myCachedHasFacets.put(typeId, value);
}
return value.getValue(typeId);
return getIndex().containsKey(typeId);
}
@Override