From a5bd0065a926ae714af4fec8a40b385d9341e9a2 Mon Sep 17 00:00:00 2001 From: Francesco Nigro Date: Thu, 13 Feb 2020 14:08:13 +0100 Subject: [PATCH] ARTEMIS-2617 Fixing KMPNeedle::searchInto API and specializing it KMPNeedle::searchInto has been specialized and copied to handle ReadableBuffer in order to save polymorphic calls on it that would make it slower on hot paths. --- .../protocol/amqp/broker/AMQPMessage.java | 1 - .../amqp/broker/AMQPMessageSymbolSearch.java | 3 +-- .../protocol/amqp/broker}/KMPNeedle.java | 24 +++++++++---------- 3 files changed, 12 insertions(+), 16 deletions(-) rename {artemis-commons/src/main/java/org/apache/activemq/artemis/utils/algo => artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker}/KMPNeedle.java (86%) diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessage.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessage.java index a4c9686b67..b47013aecc 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessage.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessage.java @@ -44,7 +44,6 @@ import org.apache.activemq.artemis.protocol.amqp.util.NettyWritable; import org.apache.activemq.artemis.protocol.amqp.util.TLSEncode; import org.apache.activemq.artemis.reader.MessageUtil; import org.apache.activemq.artemis.utils.ByteUtil; -import org.apache.activemq.artemis.utils.algo.KMPNeedle; import org.apache.activemq.artemis.utils.collections.TypedProperties; import org.apache.qpid.proton.amqp.Binary; import org.apache.qpid.proton.amqp.Symbol; diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessageSymbolSearch.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessageSymbolSearch.java index 7b046a5089..50876344e2 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessageSymbolSearch.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPMessageSymbolSearch.java @@ -22,7 +22,6 @@ import java.util.IdentityHashMap; import java.util.List; import org.apache.activemq.artemis.protocol.amqp.util.TLSEncode; -import org.apache.activemq.artemis.utils.algo.KMPNeedle; import org.apache.qpid.proton.amqp.Symbol; import org.apache.qpid.proton.amqp.messaging.AmqpSequence; import org.apache.qpid.proton.amqp.messaging.AmqpValue; @@ -67,7 +66,7 @@ final class AMQPMessageSymbolSearch { constructor.skipValue(); final int end = data.position(); for (int i = 0, count = needles.length; i < count; i++) { - final int foundIndex = needles[i].searchInto(ReadableBuffer::get, data, end, start); + final int foundIndex = needles[i].searchInto(data, start, end); if (foundIndex != -1) { return true; } diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/algo/KMPNeedle.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/KMPNeedle.java similarity index 86% rename from artemis-commons/src/main/java/org/apache/activemq/artemis/utils/algo/KMPNeedle.java rename to artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/KMPNeedle.java index 22910c8b60..f6b8744c11 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/algo/KMPNeedle.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/KMPNeedle.java @@ -14,21 +14,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.activemq.artemis.utils.algo; +package org.apache.activemq.artemis.protocol.amqp.broker; import java.util.Objects; +import org.apache.qpid.proton.codec.ReadableBuffer; + /** * Abstraction of {@code byte[] }Knuth-Morris-Pratt's needle to be used - * to perform pattern matching over indexed haystack of {@code byte}s. + * to perform pattern matching over {@link ReadableBuffer}. */ -public final class KMPNeedle { - - @FunctionalInterface - public interface IndexedByteSupplier { - - byte get(S source, int index); - } +final class KMPNeedle { private final int[] jumpTable; private final byte[] needle; @@ -66,8 +62,10 @@ public final class KMPNeedle { * This version differ from the original algorithm, because allows to fail fast (and faster) if * the remaining haystack to be processed is < of the remaining needle to be matched. */ - public int searchInto(IndexedByteSupplier haystackReader, H haystack, int end, int start) { - assert end >= 0 && start >= 0 && end >= start; + public int searchInto(ReadableBuffer haystack, int start, int end) { + if (end < 0 || start < 0 || end < start) { + return -1; + } final int length = end - start; int j = 0; final int needleLength = needle.length; @@ -78,7 +76,7 @@ public final class KMPNeedle { return -1; } final int index = start + i; - final byte value = haystackReader.get(haystack, index); + final byte value = haystack.get(index); while (j > 0 && needle[j] != value) { j = jumpTable == null ? 0 : jumpTable[j]; remainingNeedle = needleLength - j; @@ -99,5 +97,5 @@ public final class KMPNeedle { public static KMPNeedle of(byte[] needle) { return new KMPNeedle(needle); } - } +