Bug 576333 - optimize EclipseContext.localValueComputations Use a ConcurrentHashmap because its faster and has atomic operations. It is not a big hotspot though. also fixed typo "dipose"->"dispose" Change-Id: Ib1ca93f1a7cd74ab4c5391220f451a78c72497d3 Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.runtime/+/185956 Tested-by: Platform Bot <platform-bot@eclipse.org>
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextChangeEvent.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextChangeEvent.java index 39fbad1..400abe0 100644 --- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextChangeEvent.java +++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextChangeEvent.java
@@ -77,12 +77,12 @@ */ public static final int RECALC = 6; - private Object[] args; - private IEclipseContext context; - private int eventType; - private String key; + private final Object[] args; + private final IEclipseContext context; + private final int eventType; + private final String key; - private Object oldValue; + private final Object oldValue; /** * Creates a new context event.
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java index 6b92681..a83bdb4 100644 --- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java +++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/EclipseContext.java
@@ -29,6 +29,7 @@ import java.util.Objects; import java.util.Set; import java.util.Stack; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.e4.core.contexts.IContextFunction; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.contexts.RunAndTrack; @@ -90,7 +91,7 @@ } private WeakGroupedListenerList weakListeners = new WeakGroupedListenerList(); - private Map<String, ValueComputation> localValueComputations = Collections.synchronizedMap(new HashMap<>()); + private Map<String, ValueComputation> localValueComputations = new ConcurrentHashMap<>(); final protected ConcurrentNeutralValueMap<String, Object> localValues = // null values allowed new ConcurrentNeutralValueMap<>(ConcurrentNeutralValueMap.neutralObject()); @@ -195,11 +196,10 @@ } notifyOnDisposal.clear(); } - - for (ValueComputation computation : localValueComputations.values()) { - computation.dipose(); - } - localValueComputations.clear(); + localValueComputations.values().removeIf(computation -> { + computation.dispose(); + return true; + }); // if this was the parent's active child, deactivate it EclipseContext parent = getParent(); @@ -293,21 +293,20 @@ * computations and listeners that depend on this name. */ public void invalidate(String name, int eventType, Object oldValue, Object newValue, Set<Scheduled> scheduled) { - ContextChangeEvent event = null; - ValueComputation computation = localValueComputations.get(name); - if (computation != null) { - event = new ContextChangeEvent(this, eventType, null, name, oldValue); + ContextChangeEvent event = new ContextChangeEvent(this, eventType, null, name, oldValue); + + ValueComputation newComputation = localValueComputations.computeIfPresent(name, (k, computation) -> { if (computation.shouldRemove(event)) { - localValueComputations.remove(name); weakListeners.remove(computation); + return null; // remove } - computation.handleInvalid(event, scheduled); + return computation; // keep + }); + if (newComputation != null) { + newComputation.handleInvalid(event, scheduled); } Set<Computation> namedComputations = weakListeners.getListeners(name); if (namedComputations != null && !namedComputations.isEmpty()) { - if (event == null) { - event = new ContextChangeEvent(this, eventType, null, name, oldValue); - } for (Computation listener : namedComputations) { listener.handleInvalid(event, scheduled); } @@ -522,11 +521,11 @@ protected void invalidateLocalComputations(Set<Scheduled> scheduled) { ContextChangeEvent event = new ContextChangeEvent(this, ContextChangeEvent.ADDED, null, null, null); - for (Computation computation : localValueComputations.values()) { + localValueComputations.values().removeIf(computation -> { weakListeners.remove(computation); computation.handleInvalid(event, scheduled); - } - localValueComputations.clear(); + return true; + }); // We need to cleanup computations recursively see bug 468048 for (EclipseContext c : getChildren()) {
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ValueComputation.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ValueComputation.java index 9e51e96..9b3c600 100644 --- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ValueComputation.java +++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ValueComputation.java
@@ -116,7 +116,7 @@ return valid; } - public void dipose() { + public void dispose() { valid = false; } } \ No newline at end of file