You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2022/08/29 12:30:18 UTC
[ignite-3] branch main updated: IGNITE-17583 Extract BinaryTuple core parts into a separate module (#1040)
This is an automated email from the ASF dual-hosted git repository.
ptupitsyn 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 0dc1b58525 IGNITE-17583 Extract BinaryTuple core parts into a separate module (#1040)
0dc1b58525 is described below
commit 0dc1b5852531c2e7f06dc1091c21b94c454fedd3
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Mon Aug 29 15:30:12 2022 +0300
IGNITE-17583 Extract BinaryTuple core parts into a separate module (#1040)
Decouple `BinaryTupleParser`, `BinaryTupleBuilder`, `BinaryTupleReader` from internal schema functionality (`NativeTypeSpec`, etc), move to `ignite-binary-tuple` module. Allows reuse from client side.
---
modules/binary-tuple/README.md | 3 +
modules/{schema => binary-tuple}/pom.xml | 86 +-----------
.../internal/binarytuple}/BinaryTupleBuilder.java | 148 ++++-----------------
.../internal/binarytuple/BinaryTupleCommon.java | 113 ++++++++++++++++
.../binarytuple}/BinaryTupleFormatException.java | 13 +-
.../internal/binarytuple}/BinaryTupleParser.java | 67 +++++-----
.../internal/binarytuple}/BinaryTupleReader.java | 2 +-
.../internal/binarytuple}/BinaryTupleTest.java | 6 +-
modules/schema/pom.xml | 5 +
.../ignite/internal/schema/BinaryConverter.java | 6 +-
.../apache/ignite/internal/schema/BinaryTuple.java | 1 +
.../ignite/internal/schema/BinaryTupleSchema.java | 117 ++++------------
.../storage/AbstractMvTableStorageTest.java | 4 +-
.../index/impl/BinaryTupleRowSerializer.java | 75 ++++++++++-
parent/pom.xml | 12 +-
pom.xml | 1 +
16 files changed, 315 insertions(+), 344 deletions(-)
diff --git a/modules/binary-tuple/README.md b/modules/binary-tuple/README.md
new file mode 100644
index 0000000000..95980fa3ff
--- /dev/null
+++ b/modules/binary-tuple/README.md
@@ -0,0 +1,3 @@
+# Binary Tuple module
+
+Core binary tuple functionality. See [IEP-92: Binary Tuple Format](https://cwiki.apache.org/confluence/display/IGNITE/IEP-92%3A+Binary+Tuple+Format).
diff --git a/modules/schema/pom.xml b/modules/binary-tuple/pom.xml
similarity index 53%
copy from modules/schema/pom.xml
copy to modules/binary-tuple/pom.xml
index b256cb19fc..98effa4a21 100644
--- a/modules/schema/pom.xml
+++ b/modules/binary-tuple/pom.xml
@@ -29,35 +29,15 @@
<relativePath>../../parent/pom.xml</relativePath>
</parent>
- <artifactId>ignite-schema</artifactId>
+ <artifactId>ignite-binary-tuple</artifactId>
<version>3.0.0-SNAPSHOT</version>
<dependencies>
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-bytecode</artifactId>
- </dependency>
-
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-core</artifactId>
</dependency>
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-configuration</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-extended-api</artifactId>
- </dependency>
-
<!-- 3rd party dependencies -->
<dependency>
<groupId>org.jetbrains</groupId>
@@ -65,78 +45,15 @@
</dependency>
<!-- Test dependencies -->
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-configuration</artifactId>
- <scope>test</scope>
- <type>test-jar</type>
- </dependency>
-
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-core</artifactId>
- <scope>test</scope>
- <type>test-jar</type>
- </dependency>
-
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
-
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-params</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>com.github.npathai</groupId>
- <artifactId>hamcrest-optional</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <scope>test</scope>
- </dependency>
-
- <!-- Benchmarks dependencies -->
- <dependency>
- <groupId>org.openjdk.jmh</groupId>
- <artifactId>jmh-core</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>javax.annotation</groupId>
- <artifactId>javax.annotation-api</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
<plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <executions>
- <execution>
- <id>default-testJar</id>
- <goals>
- <goal>test-jar</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
@@ -159,4 +76,5 @@
</plugin>
</plugins>
</build>
+
</project>
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleBuilder.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java
similarity index 82%
rename from modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleBuilder.java
rename to modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java
index 97e4fc6749..60825b3aad 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleBuilder.java
+++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleBuilder.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.schema;
+package org.apache.ignite.internal.binarytuple;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -75,9 +75,9 @@ public class BinaryTupleBuilder {
private BinaryTupleBuilder(int numElements, boolean allowNulls, int totalValueSize) {
this.numElements = numElements;
- int base = BinaryTupleSchema.HEADER_SIZE;
+ int base = BinaryTupleCommon.HEADER_SIZE;
if (allowNulls) {
- base += BinaryTupleSchema.nullMapSize(numElements);
+ base += BinaryTupleCommon.nullMapSize(numElements);
}
entryBase = base;
@@ -85,7 +85,7 @@ public class BinaryTupleBuilder {
if (totalValueSize < 0) {
entrySize = Integer.BYTES;
} else {
- entrySize = BinaryTupleSchema.flagsToEntrySize(BinaryTupleSchema.valueSizeToFlags(totalValueSize));
+ entrySize = BinaryTupleCommon.flagsToEntrySize(BinaryTupleCommon.valueSizeToFlags(totalValueSize));
}
valueBase = base + entrySize * numElements;
@@ -93,27 +93,6 @@ public class BinaryTupleBuilder {
allocate(totalValueSize);
}
- /**
- * Creates a builder.
- *
- * @param schema Tuple schema.
- * @return Tuple builder.
- */
- public static BinaryTupleBuilder create(BinaryTupleSchema schema) {
- return create(schema.elementCount(), schema.hasNullableElements());
- }
-
- /**
- * Creates a builder.
- *
- * @param schema Tuple schema.
- * @param allowNulls True if NULL values are possible, false otherwise.
- * @return Tuple builder.
- */
- public static BinaryTupleBuilder create(BinaryTupleSchema schema, boolean allowNulls) {
- return create(schema.elementCount(), schema.hasNullableElements() && allowNulls);
- }
-
/**
* Creates a builder.
*
@@ -125,29 +104,6 @@ public class BinaryTupleBuilder {
return create(numElements, allowNulls, -1);
}
- /**
- * Creates a builder.
- *
- * @param schema Tuple schema.
- * @param totalValueSize Total estimated length of non-NULL values, -1 if not known.
- * @return Tuple builder.
- */
- public static BinaryTupleBuilder create(BinaryTupleSchema schema, int totalValueSize) {
- return create(schema.elementCount(), schema.hasNullableElements(), totalValueSize);
- }
-
- /**
- * Creates a builder.
- *
- * @param schema Tuple schema.
- * @param allowNulls True if NULL values are possible, false otherwise.
- * @param totalValueSize Total estimated length of non-NULL values, -1 if not known.
- * @return Tuple builder.
- */
- public static BinaryTupleBuilder create(BinaryTupleSchema schema, boolean allowNulls, int totalValueSize) {
- return create(schema.elementCount(), schema.hasNullableElements() && allowNulls, totalValueSize);
- }
-
/**
* Creates a builder.
*
@@ -164,7 +120,7 @@ public class BinaryTupleBuilder {
* Check if the binary tuple contains a null map.
*/
public boolean hasNullMap() {
- return entryBase > BinaryTupleSchema.HEADER_SIZE;
+ return entryBase > BinaryTupleCommon.HEADER_SIZE;
}
/**
@@ -179,8 +135,8 @@ public class BinaryTupleBuilder {
hasNullValues = true;
- int nullIndex = BinaryTupleSchema.nullOffset(elementIndex);
- byte nullMask = BinaryTupleSchema.nullMask(elementIndex);
+ int nullIndex = BinaryTupleCommon.nullOffset(elementIndex);
+ byte nullMask = BinaryTupleCommon.nullMask(elementIndex);
buffer.put(nullIndex, (byte) (buffer.get(nullIndex) | nullMask));
return proceed();
@@ -388,7 +344,7 @@ public class BinaryTupleBuilder {
try {
putString(value);
} catch (CharacterCodingException e) {
- throw new AssemblyException("Failed to encode string in binary tuple builder", e);
+ throw new BinaryTupleFormatException("Failed to encode string in binary tuple builder", e);
}
return proceed();
}
@@ -478,7 +434,7 @@ public class BinaryTupleBuilder {
* @return {@code this} for chaining.
*/
public BinaryTupleBuilder appendDateNotNull(@NotNull LocalDate value) {
- if (value != BinaryTupleSchema.DEFAULT_DATE) {
+ if (value != BinaryTupleCommon.DEFAULT_DATE) {
putDate(value);
}
return proceed();
@@ -501,7 +457,7 @@ public class BinaryTupleBuilder {
* @return {@code this} for chaining.
*/
public BinaryTupleBuilder appendTimeNotNull(@NotNull LocalTime value) {
- if (value != BinaryTupleSchema.DEFAULT_TIME) {
+ if (value != BinaryTupleCommon.DEFAULT_TIME) {
putTime(value);
}
return proceed();
@@ -524,7 +480,7 @@ public class BinaryTupleBuilder {
* @return {@code this} for chaining.
*/
public BinaryTupleBuilder appendDateTimeNotNull(@NotNull LocalDateTime value) {
- if (value != BinaryTupleSchema.DEFAULT_DATE_TIME) {
+ if (value != BinaryTupleCommon.DEFAULT_DATE_TIME) {
putDate(value.toLocalDate());
putTime(value.toLocalTime());
}
@@ -548,7 +504,7 @@ public class BinaryTupleBuilder {
* @return {@code this} for chaining.
*/
public BinaryTupleBuilder appendTimestampNotNull(@NotNull Instant value) {
- if (value != BinaryTupleSchema.DEFAULT_TIMESTAMP) {
+ if (value != BinaryTupleCommon.DEFAULT_TIMESTAMP) {
long seconds = value.getEpochSecond();
int nanos = value.getNano();
putLong(seconds);
@@ -569,63 +525,6 @@ public class BinaryTupleBuilder {
return value == null ? appendNull() : appendTimestampNotNull(value);
}
- /**
- * Append a value for the current element.
- *
- * @param schema Tuple schema.
- * @param value Element value.
- * @return {@code this} for chaining.
- */
- public BinaryTupleBuilder appendValue(BinaryTupleSchema schema, Object value) {
- BinaryTupleSchema.Element element = schema.element(elementIndex);
-
- if (value == null) {
- if (!element.nullable) {
- throw new SchemaMismatchException("NULL value for non-nullable column in binary tuple builder.");
- }
- return appendNull();
- }
-
- switch (element.typeSpec) {
- case INT8:
- return appendByte((byte) value);
- case INT16:
- return appendShort((short) value);
- case INT32:
- return appendInt((int) value);
- case INT64:
- return appendLong((long) value);
- case FLOAT:
- return appendFloat((float) value);
- case DOUBLE:
- return appendDouble((double) value);
- case NUMBER:
- return appendNumberNotNull((BigInteger) value);
- case DECIMAL:
- return appendDecimalNotNull((BigDecimal) value);
- case UUID:
- return appendUuidNotNull((UUID) value);
- case BYTES:
- return appendBytesNotNull((byte[]) value);
- case STRING:
- return appendStringNotNull((String) value);
- case BITMASK:
- return appendBitmaskNotNull((BitSet) value);
- case DATE:
- return appendDateNotNull((LocalDate) value);
- case TIME:
- return appendTimeNotNull((LocalTime) value);
- case DATETIME:
- return appendDateTimeNotNull((LocalDateTime) value);
- case TIMESTAMP:
- return appendTimestampNotNull((Instant) value);
- default:
- break;
- }
-
- throw new InvalidTypeException("Unexpected type value: " + element.typeSpec);
- }
-
/**
* Append some arbitrary content as the current element.
*
@@ -650,6 +549,15 @@ public class BinaryTupleBuilder {
return proceed();
}
+ /**
+ * Gets the current element index.
+ *
+ * @return Element index.
+ */
+ public int elementIndex() {
+ return elementIndex;
+ }
+
/**
* Finalize tuple building.
*
@@ -661,8 +569,8 @@ public class BinaryTupleBuilder {
int offset = 0;
int valueSize = buffer.position() - valueBase;
- byte flags = BinaryTupleSchema.valueSizeToFlags(valueSize);
- int desiredEntrySize = BinaryTupleSchema.flagsToEntrySize(flags);
+ byte flags = BinaryTupleCommon.valueSizeToFlags(valueSize);
+ int desiredEntrySize = BinaryTupleCommon.flagsToEntrySize(flags);
// Shrink the offset table if needed.
if (desiredEntrySize != entrySize) {
@@ -698,12 +606,12 @@ public class BinaryTupleBuilder {
// Drop or move null map if needed.
if (hasNullMap()) {
if (!hasNullValues) {
- offset += BinaryTupleSchema.nullMapSize(numElements);
+ offset += BinaryTupleCommon.nullMapSize(numElements);
} else {
- flags |= BinaryTupleSchema.NULLMAP_FLAG;
+ flags |= BinaryTupleCommon.NULLMAP_FLAG;
if (offset != 0) {
- int n = BinaryTupleSchema.nullMapSize(numElements);
- for (int i = BinaryTupleSchema.HEADER_SIZE + n - 1; i >= BinaryTupleSchema.HEADER_SIZE; i--) {
+ int n = BinaryTupleCommon.nullMapSize(numElements);
+ for (int i = BinaryTupleCommon.HEADER_SIZE + n - 1; i >= BinaryTupleCommon.HEADER_SIZE; i--) {
buffer.put(i + offset, buffer.get(i));
}
}
@@ -878,7 +786,7 @@ public class BinaryTupleBuilder {
do {
capacity *= 2;
if (capacity < 0) {
- throw new AssemblyException("Buffer overflow in binary tuple builder");
+ throw new BinaryTupleFormatException("Buffer overflow in binary tuple builder");
}
} while ((capacity - buffer.position()) < size);
diff --git a/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleCommon.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleCommon.java
new file mode 100644
index 0000000000..bb5ec098fe
--- /dev/null
+++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleCommon.java
@@ -0,0 +1,113 @@
+/*
+ * 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.binarytuple;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteInternalException;
+
+/**
+ * Common binary tuple constants and utils.
+ */
+public class BinaryTupleCommon {
+ /** Size of a tuple header, in bytes. */
+ public static final int HEADER_SIZE = 1;
+
+ /** Mask for size of entries in variable-length offset table. */
+ public static final int VARSIZE_MASK = 0b011;
+
+ /** Flag that indicates null map presence. */
+ public static final int NULLMAP_FLAG = 0b100;
+
+ /** Default value for UUID elements. */
+ public static final UUID DEFAULT_UUID = new UUID(0, 0);
+
+ /** Default value for Date elements (Jan 1st 1 BC). */
+ public static final LocalDate DEFAULT_DATE = LocalDate.of(0, 1, 1);
+
+ /** Default value for Time elements (00:00:00). */
+ public static final LocalTime DEFAULT_TIME = LocalTime.of(0, 0);
+
+ /** Default value for DateTime elements (Jan 1st 1 BC, 00:00:00). */
+ public static final LocalDateTime DEFAULT_DATE_TIME = LocalDateTime.of(0, 1, 1, 0, 0);
+
+ /** Default value for Timestamp elements. */
+ public static final Instant DEFAULT_TIMESTAMP = Instant.EPOCH;
+
+ /**
+ * Calculates flags for a given size of variable-length area.
+ *
+ * @param size Variable-length area size.
+ * @return Flags value.
+ */
+ public static byte valueSizeToFlags(long size) {
+ if (size <= 0xff) {
+ return 0b00;
+ }
+ if (size <= 0xffff) {
+ return 0b01;
+ }
+ if (size <= Integer.MAX_VALUE) {
+ return 0b10;
+ }
+ throw new IgniteInternalException("Too big binary tuple size");
+ }
+
+ /**
+ * Calculates the size of entry in variable-length offset table for given flags.
+ *
+ * @param flags Flags value.
+ * @return Size of entry in variable-length offset table.
+ */
+ public static int flagsToEntrySize(byte flags) {
+ return 1 << (flags & VARSIZE_MASK);
+ }
+
+ /**
+ * Calculates the null map size.
+ *
+ * @param numElements Number of tuple elements.
+ * @return Null map size in bytes.
+ */
+ public static int nullMapSize(int numElements) {
+ return (numElements + 7) / 8;
+ }
+
+ /**
+ * Returns offset of the byte that contains null-bit of a given tuple element.
+ *
+ * @param index Tuple element index.
+ * @return Offset of the required byte relative to the tuple start.
+ */
+ public static int nullOffset(int index) {
+ return HEADER_SIZE + index / 8;
+ }
+
+ /**
+ * Returns a null-bit mask corresponding to a given tuple element.
+ *
+ * @param index Tuple element index.
+ * @return Mask to extract the required null-bit.
+ */
+ public static byte nullMask(int index) {
+ return (byte) (1 << (index % 8));
+ }
+}
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleFormatException.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleFormatException.java
similarity index 82%
rename from modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleFormatException.java
rename to modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleFormatException.java
index 51525ce0f0..f1ac0f0a71 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleFormatException.java
+++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleFormatException.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.schema;
+package org.apache.ignite.internal.binarytuple;
import org.apache.ignite.lang.IgniteInternalException;
@@ -24,11 +24,20 @@ import org.apache.ignite.lang.IgniteInternalException;
*/
public class BinaryTupleFormatException extends IgniteInternalException {
/**
- * Constructor with error message.
+ * Constructor.
*
* @param msg Message.
*/
public BinaryTupleFormatException(String msg) {
super(msg);
}
+
+ /**
+ * Constructor.
+ *
+ * @param msg Message.
+ */
+ public BinaryTupleFormatException(String msg, Throwable cause) {
+ super(msg, cause);
+ }
}
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleParser.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java
similarity index 88%
rename from modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleParser.java
rename to modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java
index 7539ed998a..0ace31f197 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleParser.java
+++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleParser.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.schema;
+package org.apache.ignite.internal.binarytuple;
import java.math.BigInteger;
import java.nio.ByteBuffer;
@@ -46,6 +46,9 @@ public class BinaryTupleParser {
void nextElement(int index, int begin, int end);
}
+ /** UUID size in bytes. */
+ private static final int UUID_SIZE = 16;
+
/** Number of elements in the tuple. */
private final int numElements;
@@ -67,7 +70,7 @@ public class BinaryTupleParser {
* @param numElements Number of tuple elements.
* @param buffer Buffer with a binary tuple.
*/
- BinaryTupleParser(int numElements, ByteBuffer buffer) {
+ public BinaryTupleParser(int numElements, ByteBuffer buffer) {
this.numElements = numElements;
assert buffer.order() == ByteOrder.LITTLE_ENDIAN;
@@ -76,13 +79,13 @@ public class BinaryTupleParser {
byte flags = buffer.get(0);
- int base = BinaryTupleSchema.HEADER_SIZE;
- if ((flags & BinaryTupleSchema.NULLMAP_FLAG) != 0) {
- base += BinaryTupleSchema.nullMapSize(numElements);
+ int base = BinaryTupleCommon.HEADER_SIZE;
+ if ((flags & BinaryTupleCommon.NULLMAP_FLAG) != 0) {
+ base += BinaryTupleCommon.nullMapSize(numElements);
}
entryBase = base;
- entrySize = 1 << (flags & BinaryTupleSchema.VARSIZE_MASK);
+ entrySize = 1 << (flags & BinaryTupleCommon.VARSIZE_MASK);
valueBase = base + entrySize * numElements;
}
@@ -104,7 +107,7 @@ public class BinaryTupleParser {
* Check if the binary tuple contains a null map.
*/
public boolean hasNullMap() {
- return entryBase > BinaryTupleSchema.HEADER_SIZE;
+ return entryBase > BinaryTupleCommon.HEADER_SIZE;
}
/**
@@ -137,8 +140,8 @@ public class BinaryTupleParser {
}
if (offset == nextOffset && hasNullMap()) {
- int nullIndex = BinaryTupleSchema.nullOffset(index);
- byte nullMask = BinaryTupleSchema.nullMask(index);
+ int nullIndex = BinaryTupleCommon.nullOffset(index);
+ byte nullMask = BinaryTupleCommon.nullMask(index);
if ((buffer.get(nullIndex) & nullMask) != 0) {
sink.nextElement(index, 0, 0);
return;
@@ -164,8 +167,8 @@ public class BinaryTupleParser {
}
if (offset == nextOffset && hasNullMap()) {
- int nullIndex = BinaryTupleSchema.nullOffset(i);
- byte nullMask = BinaryTupleSchema.nullMask(i);
+ int nullIndex = BinaryTupleCommon.nullOffset(i);
+ byte nullMask = BinaryTupleCommon.nullMask(i);
if ((buffer.get(nullIndex) & nullMask) != 0) {
sink.nextElement(i, 0, 0);
entry += entrySize;
@@ -186,7 +189,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final byte byteValue(int begin, int end) {
+ public final byte byteValue(int begin, int end) {
switch (end - begin) {
case 0:
return 0;
@@ -204,7 +207,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final short shortValue(int begin, int end) {
+ public final short shortValue(int begin, int end) {
switch (end - begin) {
case 0:
return 0;
@@ -224,7 +227,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final int intValue(int begin, int end) {
+ public final int intValue(int begin, int end) {
switch (end - begin) {
case 0:
return 0;
@@ -246,7 +249,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final long longValue(int begin, int end) {
+ public final long longValue(int begin, int end) {
switch (end - begin) {
case 0:
return 0;
@@ -270,7 +273,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final float floatValue(int begin, int end) {
+ public final float floatValue(int begin, int end) {
switch (end - begin) {
case 0:
return 0.0F;
@@ -288,7 +291,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final double doubleValue(int begin, int end) {
+ public final double doubleValue(int begin, int end) {
switch (end - begin) {
case 0:
return 0.0;
@@ -308,7 +311,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final BigInteger numberValue(int begin, int end) {
+ public final BigInteger numberValue(int begin, int end) {
byte[] bytes;
int len = end - begin;
if (buffer.hasArray()) {
@@ -328,7 +331,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final String stringValue(int begin, int end) {
+ public final String stringValue(int begin, int end) {
byte[] bytes;
int len = end - begin;
if (buffer.hasArray()) {
@@ -348,7 +351,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final byte[] bytesValue(int begin, int end) {
+ public final byte[] bytesValue(int begin, int end) {
byte[] bytes = new byte[end - begin];
buffer.duplicate().position(begin).limit(end).get(bytes);
return bytes;
@@ -361,11 +364,11 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final UUID uuidValue(int begin, int end) {
+ public final UUID uuidValue(int begin, int end) {
int len = end - begin;
- if (len != NativeTypes.UUID.sizeInBytes()) {
+ if (len != UUID_SIZE) {
if (len == 0) {
- return BinaryTupleSchema.DEFAULT_UUID;
+ return BinaryTupleCommon.DEFAULT_UUID;
}
throw new BinaryTupleFormatException("Invalid length for a tuple element");
}
@@ -381,7 +384,7 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final BitSet bitmaskValue(int begin, int end) {
+ public final BitSet bitmaskValue(int begin, int end) {
return BitSet.valueOf(buffer.duplicate().position(begin).limit(end));
}
@@ -392,11 +395,11 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final LocalDate dateValue(int begin, int end) {
+ public final LocalDate dateValue(int begin, int end) {
int len = end - begin;
if (len != 3) {
if (len == 0) {
- return BinaryTupleSchema.DEFAULT_DATE;
+ return BinaryTupleCommon.DEFAULT_DATE;
}
throw new BinaryTupleFormatException("Invalid length for a tuple element");
}
@@ -410,11 +413,11 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final LocalTime timeValue(int begin, int end) {
+ public final LocalTime timeValue(int begin, int end) {
int len = end - begin;
if (len < 4 || len > 6) {
if (len == 0) {
- return BinaryTupleSchema.DEFAULT_TIME;
+ return BinaryTupleCommon.DEFAULT_TIME;
}
throw new BinaryTupleFormatException("Invalid length for a tuple element");
}
@@ -428,11 +431,11 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final LocalDateTime dateTimeValue(int begin, int end) {
+ public final LocalDateTime dateTimeValue(int begin, int end) {
int len = end - begin;
if (len < 7 || len > 9) {
if (len == 0) {
- return BinaryTupleSchema.DEFAULT_DATE_TIME;
+ return BinaryTupleCommon.DEFAULT_DATE_TIME;
}
throw new BinaryTupleFormatException("Invalid length for a tuple element");
}
@@ -446,11 +449,11 @@ public class BinaryTupleParser {
* @param end End offset of the element.
* @return Element value.
*/
- final Instant timestampValue(int begin, int end) {
+ public final Instant timestampValue(int begin, int end) {
int len = end - begin;
if (len != 8 && len != 12) {
if (len == 0) {
- return BinaryTupleSchema.DEFAULT_TIMESTAMP;
+ return BinaryTupleCommon.DEFAULT_TIMESTAMP;
}
throw new BinaryTupleFormatException("Invalid length for a tuple element");
}
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleReader.java b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java
similarity index 99%
rename from modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleReader.java
rename to modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java
index cad39739ca..0b30537b03 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleReader.java
+++ b/modules/binary-tuple/src/main/java/org/apache/ignite/internal/binarytuple/BinaryTupleReader.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.schema;
+package org.apache.ignite.internal.binarytuple;
import java.math.BigDecimal;
import java.math.BigInteger;
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/BinaryTupleTest.java b/modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java
similarity index 99%
rename from modules/schema/src/test/java/org/apache/ignite/internal/schema/BinaryTupleTest.java
rename to modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java
index 412d191082..76cca3ddf1 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/BinaryTupleTest.java
+++ b/modules/binary-tuple/src/test/java/org/apache/ignite/internal/binarytuple/BinaryTupleTest.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.schema;
+package org.apache.ignite.internal.binarytuple;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -49,7 +49,7 @@ public class BinaryTupleTest {
// Header: 1 byte with null map flag.
// NullMap: 1 byte with first bit set.
// Offset table: 1 zero byte
- byte[] bytes = { BinaryTupleSchema.NULLMAP_FLAG, 1, 0 };
+ byte[] bytes = { BinaryTupleCommon.NULLMAP_FLAG, 1, 0 };
var reader = new BinaryTupleReader(1, bytes);
assertEquals(bytes.length, reader.size());
@@ -87,7 +87,7 @@ public class BinaryTupleTest {
// Header: 1 byte with null map flag.
// NullMap: 1 byte with no bit set.
// Offset table: 1 zero byte
- byte[] bytes2 = { BinaryTupleSchema.NULLMAP_FLAG, 0, 0 };
+ byte[] bytes2 = { BinaryTupleCommon.NULLMAP_FLAG, 0, 0 };
byte[][] bytesArray = { bytes1, bytes2 };
diff --git a/modules/schema/pom.xml b/modules/schema/pom.xml
index b256cb19fc..616b56fc17 100644
--- a/modules/schema/pom.xml
+++ b/modules/schema/pom.xml
@@ -58,6 +58,11 @@
<artifactId>ignite-extended-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-binary-tuple</artifactId>
+ </dependency>
+
<!-- 3rd party dependencies -->
<dependency>
<groupId>org.jetbrains</groupId>
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java
index 71bd1123a6..60907b0008 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryConverter.java
@@ -20,6 +20,8 @@ package org.apache.ignite.internal.schema;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import org.apache.ignite.internal.binarytuple.BinaryTupleBuilder;
+import org.apache.ignite.internal.binarytuple.BinaryTupleParser;
import org.apache.ignite.internal.schema.row.Row;
import org.apache.ignite.internal.schema.row.RowAssembler;
import org.jetbrains.annotations.Nullable;
@@ -116,7 +118,9 @@ public class BinaryConverter {
}
// Now compose the tuple.
- BinaryTupleBuilder builder = BinaryTupleBuilder.create(tupleSchema, hasNulls, estimatedValueSize);
+ BinaryTupleBuilder builder = BinaryTupleBuilder.create(
+ tupleSchema.elementCount(), hasNulls, estimatedValueSize);
+
for (int elementIndex = 0; elementIndex < tupleSchema.elementCount(); elementIndex++) {
BinaryTupleSchema.Element elt = tupleSchema.element(elementIndex);
NativeTypeSpec typeSpec = elt.typeSpec;
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTuple.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTuple.java
index 765a0de3ca..db71a86a36 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTuple.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTuple.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.schema;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
+import org.apache.ignite.internal.binarytuple.BinaryTupleReader;
import org.apache.ignite.internal.schema.row.InternalTuple;
/**
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleSchema.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleSchema.java
index 6947a274c7..8f1b315c5b 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleSchema.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/BinaryTupleSchema.java
@@ -17,41 +17,10 @@
package org.apache.ignite.internal.schema;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.util.UUID;
-import org.apache.ignite.lang.IgniteInternalException;
-
/**
* Description of a binary tuple.
*/
public class BinaryTupleSchema {
- /** Size of a tuple header, in bytes. */
- public static final int HEADER_SIZE = 1;
-
- /** Mask for size of entries in variable-length offset table. */
- public static final int VARSIZE_MASK = 0b011;
-
- /** Flag that indicates null map presence. */
- public static final int NULLMAP_FLAG = 0b100;
-
- /** Default value for UUID elements. */
- public static final UUID DEFAULT_UUID = new UUID(0, 0);
-
- /** Default value for Date elements (Jan 1st 1 BC). */
- public static final LocalDate DEFAULT_DATE = LocalDate.of(0, 1, 1);
-
- /** Default value for Time elements (00:00:00). */
- public static final LocalTime DEFAULT_TIME = LocalTime.of(0, 0);
-
- /** Default value for DateTime elements (Jan 1st 1 BC, 00:00:00). */
- public static final LocalDateTime DEFAULT_DATE_TIME = LocalDateTime.of(0, 1, 1, 0, 0);
-
- /** Default value for Timestamp elements. */
- public static final Instant DEFAULT_TIMESTAMP = Instant.EPOCH;
-
/**
* Tuple element description used for tuple parsing and building.
*
@@ -86,6 +55,33 @@ public class BinaryTupleSchema {
this.nullable = nullable;
}
+
+ /**
+ * Gets the type spec.
+ *
+ * @return Type spec.
+ */
+ public NativeTypeSpec typeSpec() {
+ return typeSpec;
+ }
+
+ /**
+ * Gets the decimal scale.
+ *
+ * @return Decimal scale.
+ */
+ public int decimalScale() {
+ return decimalScale;
+ }
+
+ /**
+ * Gets the nullable flag.
+ *
+ * @return Nullable flag.
+ */
+ public boolean nullable() {
+ return nullable;
+ }
}
/** Tuple schema corresponding to a set of row columns going in a contiguous range. */
@@ -249,65 +245,6 @@ public class BinaryTupleSchema {
return new SparseRowSchema(elements, columns.clone(), hasNullables);
}
- /**
- * Calculates flags for a given size of variable-length area.
- *
- * @param size Variable-length area size.
- * @return Flags value.
- */
- public static byte valueSizeToFlags(long size) {
- if (size <= 0xff) {
- return 0b00;
- }
- if (size <= 0xffff) {
- return 0b01;
- }
- if (size <= Integer.MAX_VALUE) {
- return 0b10;
- }
- throw new IgniteInternalException("Too big binary tuple size");
- }
-
- /**
- * Calculates the size of entry in variable-length offset table for given flags.
- *
- * @param flags Flags value.
- * @return Size of entry in variable-length offset table.
- */
- public static int flagsToEntrySize(byte flags) {
- return 1 << (flags & VARSIZE_MASK);
- }
-
- /**
- * Calculates the null map size.
- *
- * @param numElements Number of tuple elements.
- * @return Null map size in bytes.
- */
- public static int nullMapSize(int numElements) {
- return (numElements + 7) / 8;
- }
-
- /**
- * Returns offset of the byte that contains null-bit of a given tuple element.
- *
- * @param index Tuple element index.
- * @return Offset of the required byte relative to the tuple start.
- */
- public static int nullOffset(int index) {
- return HEADER_SIZE + index / 8;
- }
-
- /**
- * Returns a null-bit mask corresponding to a given tuple element.
- *
- * @param index Tuple element index.
- * @return Mask to extract the required null-bit.
- */
- public static byte nullMask(int index) {
- return (byte) (1 << (index % 8));
- }
-
/**
* Returns the number of elements in the tuple.
*/
diff --git a/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/AbstractMvTableStorageTest.java b/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/AbstractMvTableStorageTest.java
index 442b8a4a7d..64ac10fbb1 100644
--- a/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/AbstractMvTableStorageTest.java
+++ b/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/AbstractMvTableStorageTest.java
@@ -34,8 +34,8 @@ import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.apache.ignite.configuration.NamedListView;
import org.apache.ignite.configuration.schemas.table.TableIndexView;
+import org.apache.ignite.internal.binarytuple.BinaryTupleBuilder;
import org.apache.ignite.internal.schema.BinaryTuple;
-import org.apache.ignite.internal.schema.BinaryTupleBuilder;
import org.apache.ignite.internal.schema.BinaryTupleSchema;
import org.apache.ignite.internal.schema.BinaryTupleSchema.Element;
import org.apache.ignite.internal.schema.NativeTypes;
@@ -197,7 +197,7 @@ public abstract class AbstractMvTableStorageTest extends BaseMvStoragesTest {
new Element(NativeTypes.INT32, false)
});
- ByteBuffer buffer = BinaryTupleBuilder.create(schema)
+ ByteBuffer buffer = BinaryTupleBuilder.create(schema.elementCount(), schema.hasNullableElements())
.appendInt(1)
.appendInt(2)
.build();
diff --git a/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java b/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java
index 39d62f7fac..708342dbd9 100644
--- a/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java
+++ b/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/impl/BinaryTupleRowSerializer.java
@@ -19,13 +19,23 @@ package org.apache.ignite.internal.storage.index.impl;
import static java.util.stream.Collectors.toUnmodifiableList;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.BitSet;
import java.util.List;
+import java.util.UUID;
+import org.apache.ignite.internal.binarytuple.BinaryTupleBuilder;
import org.apache.ignite.internal.schema.BinaryTuple;
-import org.apache.ignite.internal.schema.BinaryTupleBuilder;
import org.apache.ignite.internal.schema.BinaryTupleSchema;
import org.apache.ignite.internal.schema.BinaryTupleSchema.Element;
+import org.apache.ignite.internal.schema.InvalidTypeException;
import org.apache.ignite.internal.schema.NativeType;
import org.apache.ignite.internal.schema.NativeTypeSpec;
+import org.apache.ignite.internal.schema.SchemaMismatchException;
import org.apache.ignite.internal.storage.RowId;
import org.apache.ignite.internal.storage.index.HashIndexDescriptor;
import org.apache.ignite.internal.storage.index.IndexRow;
@@ -100,10 +110,11 @@ public class BinaryTupleRowSerializer {
BinaryTupleSchema prefixSchema = BinaryTupleSchema.create(prefixElements);
- BinaryTupleBuilder builder = BinaryTupleBuilder.create(prefixSchema);
+ BinaryTupleBuilder builder = BinaryTupleBuilder.create(
+ prefixSchema.elementCount(), prefixSchema.hasNullableElements());
for (Object value : prefixColumnValues) {
- builder.appendValue(prefixSchema, value);
+ appendValue(builder, prefixSchema, value);
}
return new BinaryTuple(prefixSchema, builder.build());
@@ -127,4 +138,62 @@ public class BinaryTupleRowSerializer {
return result;
}
+
+ /**
+ * Append a value for the current element.
+ *
+ * @param builder Builder.
+ * @param schema Tuple schema.
+ * @param value Element value.
+ * @return Builder for chaining.
+ */
+ private static BinaryTupleBuilder appendValue(BinaryTupleBuilder builder, BinaryTupleSchema schema, Object value) {
+ BinaryTupleSchema.Element element = schema.element(builder.elementIndex());
+
+ if (value == null) {
+ if (!element.nullable()) {
+ throw new SchemaMismatchException("NULL value for non-nullable column in binary tuple builder.");
+ }
+ return builder.appendNull();
+ }
+
+ switch (element.typeSpec()) {
+ case INT8:
+ return builder.appendByte((byte) value);
+ case INT16:
+ return builder.appendShort((short) value);
+ case INT32:
+ return builder.appendInt((int) value);
+ case INT64:
+ return builder.appendLong((long) value);
+ case FLOAT:
+ return builder.appendFloat((float) value);
+ case DOUBLE:
+ return builder.appendDouble((double) value);
+ case NUMBER:
+ return builder.appendNumberNotNull((BigInteger) value);
+ case DECIMAL:
+ return builder.appendDecimalNotNull((BigDecimal) value);
+ case UUID:
+ return builder.appendUuidNotNull((UUID) value);
+ case BYTES:
+ return builder.appendBytesNotNull((byte[]) value);
+ case STRING:
+ return builder.appendStringNotNull((String) value);
+ case BITMASK:
+ return builder.appendBitmaskNotNull((BitSet) value);
+ case DATE:
+ return builder.appendDateNotNull((LocalDate) value);
+ case TIME:
+ return builder.appendTimeNotNull((LocalTime) value);
+ case DATETIME:
+ return builder.appendDateTimeNotNull((LocalDateTime) value);
+ case TIMESTAMP:
+ return builder.appendTimestampNotNull((Instant) value);
+ default:
+ break;
+ }
+
+ throw new InvalidTypeException("Unexpected type value: " + element.typeSpec());
+ }
}
diff --git a/parent/pom.xml b/parent/pom.xml
index 7eadaa8ff7..aeb562150d 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -241,6 +241,12 @@
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-binary-tuple</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-bytecode</artifactId>
@@ -301,12 +307,6 @@
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.apache.ignite</groupId>
- <artifactId>ignite-table</artifactId>
- <version>${project.version}</version>
- </dependency>
-
<dependency>
<groupId>org.apache.ignite</groupId>
<artifactId>ignite-metastorage</artifactId>
diff --git a/pom.xml b/pom.xml
index cbb6461bc4..2f49d069b8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -42,6 +42,7 @@
<module>modules/affinity</module>
<module>modules/api</module>
<module>modules/baseline</module>
+ <module>modules/binary-tuple</module>
<module>modules/bytecode</module>
<module>modules/cli</module>
<module>modules/cli-common</module>