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 4dc19599ef9 IGNITE-26016 Prepare ByteBufferAccessor for external usage (#6313) 4dc19599ef9 is described below commit 4dc19599ef9967cbab4b209b1acb7dbd71f02291 Author: Ivan Bessonov <bessonov...@gmail.com> AuthorDate: Thu Jul 24 14:32:11 2025 +0300 IGNITE-26016 Prepare ByteBufferAccessor for external usage (#6313) --- .../internal/binarytuple/BinaryTupleParser.java | 42 ++++--- .../internal/binarytuple/BinaryTupleReader.java | 36 +++--- .../schema/BinaryTupleComparatorUtils.java | 124 +++++++++++++++++---- .../internal/schema/UnsafeByteBufferAccessor.java | 5 +- 4 files changed, 150 insertions(+), 57 deletions(-) diff --git a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java index 1f9645e228c..6382081ef8a 100644 --- a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java +++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java @@ -68,7 +68,7 @@ public class BinaryTupleParser { private final int valueBase; /** ByteBuffer accessor for reading data from the underlying buffer. */ - private final ByteBufferAccessor byteBufferAccessor; + protected final ByteBufferAccessor byteBufferAccessor; /** Reader for reading offsets from offset table in the buffer. */ private final OffsetTableReader offsetTableReader; @@ -242,11 +242,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final boolean booleanValue(int begin, int end) { + public static boolean booleanValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; if (len == Byte.BYTES) { @@ -259,11 +260,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final byte byteValue(int begin, int end) { + public static byte byteValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; switch (len) { case Byte.BYTES: @@ -276,11 +278,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final short shortValue(int begin, int end) { + public static short shortValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; switch (len) { case Byte.BYTES: @@ -295,11 +298,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final int intValue(int begin, int end) { + public static int intValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; switch (len) { case Byte.BYTES: @@ -316,11 +320,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final long longValue(int begin, int end) { + public static long longValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; switch (len) { case Byte.BYTES: @@ -339,11 +344,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final float floatValue(int begin, int end) { + public static float floatValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; switch (len) { case Float.BYTES: @@ -356,11 +362,12 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final double doubleValue(int begin, int end) { + public static double doubleValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; switch (len) { case Float.BYTES: @@ -487,46 +494,49 @@ public class BinaryTupleParser { /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final LocalDate dateValue(int begin, int end) { + public static LocalDate dateValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; if (len != 3) { throw new BinaryTupleFormatException("Invalid length for a tuple element: " + len); } - return getDate(begin); + return getDate(byteBufferAccessor, begin); } /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final LocalTime timeValue(int begin, int end) { + public static LocalTime timeValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; if (len < 4 || len > 6) { throw new BinaryTupleFormatException("Invalid length for a tuple element: " + len); } - return getTime(begin, len); + return getTime(byteBufferAccessor, begin, len); } /** * Reads value of specified element. * + * @param byteBufferAccessor Accessor for binary tuple bytes. * @param begin Start offset of the element. * @param end End offset of the element. * @return Element value. */ - public final LocalDateTime dateTimeValue(int begin, int end) { + public static LocalDateTime dateTimeValue(ByteBufferAccessor byteBufferAccessor, int begin, int end) { int len = end - begin; if (len < 7 || len > 9) { throw new BinaryTupleFormatException("Invalid length for a tuple element: " + len); } - return LocalDateTime.of(getDate(begin), getTime(begin + 3, len - 3)); + return LocalDateTime.of(getDate(byteBufferAccessor, begin), getTime(byteBufferAccessor, begin + 3, len - 3)); } /** @@ -616,7 +626,7 @@ public class BinaryTupleParser { /** * Decodes a Date element. */ - private LocalDate getDate(int offset) { + private static LocalDate getDate(ByteBufferAccessor byteBufferAccessor, int offset) { int date = Short.toUnsignedInt(byteBufferAccessor.getShort(offset)); date |= ((int) byteBufferAccessor.get(offset + 2)) << 16; @@ -630,7 +640,7 @@ public class BinaryTupleParser { /** * Decodes a Time element. */ - private LocalTime getTime(int offset, int length) { + private static LocalTime getTime(ByteBufferAccessor byteBufferAccessor, int offset, int length) { long time = Integer.toUnsignedLong(byteBufferAccessor.getInt(offset)); int nanos; diff --git a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java index eaaab4f60bd..49a9fbc6940 100644 --- a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java +++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java @@ -99,7 +99,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP public boolean booleanValue(int index) { seek(index); - return booleanValue(begin, end); + return booleanValue(byteBufferAccessor, begin, end); } /** @@ -115,7 +115,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP return null; } - return booleanValue(begin, end); + return booleanValue(byteBufferAccessor, begin, end); } /** @@ -126,7 +126,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public byte byteValue(int index) { seek(index); - return byteValue(begin, end); + return byteValue(byteBufferAccessor, begin, end); } /** @@ -137,7 +137,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable Byte byteValueBoxed(int index) { seek(index); - return begin == end ? null : byteValue(begin, end); + return begin == end ? null : byteValue(byteBufferAccessor, begin, end); } /** @@ -148,7 +148,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public short shortValue(int index) { seek(index); - return shortValue(begin, end); + return shortValue(byteBufferAccessor, begin, end); } /** @@ -159,7 +159,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable Short shortValueBoxed(int index) { seek(index); - return begin == end ? null : shortValue(begin, end); + return begin == end ? null : shortValue(byteBufferAccessor, begin, end); } /** @@ -170,7 +170,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public int intValue(int index) { seek(index); - return intValue(begin, end); + return intValue(byteBufferAccessor, begin, end); } /** @@ -181,7 +181,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable Integer intValueBoxed(int index) { seek(index); - return begin == end ? null : intValue(begin, end); + return begin == end ? null : intValue(byteBufferAccessor, begin, end); } /** @@ -192,7 +192,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public long longValue(int index) { seek(index); - return longValue(begin, end); + return longValue(byteBufferAccessor, begin, end); } /** @@ -203,7 +203,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable Long longValueBoxed(int index) { seek(index); - return begin == end ? null : longValue(begin, end); + return begin == end ? null : longValue(byteBufferAccessor, begin, end); } /** @@ -214,7 +214,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public float floatValue(int index) { seek(index); - return floatValue(begin, end); + return floatValue(byteBufferAccessor, begin, end); } /** @@ -225,7 +225,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable Float floatValueBoxed(int index) { seek(index); - return begin == end ? null : floatValue(begin, end); + return begin == end ? null : floatValue(byteBufferAccessor, begin, end); } /** @@ -236,7 +236,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public double doubleValue(int index) { seek(index); - return doubleValue(begin, end); + return doubleValue(byteBufferAccessor, begin, end); } /** @@ -247,7 +247,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable Double doubleValueBoxed(int index) { seek(index); - return begin == end ? null : doubleValue(begin, end); + return begin == end ? null : doubleValue(byteBufferAccessor, begin, end); } /** @@ -264,7 +264,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP return null; } - short valScale = shortValue(begin, begin + 2); + short valScale = shortValue(byteBufferAccessor, begin, begin + 2); BigDecimal decimalValue = new BigDecimal(numberValue(begin + 2, end), valScale); @@ -323,7 +323,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable LocalDate dateValue(int index) { seek(index); - return begin == end ? null : dateValue(begin, end); + return begin == end ? null : dateValue(byteBufferAccessor, begin, end); } /** @@ -334,7 +334,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable LocalTime timeValue(int index) { seek(index); - return begin == end ? null : timeValue(begin, end); + return begin == end ? null : timeValue(byteBufferAccessor, begin, end); } /** @@ -345,7 +345,7 @@ public class BinaryTupleReader extends BinaryTupleParser implements BinaryTupleP */ public @Nullable LocalDateTime dateTimeValue(int index) { seek(index); - return begin == end ? null : dateTimeValue(begin, end); + return begin == end ? null : dateTimeValue(byteBufferAccessor, begin, end); } /** 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 53e0a0eb6a6..8643c350b9d 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 @@ -31,7 +31,7 @@ import org.apache.ignite.sql.ColumnType; /** * The utility class has methods to use to compare fields in binary representation. */ -class BinaryTupleComparatorUtils { +public class BinaryTupleComparatorUtils { /** * Compares individual fields of two tuples using ascending order. */ @@ -118,14 +118,31 @@ class BinaryTupleComparatorUtils { tuple1.seek(colIndex); int begin1 = tuple1.begin(); int end1 = tuple1.end(); - ByteBufferAccessor buf1 = tuple1.accessor(); - int fullSize1 = end1 - begin1; - int trimmedSize1 = Math.min(fullSize1, buf1.capacity() - begin1); tuple2.seek(colIndex); int begin2 = tuple2.begin(); int end2 = tuple2.end(); - ByteBufferAccessor buf2 = tuple2.accessor(); + + return compareAsTimestamp(tuple1.accessor(), begin1, end1, tuple2.accessor(), begin2, end2); + } + + /** + * Compares timestamp values of two binary tuples. + * + * @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 #compareAsTimestamp(BinaryTupleReader, BinaryTupleReader, int) + */ + public static int compareAsTimestamp(ByteBufferAccessor buf1, int begin1, int end1, ByteBufferAccessor buf2, int begin2, int end2) { + int fullSize1 = end1 - begin1; + int trimmedSize1 = Math.min(fullSize1, buf1.capacity() - begin1); + int fullSize2 = end2 - begin2; int trimmedSize2 = Math.min(fullSize2, buf2.capacity() - begin2); @@ -175,12 +192,27 @@ class BinaryTupleComparatorUtils { static int compareAsUuid(BinaryTupleReader tuple1, BinaryTupleReader tuple2, int colIndex) { tuple1.seek(colIndex); int begin1 = tuple1.begin(); - ByteBufferAccessor buf1 = tuple1.accessor(); - int trimmedSize1 = Math.min(16, buf1.capacity() - begin1); tuple2.seek(colIndex); int begin2 = tuple2.begin(); - ByteBufferAccessor buf2 = tuple2.accessor(); + + return compareAsUuid(tuple1.accessor(), begin1, tuple2.accessor(), begin2); + } + + /** + * Compares UUID values of two binary tuples. + * + * @param buf1 Buffer accessor for the first tuple. + * @param begin1 Begin position in the first tuple. + * @param buf2 Buffer accessor for the second tuple. + * @param begin2 Begin position in the second tuple. + * @return Comparison result. + * + * @see #compareAsUuid(BinaryTupleReader, BinaryTupleReader, int) + */ + public static int compareAsUuid(ByteBufferAccessor buf1, int begin1, ByteBufferAccessor buf2, int begin2) { + int trimmedSize1 = Math.min(16, buf1.capacity() - begin1); + int trimmedSize2 = Math.min(16, buf2.capacity() - begin2); int remaining = Math.min(trimmedSize1, trimmedSize2); @@ -221,8 +253,27 @@ class BinaryTupleComparatorUtils { int begin1 = tuple1.begin(); int end1 = tuple1.end(); - ByteBufferAccessor buf1 = tuple1.accessor(); + tuple2.seek(colIndex); + int begin2 = tuple2.begin(); + int end2 = tuple2.end(); + return compareAsBytes(tuple1.accessor(), begin1, end1, tuple2.accessor(), begin2, end2); + } + + /** + * Compares {@code byte[]} values of two binary tuples. + * + * @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 #compareAsBytes(BinaryTupleReader, BinaryTupleReader, int) + */ + public static int compareAsBytes(ByteBufferAccessor buf1, int begin1, int end1, ByteBufferAccessor buf2, int begin2, int end2) { if (buf1.get(begin1) == BinaryTupleCommon.VARLEN_EMPTY_BYTE) { begin1++; } @@ -230,12 +281,6 @@ class BinaryTupleComparatorUtils { int fullSize1 = end1 - begin1; int trimmedSize1 = Math.min(fullSize1, buf1.capacity() - begin1); - tuple2.seek(colIndex); - int begin2 = tuple2.begin(); - int end2 = tuple2.end(); - - ByteBufferAccessor buf2 = tuple2.accessor(); - if (buf2.get(begin2) == BinaryTupleCommon.VARLEN_EMPTY_BYTE) { begin2++; } @@ -293,8 +338,32 @@ class BinaryTupleComparatorUtils { int begin1 = tuple1.begin(); int end1 = tuple1.end(); - ByteBufferAccessor buf1 = tuple1.accessor(); + tuple2.seek(colIndex); + int begin2 = tuple2.begin(); + int end2 = tuple2.end(); + + return compareAsString(tuple1.accessor(), begin1, end1, tuple2.accessor(), begin2, end2, ignoreCase); + } + /** + * Compares string values of two binary tuples. + * + * @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. + * @param ignoreCase Case sensitivity flag. + * @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, + boolean ignoreCase + ) { if (buf1.get(begin1) == BinaryTupleCommon.VARLEN_EMPTY_BYTE) { begin1++; } @@ -302,12 +371,6 @@ class BinaryTupleComparatorUtils { int fullStrLength1 = end1 - begin1; int trimmedSize1 = Math.min(fullStrLength1, buf1.capacity() - begin1); - tuple2.seek(colIndex); - int begin2 = tuple2.begin(); - int end2 = tuple2.end(); - - ByteBufferAccessor buf2 = tuple2.accessor(); - if (buf2.get(begin2) == BinaryTupleCommon.VARLEN_EMPTY_BYTE) { begin2++; } @@ -346,6 +409,23 @@ class BinaryTupleComparatorUtils { ); } + /** + * 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. diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/UnsafeByteBufferAccessor.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/UnsafeByteBufferAccessor.java index 7ab83fcc6d3..5527bef58c5 100644 --- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/UnsafeByteBufferAccessor.java +++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/UnsafeByteBufferAccessor.java @@ -29,7 +29,7 @@ import org.apache.ignite.internal.util.GridUnsafe; * This class supports reading various primitive types (e.g., `byte`, `int`, `long`, etc.) * and handles byte order differences between the buffer and the native system. */ -class UnsafeByteBufferAccessor implements ByteBufferAccessor { +public class UnsafeByteBufferAccessor implements ByteBufferAccessor { /** Whether the byte order of the underlying buffer is reversed compared to the native byte order. */ private static final boolean REVERSE_BYTE_ORDER = GridUnsafe.NATIVE_BYTE_ORDER != BinaryTupleParser.ORDER; @@ -37,6 +37,9 @@ class UnsafeByteBufferAccessor implements ByteBufferAccessor { private final long addr; private final int capacity; + /** + * Constructor that initializes the accessor with a {@link ByteBuffer}. + */ public UnsafeByteBufferAccessor(ByteBuffer buff) { if (buff.isDirect()) { bytes = null;