You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2021/03/14 18:19:49 UTC

[camel] 03/04: camel-core - Optimize exchange properties to create on-demand as camel-core uses only internal properties to store state.

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 4cf3569a1d044f107c867944517d171bdd1a402b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Mar 14 18:30:07 2021 +0100

    camel-core - Optimize exchange properties to create on-demand as camel-core uses only internal properties to store state.
---
 .../org/apache/camel/support/AbstractExchange.java | 65 +++++++++++++---------
 .../camel/support/DefaultPooledExchange.java       |  7 +++
 2 files changed, 46 insertions(+), 26 deletions(-)

diff --git a/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java b/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
index 714a01b..37282a6 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
@@ -58,8 +58,7 @@ class AbstractExchange implements ExtendedExchange {
     static final Object[] EMPTY_INTERNAL_PROPERTIES = new Object[INTERNAL_LENGTH];
 
     final CamelContext context;
-    // optimize to create properties always and with a reasonable small size
-    final Map<String, Object> properties = new ConcurrentHashMap<>(8);
+    Map<String, Object> properties; // create properties on-demand as we use internal properties mostly
     // optimize for internal exchange properties (not intended for end users)
     final Object[] internalProperties = new Object[INTERNAL_LENGTH];
     long created;
@@ -265,7 +264,7 @@ class AbstractExchange implements ExtendedExchange {
             answer = internalProperties[key.ordinal()];
             // if the property is not an internal then fallback to lookup in the properties map
         }
-        if (answer == null) {
+        if (answer == null && properties != null) {
             answer = properties.get(name);
         }
         return answer;
@@ -329,8 +328,11 @@ class AbstractExchange implements ExtendedExchange {
             setProperty(key, value);
         } else if (value != null) {
             // avoid the NullPointException
+            if (properties == null) {
+                this.properties = new ConcurrentHashMap<>(8);
+            }
             properties.put(name, value);
-        } else {
+        } else if (properties != null) {
             // if the value is null, we just remove the key from the map
             properties.remove(name);
         }
@@ -338,7 +340,11 @@ class AbstractExchange implements ExtendedExchange {
 
     @Override
     public void setProperties(Map<String, Object> properties) {
-        this.properties.clear();
+        if (this.properties == null) {
+            this.properties = new ConcurrentHashMap<>(8);
+        } else {
+            this.properties.clear();
+        }
         this.properties.putAll(properties);
     }
 
@@ -363,7 +369,9 @@ class AbstractExchange implements ExtendedExchange {
     public boolean removeProperties(String pattern, String... excludePatterns) {
         // special optimized
         if (excludePatterns == null && "*".equals(pattern)) {
-            properties.clear();
+            if (properties != null) {
+                properties.clear();
+            }
             // reset array by copying over from empty which is a very fast JVM optimized operation
             System.arraycopy(EMPTY_INTERNAL_PROPERTIES, 0, this.internalProperties, 0, INTERNAL_LENGTH);
             return true;
@@ -382,27 +390,29 @@ class AbstractExchange implements ExtendedExchange {
         }
 
         // store keys to be removed as we cannot loop and remove at the same time in implementations such as HashMap
-        Set<String> toBeRemoved = null;
-        for (String key : properties.keySet()) {
-            if (PatternHelper.matchPattern(key, pattern)) {
-                if (excludePatterns != null && PatternHelper.isExcludePatternMatch(key, excludePatterns)) {
-                    continue;
-                }
-                matches = true;
-                if (toBeRemoved == null) {
-                    toBeRemoved = new HashSet<>();
+        if (properties != null) {
+            Set<String> toBeRemoved = null;
+            for (String key : properties.keySet()) {
+                if (PatternHelper.matchPattern(key, pattern)) {
+                    if (excludePatterns != null && PatternHelper.isExcludePatternMatch(key, excludePatterns)) {
+                        continue;
+                    }
+                    matches = true;
+                    if (toBeRemoved == null) {
+                        toBeRemoved = new HashSet<>();
+                    }
+                    toBeRemoved.add(key);
                 }
-                toBeRemoved.add(key);
             }
-        }
 
-        if (matches && toBeRemoved != null) {
-            if (toBeRemoved.size() == properties.size()) {
-                // special optimization when all should be removed
-                properties.clear();
-            } else {
-                for (String key : toBeRemoved) {
-                    properties.remove(key);
+            if (matches && toBeRemoved != null) {
+                if (toBeRemoved.size() == properties.size()) {
+                    // special optimization when all should be removed
+                    properties.clear();
+                } else {
+                    for (String key : toBeRemoved) {
+                        properties.remove(key);
+                    }
                 }
             }
         }
@@ -412,6 +422,9 @@ class AbstractExchange implements ExtendedExchange {
 
     @Override
     public Map<String, Object> getProperties() {
+        if (properties == null) {
+            this.properties = new ConcurrentHashMap<>(8);
+        }
         return properties;
     }
 
@@ -419,7 +432,7 @@ class AbstractExchange implements ExtendedExchange {
     public Map<String, Object> getAllProperties() {
         // include also internal properties (creates a new map)
         Map<String, Object> map = getInternalProperties();
-        if (!properties.isEmpty()) {
+        if (properties != null && !properties.isEmpty()) {
             map.putAll(properties);
         }
         return map;
@@ -427,7 +440,7 @@ class AbstractExchange implements ExtendedExchange {
 
     @Override
     public boolean hasProperties() {
-        return !properties.isEmpty();
+        return properties != null && !properties.isEmpty();
     }
 
     @Override
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java
index 0ffd66b4..43bdf31 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.support;
 
+import java.util.concurrent.ConcurrentHashMap;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
@@ -37,26 +39,31 @@ public final class DefaultPooledExchange extends AbstractExchange implements Poo
     public DefaultPooledExchange(CamelContext context) {
         super(context);
         this.originalPattern = getPattern();
+        this.properties = new ConcurrentHashMap<>(8);
     }
 
     public DefaultPooledExchange(CamelContext context, ExchangePattern pattern) {
         super(context, pattern);
         this.originalPattern = pattern;
+        this.properties = new ConcurrentHashMap<>(8);
     }
 
     public DefaultPooledExchange(Exchange parent) {
         super(parent);
         this.originalPattern = parent.getPattern();
+        this.properties = new ConcurrentHashMap<>(8);
     }
 
     public DefaultPooledExchange(Endpoint fromEndpoint) {
         super(fromEndpoint);
         this.originalPattern = getPattern();
+        this.properties = new ConcurrentHashMap<>(8);
     }
 
     public DefaultPooledExchange(Endpoint fromEndpoint, ExchangePattern pattern) {
         super(fromEndpoint, pattern);
         this.originalPattern = pattern;
+        this.properties = new ConcurrentHashMap<>(8);
     }
 
     public boolean isAutoRelease() {