You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ta...@apache.org on 2019/06/18 18:37:49 UTC

[qpid-jms] branch master updated: QPIDJMS-461 Optimize the default message ID builder

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

tabish pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-jms.git


The following commit(s) were added to refs/heads/master by this push:
     new d8a8938  QPIDJMS-461 Optimize the default message ID builder
d8a8938 is described below

commit d8a893844d8c8879b8fc2aaf89a9e8ebc1608dbb
Author: Timothy Bish <ta...@gmail.com>
AuthorDate: Tue Jun 18 10:31:21 2019 -0400

    QPIDJMS-461 Optimize the default message ID builder
    
    Change the builtin Message ID builder to create a builder
    per producer and optimize the string handling used to create
    the Message ID from the producer id and sequence number.
---
 .../org/apache/qpid/jms/JmsMessageProducer.java    |  2 +-
 .../qpid/jms/message/JmsMessageIDBuilder.java      | 63 ++++++++++++++++++++--
 .../qpid/jms/policy/JmsDefaultMessageIDPolicy.java | 27 ++++++++--
 3 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsMessageProducer.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsMessageProducer.java
index e44b132..921dc70 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsMessageProducer.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/JmsMessageProducer.java
@@ -64,7 +64,7 @@ public class JmsMessageProducer implements AutoCloseable, MessageProducer {
         this.anonymousProducer = destination == null;
 
         JmsMessageIDBuilder messageIDBuilder =
-            session.getMessageIDPolicy().getMessageIDBuilder(session, destination);
+            session.getMessageIDPolicy().getMessageIDBuilder(session, destination).initialize(producerId.toString());
 
         this.producerInfo = new JmsProducerInfo(producerId, messageIDBuilder);
         this.producerInfo.setDestination(destination);
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/message/JmsMessageIDBuilder.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/message/JmsMessageIDBuilder.java
index 319506b..9d5b002 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/message/JmsMessageIDBuilder.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/message/JmsMessageIDBuilder.java
@@ -30,15 +30,38 @@ public interface JmsMessageIDBuilder {
         DEFAULT {
             @Override
             public JmsMessageIDBuilder createBuilder() {
+
+                /**
+                 * The default builder is meant to be used as a single instance per producer
+                 * and will yield incorrect results if used across multiple producer instances.
+                 */
                 return new JmsMessageIDBuilder() {
 
+                    private final StringBuilder builder = new StringBuilder();
+                    private int idPrefixLength = -1;
+
                     @Override
                     public Object createMessageID(String producerId, long messageSequence) {
-                        String messageId = producerId + "-" + messageSequence;
-                        if (!AmqpMessageIdHelper.hasMessageIdPrefix(messageId)) {
-                            messageId = AmqpMessageIdHelper.JMS_ID_PREFIX + messageId;
+                        if (idPrefixLength < 0) {
+                            initialize(producerId);
+                        }
+
+                        builder.setLength(idPrefixLength);
+                        builder.append(messageSequence);
+
+                        return builder.toString();
+                    }
+
+                    @Override
+                    public JmsMessageIDBuilder initialize(String producerId) {
+                        if (!AmqpMessageIdHelper.hasMessageIdPrefix(producerId)) {
+                            builder.append(AmqpMessageIdHelper.JMS_ID_PREFIX);
                         }
-                        return messageId;
+                        builder.append(producerId).append("-");
+
+                        idPrefixLength = builder.length();
+
+                        return this;
                     }
 
                     @Override
@@ -113,7 +136,21 @@ public interface JmsMessageIDBuilder {
          * @throws IllegalArgumentException if the named type is unknown.
          */
         public static JmsMessageIDBuilder create(String value) {
-            return valueOf(value.toUpperCase(Locale.ENGLISH)).createBuilder();
+            return validate(value).createBuilder();
+        }
+
+        /**
+         * Validates the value given maps to the built in message ID builders and
+         * return the builder enumeration that it maps to which can later be used
+         * to create builders of that type.
+         *
+         * @param value
+         * 		The name of one of the built in message ID builders.
+         *
+         * @return the enumeration value that maps to the built in builder.
+         */
+        public static BUILTIN validate(String value) {
+            return valueOf(value.toUpperCase(Locale.ENGLISH));
         }
     }
 
@@ -130,4 +167,20 @@ public interface JmsMessageIDBuilder {
      */
     Object createMessageID(String producerId, long messageSequence);
 
+    /**
+     * Provides an initialization point for Message ID builders in order for them
+     * to be able to better optimize the creation of the ID values depending on the
+     * implementation of the builder.
+     *
+     * For builders that are created in a one per producer fashion this methods is
+     * given the producer Id that the builder will be assigned to which can allow
+     * for caching a custom id encoding etc.
+     *
+     * @param producerId
+     * 		The unique Id of a producer object that will be using the builder.
+     *
+     * @return the builder instance for chaining.
+     */
+    default JmsMessageIDBuilder initialize(String producerId) { return this; }
+
 }
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/policy/JmsDefaultMessageIDPolicy.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/policy/JmsDefaultMessageIDPolicy.java
index 2051561..a6b45b5 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/policy/JmsDefaultMessageIDPolicy.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/policy/JmsDefaultMessageIDPolicy.java
@@ -26,7 +26,15 @@ import org.apache.qpid.jms.message.JmsMessageIDBuilder;
  */
 public class JmsDefaultMessageIDPolicy implements JmsMessageIDPolicy {
 
-    private JmsMessageIDBuilder messageIDBuilder = JmsMessageIDBuilder.BUILTIN.DEFAULT.createBuilder();
+    /**
+     * A global builder instance to use instead of allocating one on each builder get.
+     */
+    private volatile JmsMessageIDBuilder messageIDBuilder = null;
+
+    /**
+     * The message id builder type that should be used when creating a new builder instance.
+     */
+    private JmsMessageIDBuilder.BUILTIN messageIDBuilderType = JmsMessageIDBuilder.BUILTIN.DEFAULT;
 
     /**
      * Initialize default Message ID builder policy
@@ -42,6 +50,7 @@ public class JmsDefaultMessageIDPolicy implements JmsMessageIDPolicy {
      */
     public JmsDefaultMessageIDPolicy(JmsDefaultMessageIDPolicy source) {
         this.messageIDBuilder = source.messageIDBuilder;
+        this.messageIDBuilderType = source.messageIDBuilderType;
     }
 
     @Override
@@ -51,7 +60,7 @@ public class JmsDefaultMessageIDPolicy implements JmsMessageIDPolicy {
 
     @Override
     public JmsMessageIDBuilder getMessageIDBuilder(JmsSession session, JmsDestination destination) {
-        return messageIDBuilder;
+        return getMessageIDBuilder();
     }
 
     /**
@@ -61,18 +70,26 @@ public class JmsDefaultMessageIDPolicy implements JmsMessageIDPolicy {
      *      The name of the Message type to use when sending a message.
      */
     public void setMessageIDType(String type) {
-        this.messageIDBuilder = JmsMessageIDBuilder.BUILTIN.create(type);
+        this.messageIDBuilderType = JmsMessageIDBuilder.BUILTIN.validate(type);
     }
 
     /**
      * @return the type name of the configured JmsMessageIDBuilder.
      */
     public String getMessageIDType() {
-        return this.messageIDBuilder.toString();
+        return getMessageIDBuilder().toString();
     }
 
     public JmsMessageIDBuilder getMessageIDBuilder() {
-        return messageIDBuilder;
+        JmsMessageIDBuilder builder = this.messageIDBuilder;
+
+        // If the user has not overridden the create a builder on each call behavior
+        // by passing in a single global instance than use the current set type to
+        // create a new builder each time this method is called.
+        if (builder == null) {
+            builder = messageIDBuilderType.createBuilder();
+        }
+        return builder;
     }
 
     public void setMessageIDBuilder(JmsMessageIDBuilder messageIDBuilder) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org