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

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

commit 73d3b17d1805202672af4c692774204d0e575c77
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Fri Mar 12 06:50:05 2021 +0100

    CAMEL-16326: camel-core - Optimize usage of exchanage properties for state 
in routing engine.
---
 .../src/main/java/org/apache/camel/Exchange.java     | 13 +++++++++++--
 .../java/org/apache/camel/ExchangePropertyKey.java   |  6 ------
 .../main/java/org/apache/camel/ExtendedExchange.java |  1 +
 .../camel/impl/engine/CamelInternalProcessor.java    |  7 ++++++-
 .../org/apache/camel/impl/DefaultExchangeTest.java   | 15 ++++++++++++++-
 .../org/apache/camel/support/AbstractExchange.java   | 20 ++++++++++++++++++--
 .../apache/camel/support/DefaultPooledExchange.java  |  3 ++-
 7 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/Exchange.java 
b/core/camel-api/src/main/java/org/apache/camel/Exchange.java
index 1111043..f565313 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Exchange.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Exchange.java
@@ -404,13 +404,22 @@ public interface Exchange {
     boolean removeProperties(String pattern, String... excludePatterns);
 
     /**
-     * Returns all of the properties associated with the exchange
+     * Returns the properties associated with the exchange
      *
-     * @return all the properties in a Map
+     * @return the properties in a Map
+     * @see #getAllProperties()
      */
     Map<String, Object> getProperties();
 
     /**
+     * Returns all (both internal and custom) of the properties associated 
with the exchange
+     *
+     * @return all (both internal and custom) the properties in a Map
+     * @see #getProperties()
+     */
+    Map<String, Object> getAllProperties();
+
+    /**
      * Returns whether any properties has been set
      *
      * @return <tt>true</tt> if any properties has been set
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java 
b/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java
index c4d2c68..0f5978e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java
@@ -21,12 +21,6 @@ package org.apache.camel;
  */
 public enum ExchangePropertyKey {
 
-    // TODO: sort by most commonly used (not A..Z)
-    // so we can say 0..10 are frequently used
-    // and 11..end are possible used
-    // then we can optimize and have dirty flags for possible used
-    // and if not dirty then no need to go so far in the array
-
     AGGREGATED_COMPLETED_BY(Exchange.AGGREGATED_COMPLETED_BY),
     AGGREGATED_CORRELATION_KEY(Exchange.AGGREGATED_CORRELATION_KEY),
     AGGREGATED_SIZE(Exchange.AGGREGATED_SIZE),
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/ExtendedExchange.java 
b/core/camel-api/src/main/java/org/apache/camel/ExtendedExchange.java
index bf1866e..d51da72 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExtendedExchange.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedExchange.java
@@ -182,6 +182,7 @@ public interface ExtendedExchange extends Exchange {
 
     /**
      * Gets the internal properties from this exchange.
+     * The known set of internal keys is defined in {@link 
ExchangePropertyKey}.
      * <p/>
      * This method is only intended for Camel internally.
      *
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
index 981110f..289b289 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java
@@ -107,6 +107,7 @@ public class CamelInternalProcessor extends 
DelegateAsyncProcessor implements In
     private final ShutdownStrategy shutdownStrategy;
     private final List<CamelInternalProcessorAdvice<?>> advices = new 
ArrayList<>();
     private byte statefulAdvices;
+    private Object[] EMPTY_STATEFUL_STATES;
     private PooledObjectFactory<CamelInternalTask> taskFactory;
 
     public CamelInternalProcessor(CamelContext camelContext) {
@@ -132,6 +133,9 @@ public class CamelInternalProcessor extends 
DelegateAsyncProcessor implements In
             int capacity = 
camelContext.adapt(ExtendedCamelContext.class).getExchangeFactory().getCapacity();
             taskFactory.setCapacity(capacity);
             LOG.trace("Using TaskFactory: {}", taskFactory);
+
+            // create empty array we can use for reset
+            EMPTY_STATEFUL_STATES = new Object[statefulAdvices];
         }
 
         ServiceHelper.buildService(taskFactory, processor);
@@ -223,7 +227,8 @@ public class CamelInternalProcessor extends 
DelegateAsyncProcessor implements In
 
         @Override
         public void reset() {
-            Arrays.fill(states, null);
+            // reset array by copying over from empty which is a very fast JVM 
optimized operation
+            System.arraycopy(EMPTY_STATEFUL_STATES, 0, states, 0, 
statefulAdvices);
             this.exchange = null;
             this.originalCallback = null;
         }
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java 
b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java
index 19a8c2f..8e77d35 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeTest.java
@@ -23,6 +23,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.ExchangePropertyKey;
 import org.apache.camel.ExchangeTestSupport;
+import org.apache.camel.ExtendedExchange;
 import org.apache.camel.InvalidPayloadException;
 import org.apache.camel.Message;
 import org.apache.camel.RuntimeCamelException;
@@ -231,7 +232,7 @@ public class DefaultExchangeTest extends 
ExchangeTestSupport {
     }
 
     @Test
-    public void testRemoveKnownProperties() throws Exception {
+    public void testRemoveInternalProperties() throws Exception {
         exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, "iso-8859-1");
 
         assertEquals("iso-8859-1", 
exchange.getProperty(ExchangePropertyKey.CHARSET_NAME));
@@ -255,6 +256,18 @@ public class DefaultExchangeTest extends 
ExchangeTestSupport {
     }
 
     @Test
+    public void testAllProperties() throws Exception {
+        exchange.removeProperties("*");
+        exchange.setProperty("foo", 123);
+        exchange.setProperty(ExchangePropertyKey.TO_ENDPOINT, "seda:bar");
+        exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, "iso-8859-1");
+
+        assertEquals(1, exchange.getProperties().size());
+        assertEquals(2, 
exchange.adapt(ExtendedExchange.class).getInternalProperties().size());
+        assertEquals(3, exchange.getAllProperties().size());
+    }
+
+    @Test
     public void testInType() throws Exception {
         exchange.setIn(new MyMessage(context));
 
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 bb24ecd..62e4f1f 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
@@ -52,11 +52,16 @@ import org.apache.camel.util.ObjectHelper;
  */
 class AbstractExchange implements ExtendedExchange {
 
+    // number of elements in array
+    static final int INTERNAL_LENGTH = ExchangePropertyKey.values().length;
+    // empty array for reset
+    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);
     // optimize for internal exchange properties (not intended for end users)
-    final Object[] internalProperties = new 
Object[ExchangePropertyKey.values().length];
+    final Object[] internalProperties = new Object[INTERNAL_LENGTH];
     long created;
     Message in;
     Message out;
@@ -358,7 +363,8 @@ class AbstractExchange implements ExtendedExchange {
         // special optimized
         if (excludePatterns == null && "*".equals(pattern)) {
             properties.clear();
-            Arrays.fill(internalProperties, null);
+            // 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;
         }
 
@@ -409,6 +415,16 @@ class AbstractExchange implements ExtendedExchange {
     }
 
     @Override
+    public Map<String, Object> getAllProperties() {
+        // include also internal properties (creates a new map)
+        Map<String, Object> map = getInternalProperties();
+        if (!properties.isEmpty()) {
+            map.putAll(properties);
+        }
+        return map;
+    }
+
+    @Override
     public boolean hasProperties() {
         return !properties.isEmpty();
     }
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 f3bad21..11b6bd4 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
@@ -78,7 +78,8 @@ public final class DefaultPooledExchange extends 
AbstractExchange implements Poo
         if (created > 0 && (forced || autoRelease)) {
             this.created = 0; // by setting to 0 we also flag that this 
exchange is done and needs to be reset to use again
             this.properties.clear();
-            Arrays.fill(this.internalProperties, null);
+            // 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);
             this.exchangeId = null;
             if (in != null && in.getClass() == originalInClassType) {
                 // okay we can reuse in

Reply via email to