This is an automated email from the ASF dual-hosted git repository. orpiske pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new b573466c4b6 CAMEL-19058: wrap some internal properties in an EnumMap b573466c4b6 is described below commit b573466c4b6171bb12d23049e74bc400bc634b35 Author: Otavio Rodolfo Piske <angusyo...@gmail.com> AuthorDate: Wed May 3 09:39:44 2023 +0200 CAMEL-19058: wrap some internal properties in an EnumMap This should make it simpler to abstract their complexity while maintaining reasonable performance (as they are used in many parts within the hot path) --- .../org/apache/camel/support/AbstractExchange.java | 40 +++++++--------------- .../camel/support/DefaultPooledExchange.java | 3 +- .../org/apache/camel/support/MessageSupport.java | 16 ++++----- 3 files changed, 20 insertions(+), 39 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 2533c79bc6d..edc6b887344 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 @@ -16,6 +16,7 @@ */ package org.apache.camel.support; +import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -51,15 +52,10 @@ import static org.apache.camel.support.MessageHelper.copyBody; * @see DefaultExchange */ class AbstractExchange implements Exchange { - // number of elements in array - protected static final int INTERNAL_LENGTH = ExchangePropertyKey.values().length; - // empty array for reset - protected static final Object[] EMPTY_INTERNAL_PROPERTIES = new Object[INTERNAL_LENGTH]; + protected final EnumMap<ExchangePropertyKey, Object> internalProperties = new EnumMap<>(ExchangePropertyKey.class); protected final CamelContext context; protected Map<String, Object> properties; // create properties on-demand as we use internal properties mostly - // optimize for internal exchange properties (not intended for end users) - protected final Object[] internalProperties = new Object[INTERNAL_LENGTH]; protected long created; protected Message in; protected Message out; @@ -155,17 +151,11 @@ class AbstractExchange implements Exchange { safeCopyProperties(this.safeCopyProperties, exchange.getSafeCopyProperties()); } // copy over internal properties - System.arraycopy(internalProperties, 0, exchange.internalProperties, 0, internalProperties.length); + exchange.internalProperties.putAll(internalProperties); if (getContext().isMessageHistory()) { - // safe copy message history using a defensive copy - List<MessageHistory> history - = (List<MessageHistory>) exchange.internalProperties[ExchangePropertyKey.MESSAGE_HISTORY.ordinal()]; - if (history != null) { - // use thread-safe list as message history may be accessed concurrently - exchange.internalProperties[ExchangePropertyKey.MESSAGE_HISTORY.ordinal()] - = new CopyOnWriteArrayList<>(history); - } + exchange.internalProperties.computeIfPresent(ExchangePropertyKey.MESSAGE_HISTORY, + (k, v) -> new CopyOnWriteArrayList<>((List<MessageHistory>) v)); } return exchange; @@ -205,7 +195,7 @@ class AbstractExchange implements Exchange { @Override public Object getProperty(ExchangePropertyKey key) { - return internalProperties[key.ordinal()]; + return internalProperties.get(key); } @Override @@ -253,14 +243,12 @@ class AbstractExchange implements Exchange { @Override public void setProperty(ExchangePropertyKey key, Object value) { - internalProperties[key.ordinal()] = value; + internalProperties.put(key, value); } @Override public Object removeProperty(ExchangePropertyKey key) { - Object old = internalProperties[key.ordinal()]; - internalProperties[key.ordinal()] = null; - return old; + return internalProperties.remove(key); } @Override @@ -268,7 +256,7 @@ class AbstractExchange implements Exchange { Object answer = null; ExchangePropertyKey key = ExchangePropertyKey.asExchangePropertyKey(name); if (key != null) { - answer = internalProperties[key.ordinal()]; + answer = internalProperties.get(key); // if the property is not an internal then fallback to lookup in the properties map } if (answer == null && properties != null) { @@ -372,8 +360,7 @@ class AbstractExchange implements Exchange { 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); + internalProperties.clear(); return true; } @@ -385,7 +372,7 @@ class AbstractExchange implements Exchange { continue; } matches = true; - internalProperties[epk.ordinal()] = null; + internalProperties.remove(epk); } } @@ -683,14 +670,13 @@ class AbstractExchange implements Exchange { } void copyInternalProperties(Exchange target) { - AbstractExchange ae = (AbstractExchange) target; - System.arraycopy(internalProperties, 0, ae.internalProperties, 0, INTERNAL_LENGTH); + ((AbstractExchange) target).internalProperties.putAll(internalProperties); } Map<String, Object> getInternalProperties() { Map<String, Object> map = new HashMap<>(); for (ExchangePropertyKey key : ExchangePropertyKey.values()) { - Object value = internalProperties[key.ordinal()]; + Object value = internalProperties.get(key); if (value != null) { map.put(key.getName(), value); } 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 33e65434f07..75bcfca549a 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 @@ -83,8 +83,7 @@ public final class DefaultPooledExchange extends AbstractExchange implements Poo if (created > 0) { 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(); - // 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); + internalProperties.clear(); if (this.safeCopyProperties != null) { this.safeCopyProperties.clear(); } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java index 78cf5a979c8..12896a5ee89 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java @@ -16,7 +16,7 @@ */ package org.apache.camel.support; -import java.util.Arrays; +import java.util.EnumMap; import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; @@ -36,8 +36,6 @@ import org.apache.camel.trait.message.MessageTrait; * from {@link DefaultMessage} */ public abstract class MessageSupport implements Message, CamelContextAware, DataTypeAware { - private static final int NUM_TRAITS = MessageTrait.values().length; - CamelContext camelContext; TypeConverter typeConverter; private Exchange exchange; @@ -45,13 +43,13 @@ public abstract class MessageSupport implements Message, CamelContextAware, Data private String messageId; private long messageTimestamp; - private final Object[] traits = new Object[NUM_TRAITS]; + private final EnumMap<MessageTrait, Object> traits = new EnumMap<>(MessageTrait.class); @Override public void reset() { body = null; messageId = null; - Arrays.fill(traits, null); + traits.clear(); } @Override @@ -312,18 +310,16 @@ public abstract class MessageSupport implements Message, CamelContextAware, Data @Override public boolean hasTrait(MessageTrait trait) { - Object payload = traits[trait.ordinal()]; - - return payload != null; + return traits.containsKey(trait); } @Override public Object getPayloadForTrait(MessageTrait trait) { - return traits[trait.ordinal()]; + return traits.get(trait); } @Override public void setPayloadForTrait(MessageTrait trait, Object object) { - traits[trait.ordinal()] = object; + traits.put(trait, object); } }