memory: remember there is no Double instance cache, so each boxed double is a new shiny Double

This commit is contained in:
Alexey Kudravtsev
2012-09-25 14:46:22 +04:00
parent 4eb6a41909
commit 7f33796083
7 changed files with 134 additions and 115 deletions
@@ -87,7 +87,7 @@ public class ImageFileEditorState implements TransferableFileEditorState, Serial
o = options.get(ZOOM_FACTOR_OPTION);
if (o != null) {
zoomFactor = Double.valueOf(o);
zoomFactor = Double.parseDouble(o);
}
}
}
@@ -17,7 +17,6 @@
package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Trinity;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceProvider;
@@ -33,32 +32,37 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author maxim
*/
public abstract class NamedObjectProviderBinding<Provider> implements ProviderBinding<Provider> {
private final ConcurrentMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>> myNamesToProvidersMap = new ConcurrentHashMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>>(5);
private final ConcurrentMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>> myNamesToProvidersMapInsensitive = new ConcurrentHashMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>>(5);
private final ConcurrentMap<String, List<ProviderInfo<Provider, ElementPattern>>> myNamesToProvidersMap = new ConcurrentHashMap<String, List<ProviderInfo<Provider,ElementPattern>>>(5);
private final ConcurrentMap<String, List<ProviderInfo<Provider, ElementPattern>>> myNamesToProvidersMapInsensitive = new ConcurrentHashMap<String, List<ProviderInfo<Provider, ElementPattern>>>(5);
public void registerProvider(@NonNls String[] names, ElementPattern filter, boolean caseSensitive, Provider provider, final double priority) {
final ConcurrentMap<String, CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>>> map = caseSensitive ? myNamesToProvidersMap : myNamesToProvidersMapInsensitive;
public void registerProvider(@NonNls @NotNull String[] names,
@NotNull ElementPattern filter,
boolean caseSensitive,
@NotNull Provider provider,
final double priority) {
final ConcurrentMap<String, List<ProviderInfo<Provider, ElementPattern>>> map = caseSensitive ? myNamesToProvidersMap : myNamesToProvidersMapInsensitive;
for (final String attributeName : names) {
CopyOnWriteArrayList<Trinity<Provider, ElementPattern,Double>> psiReferenceProviders = map.get(attributeName);
List<ProviderInfo<Provider, ElementPattern>> psiReferenceProviders = map.get(attributeName);
if (psiReferenceProviders == null) {
psiReferenceProviders = ConcurrencyUtil.cacheOrGet(map, caseSensitive ? attributeName : attributeName.toLowerCase(), ContainerUtil.<Trinity<Provider, ElementPattern, Double>>createEmptyCOWList());
String key = caseSensitive ? attributeName : attributeName.toLowerCase();
psiReferenceProviders = ConcurrencyUtil.cacheOrGet(map, key, ContainerUtil.<ProviderInfo<Provider,ElementPattern>>createEmptyCOWList());
}
psiReferenceProviders.add(new Trinity<Provider, ElementPattern,Double>(provider, filter, priority));
psiReferenceProviders.add(new ProviderInfo<Provider,ElementPattern>(provider, filter, priority));
}
}
@Override
public void addAcceptableReferenceProviders(@NotNull PsiElement position, @NotNull List list,
PsiReferenceService.Hints hints) {
public void addAcceptableReferenceProviders(@NotNull PsiElement position,
@NotNull List<ProviderInfo<Provider, ProcessingContext>> list,
@NotNull PsiReferenceService.Hints hints) {
String name = getName(position);
if (name != null) {
addMatchingProviders(position, myNamesToProvidersMap.get(name), list, hints);
@@ -67,17 +71,17 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
}
@Override
public void unregisterProvider(final Provider provider) {
for (final CopyOnWriteArrayList<Trinity<Provider, ElementPattern, Double>> list : myNamesToProvidersMap.values()) {
for (final Trinity<Provider, ElementPattern, Double> trinity : new ArrayList<Trinity<Provider, ElementPattern, Double>>(list)) {
if (trinity.first.equals(provider)) {
public void unregisterProvider(@NotNull final Provider provider) {
for (final List<ProviderInfo<Provider, ElementPattern>> list : myNamesToProvidersMap.values()) {
for (final ProviderInfo<Provider, ElementPattern> trinity : new ArrayList<ProviderInfo<Provider,ElementPattern>>(list)) {
if (trinity.provider.equals(provider)) {
list.remove(trinity);
}
}
}
for (final CopyOnWriteArrayList<Trinity<Provider, ElementPattern, Double>> list : myNamesToProvidersMapInsensitive.values()) {
for (final Trinity<Provider, ElementPattern, Double> trinity : new ArrayList<Trinity<Provider, ElementPattern, Double>>(list)) {
if (trinity.first.equals(provider)) {
for (final List<ProviderInfo<Provider, ElementPattern>> list : myNamesToProvidersMapInsensitive.values()) {
for (final ProviderInfo<Provider, ElementPattern> trinity : new ArrayList<ProviderInfo<Provider,ElementPattern>>(list)) {
if (trinity.provider.equals(provider)) {
list.remove(trinity);
}
}
@@ -85,15 +89,16 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
}
@Nullable
abstract protected String getName(final PsiElement position);
protected abstract String getName(final PsiElement position);
private static <T> void addMatchingProviders(final PsiElement position, @Nullable final List<Trinity<T, ElementPattern, Double>> providerList,
final List<Trinity<T, ProcessingContext, Double>> ret,
PsiReferenceService.Hints hints) {
private void addMatchingProviders(final PsiElement position,
@Nullable final List<ProviderInfo<Provider, ElementPattern>> providerList,
@NotNull List<ProviderInfo<Provider, ProcessingContext>> ret,
PsiReferenceService.Hints hints) {
if (providerList == null) return;
for(Trinity<T,ElementPattern,Double> trinity:providerList) {
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.first).acceptsHints(position, hints)) {
for(ProviderInfo<Provider, ElementPattern> trinity:providerList) {
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.provider).acceptsHints(position, hints)) {
continue;
}
@@ -103,12 +108,12 @@ public abstract class NamedObjectProviderBinding<Provider> implements ProviderBi
}
boolean suitable = false;
try {
suitable = trinity.second.accepts(position, context);
suitable = trinity.processingContext.accepts(position, context);
}
catch (IndexNotReadyException ignored) {
}
if (suitable) {
ret.add(Trinity.create(trinity.first, context, trinity.third));
ret.add(new ProviderInfo<Provider,ProcessingContext>(trinity.provider, context, trinity.priority));
}
}
}
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceService;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -30,8 +31,20 @@ import java.util.List;
* To change this template use Options | File Templates.
*/
public interface ProviderBinding<T> {
void addAcceptableReferenceProviders(@NotNull PsiElement position, @NotNull List list,
PsiReferenceService.Hints hints);
class ProviderInfo<T, Context> {
public final T provider;
public final Context processingContext;
public final double priority;
void unregisterProvider(final T provider);
public ProviderInfo(@NotNull T provider, @NotNull Context processingContext, double priority) {
this.provider = provider;
this.processingContext = processingContext;
this.priority = priority;
}
}
void addAcceptableReferenceProviders(@NotNull PsiElement position,
@NotNull List<ProviderInfo<T, ProcessingContext>> list,
@NotNull PsiReferenceService.Hints hints);
void unregisterProvider(@NotNull T provider);
}
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.openapi.util.Trinity;
import com.intellij.patterns.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceProvider;
@@ -40,9 +39,8 @@ import java.util.concurrent.ConcurrentMap;
* @author Dmitry Avdeev
*/
public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
private final ConcurrentMap<Class, SimpleProviderBinding> myBindingsMap = new ConcurrentHashMap<Class, SimpleProviderBinding>();
private final ConcurrentMap<Class, NamedObjectProviderBinding> myNamedBindingsMap = new ConcurrentHashMap<Class, NamedObjectProviderBinding>();
private final ConcurrentMap<Class, SimpleProviderBinding<PsiReferenceProvider>> myBindingsMap = new ConcurrentHashMap<Class, SimpleProviderBinding<PsiReferenceProvider>>();
private final ConcurrentMap<Class, NamedObjectProviderBinding<PsiReferenceProvider>> myNamedBindingsMap = new ConcurrentHashMap<Class, NamedObjectProviderBinding<PsiReferenceProvider>>();
private final FactoryMap<Class, Class[]> myKnownSupers = new ConcurrentFactoryMap<Class, Class[]>() {
@Override
protected Class[] create(Class key) {
@@ -71,7 +69,8 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
@NotNull Class scope,
@NotNull PsiReferenceProvider provider,
double priority) {
registerReferenceProvider(PlatformPatterns.psiElement(scope).and(new FilterPattern(elementFilter)), provider, priority);
PsiElementPattern.Capture<PsiElement> capture = PlatformPatterns.psiElement(scope);
registerReferenceProvider(capture.and(new FilterPattern(elementFilter)), provider, priority);
}
@Override
@@ -81,36 +80,35 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
myKnownSupers.clear(); // we should clear the cache
final Class scope = pattern.getCondition().getInitialCondition().getAcceptedClass();
final List<PatternCondition<? super T>> conditions = pattern.getCondition().getConditions();
for (int i = 0, conditionsSize = conditions.size(); i < conditionsSize; i++) {
PatternCondition<? super T> _condition = conditions.get(i);
if (_condition instanceof PsiNamePatternCondition) {
final PsiNamePatternCondition<?> nameCondition = (PsiNamePatternCondition)_condition;
List<PatternCondition<? super String>> conditions1 = nameCondition.getNamePattern().getCondition().getConditions();
for (int i1 = 0, conditions1Size = conditions1.size(); i1 < conditions1Size; i1++) {
PatternCondition<? super String> condition = conditions1.get(i1);
if (condition instanceof ValuePatternCondition) {
final Collection<String> strings = ((ValuePatternCondition)condition).getValues();
registerNamedReferenceProvider(ArrayUtil.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern);
return;
}
if (condition instanceof CaseInsensitiveValuePatternCondition) {
final String[] strings = ((CaseInsensitiveValuePatternCondition)condition).getValues();
registerNamedReferenceProvider(strings, nameCondition, scope, false, provider, priority, pattern);
return;
}
}
break;
for (PatternCondition<? super T> _condition : conditions) {
if (!(_condition instanceof PsiNamePatternCondition)) {
continue;
}
final PsiNamePatternCondition<?> nameCondition = (PsiNamePatternCondition)_condition;
List<PatternCondition<? super String>> conditions1 = nameCondition.getNamePattern().getCondition().getConditions();
for (PatternCondition<? super String> condition1 : conditions1) {
if (condition1 instanceof ValuePatternCondition) {
final Collection<String> strings = ((ValuePatternCondition)condition1).getValues();
registerNamedReferenceProvider(ArrayUtil.toStringArray(strings), nameCondition, scope, true, provider, priority, pattern);
return;
}
if (condition1 instanceof CaseInsensitiveValuePatternCondition) {
final String[] strings = ((CaseInsensitiveValuePatternCondition)condition1).getValues();
registerNamedReferenceProvider(strings, nameCondition, scope, false, provider, priority, pattern);
return;
}
}
break;
}
while (true) {
final SimpleProviderBinding providerBinding = myBindingsMap.get(scope);
SimpleProviderBinding<PsiReferenceProvider> providerBinding = myBindingsMap.get(scope);
if (providerBinding != null) {
providerBinding.registerProvider(provider, pattern, priority);
return;
}
final SimpleProviderBinding binding = new SimpleProviderBinding();
SimpleProviderBinding<PsiReferenceProvider> binding = new SimpleProviderBinding<PsiReferenceProvider>();
binding.registerProvider(provider, pattern, priority);
if (myBindingsMap.putIfAbsent(scope, binding) == null) break;
}
@@ -126,19 +124,22 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
}
public void unregisterReferenceProvider(@NotNull Class scope, @NotNull PsiReferenceProvider provider) {
final ProviderBinding providerBinding = myBindingsMap.get(scope);
ProviderBinding<PsiReferenceProvider> providerBinding = myBindingsMap.get(scope);
providerBinding.unregisterProvider(provider);
}
private void registerNamedReferenceProvider(final String[] names, final PsiNamePatternCondition<?> nameCondition,
final Class scopeClass,
private void registerNamedReferenceProvider(@NotNull String[] names,
final PsiNamePatternCondition<?> nameCondition,
@NotNull Class scopeClass,
final boolean caseSensitive,
final PsiReferenceProvider provider, final double priority, final ElementPattern pattern) {
NamedObjectProviderBinding providerBinding = myNamedBindingsMap.get(scopeClass);
@NotNull PsiReferenceProvider provider,
final double priority,
@NotNull ElementPattern pattern) {
NamedObjectProviderBinding<PsiReferenceProvider> providerBinding = myNamedBindingsMap.get(scopeClass);
if (providerBinding == null) {
providerBinding = ConcurrencyUtil.cacheOrGet(myNamedBindingsMap, scopeClass, new NamedObjectProviderBinding() {
providerBinding = ConcurrencyUtil.cacheOrGet(myNamedBindingsMap, scopeClass, new NamedObjectProviderBinding<PsiReferenceProvider>() {
@Override
protected String getName(final PsiElement position) {
return nameCondition.getPropertyValue(position);
@@ -158,17 +159,17 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
}
@NotNull
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> getPairsByElement(@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints) {
List<ProviderBinding.ProviderInfo<PsiReferenceProvider,ProcessingContext>> getPairsByElement(@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints) {
final Class<? extends PsiElement> clazz = element.getClass();
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> ret = null;
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> ret = null;
for (Class aClass : myKnownSupers.get(clazz)) {
final SimpleProviderBinding simpleBinding = myBindingsMap.get(aClass);
final NamedObjectProviderBinding namedBinding = myNamedBindingsMap.get(aClass);
SimpleProviderBinding<PsiReferenceProvider> simpleBinding = myBindingsMap.get(aClass);
NamedObjectProviderBinding<PsiReferenceProvider> namedBinding = myNamedBindingsMap.get(aClass);
if (simpleBinding == null && namedBinding == null) continue;
if (ret == null) ret = new SmartList<Trinity<PsiReferenceProvider, ProcessingContext, Double>>();
if (ret == null) ret = new SmartList<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>>();
if (simpleBinding != null) {
simpleBinding.addAcceptableReferenceProviders(element, ret, hints);
}
@@ -176,6 +177,6 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
namedBinding.addAcceptableReferenceProviders(element, ret, hints);
}
}
return ret == null ? Collections.<Trinity<PsiReferenceProvider, ProcessingContext, Double>>emptyList() : ret;
return ret == null ? Collections.<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>>emptyList() : ret;
}
}
@@ -18,7 +18,7 @@ package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Trinity;
import com.intellij.openapi.util.Comparing;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
@@ -32,12 +32,12 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
private static final LanguageExtension<PsiReferenceContributor> CONTRIBUTOR_EXTENSION = new LanguageExtension<PsiReferenceContributor>(PsiReferenceContributor.EP_NAME.getName());
private static final LanguageExtension<PsiReferenceProviderBean> REFERENCE_PROVIDER_EXTENSION = new LanguageExtension<PsiReferenceProviderBean>(PsiReferenceProviderBean.EP_NAME.getName());
private static final Comparator<Trinity<PsiReferenceProvider, ProcessingContext, Double>> PRIORITY_COMPARATOR =
new Comparator<Trinity<PsiReferenceProvider, ProcessingContext, Double>>() {
private static final Comparator<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> PRIORITY_COMPARATOR =
new Comparator<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>>() {
@Override
public int compare(final Trinity<PsiReferenceProvider, ProcessingContext, Double> o1,
final Trinity<PsiReferenceProvider, ProcessingContext, Double> o2) {
return o2.getThird().compareTo(o1.getThird());
public int compare(ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> o1,
ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> o2) {
return Comparing.compare(o2.priority, o1.priority);
}
};
@@ -85,11 +85,11 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
@Override
protected PsiReference[] doGetReferencesFromProviders(PsiElement context,
PsiReferenceService.Hints hints) {
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> providersForContextLanguage;
providersForContextLanguage = getRegistrar(context.getLanguage()).getPairsByElement(context, hints);
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> providersForContextLanguage =
getRegistrar(context.getLanguage()).getPairsByElement(context, hints);
List<Trinity<PsiReferenceProvider, ProcessingContext, Double>> providersForAllLanguages;
providersForAllLanguages = getRegistrar(Language.ANY).getPairsByElement(context, hints);
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> providersForAllLanguages =
getRegistrar(Language.ANY).getPairsByElement(context, hints);
int providersCount = providersForContextLanguage.size() + providersForAllLanguages.size();
@@ -98,35 +98,30 @@ public class ReferenceProvidersRegistryImpl extends ReferenceProvidersRegistry {
}
if (providersCount == 1) {
final Trinity<PsiReferenceProvider, ProcessingContext, Double> firstProvider =
final ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> firstProvider =
(providersForAllLanguages.isEmpty() ? providersForContextLanguage : providersForAllLanguages).get(0);
return firstProvider.getFirst().getReferencesByElement(context, firstProvider.getSecond());
return firstProvider.provider.getReferencesByElement(context, firstProvider.processingContext);
}
Trinity<PsiReferenceProvider, ProcessingContext, Double>[] providers = new Trinity[providersCount];
int i = 0;
for (Trinity<PsiReferenceProvider, ProcessingContext, Double> provider : providersForContextLanguage) {
providers[i++] = provider;
}
for (Trinity<PsiReferenceProvider, ProcessingContext, Double> provider : providersForAllLanguages) {
providers[i++] = provider;
}
List<ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>> list =
ContainerUtil.concat(providersForContextLanguage, providersForAllLanguages);
@SuppressWarnings("unchecked")
ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext>[] providers = list.toArray(new ProviderBinding.ProviderInfo[list.size()]);
Arrays.sort(providers, PRIORITY_COMPARATOR);
List<PsiReference> result = new ArrayList<PsiReference>();
final double maxPriority = providers[0].getThird();
final double maxPriority = providers[0].priority;
next:
for (Trinity<PsiReferenceProvider, ProcessingContext, Double> trinity : providers) {
for (ProviderBinding.ProviderInfo<PsiReferenceProvider, ProcessingContext> trinity : providers) {
final PsiReference[] refs;
try {
refs = trinity.getFirst().getReferencesByElement(context, trinity.getSecond());
refs = trinity.provider.getReferencesByElement(context, trinity.processingContext);
}
catch(IndexNotReadyException ex) {
continue;
}
if (trinity.getThird().doubleValue() != maxPriority) {
if (trinity.priority != maxPriority) {
for (PsiReference ref : refs) {
for (PsiReference reference : result) {
if (ref != null && ReferenceRange.containsRangeInElement(reference, ref.getRangeInElement())) {
@@ -17,7 +17,6 @@
package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.util.Trinity;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceProvider;
@@ -37,17 +36,18 @@ import java.util.List;
* To change this template use Options | File Templates.
*/
public class SimpleProviderBinding<Provider> implements ProviderBinding<Provider> {
private final List<Trinity<Provider, ElementPattern, Double>> myProviderPairs = ContainerUtil.createEmptyCOWList();
private final List<ProviderInfo<Provider, ElementPattern>> myProviderPairs = ContainerUtil.createEmptyCOWList();
public void registerProvider(Provider provider,ElementPattern pattern, double priority){
myProviderPairs.add(Trinity.create(provider, pattern, priority));
myProviderPairs.add(new ProviderInfo<Provider, ElementPattern>(provider, pattern, priority));
}
@Override
public void addAcceptableReferenceProviders(@NotNull PsiElement position, @NotNull List list,
PsiReferenceService.Hints hints) {
for(Trinity<Provider,ElementPattern,Double> trinity:myProviderPairs) {
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.first).acceptsHints(position, hints)) {
public void addAcceptableReferenceProviders(@NotNull PsiElement position,
@NotNull List<ProviderInfo<Provider, ProcessingContext>> list,
@NotNull PsiReferenceService.Hints hints) {
for(ProviderInfo<Provider, ElementPattern> trinity:myProviderPairs) {
if (hints != PsiReferenceService.Hints.NO_HINTS && !((PsiReferenceProvider)trinity.provider).acceptsHints(position, hints)) {
continue;
}
@@ -57,20 +57,20 @@ public class SimpleProviderBinding<Provider> implements ProviderBinding<Provider
}
boolean suitable = false;
try {
suitable = trinity.second.accepts(position, context);
suitable = trinity.processingContext.accepts(position, context);
}
catch (IndexNotReadyException ignored) {
}
if (suitable) {
list.add(Trinity.create(trinity.first, context, trinity.third));
list.add(new ProviderInfo<Provider, ProcessingContext>(trinity.provider, context, trinity.priority));
}
}
}
@Override
public void unregisterProvider(final Provider provider) {
for (final Trinity<Provider, ElementPattern, Double> trinity : new ArrayList<Trinity<Provider, ElementPattern, Double>>(myProviderPairs)) {
if (trinity.first.equals(provider)) {
public void unregisterProvider(@NotNull final Provider provider) {
for (final ProviderInfo<Provider, ElementPattern> trinity : new ArrayList<ProviderInfo<Provider, ElementPattern>>(myProviderPairs)) {
if (trinity.provider.equals(provider)) {
myProviderPairs.remove(trinity);
}
}
@@ -15,8 +15,9 @@
*/
package git4idea.commands;
import java.util.HashMap;
import java.util.Map;
import gnu.trove.TObjectDoubleHashMap;
import gnu.trove.TObjectDoubleProcedure;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -28,8 +29,8 @@ import java.util.regex.Pattern;
public class GitStandardProgressAnalyzer implements GitProgressAnalyzer {
// progress of each operation is stored here. this is an overhead since operations go one by one,
// but it looks simplier than storing current operation, checking that ther was no skipped, etc.
private Map<Operation, Double> myOperationsProgress = new HashMap<Operation, Double>(4);
// but it looks simpler than storing current operation, checking that ther was no skipped, etc.
private TObjectDoubleHashMap<Operation> myOperationsProgress = new TObjectDoubleHashMap<Operation>(4);
/**
* A long git command usually consists of the operations in this enum.
@@ -96,11 +97,15 @@ public class GitStandardProgressAnalyzer implements GitProgressAnalyzer {
}
}
// counting progress
double totalProgress = 0;
for (Map.Entry<Operation, Double> progressEntry : myOperationsProgress.entrySet()) {
totalProgress += progressEntry.getKey().myFractionInTotal * progressEntry.getValue();
}
return totalProgress;
final double[] totalProgress = new double[1];
myOperationsProgress.forEachEntry(new TObjectDoubleProcedure<Operation>() {
@Override
public boolean execute(Operation operation, double progress) {
totalProgress[0] += operation.myFractionInTotal * progress;
return true;
}
});
return totalProgress[0];
}
}