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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]