From 4ebbcfd414489bb5d63a57da81bc35fcab9f36d5 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 17 Jan 2014 13:39:54 +0400 Subject: [PATCH] EA-52519 - IAE: TObjectHash.throwObjectContractViolation --- .../daemon/impl/SeverityRegistrar.java | 180 ++++++++++-------- 1 file changed, 102 insertions(+), 78 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java index e5c719b70860..3e0213cdf631 100644 --- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java +++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * 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. @@ -27,8 +27,9 @@ import com.intellij.openapi.util.JDOMExternalizableStringList; import com.intellij.openapi.util.WriteExternalException; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.util.concurrency.AtomicFieldUpdater; +import com.intellij.util.containers.ConcurrentHashMap; import com.intellij.util.containers.ContainerUtil; -import gnu.trove.THashMap; import gnu.trove.TObjectIntHashMap; import gnu.trove.TObjectIntProcedure; import org.jdom.Element; @@ -48,13 +49,13 @@ import java.util.List; public class SeverityRegistrar implements JDOMExternalizable, Comparator { @NonNls private static final String INFO_TAG = "info"; @NonNls private static final String COLOR_ATTRIBUTE = "color"; - private final Map myMap = new THashMap(); - private final Map myRendererColors = new THashMap(); + private final Map myMap = new ConcurrentHashMap(); + private final Map myRendererColors = new ConcurrentHashMap(); - private final OrderMap myOrder = new OrderMap(); + private volatile OrderMap myOrderMap; private JDOMExternalizableStringList myReadOrder; - private static final Map STANDARD_SEVERITIES = new THashMap(); + private static final Map STANDARD_SEVERITIES = new ConcurrentHashMap(); public SeverityRegistrar() { } @@ -68,7 +69,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator knownSeverities = getDefaultOrder(); - myOrder.retainEntries(new TObjectIntProcedure() { + orderMap.retainEntries(new TObjectIntProcedure() { @Override public boolean execute(HighlightSeverity severity, int order) { return knownSeverities.contains(severity); } }); - if (myOrder.isEmpty()) { - setFromList(knownSeverities); + if (orderMap.isEmpty()) { + orderMap = fromList(knownSeverities); } - //enforce include all known - List list = getOrderAsList(); - for (int i = 0; i < knownSeverities.size(); i++) { - HighlightSeverity stdSeverity = knownSeverities.get(i); - if (!list.contains(stdSeverity)) { - for (int oIdx = 0; oIdx < list.size(); oIdx++) { - HighlightSeverity orderSeverity = list.get(oIdx); - HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity.toString()); - if (type != null && knownSeverities.indexOf(type.getSeverity(null)) > i) { - list.add(oIdx, stdSeverity); - myReadOrder = null; - break; + else { + //enforce include all known + List list = getOrderAsList(orderMap); + for (int i = 0; i < knownSeverities.size(); i++) { + HighlightSeverity stdSeverity = knownSeverities.get(i); + if (!list.contains(stdSeverity)) { + for (int oIdx = 0; oIdx < list.size(); oIdx++) { + HighlightSeverity orderSeverity = list.get(oIdx); + HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity.getName()); + if (type != null && knownSeverities.indexOf(type.getSeverity(null)) > i) { + list.add(oIdx, stdSeverity); + myReadOrder = null; + break; + } } } } + orderMap = fromList(list); } - setFromList(list); + myOrderMap = orderMap; } @Override public void writeExternal(Element element) throws WriteExternalException { - List list = getOrderAsList(); - for (HighlightSeverity s : list) { + List list = getOrderAsList(getOrderMap()); + for (HighlightSeverity severity : list) { Element info = new Element(INFO_TAG); - String severity = s.toString(); - final SeverityBasedTextAttributes infoType = myMap.get(severity); + String severityName = severity.getName(); + final SeverityBasedTextAttributes infoType = getAttributesBySeverity(severity); if (infoType != null) { infoType.writeExternal(info); - final Color color = myRendererColors.get(severity); + final Color color = myRendererColors.get(severityName); if (color != null) { info.setAttribute(COLOR_ATTRIBUTE, Integer.toString(color.getRGB() & 0xFFFFFF, 16)); } @@ -194,11 +201,11 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator() { + final JDOMExternalizableStringList ext = new JDOMExternalizableStringList(Collections.nCopies(getOrderMap().size(), "")); + getOrderMap().forEachEntry(new TObjectIntProcedure() { @Override public boolean execute(HighlightSeverity orderSeverity, int oIdx) { - ext.set(oIdx, orderSeverity.toString()); + ext.set(oIdx, orderSeverity.getName()); return true; } }); @@ -207,9 +214,9 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator getOrderAsList() { + private List getOrderAsList(@NotNull OrderMap orderMap) { List list = new ArrayList(); - for (Object o : getOrder().keys()) { + for (Object o : orderMap.keys()) { list.add((HighlightSeverity)o); } Collections.sort(list, this); @@ -217,12 +224,12 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator() { + getOrderMap().forEachEntry(new TObjectIntProcedure() { @Override public boolean execute(HighlightSeverity severity, int order) { if (order == i) { @@ -236,7 +243,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator max) max = values[i]; @@ -253,7 +260,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator createCurrentSeverities() { + private List createCurrentSeverityNames() { List list = new ArrayList(); list.addAll(STANDARD_SEVERITIES.keySet()); list.addAll(myMap.keySet()); @@ -268,37 +275,50 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator order = getDefaultOrder(); - setFromList(order); + private OrderMap getOrderMap() { + OrderMap orderMap; + OrderMap defaultOrder = null; + while ((orderMap = myOrderMap) == null) { + if (defaultOrder == null) { + defaultOrder = fromList(getDefaultOrder()); + } + boolean replaced = ORDER_MAP_UPDATER.compareAndSet(this, null, defaultOrder); + if (replaced) { + orderMap = defaultOrder; + break; + } } - return myOrder; + return orderMap; } - private void setFromList(@NotNull List order) { - myOrder.clear(); - for (int i = 0; i < order.size(); i++) { - HighlightSeverity severity = order.get(i); - myOrder.put(severity, i); + private static final AtomicFieldUpdater ORDER_MAP_UPDATER = AtomicFieldUpdater.forFieldOfType(SeverityRegistrar.class, OrderMap.class); + + @NotNull + private static OrderMap fromList(@NotNull List orderList) { + OrderMap orderMap = new OrderMap(orderList.size()); + for (int i = 0; i < orderList.size(); i++) { + HighlightSeverity severity = orderList.get(i); + orderMap.put(severity, i); } + orderMap.trimToSize(); + return orderMap; } @NotNull @@ -315,13 +335,13 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator order) { - setFromList(order); + public void setOrder(@NotNull List orderList) { + myOrderMap = fromList(orderList); myReadOrder = null; } public int getSeverityIdx(@NotNull HighlightSeverity severity) { - return getOrder().getOrder(severity, -1); + return getOrderMap().getOrder(severity, -1); } public boolean isDefaultSeverity(@NotNull HighlightSeverity severity) { @@ -336,6 +356,10 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator { + private OrderMap(int initialCapacity) { + super(initialCapacity); + } + private int getOrder(@NotNull HighlightSeverity severity, int defaultOrder) { int index = index(severity); return index < 0 ? defaultOrder : _values[index]; @@ -348,24 +372,25 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator standardSeverities() { return STANDARD_SEVERITIES.values(); } - }