ibessonov commented on code in PR #5686:
URL: https://github.com/apache/ignite-3/pull/5686#discussion_r2071394218


##########
modules/storage-api/src/main/java/org/apache/ignite/internal/storage/util/StorageUtils.java:
##########
@@ -291,4 +292,19 @@ public static BinaryTupleComparator 
binaryTupleComparator(List<StorageSortedInde
 
         return new BinaryTupleComparator(columnCollation, columnTypes);
     }
+
+    /**
+     * Creates a comparator for a Sorted Index identified by the given columns 
descriptors.
+     */
+    public static PartialBinaryTupleComparator 
partialBinaryTupleComparator(List<StorageSortedIndexColumnDescriptor> columns) {
+        List<CatalogColumnCollation> columnCollation = new 
ArrayList<>(columns.size());
+        List<NativeType> columnTypes = new ArrayList<>(columns.size());
+
+        for (StorageSortedIndexColumnDescriptor col : columns) {
+            columnCollation.add(CatalogColumnCollation.get(col.asc(), 
!col.asc()));

Review Comment:
   Please add a comment that would explain why `nullsFirst` is `!col.asc()`, 
it's not really obvious



##########
modules/core/src/main/java/org/apache/ignite/internal/util/ByteUtils.java:
##########
@@ -412,4 +413,23 @@ public static UUID bytesToUuid(byte[] bytes, int offset) {
 
         return new UUID(higher, lower);
     }
+
+    /**
+     * Truncates a byte array to the size specified.
+     *
+     * @param bytes Origin byte array.
+     * @param maxLength Length of truncate.
+     * @return Truncated array.
+     */
+    public static byte @Nullable [] trimToSize(byte[] bytes, int maxLength) {
+        if (bytes == null) {
+            return null;
+        }
+
+        if (maxLength <= 0) {
+            return new byte[0];

Review Comment:
   ```suggestion
               return ArrayUtils.BYTE_EMPTY_ARRAY;
   ```



##########
modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleComparatorUtils.java:
##########
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.schema;
+
+import static java.lang.Integer.signum;
+import static 
org.apache.ignite.internal.binarytuple.BinaryTupleCommon.EQUALITY_FLAG;
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import org.apache.ignite.internal.binarytuple.BinaryTupleReader;
+import org.apache.ignite.internal.type.NativeTypeSpec;
+
+/**
+ * The utility class has methods to use to compare fields in binary 
representation.
+ */
+class BinaryTupleComparatorUtils {
+    /**
+     * Compares individual fields of two tuples using ascending order.
+     */
+    @SuppressWarnings("DataFlowIssue")
+    static int compareFieldValue(NativeTypeSpec typeSpec, BinaryTupleReader 
tuple1, int index1, BinaryTupleReader tuple2, int index2) {
+        switch (typeSpec) {
+            case INT8:
+            case BOOLEAN:
+                return Byte.compare(tuple1.byteValue(index1), 
tuple2.byteValue(index2));
+
+            case INT16:
+                return Short.compare(tuple1.shortValue(index1), 
tuple2.shortValue(index2));
+
+            case INT32:
+                return Integer.compare(tuple1.intValue(index1), 
tuple2.intValue(index2));
+
+            case INT64:
+                return Long.compare(tuple1.longValue(index1), 
tuple2.longValue(index2));
+
+            case FLOAT:
+                return Float.compare(tuple1.floatValue(index1), 
tuple2.floatValue(index2));
+
+            case DOUBLE:
+                return Double.compare(tuple1.doubleValue(index1), 
tuple2.doubleValue(index2));
+
+            case BYTES:
+                return Arrays.compareUnsigned(tuple1.bytesValue(index1), 
tuple2.bytesValue(index2));
+
+            case UUID:
+                return 
tuple1.uuidValue(index1).compareTo(tuple2.uuidValue(index2));
+
+            case STRING:
+                return 
tuple1.stringValue(index1).compareTo(tuple2.stringValue(index2));
+
+            case DECIMAL:
+                BigDecimal numeric1 = tuple1.decimalValue(index1, 
Integer.MIN_VALUE);
+                BigDecimal numeric2 = tuple2.decimalValue(index2, 
Integer.MIN_VALUE);
+
+                return numeric1.compareTo(numeric2);
+
+            case TIMESTAMP:
+                return 
tuple1.timestampValue(index1).compareTo(tuple2.timestampValue(index2));
+
+            case DATE:
+                return 
tuple1.dateValue(index1).compareTo(tuple2.dateValue(index2));
+
+            case TIME:
+                return 
tuple1.timeValue(index1).compareTo(tuple2.timeValue(index2));
+
+            case DATETIME:
+                return 
tuple1.dateTimeValue(index1).compareTo(tuple2.dateTimeValue(index2));
+
+            default:
+                throw new IllegalArgumentException(format("Unsupported column 
type in binary tuple comparator. [type={}]", typeSpec));
+        }
+    }
+
+    static boolean isFlagSet(ByteBuffer tuple, int flag) {
+        return (tuple.get(0) & flag) != 0;
+    }
+
+    static int equalityFlag(ByteBuffer tuple) {
+        return isFlagSet(tuple, EQUALITY_FLAG) ? 1 : -1;
+    }
+
+    /**
+     * Compares a value in a binary tuple, interpreted as a string, with a 
given string.
+     * The comparison can be performed as case-sensitive or case-insensitive.
+     * The method first attempts a fast comparison for ASCII sequences and 
falls back
+     * to Unicode comparison if non-ASCII characters are detected.
+     *
+     * @param tuple The BinaryTupleReader containing the tuple to be compared.
+     * @param colIndex The column index in the tuple to retrieve the value for 
comparison.
+     * @param cmp The string to compare the value in the tuple against.
+     * @param ignoreCase Flag indicating whether the comparison should ignore 
case differences.
+     * @return 0 if the strings are equal, a negative value if the tuple 
string is lexicographically
+     *         less than the given string, or a positive value if it is 
greater.
+     */
+    static int compareAsString(BinaryTupleReader tuple, int colIndex, String 
cmp, boolean ignoreCase) {
+        tuple.seek(colIndex);
+        int begin = tuple.begin();
+        int end = tuple.end();
+
+        ByteBuffer buf = tuple.byteBuffer();
+        int fullSrtLength = end - begin;
+        int trimmedSize = Math.min(fullSrtLength, buf.capacity() - begin);
+        byte[] bytes = new byte[trimmedSize];
+
+        buf.duplicate().position(begin).limit(begin + trimmedSize).get(bytes);
+
+        char[] cmpArray = cmp.toCharArray();

Review Comment:
   I'm not really convinced that we need to copy these arrays, especially in 
case of `cmpArray`. I presume that version without copying was slower, is that 
the case? Please add some small comment



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to