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