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

ibessonov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new de6546bfaf3 IGNITE-27166 Optimize ascii strings comparison (#7068)
de6546bfaf3 is described below

commit de6546bfaf349ac64f4fc2825b4e7b1c32f85818
Author: Ivan Bessonov <[email protected]>
AuthorDate: Wed Nov 26 10:31:30 2025 +0300

    IGNITE-27166 Optimize ascii strings comparison (#7068)
---
 .../schema/BinaryTupleComparatorUtils.java         | 81 ++++++++--------------
 .../internal/schema/PartialBinaryTupleMatcher.java |  2 +-
 2 files changed, 28 insertions(+), 55 deletions(-)

diff --git 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleComparatorUtils.java
 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleComparatorUtils.java
index bc7d29f7510..6d4a8f940eb 100644
--- 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleComparatorUtils.java
+++ 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleComparatorUtils.java
@@ -69,7 +69,7 @@ public class BinaryTupleComparatorUtils {
                 return compareAsUuid(tuple1, tuple2, index);
 
             case STRING:
-                return compareAsString(tuple1, tuple2, index, false);
+                return compareAsString(tuple1, tuple2, index);
 
             case DECIMAL:
                 BigDecimal numeric1 = tuple1.decimalValue(index, 
Integer.MIN_VALUE);
@@ -329,11 +329,10 @@ public class BinaryTupleComparatorUtils {
      * @param tuple1 the first binary tuple reader
      * @param tuple2 the second binary tuple reader
      * @param colIndex the index of the column in the tuple to compare
-     * @param ignoreCase specifies whether the comparison should ignore case 
differences
      * @return a negative integer, zero, or a positive integer if the first 
tuple is less than, equal to,
      *         or greater than the second tuple, respectively
      */
-    static int compareAsString(BinaryTupleReader tuple1, BinaryTupleReader 
tuple2, int colIndex, boolean ignoreCase) {
+    static int compareAsString(BinaryTupleReader tuple1, BinaryTupleReader 
tuple2, int colIndex) {
         tuple1.seek(colIndex);
         int begin1 = tuple1.begin();
         int end1 = tuple1.end();
@@ -342,7 +341,7 @@ public class BinaryTupleComparatorUtils {
         int begin2 = tuple2.begin();
         int end2 = tuple2.end();
 
-        return compareAsString(tuple1.accessor(), begin1, end1, 
tuple2.accessor(), begin2, end2, ignoreCase);
+        return compareAsString(tuple1.accessor(), begin1, end1, 
tuple2.accessor(), begin2, end2);
     }
 
     /**
@@ -354,15 +353,12 @@ public class BinaryTupleComparatorUtils {
      * @param buf2 Buffer accessor for the second tuple.
      * @param begin2 Begin position in the second tuple.
      * @param end2 End position in the second tuple.
-     * @param ignoreCase Case sensitivity flag.
      * @return Comparison result.
-     *
-     * @see #compareAsString(BinaryTupleReader, BinaryTupleReader, int, 
boolean)
+     * @see #compareAsString(BinaryTupleReader, BinaryTupleReader, int)
      */
     public static int compareAsString(
             ByteBufferAccessor buf1, int begin1, int end1,
-            ByteBufferAccessor buf2, int begin2, int end2,
-            boolean ignoreCase
+            ByteBufferAccessor buf2, int begin2, int end2
     ) {
         if (buf1.get(begin1) == BinaryTupleCommon.VARLEN_EMPTY_BYTE) {
             begin1++;
@@ -387,8 +383,7 @@ public class BinaryTupleComparatorUtils {
                 buf2,
                 begin2,
                 fullStrLength2,
-                trimmedSize2,
-                ignoreCase
+                trimmedSize2
         );
 
         if (asciiResult != Integer.MIN_VALUE) {
@@ -404,28 +399,10 @@ public class BinaryTupleComparatorUtils {
                 buf2,
                 begin2,
                 fullStrLength2,
-                trimmedSize2,
-                ignoreCase
+                trimmedSize2
         );
     }
 
-    /**
-     * Compares string values of two binary tuples. Case sensitive.
-     *
-     * @param buf1 Buffer accessor for the first tuple.
-     * @param begin1 Begin position in the first tuple.
-     * @param end1 End position in the first tuple.
-     * @param buf2 Buffer accessor for the second tuple.
-     * @param begin2 Begin position in the second tuple.
-     * @param end2 End position in the second tuple.
-     * @return Comparison result.
-     *
-     * @see #compareAsString(BinaryTupleReader, BinaryTupleReader, int, 
boolean)
-     */
-    public static int compareAsString(ByteBufferAccessor buf1, int begin1, int 
end1, ByteBufferAccessor buf2, int begin2, int end2) {
-        return compareAsString(buf1, begin1, end1, buf2, begin2, end2, false);
-    }
-
     /**
      * Decodes the next UTF-8 code point from the specified buffer starting at 
the given index.
      * The method updates the index array to reflect the position after the 
decoded code point.
@@ -496,7 +473,6 @@ public class BinaryTupleComparatorUtils {
      * @param begin2 the starting position of the second string in the buffer
      * @param fullStrLength2 the full length of the second string in characters
      * @param trimmedSize2 the size limit of the second string in bytes used 
for comparison
-     * @param ignoreCase specifies whether the comparison should ignore case 
differences
      * @return a negative integer if the first string is less than the second 
string,
      *         zero if they are equal, or a positive integer if the first 
string is
      *         greater than the second string. Returns 0 if either string is 
truncated
@@ -510,8 +486,7 @@ public class BinaryTupleComparatorUtils {
             ByteBufferAccessor buf2,
             int begin2,
             int fullStrLength2,
-            int trimmedSize2,
-            boolean ignoreCase
+            int trimmedSize2
     ) {
         int remaining = Math.min(trimmedSize1, trimmedSize2);
 
@@ -531,15 +506,7 @@ public class BinaryTupleComparatorUtils {
             char v2 = (char) cp2;
 
             if (v1 != v2) {
-                if (ignoreCase) {
-                    char upper1 = Character.toUpperCase(v1);
-                    char upper2 = Character.toUpperCase(v2);
-                    if (upper1 != upper2) {
-                        return signum(upper1 - upper2);
-                    }
-                } else {
-                    return signum(v1 - v2);
-                }
+                return signum(v1 - v2);
             }
         }
 
@@ -564,7 +531,6 @@ public class BinaryTupleComparatorUtils {
      * @param begin2 the starting position of the second ASCII sequence in the 
buffer
      * @param fullStrLength2 the full length of the second ASCII sequence in 
characters
      * @param trimmedSize2 the size limit of the second sequence used for 
comparison
-     * @param ignoreCase specifies whether the comparison should ignore case 
differences
      * @return a negative integer if the first sequence is less than the 
second sequence,
      *         zero if they are equal, or a positive integer if the first 
sequence is greater.
      *         If either sequence contains non-ASCII characters, returns 
Integer.MIN_VALUE.
@@ -578,12 +544,27 @@ public class BinaryTupleComparatorUtils {
             ByteBufferAccessor buf2,
             int begin2,
             int fullStrLength2,
-            int trimmedSize2,
-            boolean ignoreCase
+            int trimmedSize2
     ) {
         int i = 0;
         int remaining = Math.min(trimmedSize1, trimmedSize2);
 
+        while (i + Long.BYTES < remaining) {
+            long w1 = buf1.getLong(begin1 + i);
+            long w2 = buf2.getLong(begin2 + i);
+
+            if (((w1 | w2) & 0x8080808080808080L) != 0) {
+                return Integer.MIN_VALUE;
+            }
+
+            if (w1 != w2) {
+                // Big endian comparison of 8 ASCII characters. None of the 
bytes have a sign bit set, so no masks required.
+                return Long.compare(Long.reverseBytes(w1), 
Long.reverseBytes(w2));
+            }
+
+            i += Long.BYTES;
+        }
+
         while (i < remaining) {
             byte b1 = buf1.get(begin1 + i);
             byte b2 = buf2.get(begin2 + i);
@@ -599,15 +580,7 @@ public class BinaryTupleComparatorUtils {
             i++;
 
             if (v1 != v2) {
-                if (ignoreCase) {
-                    char upper1 = Character.toUpperCase(v1);
-                    char upper2 = Character.toUpperCase(v2);
-                    if (upper1 != upper2) {
-                        return signum(upper1 - upper2);
-                    }
-                } else {
-                    return signum(v1 - v2);
-                }
+                return signum(v1 - v2);
             }
         }
 
diff --git 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/PartialBinaryTupleMatcher.java
 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/PartialBinaryTupleMatcher.java
index 09384322378..09858b0d14b 100644
--- 
a/modules/schema/src/main/java/org/apache/ignite/internal/schema/PartialBinaryTupleMatcher.java
+++ 
b/modules/schema/src/main/java/org/apache/ignite/internal/schema/PartialBinaryTupleMatcher.java
@@ -161,7 +161,7 @@ public class PartialBinaryTupleMatcher {
                 return compareAsUuid(partialTuple, tuple2, index);
 
             case STRING:
-                return compareAsString(partialTuple, tuple2, index, false);
+                return compareAsString(partialTuple, tuple2, index);
 
             case TIMESTAMP:
                 return compareAsTimestamp(partialTuple, tuple2, index);

Reply via email to