You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2020/11/19 11:45:40 UTC
[ignite] branch ignite-13618 updated (5cc7dd0 -> 143fcc2)
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a change to branch ignite-13618
in repository https://gitbox.apache.org/repos/asf/ignite.git.
from 5cc7dd0 WIP. Replace reflection with unsafe.
new 3a0646d WIP. Add serializer generator.
new 143fcc2 WIP. Drop junit4 dependency.
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
modules/commons/pom.xml | 25 +-
.../ignite/internal/schema/TupleAssembler.java | 4 -
.../marshaller/FieldAccessExprGenerator.java | 76 ++++
.../marshaller/JaninoSerializerGenerator.java | 382 +++++++++++++++++++++
.../internal/schema/marshaller/JavaSerializer.java | 91 +----
...onException.java => JavaSerializerFactory.java} | 17 +-
.../internal/schema/marshaller/Marshaller.java | 44 ++-
.../schema/marshaller/MarshallerFactory.java | 74 ----
.../internal/schema/marshaller/MarshallerUtil.java | 95 +++++
.../marshaller/ObjectMarshallerExprGenerator.java | 68 ++++
.../schema/marshaller/SerializationException.java | 10 +
...SerializationException.java => Serializer.java} | 25 +-
...zationException.java => SerializerFactory.java} | 24 +-
...FieldAccessor.java => UnsafeFieldAccessor.java} | 32 +-
.../ignite/internal/schema/SchemaTestSuite.java | 41 ---
.../schema/marshaller/FieldAccessorTest.java | 8 +-
.../schema/marshaller/JavaSerializerTest.java | 136 +++++---
17 files changed, 848 insertions(+), 304 deletions(-)
create mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessExprGenerator.java
create mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JaninoSerializerGenerator.java
copy modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/{SerializationException.java => JavaSerializerFactory.java} (74%)
delete mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerFactory.java
create mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerUtil.java
create mode 100644 modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/ObjectMarshallerExprGenerator.java
copy modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/{SerializationException.java => Serializer.java} (63%)
copy modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/{SerializationException.java => SerializerFactory.java} (66%)
rename modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/{FieldAccessor.java => UnsafeFieldAccessor.java} (92%)
delete mode 100644 modules/commons/src/test/java/org/apache/ignite/internal/schema/SchemaTestSuite.java
[ignite] 01/02: WIP. Add serializer generator.
Posted by am...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch ignite-13618
in repository https://gitbox.apache.org/repos/asf/ignite.git
commit 3a0646d3aafb30b8b281e22fcb29dd13f0f67e35
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Thu Nov 19 13:51:27 2020 +0300
WIP. Add serializer generator.
---
.../ignite/internal/schema/TupleAssembler.java | 4 -
.../marshaller/FieldAccessExprGenerator.java | 76 ++++
.../marshaller/JaninoSerializerGenerator.java | 382 +++++++++++++++++++++
.../internal/schema/marshaller/JavaSerializer.java | 91 +----
...onException.java => JavaSerializerFactory.java} | 17 +-
.../internal/schema/marshaller/Marshaller.java | 44 ++-
.../schema/marshaller/MarshallerFactory.java | 74 ----
.../internal/schema/marshaller/MarshallerUtil.java | 95 +++++
.../marshaller/ObjectMarshallerExprGenerator.java | 68 ++++
.../schema/marshaller/SerializationException.java | 10 +
...SerializationException.java => Serializer.java} | 25 +-
...zationException.java => SerializerFactory.java} | 24 +-
...FieldAccessor.java => UnsafeFieldAccessor.java} | 32 +-
.../schema/marshaller/FieldAccessorTest.java | 8 +-
.../schema/marshaller/JavaSerializerTest.java | 360 ++++++++++---------
15 files changed, 925 insertions(+), 385 deletions(-)
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/TupleAssembler.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/TupleAssembler.java
index 45d3982..71c3eda 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/TupleAssembler.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/TupleAssembler.java
@@ -17,12 +17,8 @@
package org.apache.ignite.internal.schema;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
-import java.nio.charset.CoderResult;
import java.nio.charset.StandardCharsets;
import java.util.BitSet;
import java.util.UUID;
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessExprGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessExprGenerator.java
new file mode 100644
index 0000000..1ef3484
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessExprGenerator.java
@@ -0,0 +1,76 @@
+/*
+ * 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.marshaller;
+
+class FieldAccessExprGenerator {
+ final long offset;
+ final int colIdx;
+
+ private final String castClass;
+ private final String putFieldMethod;
+ private final String getFieldMethod;
+ private final String writeColMethod;
+ private final String readColMethod;
+
+ public FieldAccessExprGenerator(int colIdx, String castClass, String writeColMethod,
+ String readColMethod, long offset) {
+ this(colIdx, castClass, readColMethod, writeColMethod, offset,
+ "IgniteUnsafeUtils.getObjectField", "IgniteUnsafeUtils.putObjectField");
+ }
+
+ public FieldAccessExprGenerator(int colIdx, String readColMethod, String writeColMethod, long offset,
+ String getFieldMethod, String putFieldMethod) {
+ this(colIdx, null, readColMethod, writeColMethod, offset, getFieldMethod, putFieldMethod);
+ }
+
+ private FieldAccessExprGenerator(int colIdx, String castClass, String readColMethod, String writeColMethod,
+ long offset, String getFieldMethod, String putFieldMethod) {
+ this.offset = offset;
+ this.colIdx = colIdx;
+ this.castClass = castClass;
+ this.putFieldMethod = putFieldMethod;
+ this.getFieldMethod = getFieldMethod;
+ this.writeColMethod = writeColMethod;
+ this.readColMethod = readColMethod;
+ }
+
+ public String getFieldExpr() {
+ if (offset == -1)
+ return "obj";
+
+ return getFieldMethod + "(obj, " + offset + ')';
+ }
+
+ public final void addPutFieldExpr(StringBuilder sb, String val, String indent) {
+ sb.append(indent).append(putFieldMethod).append("(obj, ").append(offset).append(", ").append(val).append(')');
+ sb.append(";" + JaninoSerializerGenerator.LF);
+ }
+
+ public final void addWriteColumnExpr(StringBuilder sb, String expr, String indent) {
+ sb.append(indent).append(writeColMethod).append('(');
+
+ if (castClass != null)
+ sb.append("(").append(castClass).append(")");
+
+ sb.append(expr).append(");" + JaninoSerializerGenerator.LF);
+ }
+
+ public String readColumnExpr() {
+ return readColMethod + "(" + colIdx + ")";
+ }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JaninoSerializerGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JaninoSerializerGenerator.java
new file mode 100644
index 0000000..e96e5c2
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JaninoSerializerGenerator.java
@@ -0,0 +1,382 @@
+/*
+ * 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.marshaller;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import org.apache.ignite.internal.schema.Columns;
+import org.apache.ignite.internal.schema.SchemaDescriptor;
+import org.apache.ignite.internal.util.IgniteUnsafeUtils;
+import org.codehaus.commons.compiler.CompilerFactoryFactory;
+import org.codehaus.commons.compiler.IClassBodyEvaluator;
+
+/**
+ *
+ */
+public class JaninoSerializerGenerator implements SerializerFactory {
+ /** Tabulate. */
+ static final String TAB = " ";
+
+ /** Line feed. */
+ static final char LF = '\n';
+
+ /** Debug flag. */
+ private static final boolean enabledDebug = false;
+
+ @Override public Serializer create(
+ SchemaDescriptor schema,
+ Class<?> keyClass,
+ Class<?> valClass
+ ) {
+ try {
+ final String packageName = "org.apache.ignite.internal.schema.marshaller.";
+ final String className = "JaninoSerializerForSchema_" + schema.version();
+
+ final IClassBodyEvaluator ce = CompilerFactoryFactory.getDefaultCompilerFactory().newClassBodyEvaluator();
+
+ ce.setClassName(packageName + className);
+ ce.setImplementedInterfaces(new Class[] {Serializer.class});
+ ce.setDefaultImports(
+ "java.util.UUID",
+ "java.util.BitSet",
+
+ "org.apache.ignite.internal.schema.ByteBufferTuple",
+ "org.apache.ignite.internal.schema.Columns",
+ "org.apache.ignite.internal.schema.SchemaDescriptor",
+ "org.apache.ignite.internal.schema.Tuple",
+ "org.apache.ignite.internal.schema.TupleAssembler",
+ "org.apache.ignite.internal.util.IgniteUnsafeUtils"
+ );
+
+ final StringBuilder sb = new StringBuilder(8 * 1024);
+
+ // Create class fields and constructor.
+ sb.append("private final SchemaDescriptor schema;" + LF);
+ sb.append("private final Class kClass;" + LF);
+ sb.append("private final Class vClass;" + LF);
+ // Constructor.
+ sb.append(LF + "public ").append(className).append("(SchemaDescriptor schema, Class kClass, Class vClass) {" + LF);
+ sb.append(TAB + "this.kClass = kClass;" + LF);
+ sb.append(TAB + "this.vClass = vClass;" + LF);
+ sb.append(TAB + "this.schema = schema; " + LF);
+ sb.append("}" + LF);
+
+ // Build field accessor generators.
+ final ObjectMarshallerExprGenerator keyMarsh = createObjectMarshaller(keyClass, "kClass", schema.keyColumns(), 0);
+ final ObjectMarshallerExprGenerator valMarsh = createObjectMarshaller(valClass, "vClass", schema.valueColumns(), schema.keyColumns().length());
+
+ generateTupleFactoryMethod(sb, schema, keyMarsh, valMarsh);
+
+ writeSerializeMethod(sb, keyMarsh, valMarsh);
+ writeDeserializeMethods(sb, keyMarsh, valMarsh);
+
+ final String code = sb.toString();
+
+ if (enabledDebug) {
+ ce.setDebuggingInformation(true, true, true);
+ //TODO: pass to logger.
+ System.out.println(code);
+ }
+
+ ce.setParentClassLoader(getClass().getClassLoader());
+ ce.cook(code);
+
+ try {
+ final Constructor<Serializer> ctor = (Constructor<Serializer>)ce.getClazz()
+ .getDeclaredConstructor(schema.getClass(), Class.class, Class.class);
+
+ return ctor.newInstance(schema, keyClass, valClass);
+ }
+ catch (Exception ex) {
+ System.err.println(code);
+
+ throw ex;
+ }
+ }
+ catch (Exception ex) {
+ //TODO: fallback to java serializer?
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ private ObjectMarshallerExprGenerator createObjectMarshaller(Class<?> aClass, String classField, Columns columns,
+ int firstColIdx) {
+ BinaryMode mode = MarshallerUtil.mode(aClass);
+
+ if (mode != null)
+ return new ObjectMarshallerExprGenerator.IdentityObjectMarshaller(createAccessor(mode, firstColIdx, -1L));
+
+ FieldAccessExprGenerator[] accessors = new FieldAccessExprGenerator[columns.length()];
+ try {
+ for (int i = 0; i < columns.length(); i++) {
+ final Field field = aClass.getDeclaredField(columns.column(i).name());
+
+ accessors[i] = createAccessor(
+ MarshallerUtil.mode(field.getType()),
+ firstColIdx + i /* schma absolute index. */,
+ IgniteUnsafeUtils.objectFieldOffset(field));
+ }
+ }
+ catch (NoSuchFieldException ex) {
+ throw new IllegalStateException(ex);
+ }
+
+ return new ObjectMarshallerExprGenerator(classField, accessors);
+ }
+
+ private FieldAccessExprGenerator createAccessor(BinaryMode mode, int colIdx, long offset) {
+ switch (mode) {
+ case BYTE:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "Byte",
+ "asm.appendByte",
+ "tuple.byteValueBoxed",
+ offset);
+
+ case P_BYTE:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "tuple.byteValue", "asm.appendByte",
+ offset,
+ "IgniteUnsafeUtils.getByteField",
+ "IgniteUnsafeUtils.putByteField"
+ );
+
+ case SHORT:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "Short",
+ "asm.appendShort",
+ "tuple.shortValueBoxed",
+ offset);
+
+ case P_SHORT:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "tuple.shortValue", "asm.appendShort",
+ offset,
+ "IgniteUnsafeUtils.getShortField",
+ "IgniteUnsafeUtils.putShortField"
+ );
+
+ case INT:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "Integer",
+ "asm.appendInt",
+ "tuple.intValueBoxed",
+ offset);
+
+ case P_INT:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "tuple.intValue", "asm.appendInt",
+ offset,
+ "IgniteUnsafeUtils.getIntField",
+ "IgniteUnsafeUtils.putIntField"
+ );
+
+ case LONG:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "Long",
+ "asm.appendLong",
+ "tuple.longValueBoxed",
+ offset);
+
+ case P_LONG:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "tuple.longValue", "asm.appendLong",
+ offset,
+ "IgniteUnsafeUtils.getLongField",
+ "IgniteUnsafeUtils.putLongField"
+ );
+
+ case FLOAT:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "Float",
+ "asm.appendFloat",
+ "tuple.floatValueBoxed",
+ offset);
+
+ case P_FLOAT:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "tuple.floatValue", "asm.appendFloat",
+ offset,
+ "IgniteUnsafeUtils.getFloatField",
+ "IgniteUnsafeUtils.putFloatField"
+ );
+
+ case DOUBLE:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "Double",
+ "asm.appendDouble",
+ "tuple.doubleValueBoxed",
+ offset);
+
+ case P_DOUBLE:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "tuple.doubleValue", "asm.appendDouble",
+ offset,
+ "IgniteUnsafeUtils.getDoubleField",
+ "IgniteUnsafeUtils.putDoubleField"
+ );
+
+ case UUID:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "UUID",
+ "asm.appendUuid",
+ "tuple.uuidValue",
+ offset);
+
+ case BITSET:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "BitSet",
+ "asm.appendBitmask",
+ "tuple.bitmaskValue",
+ offset);
+
+ case STRING:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "String",
+ "asm.appendString",
+ "tuple.stringValue",
+ offset);
+
+ case BYTE_ARR:
+ return new FieldAccessExprGenerator(
+ colIdx,
+ "byte[]",
+ "asm.appendBytes",
+ "tuple.bytesValue",
+ offset);
+ default:
+ throw new IllegalStateException("Unsupportd binary mode");
+ }
+ }
+
+ private void writeSerializeMethod(StringBuilder sb,
+ ObjectMarshallerExprGenerator keyMarsh,
+ ObjectMarshallerExprGenerator valMarsh
+ ) {
+ sb.append(LF + "@Override public byte[] serialize(Object key, Object val) throws SerializationException {" + LF);
+ sb.append(TAB + "TupleAssembler asm = createAssembler(key, val);" + LF);
+
+ sb.append(TAB + "{" + LF);
+ sb.append(TAB + TAB + "Object obj = key;" + LF);
+ keyMarsh.marshallObject(sb, TAB + TAB);
+ sb.append(TAB + "} {" + LF);
+ sb.append(TAB + TAB + "Object obj = val;" + LF);
+ valMarsh.marshallObject(sb, TAB + TAB);
+ sb.append(TAB + "}" + LF);
+
+ sb.append(TAB + "return asm.build();" + LF);
+ sb.append("}" + LF);
+ }
+
+ private void writeDeserializeMethods(StringBuilder sb,
+ ObjectMarshallerExprGenerator keyMarsh,
+ ObjectMarshallerExprGenerator valMarsh
+ ) {
+ sb.append(LF + "@Override public Object deserializeKey(byte[] data) throws SerializationException {" + LF);
+ sb.append(TAB + "Tuple tuple = new ByteBufferTuple(schema, data);" + LF);
+
+ keyMarsh.unmarshallObject(sb, TAB);
+
+ sb.append(TAB + "return obj;" + LF);
+ sb.append("}" + LF);
+
+ sb.append(LF + "@Override public Object deserializeValue(byte[] data) throws SerializationException {" + LF);
+ sb.append(TAB + "Tuple tuple = new ByteBufferTuple(schema, data);" + LF);
+
+ valMarsh.unmarshallObject(sb, TAB);
+
+ sb.append(TAB + "return obj;" + LF);
+ sb.append("}" + LF);
+ }
+
+ private void generateTupleFactoryMethod(
+ StringBuilder sb,
+ SchemaDescriptor schema,
+ ObjectMarshallerExprGenerator keyMarsh,
+ ObjectMarshallerExprGenerator valMarsh
+ ) {
+ sb.append(LF + "TupleAssembler createAssembler(Object key, Object val) {" + LF);
+ sb.append(TAB + "int nonNullVarlenKeys = 0; int nonNullVarlenValues = 0;" + LF);
+ sb.append(TAB + "int nonNullVarlenKeysSize = 0; int nonNullVarlenValuesSize = 0;" + LF);
+ sb.append(LF);
+ sb.append(TAB + "Columns keyCols = schema.keyColumns();" + LF);
+ sb.append(TAB + "Columns valCols = schema.valueColumns();" + LF);
+ sb.append(LF);
+
+ Columns keyCols = schema.keyColumns();
+ if (keyCols.firstVarlengthColumn() >= 0) {
+ sb.append(TAB + "{" + LF);
+ sb.append(TAB + TAB + "Object fVal, obj = key;" + LF);
+
+ for (int i = keyCols.firstVarlengthColumn(); i < keyCols.length(); i++) {
+ assert !keyCols.column(i).type().spec().fixedLength();
+
+ sb.append(TAB + TAB + "assert !keyCols.column(").append(i).append(").type().spec().fixedLength();" + LF);
+ sb.append(TAB + TAB + "fVal = ").append(keyMarsh.accessors[i].getFieldExpr()).append(";" + LF);
+ sb.append(TAB + TAB + "if (fVal != null) {" + LF);
+ sb.append(TAB + TAB + TAB + "nonNullVarlenKeysSize += MarshallerUtil.getValueSize(fVal, keyCols.column(").append(i).append(").type());").append(LF);
+ sb.append(TAB + TAB + TAB + "nonNullVarlenKeys++;" + LF);
+ sb.append(TAB + TAB + "}" + LF);
+ }
+
+ sb.append(TAB + "}" + LF);
+ }
+
+ Columns valCols = schema.valueColumns();
+ if (valCols.firstVarlengthColumn() >= 0) {
+ sb.append(TAB + "{" + LF);
+ sb.append(TAB + TAB + "Object fVal, obj = val;" + LF);
+
+ for (int i = valCols.firstVarlengthColumn(); i < valCols.length(); i++) {
+ assert !valCols.column(i).type().spec().fixedLength();
+
+ sb.append(TAB + TAB + "assert !valCols.column(").append(i).append(").type().spec().fixedLength();" + LF);
+ sb.append(TAB + TAB + "fVal = ").append(valMarsh.accessors[i].getFieldExpr()).append(";" + LF);
+ sb.append(TAB + TAB + "if (fVal != null) {" + LF);
+ sb.append(TAB + TAB + TAB + "nonNullVarlenValuesSize += MarshallerUtil.getValueSize(fVal, valCols.column(").append(i).append(").type());" + LF);
+ sb.append(TAB + TAB + TAB + "nonNullVarlenValues++;" + LF);
+ sb.append(TAB + TAB + "}" + LF);
+ }
+ sb.append(TAB + "}" + LF);
+ }
+
+ sb.append(LF);
+ sb.append(TAB + "int size = TupleAssembler.tupleSize(" + LF);
+ sb.append(TAB + TAB + "keyCols, nonNullVarlenKeys, nonNullVarlenKeysSize, " + LF);
+ sb.append(TAB + TAB + "valCols, nonNullVarlenValues, nonNullVarlenValuesSize); " + LF);
+ sb.append(LF);
+
+ sb.append(TAB + "return new TupleAssembler(schema, size, nonNullVarlenKeys, nonNullVarlenValues);" + LF);
+ sb.append("}" + LF);
+ }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializer.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializer.java
index 9294ce9..1aae7b2 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializer.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializer.java
@@ -21,66 +21,16 @@ import java.util.BitSet;
import java.util.UUID;
import org.apache.ignite.internal.schema.ByteBufferTuple;
import org.apache.ignite.internal.schema.Columns;
-import org.apache.ignite.internal.schema.NativeType;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.Tuple;
import org.apache.ignite.internal.schema.TupleAssembler;
+import static org.apache.ignite.internal.schema.marshaller.MarshallerUtil.getValueSize;
+
/**
- * Cache objects (de)serializer.
- * <p>
- * TODO: Extract interface.
+ * Reflection based (de)serializer.
*/
-public class JavaSerializer {
- /**
- * Gets binary read/write mode for given class.
- *
- * @param cls Type.
- * @return Binary mode.
- */
- public static BinaryMode mode(Class<?> cls) {
- assert cls != null;
-
- // Primitives.
- if (cls == byte.class)
- return BinaryMode.P_BYTE;
- else if (cls == short.class)
- return BinaryMode.P_SHORT;
- else if (cls == int.class)
- return BinaryMode.P_INT;
- else if (cls == long.class)
- return BinaryMode.P_LONG;
- else if (cls == float.class)
- return BinaryMode.P_FLOAT;
- else if (cls == double.class)
- return BinaryMode.P_DOUBLE;
-
- // Boxed primitives.
- else if (cls == Byte.class)
- return BinaryMode.BYTE;
- else if (cls == Short.class)
- return BinaryMode.SHORT;
- else if (cls == Integer.class)
- return BinaryMode.INT;
- else if (cls == Long.class)
- return BinaryMode.LONG;
- else if (cls == Float.class)
- return BinaryMode.FLOAT;
- else if (cls == Double.class)
- return BinaryMode.DOUBLE;
-
- // Other types
- else if (cls == byte[].class)
- return BinaryMode.BYTE_ARR;
- else if (cls == String.class)
- return BinaryMode.STRING;
- else if (cls == UUID.class)
- return BinaryMode.UUID;
- else if (cls == BitSet.class)
- return BinaryMode.BITSET;
-
- return null;
- }
+public class JavaSerializer implements Serializer {
/**
* Reads value object from tuple.
@@ -253,8 +203,8 @@ public class JavaSerializer {
this.keyClass = keyClass;
this.valClass = valClass;
- keyMarsh = MarshallerFactory.createMarshaller(schema.keyColumns(), 0, keyClass);
- valMarsh = MarshallerFactory.createMarshaller(schema.valueColumns(), schema.keyColumns().length(), valClass);
+ keyMarsh = Marshaller.createMarshaller(schema.keyColumns(), 0, keyClass);
+ valMarsh = Marshaller.createMarshaller(schema.valueColumns(), schema.keyColumns().length(), valClass);
}
/**
@@ -264,7 +214,7 @@ public class JavaSerializer {
* @param val Value object.
* @return Serialized key-value pair.
*/
- public byte[] serialize(Object key, Object val) throws SerializationException {
+ @Override public byte[] serialize(Object key, Object val) throws SerializationException {
assert keyClass.isInstance(key);
assert val == null || valClass.isInstance(val);
@@ -286,9 +236,8 @@ public class JavaSerializer {
* @param key Key object.
* @param val Value object.
* @return Tuple assembler.
- * @throws SerializationException If failed.
*/
- private TupleAssembler createAssembler(Object key, Object val) throws SerializationException {
+ private TupleAssembler createAssembler(Object key, Object val) {
ObjectStatistic keyStat = collectObjectStats(schema.keyColumns(), keyMarsh, key);
ObjectStatistic valStat = collectObjectStats(schema.valueColumns(), valMarsh, val);
@@ -328,29 +277,9 @@ public class JavaSerializer {
}
/**
- * Calculates size for serialized value of varlen type.
- *
- * @param val Field value.
- * @param type Mapped type.
- * @return Serialized value size.
- */
- private int getValueSize(Object val, NativeType type) {
- switch (type.spec()) {
- case BYTES:
- return ((byte[])val).length;
-
- case STRING:
- return TupleAssembler.utf8EncodedLength((CharSequence)val);
-
- default:
- throw new IllegalStateException("Unsupported test varsize type: " + type);
- }
- }
-
- /**
* @return Key object.
*/
- public Object deserializeKey(byte[] data) throws SerializationException {
+ @Override public Object deserializeKey(byte[] data) throws SerializationException {
final Tuple tuple = new ByteBufferTuple(schema, data);
final Object o = keyMarsh.readObject(tuple);
@@ -363,7 +292,7 @@ public class JavaSerializer {
/**
* @return Value object.
*/
- public Object deserializeValue(byte[] data) throws SerializationException {
+ @Override public Object deserializeValue(byte[] data) throws SerializationException {
final Tuple tuple = new ByteBufferTuple(schema, data);
// TODO: add tomstone support.
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerFactory.java
similarity index 74%
copy from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
copy to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerFactory.java
index aa8a497..93351bb 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerFactory.java
@@ -17,17 +17,10 @@
package org.apache.ignite.internal.schema.marshaller;
-/**
- * Serialization exception.
- */
-public class SerializationException extends Exception {
- /**
- * Constructor.
- *
- * @param message Message.
- * @param cause Cause.
- */
- public SerializationException(String message, Throwable cause) {
- super(message, cause);
+import org.apache.ignite.internal.schema.SchemaDescriptor;
+
+public class JavaSerializerFactory implements SerializerFactory {
+ @Override public Serializer create(SchemaDescriptor schema, Class<?> keyClass, Class<?> valClass) {
+ return new JavaSerializer(schema, keyClass, valClass);
}
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Marshaller.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Marshaller.java
index 3b73a3e..deb6150 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Marshaller.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Marshaller.java
@@ -35,6 +35,8 @@
package org.apache.ignite.internal.schema.marshaller;
import java.util.Objects;
+import org.apache.ignite.internal.schema.Column;
+import org.apache.ignite.internal.schema.Columns;
import org.apache.ignite.internal.schema.Tuple;
import org.apache.ignite.internal.schema.TupleAssembler;
import org.jetbrains.annotations.Nullable;
@@ -44,10 +46,44 @@ import org.jetbrains.annotations.Nullable;
*/
public class Marshaller {
/**
+ * Creates marshaller for class.
+ *
+ * @param cols Columns.
+ * @param firstColId First column position in schema.
+ * @param aClass Type.
+ * @return Marshaller.
+ */
+ public static Marshaller createMarshaller(Columns cols, int firstColId, Class<? extends Object> aClass) {
+ final BinaryMode mode = MarshallerUtil.mode(aClass);
+
+ if (mode != null) {
+ final Column col = cols.column(0);
+
+ assert cols.length() == 1;
+ assert mode.typeSpec() == col.type().spec() : "Target type is not compatible.";
+ assert !aClass.isPrimitive() : "Non-nullable types are not allowed.";
+
+ return new Marshaller(UnsafeFieldAccessor.createIdentityAccessor(col, firstColId, mode));
+ }
+
+ UnsafeFieldAccessor[] fieldAccessors = new UnsafeFieldAccessor[cols.length()];
+
+ // Build accessors
+ for (int i = 0; i < cols.length(); i++) {
+ final Column col = cols.column(i);
+
+ final int colIdx = firstColId + i; /* Absolute column idx in schema. */
+ fieldAccessors[i] = UnsafeFieldAccessor.create(aClass, col, colIdx);
+ }
+
+ return new Marshaller(new ObjectFactory<>(aClass), fieldAccessors);
+ }
+
+ /**
* Field accessors for mapped columns.
* Array has same size and order as columns.
*/
- private final FieldAccessor[] fieldAccessors;
+ private final UnsafeFieldAccessor[] fieldAccessors;
/**
* Object factory for complex types or {@code null} for basic type.
@@ -62,7 +98,7 @@ public class Marshaller {
* @param fieldAccessors Object field accessors for mapped columns.
*/
@SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType")
- public Marshaller(Factory<?> factory, FieldAccessor[] fieldAccessors) {
+ public Marshaller(Factory<?> factory, UnsafeFieldAccessor[] fieldAccessors) {
this.fieldAccessors = fieldAccessors;
this.factory = Objects.requireNonNull(factory);
}
@@ -73,8 +109,8 @@ public class Marshaller {
*
* @param fieldAccessor Identity field accessor for object of basic type.
*/
- public Marshaller(FieldAccessor fieldAccessor) {
- fieldAccessors = new FieldAccessor[] {fieldAccessor};
+ public Marshaller(UnsafeFieldAccessor fieldAccessor) {
+ fieldAccessors = new UnsafeFieldAccessor[] {fieldAccessor};
factory = null;
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerFactory.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerFactory.java
deleted file mode 100644
index 3e642da..0000000
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerFactory.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * 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.marshaller;
-
-import org.apache.ignite.internal.schema.Column;
-import org.apache.ignite.internal.schema.Columns;
-
-public abstract class MarshallerFactory {
- /**
- * Creates marshaller for class.
- *
- * @param cols Columns.
- * @param firstColId First column position in schema.
- * @param aClass Type.
- * @return Marshaller.
- */
- public static Marshaller createMarshaller(Columns cols, int firstColId, Class<? extends Object> aClass) {
- final BinaryMode mode = JavaSerializer.mode(aClass);
-
- if (mode != null) {
- final Column col = cols.column(0);
-
- assert cols.length() == 1;
- assert mode.typeSpec() == col.type().spec() : "Target type is not compatible.";
- assert !aClass.isPrimitive() : "Non-nullable types are not allowed.";
-
- return new Marshaller(FieldAccessor.createIdentityAccessor(col, firstColId, mode));
- }
-
- FieldAccessor[] fieldAccessors = new FieldAccessor[cols.length()];
-
- // Build accessors
- for (int i = 0; i < cols.length(); i++) {
- final Column col = cols.column(i);
-
- final int colIdx = firstColId + i; /* Absolute column idx in schema. */
- fieldAccessors[i] = FieldAccessor.create(aClass, col, colIdx);
- }
-
- return new Marshaller(new ObjectFactory<>(aClass), fieldAccessors);
- }
-}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerUtil.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerUtil.java
new file mode 100644
index 0000000..d6ff9eb
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerUtil.java
@@ -0,0 +1,95 @@
+/*
+ * 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.marshaller;
+
+import java.util.BitSet;
+import java.util.UUID;
+import org.apache.ignite.internal.schema.NativeType;
+import org.apache.ignite.internal.schema.TupleAssembler;
+
+public class MarshallerUtil {
+ /**
+ * Calculates size for serialized value of varlen type.
+ *
+ * @param val Field value.
+ * @param type Mapped type.
+ * @return Serialized value size.
+ */
+ public static int getValueSize(Object val, NativeType type) {
+ switch (type.spec()) {
+ case BYTES:
+ return ((byte[])val).length;
+
+ case STRING:
+ return TupleAssembler.utf8EncodedLength((CharSequence)val);
+
+ default:
+ throw new IllegalStateException("Unsupported test varsize type: " + type);
+ }
+ }
+
+ /**
+ * Gets binary read/write mode for given class.
+ *
+ * @param cls Type.
+ * @return Binary mode.
+ */
+ public static BinaryMode mode(Class<?> cls) {
+ assert cls != null;
+
+ // Primitives.
+ if (cls == byte.class)
+ return BinaryMode.P_BYTE;
+ else if (cls == short.class)
+ return BinaryMode.P_SHORT;
+ else if (cls == int.class)
+ return BinaryMode.P_INT;
+ else if (cls == long.class)
+ return BinaryMode.P_LONG;
+ else if (cls == float.class)
+ return BinaryMode.P_FLOAT;
+ else if (cls == double.class)
+ return BinaryMode.P_DOUBLE;
+
+ // Boxed primitives.
+ else if (cls == Byte.class)
+ return BinaryMode.BYTE;
+ else if (cls == Short.class)
+ return BinaryMode.SHORT;
+ else if (cls == Integer.class)
+ return BinaryMode.INT;
+ else if (cls == Long.class)
+ return BinaryMode.LONG;
+ else if (cls == Float.class)
+ return BinaryMode.FLOAT;
+ else if (cls == Double.class)
+ return BinaryMode.DOUBLE;
+
+ // Other types
+ else if (cls == byte[].class)
+ return BinaryMode.BYTE_ARR;
+ else if (cls == String.class)
+ return BinaryMode.STRING;
+ else if (cls == UUID.class)
+ return BinaryMode.UUID;
+ else if (cls == BitSet.class)
+ return BinaryMode.BITSET;
+
+ return null;
+ }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/ObjectMarshallerExprGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/ObjectMarshallerExprGenerator.java
new file mode 100644
index 0000000..f6a274a
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/ObjectMarshallerExprGenerator.java
@@ -0,0 +1,68 @@
+/*
+ * 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.marshaller;
+
+class ObjectMarshallerExprGenerator {
+ private final String classFieldExpr;
+ protected FieldAccessExprGenerator[] accessors;
+
+ public ObjectMarshallerExprGenerator(String classFieldExpr, FieldAccessExprGenerator[] accessors) {
+ this.accessors = accessors;
+ this.classFieldExpr = classFieldExpr;
+ }
+
+ public void unmarshallObject(StringBuilder sb, String indent) {
+ sb.append(indent).append("Object obj;" + JaninoSerializerGenerator.LF);
+ sb.append(indent).append("try {" + JaninoSerializerGenerator.LF);
+ sb.append(indent).append(JaninoSerializerGenerator.TAB + "obj = IgniteUnsafeUtils.allocateInstance(").append(classFieldExpr).append(");" + JaninoSerializerGenerator.LF);
+
+ for (int i = 0; i < accessors.length; i++)
+ accessors[i].addPutFieldExpr(sb, accessors[i].readColumnExpr(), indent + JaninoSerializerGenerator.TAB);
+ sb.append(indent).append("} catch (InstantiationException ex) {" + JaninoSerializerGenerator.LF);
+
+ sb.append(indent).append(JaninoSerializerGenerator.TAB + "throw new SerializationException(\"Failed to instantiate object: \" + ")
+ .append(classFieldExpr).append(".getSimpleName(), ex);").append(JaninoSerializerGenerator.LF);
+ sb.append(indent).append("}" + JaninoSerializerGenerator.LF);
+ }
+
+ public void marshallObject(StringBuilder sb, String indent) {
+ sb.append(indent).append("try {" + JaninoSerializerGenerator.LF);
+
+ for (int i = 0; i < accessors.length; i++)
+ accessors[i].addWriteColumnExpr(sb, accessors[i].getFieldExpr(), indent + JaninoSerializerGenerator.TAB);
+
+ sb.append(indent).append("} catch (Exception ex) {" + JaninoSerializerGenerator.LF);
+ sb.append(indent).append(JaninoSerializerGenerator.TAB + "throw new SerializationException(ex);").append(JaninoSerializerGenerator.LF);
+ sb.append(indent).append("}" + JaninoSerializerGenerator.LF);
+ }
+
+ static class IdentityObjectMarshaller extends ObjectMarshallerExprGenerator {
+ IdentityObjectMarshaller(FieldAccessExprGenerator accessors) {
+ super(null, new FieldAccessExprGenerator[] {accessors});
+ }
+
+ @Override public void marshallObject(StringBuilder sb, String indent) {
+ for (int i = 0; i < accessors.length; i++)
+ accessors[i].addWriteColumnExpr(sb, "obj", indent);
+ }
+
+ @Override public void unmarshallObject(StringBuilder sb, String indent) {
+ sb.append(indent).append("Object obj = ").append(accessors[0].readColumnExpr()).append(";" + JaninoSerializerGenerator.LF);
+ }
+ }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
index aa8a497..e690710 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
@@ -24,6 +24,16 @@ public class SerializationException extends Exception {
/**
* Constructor.
*
+ * @param cause Cause.
+ */
+ public SerializationException(Throwable cause) {
+ // Used by serializers generated with Janino.
+ super(cause);
+ }
+
+ /**
+ * Constructor.
+ *
* @param message Message.
* @param cause Cause.
*/
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java
similarity index 63%
copy from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
copy to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java
index aa8a497..21a1560 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java
@@ -18,16 +18,25 @@
package org.apache.ignite.internal.schema.marshaller;
/**
- * Serialization exception.
+ * Key-value objects (de)serializer.
*/
-public class SerializationException extends Exception {
+public interface Serializer {
/**
- * Constructor.
+ * Writes key-value pair to tuple.
*
- * @param message Message.
- * @param cause Cause.
+ * @param key Key object.
+ * @param val Value object.
+ * @return Serialized key-value pair.
*/
- public SerializationException(String message, Throwable cause) {
- super(message, cause);
- }
+ byte[] serialize(Object key, Object val) throws SerializationException;
+
+ /**
+ * @return Key object.
+ */
+ Object deserializeKey(byte[] data) throws SerializationException;
+
+ /**
+ * @return Value object.
+ */
+ Object deserializeValue(byte[] data) throws SerializationException;
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java
similarity index 66%
copy from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
copy to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java
index aa8a497..b83e9b9 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializationException.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java
@@ -17,17 +17,17 @@
package org.apache.ignite.internal.schema.marshaller;
-/**
- * Serialization exception.
- */
-public class SerializationException extends Exception {
- /**
- * Constructor.
- *
- * @param message Message.
- * @param cause Cause.
- */
- public SerializationException(String message, Throwable cause) {
- super(message, cause);
+import org.apache.ignite.internal.schema.SchemaDescriptor;
+
+public interface SerializerFactory {
+ public static SerializerFactory createJaninoSerializerFactory() {
+ return new JaninoSerializerGenerator();
+ }
+
+ public static SerializerFactory createJavaSerializerFactory() {
+ return new JavaSerializerFactory();
+
}
+
+ public Serializer create(SchemaDescriptor schema, Class<?> keyClass, Class<?> valClass);
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessor.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/UnsafeFieldAccessor.java
similarity index 92%
rename from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessor.java
rename to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/UnsafeFieldAccessor.java
index 713553d..1f286c6 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/FieldAccessor.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/UnsafeFieldAccessor.java
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
* Field accessor to speedup access.
*/
// TODO: Extract interface, move to java-8 profile and add Java9+ implementation using VarHandles.
-public abstract class FieldAccessor {
+public abstract class UnsafeFieldAccessor {
/**
* TODO: implement sesitive information filtering.
*
@@ -64,14 +64,14 @@ public abstract class FieldAccessor {
* @param colIdx Column index in schema.
* @return Accessor.
*/
- static FieldAccessor create(Class<?> type, Column col, int colIdx) {
+ static UnsafeFieldAccessor create(Class<?> type, Column col, int colIdx) {
try {
final Field field = type.getDeclaredField(col.name());
if (field.getType().isPrimitive() && col.nullable())
throw new IllegalArgumentException("Failed to map non-nullable field to nullable column [name=" + field.getName() + ']');
- BinaryMode mode = JavaSerializer.mode(field.getType());
+ BinaryMode mode = MarshallerUtil.mode(field.getType());
switch (mode) {
case P_BYTE:
@@ -123,7 +123,7 @@ public abstract class FieldAccessor {
* @param mode Binary mode.
* @return Accessor.
*/
- static FieldAccessor createIdentityAccessor(Column col, int colIdx, BinaryMode mode) {
+ static UnsafeFieldAccessor createIdentityAccessor(Column col, int colIdx, BinaryMode mode) {
switch (mode) {
// Marshaller read/write object contract methods allowed boxed types only.
case P_BYTE:
@@ -160,7 +160,7 @@ public abstract class FieldAccessor {
* @param colIdx Column index.
* @param mode Binary mode;
*/
- protected FieldAccessor(Field field, int colIdx, BinaryMode mode) {
+ protected UnsafeFieldAccessor(Field field, int colIdx, BinaryMode mode) {
assert field != null;
assert colIdx >= 0;
assert mode != null;
@@ -169,8 +169,6 @@ public abstract class FieldAccessor {
this.mode = mode;
offset = IgniteUnsafeUtils.objectFieldOffset(field);
name = field.getName();
-
- field.setAccessible(true);
}
/**
@@ -179,7 +177,7 @@ public abstract class FieldAccessor {
* @param colIdx Column index.
* @param mode Binary mode;
*/
- private FieldAccessor(int colIdx, BinaryMode mode) {
+ private UnsafeFieldAccessor(int colIdx, BinaryMode mode) {
assert colIdx >= 0;
assert mode != null;
@@ -211,7 +209,7 @@ public abstract class FieldAccessor {
}
catch (Exception ex) {
if (includeSensitive() && name != null)
- throw new SerializationException("Failed to write field [name=" + name + ']', ex);
+ throw new SerializationException("Failed to read field [id=" + colIdx + ']', ex);
else
throw new SerializationException("Failed to write field [id=" + colIdx + ']', ex);
}
@@ -277,7 +275,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code byte} type.
*/
- private static class IdentityAccessor extends FieldAccessor {
+ private static class IdentityAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -312,7 +310,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code byte} type.
*/
- private static class BytePrimitiveAccessor extends FieldAccessor {
+ private static class BytePrimitiveAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -341,7 +339,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code short} type.
*/
- private static class ShortPrimitiveAccessor extends FieldAccessor {
+ private static class ShortPrimitiveAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -370,7 +368,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code int} type.
*/
- private static class IntPrimitiveAccessor extends FieldAccessor {
+ private static class IntPrimitiveAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -399,7 +397,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code long} type.
*/
- private static class LongPrimitiveAccessor extends FieldAccessor {
+ private static class LongPrimitiveAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -428,7 +426,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code float} type.
*/
- private static class FloatPrimitiveAccessor extends FieldAccessor {
+ private static class FloatPrimitiveAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -457,7 +455,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of primitive {@code double} type.
*/
- private static class DoublePrimitiveAccessor extends FieldAccessor {
+ private static class DoublePrimitiveAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
@@ -486,7 +484,7 @@ public abstract class FieldAccessor {
/**
* Accessor for field of reference type.
*/
- private static class ReferenceFieldAccessor extends FieldAccessor {
+ private static class ReferenceFieldAccessor extends UnsafeFieldAccessor {
/**
* Constructor.
*
diff --git a/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/FieldAccessorTest.java b/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/FieldAccessorTest.java
index 461d66a..a4a3c56 100644
--- a/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/FieldAccessorTest.java
+++ b/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/FieldAccessorTest.java
@@ -101,7 +101,7 @@ public class FieldAccessorTest {
final TestObject obj = TestObject.randomObject(rnd);
for (int i = 0; i < cols.length; i++) {
- FieldAccessor accessor = FieldAccessor.create(TestObject.class, cols[i], i);
+ UnsafeFieldAccessor accessor = UnsafeFieldAccessor.create(TestObject.class, cols[i], i);
accessor.write(obj, tupleAssembler);
}
@@ -109,7 +109,7 @@ public class FieldAccessorTest {
final TestObject restoredObj = new TestObject();
for (int i = 0; i < cols.length; i++) {
- FieldAccessor accessor = FieldAccessor.create(TestObject.class, cols[i], i);
+ UnsafeFieldAccessor accessor = UnsafeFieldAccessor.create(TestObject.class, cols[i], i);
accessor.read(restoredObj, tuple);
}
@@ -139,7 +139,7 @@ public class FieldAccessorTest {
*/
@Test
public void testIdentityAccessor() throws Exception {
- final FieldAccessor accessor = FieldAccessor.createIdentityAccessor(
+ final UnsafeFieldAccessor accessor = UnsafeFieldAccessor.createIdentityAccessor(
new Column("col0", STRING, true),
0,
BinaryMode.STRING);
@@ -157,7 +157,7 @@ public class FieldAccessorTest {
*/
@Test
public void testWrongIdentityAccessor() throws Exception {
- final FieldAccessor accessor = FieldAccessor.createIdentityAccessor(
+ final UnsafeFieldAccessor accessor = UnsafeFieldAccessor.createIdentityAccessor(
new Column("col0", STRING, true),
42,
BinaryMode.UUID);
diff --git a/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java b/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java
index 3cfb0da..53550b5 100644
--- a/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java
+++ b/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.schema.marshaller;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
@@ -30,7 +31,8 @@ import org.apache.ignite.internal.schema.NativeTypeSpec;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.TestUtils;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
import static org.apache.ignite.internal.schema.NativeType.BYTE;
import static org.apache.ignite.internal.schema.NativeType.BYTES;
@@ -43,13 +45,20 @@ import static org.apache.ignite.internal.schema.NativeType.STRING;
import static org.apache.ignite.internal.schema.NativeType.UUID;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Serializer test.
*/
public class JavaSerializerTest {
+
+ private static List<SerializerFactory> serializerFactoryProvider() {
+ return Arrays.asList(
+ new JaninoSerializerGenerator(),
+ new JavaSerializerFactory()
+ );
+ }
+
/** Random. */
private Random rnd;
@@ -66,189 +75,202 @@ public class JavaSerializerTest {
}
/**
- * @throws SerializationException If serialization failed.
+ *
*/
- @Test
- public void testBasicTypes() throws SerializationException {
+ @ParameterizedTest
+ @MethodSource("serializerFactoryProvider")
+ public void testBasicTypes(SerializerFactory factory) throws SerializationException {
// Fixed types:
- checkBasicType(BYTE, BYTE);
- checkBasicType(SHORT, SHORT);
- checkBasicType(INTEGER, INTEGER);
- checkBasicType(LONG, LONG);
- checkBasicType(FLOAT, FLOAT);
- checkBasicType(DOUBLE, DOUBLE);
- checkBasicType(UUID, UUID);
- checkBasicType(Bitmask.of(4), Bitmask.of(5));
+ checkBasicType(factory, BYTE, BYTE);
+ checkBasicType(factory, SHORT, SHORT);
+ checkBasicType(factory, INTEGER, INTEGER);
+ checkBasicType(factory, LONG, LONG);
+ checkBasicType(factory, FLOAT, FLOAT);
+ checkBasicType(factory, DOUBLE, DOUBLE);
+ checkBasicType(factory, UUID, UUID);
+ checkBasicType(factory, Bitmask.of(4), Bitmask.of(5));
// Varlen types:
- checkBasicType(BYTES, BYTES);
- checkBasicType(STRING, STRING);
+ checkBasicType(factory, BYTES, BYTES);
+ checkBasicType(factory, STRING, STRING);
// Mixed:
- checkBasicType(LONG, INTEGER);
- checkBasicType(INTEGER, BYTES);
- checkBasicType(STRING, LONG);
- checkBasicType(Bitmask.of(9), BYTES);
- }
-
- /**
- * @throws SerializationException If serialization failed.
- */
- @Test
- public void testComplexType() throws SerializationException {
- Column[] cols = new Column[] {
- new Column("pByteCol", BYTE, false),
- new Column("pShortCol", SHORT, false),
- new Column("pIntCol", INTEGER, false),
- new Column("pLongCol", LONG, false),
- new Column("pFloatCol", FLOAT, false),
- new Column("pDoubleCol", DOUBLE, false),
-
- new Column("byteCol", BYTE, true),
- new Column("shortCol", SHORT, true),
- new Column("intCol", INTEGER, true),
- new Column("longCol", LONG, true),
- new Column("floatCol", FLOAT, true),
- new Column("doubleCol", DOUBLE, true),
-
- new Column("uuidCol", UUID, true),
- new Column("bitmaskCol", Bitmask.of(42), true),
- new Column("stringCol", STRING, true),
- new Column("bytesCol", BYTES, true),
- };
-
- SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-
- final Object key = TestObject.randomObject(rnd);
- final Object val = TestObject.randomObject(rnd);
-
- JavaSerializer serializer = new JavaSerializer(schema, key.getClass(), val.getClass());
-
- byte[] bytes = serializer.serialize(key, val);
-
- Object key1 = serializer.deserializeKey(bytes);
- Object val1 = serializer.deserializeValue(bytes);
-
- assertTrue(key.getClass().isInstance(key1));
- assertTrue(val.getClass().isInstance(val1));
-
- assertEquals(key, key);
- assertEquals(val, val1);
- }
-
- /**
- *
- */
- @Test
- public void testClassWithIncorrectBitmaskSize() {
- Column[] cols = new Column[] {
- new Column("pLongCol", LONG, false),
- new Column("bitmaskCol", Bitmask.of(9), true),
- };
-
- SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-
- final Object key = TestObject.randomObject(rnd);
- final Object val = TestObject.randomObject(rnd);
-
- JavaSerializer serializer = new JavaSerializer(schema, key.getClass(), val.getClass());
-
- assertThrows(
- SerializationException.class,
- () -> serializer.serialize(key, val),
- "Failed to write field [name=bitmaskCol]"
- );
- }
-
- /**
- *
- */
- @Test
- public void testClassWithWrongFieldType() {
- Column[] cols = new Column[] {
- new Column("bitmaskCol", Bitmask.of(42), true),
- new Column("shortCol", UUID, true)
- };
-
- SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-
- final Object key = TestObject.randomObject(rnd);
- final Object val = TestObject.randomObject(rnd);
-
- JavaSerializer serializer = new JavaSerializer(schema, key.getClass(), val.getClass());
-
- assertThrows(
- SerializationException.class,
- () -> serializer.serialize(key, val),
- "Failed to write field [name=shortCol]"
- );
+ checkBasicType(factory, LONG, INTEGER);
+ checkBasicType(factory, FLOAT, DOUBLE);
+ checkBasicType(factory, INTEGER, BYTES);
+ checkBasicType(factory, STRING, LONG);
+ checkBasicType(factory, Bitmask.of(9), BYTES);
}
- /**
- *
- */
- @Test
- public void testClassWithPrivateConstructor() throws SerializationException {
- Column[] cols = new Column[] {
- new Column("pLongCol", LONG, false),
- };
-
- SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-
- final Object key = PrivateTestObject.randomObject(rnd);
- final Object val = PrivateTestObject.randomObject(rnd);
-
- JavaSerializer serializer = new JavaSerializer(schema, key.getClass(), val.getClass());
-
- byte[] bytes = serializer.serialize(key, val);
-
- Object key1 = serializer.deserializeKey(bytes);
- Object val1 = serializer.deserializeValue(bytes);
-
- assertTrue(key.getClass().isInstance(key1));
- assertTrue(val.getClass().isInstance(val1));
-
- assertEquals(key, key);
- assertEquals(val, val1);
- }
-
- /**
- *
- */
- @Test
- public void testClassWithNoDefaultConstructor() throws SerializationException {
- Column[] cols = new Column[] {
- new Column("pLongCol", LONG, false),
- };
-
- SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-
- final Object key = WrongTestObject.randomObject(rnd);
- final Object val = WrongTestObject.randomObject(rnd);
-
- final JavaSerializer serializer = new JavaSerializer(schema, key.getClass(), val.getClass());
-
- final byte[] bytes = serializer.serialize(key, val);
-
- Object key1 = serializer.deserializeKey(bytes);
- Object val1 = serializer.deserializeValue(bytes);
-
- assertTrue(key.getClass().isInstance(key1));
- assertTrue(val.getClass().isInstance(val1));
-
- assertEquals(key, key);
- assertEquals(val, val1);
- }
+// /**
+// * @throws SerializationException If serialization failed.
+// */
+// @ParameterizedTest
+// @DisplayName("testComplexType")
+// @MethodSource("serializerFactoryProvider")
+// public void testComplexType(SerializerFactory factory) throws SerializationException {
+// Column[] cols = new Column[] {
+// new Column("pByteCol", BYTE, false),
+// new Column("pShortCol", SHORT, false),
+// new Column("pIntCol", INTEGER, false),
+// new Column("pLongCol", LONG, false),
+// new Column("pFloatCol", FLOAT, false),
+// new Column("pDoubleCol", DOUBLE, false),
+//
+// new Column("byteCol", BYTE, true),
+// new Column("shortCol", SHORT, true),
+// new Column("intCol", INTEGER, true),
+// new Column("longCol", LONG, true),
+// new Column("floatCol", FLOAT, true),
+// new Column("doubleCol", DOUBLE, true),
+//
+// new Column("uuidCol", UUID, true),
+// new Column("bitmaskCol", Bitmask.of(42), true),
+// new Column("stringCol", STRING, true),
+// new Column("bytesCol", BYTES, true),
+// };
+//
+// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+//
+// final Object key = TestObject.randomObject(rnd);
+// final Object val = TestObject.randomObject(rnd);
+//
+// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+//
+// byte[] bytes = serializer.serialize(key, val);
+//
+// // Try different order.
+// Object restoredVal = serializer.deserializeValue(bytes);
+// Object restoredKey = serializer.deserializeKey(bytes);
+//
+// assertTrue(key.getClass().isInstance(restoredKey));
+// assertTrue(val.getClass().isInstance(restoredVal));
+//
+// assertEquals(key, restoredKey);
+// assertEquals(val, restoredVal);
+// }
+//
+// /**
+// *
+// */
+// @ParameterizedTest
+// @MethodSource("serializerFactoryProvider")
+// public void testClassWithIncorrectBitmaskSize(SerializerFactory factory) {
+// Column[] cols = new Column[] {
+// new Column("pLongCol", LONG, false),
+// new Column("bitmaskCol", Bitmask.of(9), true),
+// };
+//
+// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+//
+// final Object key = TestObject.randomObject(rnd);
+// final Object val = TestObject.randomObject(rnd);
+//
+// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+//
+// assertThrows(
+// SerializationException.class,
+// () -> serializer.serialize(key, val),
+// "Failed to write field [name=bitmaskCol]"
+// );
+// }
+//
+// /**
+// *
+// */
+// @ParameterizedTest
+// @DisplayName("testClassWithWrongFieldType")
+// @MethodSource("serializerFactoryProvider")
+// public void testClassWithWrongFieldType(SerializerFactory factory) throws Exception {
+// Column[] cols = new Column[] {
+// new Column("bitmaskCol", Bitmask.of(42), true),
+// new Column("shortCol", UUID, true)
+// };
+//
+// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+//
+// final Object key = TestObject.randomObject(rnd);
+// final Object val = TestObject.randomObject(rnd);
+//
+// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+//
+// assertThrows(
+// SerializationException.class,
+// () -> serializer.serialize(key, val),
+// "Failed to write field [name=shortCol]"
+// );
+// }
+//
+// /**
+// *
+// */
+// @ParameterizedTest
+// @MethodSource("serializerFactoryProvider")
+// public void testClassWithPrivateConstructor(SerializerFactory factory) throws SerializationException {
+// Column[] cols = new Column[] {
+// new Column("pLongCol", LONG, false),
+// };
+//
+// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+//
+// final Object key = PrivateTestObject.randomObject(rnd);
+// final Object val = PrivateTestObject.randomObject(rnd);
+//
+// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+//
+// byte[] bytes = serializer.serialize(key, val);
+//
+// Object key1 = serializer.deserializeKey(bytes);
+// Object val1 = serializer.deserializeValue(bytes);
+//
+// assertTrue(key.getClass().isInstance(key1));
+// assertTrue(val.getClass().isInstance(val1));
+//
+// assertEquals(key, key);
+// assertEquals(val, val1);
+// }
+//
+// /**
+// *
+// */
+// @ParameterizedTest
+// @DisplayName("testClassWithNoDefaultConstructor")
+// @MethodSource("serializerFactoryProvider")
+// public void testClassWithNoDefaultConstructor(SerializerFactory factory) throws SerializationException {
+// Column[] cols = new Column[] {
+// new Column("pLongCol", LONG, false),
+// };
+//
+// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+//
+// final Object key = WrongTestObject.randomObject(rnd);
+// final Object val = WrongTestObject.randomObject(rnd);
+//
+// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+//
+// byte[] bytes = serializer.serialize(key, val);
+//
+// Object key1 = serializer.deserializeKey(bytes);
+// Object val1 = serializer.deserializeValue(bytes);
+//
+// assertTrue(key.getClass().isInstance(key1));
+// assertTrue(val.getClass().isInstance(val1));
+//
+// assertEquals(key, key);
+// assertEquals(val, val1);
+// }
/**
* Generate random key-value pair of given types and
* check serialization and deserialization works fine.
*
+ * @param factory Serializer factory.
* @param keyType Key type.
* @param valType Value type.
* @throws SerializationException If (de)serialization failed.
*/
- private void checkBasicType(NativeType keyType, NativeType valType) throws SerializationException {
+ private void checkBasicType(SerializerFactory factory, NativeType keyType,
+ NativeType valType) throws SerializationException {
final Object key = generateRandomValue(keyType);
final Object val = generateRandomValue(valType);
@@ -257,7 +279,7 @@ public class JavaSerializerTest {
SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(keyCols), new Columns(valCols));
- JavaSerializer serializer = new JavaSerializer(schema, key.getClass(), val.getClass());
+ Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
byte[] bytes = serializer.serialize(key, val);
[ignite] 02/02: WIP. Drop junit4 dependency.
Posted by am...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch ignite-13618
in repository https://gitbox.apache.org/repos/asf/ignite.git
commit 143fcc227c3532c704fe2295c7ad75bced93daa1
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Thu Nov 19 13:51:54 2020 +0300
WIP. Drop junit4 dependency.
---
modules/commons/pom.xml | 25 +-
.../ignite/internal/schema/SchemaTestSuite.java | 41 ---
.../schema/marshaller/JavaSerializerTest.java | 344 +++++++++++----------
3 files changed, 207 insertions(+), 203 deletions(-)
diff --git a/modules/commons/pom.xml b/modules/commons/pom.xml
index 9308376..472e960 100644
--- a/modules/commons/pom.xml
+++ b/modules/commons/pom.xml
@@ -34,6 +34,8 @@
<!-- Dependencies versions -->
<jetbrains.annotations.version>20.1.0</jetbrains.annotations.version>
+ <jetbrains.annotations.version>20.1.0</jetbrains.annotations.version>
+ <janino.version>3.0.11</janino.version>
<junit.jupiter.version>5.7.0</junit.jupiter.version>
<junit.platform.version>1.7.0</junit.platform.version>
<mockito.version>1.10.19</mockito.version>
@@ -41,7 +43,7 @@
<!-- Maven plugins versions. -->
<apache.rat.plugin.version>0.13</apache.rat.plugin.version>
<maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
- <maven.surefire.plugin.version>3.0.0-M4</maven.surefire.plugin.version>
+ <maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
<maven.checkstyle.plugin.version>3.1.1</maven.checkstyle.plugin.version>
<checkstyle.puppycrawl.version>8.37</checkstyle.puppycrawl.version>
</properties>
@@ -152,18 +154,24 @@
<version>${jetbrains.annotations.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.janino</groupId>
+ <artifactId>janino</artifactId>
+ <version>${janino.version}</version>
+ </dependency>
+
<!-- Test dependencies. -->
<!--JUnit 5-->
<dependency>
<groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter-engine</artifactId>
+ <artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.junit.platform</groupId>
- <artifactId>junit-platform-runner</artifactId>
- <version>${junit.platform.version}</version>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-params</artifactId>
+ <version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
@@ -191,6 +199,13 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.plugin.version}</version>
+ <dependencies>
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter-engine</artifactId>
+ <version>${junit.jupiter.version}</version>
+ </dependency>
+ </dependencies>
</plugin>
</plugins>
</build>
diff --git a/modules/commons/src/test/java/org/apache/ignite/internal/schema/SchemaTestSuite.java b/modules/commons/src/test/java/org/apache/ignite/internal/schema/SchemaTestSuite.java
deleted file mode 100644
index 0b64ff2..0000000
--- a/modules/commons/src/test/java/org/apache/ignite/internal/schema/SchemaTestSuite.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 org.apache.ignite.internal.schema.marshaller.FieldAccessorTest;
-import org.apache.ignite.internal.schema.marshaller.JavaSerializerTest;
-import org.junit.platform.runner.JUnitPlatform;
-import org.junit.platform.suite.api.SelectClasses;
-import org.junit.runner.RunWith;
-
-/**
- *
- */
-@SuppressWarnings("JUnit5Platform")
-@RunWith(JUnitPlatform.class)
-@SelectClasses({
- JavaSerializerTest.class,
- FieldAccessorTest.class,
- ExpandableByteBufTest.class,
- NativeTypeTest.class,
- ColumnTest.class,
- ColumnsTest.class,
- TupleTest.class
-})
-public class SchemaTestSuite {
-}
diff --git a/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java b/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java
index 53550b5..d20651c 100644
--- a/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java
+++ b/modules/commons/src/test/java/org/apache/ignite/internal/schema/marshaller/JavaSerializerTest.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
+import java.util.stream.Stream;
import org.apache.ignite.internal.schema.Bitmask;
import org.apache.ignite.internal.schema.Column;
import org.apache.ignite.internal.schema.Columns;
@@ -31,6 +32,8 @@ import org.apache.ignite.internal.schema.NativeTypeSpec;
import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.TestUtils;
import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DynamicNode;
+import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@@ -45,7 +48,10 @@ import static org.apache.ignite.internal.schema.NativeType.STRING;
import static org.apache.ignite.internal.schema.NativeType.UUID;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.DynamicContainer.dynamicContainer;
+import static org.junit.jupiter.api.DynamicTest.dynamicTest;
/**
* Serializer test.
@@ -77,6 +83,33 @@ public class JavaSerializerTest {
/**
*
*/
+ @TestFactory
+ public Stream<DynamicNode> testBasicTypes() {
+ NativeType[] types = new NativeType[] {BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, UUID, STRING, BYTES, Bitmask.of(5)};
+
+ return serializerFactoryProvider().stream().map(factory ->
+ dynamicContainer(factory.getClass().getSimpleName(),
+ Stream.concat(
+ // Test pure types.
+ Stream.of(types).map(type ->
+ dynamicTest("testBasicTypes(" + type.spec().name() + ')', () -> checkBasicType(factory, type, type))
+ ),
+
+ // Test pairs of mixed types.
+ Stream.of(
+ dynamicTest("testMixTypes 1", () -> checkBasicType(factory, LONG, INTEGER)),
+ dynamicTest("testMixTypes 1", () -> checkBasicType(factory, FLOAT, DOUBLE)),
+ dynamicTest("testMixTypes 1", () -> checkBasicType(factory, INTEGER, BYTES)),
+ dynamicTest("testMixTypes 1", () -> checkBasicType(factory, STRING, LONG)),
+ dynamicTest("testMixTypes 1", () -> checkBasicType(factory, Bitmask.of(9), BYTES))
+ )
+ )
+ ));
+ }
+
+ /**
+ *
+ */
@ParameterizedTest
@MethodSource("serializerFactoryProvider")
public void testBasicTypes(SerializerFactory factory) throws SerializationException {
@@ -102,163 +135,160 @@ public class JavaSerializerTest {
checkBasicType(factory, Bitmask.of(9), BYTES);
}
-// /**
-// * @throws SerializationException If serialization failed.
-// */
-// @ParameterizedTest
-// @DisplayName("testComplexType")
-// @MethodSource("serializerFactoryProvider")
-// public void testComplexType(SerializerFactory factory) throws SerializationException {
-// Column[] cols = new Column[] {
-// new Column("pByteCol", BYTE, false),
-// new Column("pShortCol", SHORT, false),
-// new Column("pIntCol", INTEGER, false),
-// new Column("pLongCol", LONG, false),
-// new Column("pFloatCol", FLOAT, false),
-// new Column("pDoubleCol", DOUBLE, false),
-//
-// new Column("byteCol", BYTE, true),
-// new Column("shortCol", SHORT, true),
-// new Column("intCol", INTEGER, true),
-// new Column("longCol", LONG, true),
-// new Column("floatCol", FLOAT, true),
-// new Column("doubleCol", DOUBLE, true),
-//
-// new Column("uuidCol", UUID, true),
-// new Column("bitmaskCol", Bitmask.of(42), true),
-// new Column("stringCol", STRING, true),
-// new Column("bytesCol", BYTES, true),
-// };
-//
-// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-//
-// final Object key = TestObject.randomObject(rnd);
-// final Object val = TestObject.randomObject(rnd);
-//
-// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
-//
-// byte[] bytes = serializer.serialize(key, val);
-//
-// // Try different order.
-// Object restoredVal = serializer.deserializeValue(bytes);
-// Object restoredKey = serializer.deserializeKey(bytes);
-//
-// assertTrue(key.getClass().isInstance(restoredKey));
-// assertTrue(val.getClass().isInstance(restoredVal));
-//
-// assertEquals(key, restoredKey);
-// assertEquals(val, restoredVal);
-// }
-//
-// /**
-// *
-// */
-// @ParameterizedTest
-// @MethodSource("serializerFactoryProvider")
-// public void testClassWithIncorrectBitmaskSize(SerializerFactory factory) {
-// Column[] cols = new Column[] {
-// new Column("pLongCol", LONG, false),
-// new Column("bitmaskCol", Bitmask.of(9), true),
-// };
-//
-// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-//
-// final Object key = TestObject.randomObject(rnd);
-// final Object val = TestObject.randomObject(rnd);
-//
-// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
-//
-// assertThrows(
-// SerializationException.class,
-// () -> serializer.serialize(key, val),
-// "Failed to write field [name=bitmaskCol]"
-// );
-// }
-//
-// /**
-// *
-// */
-// @ParameterizedTest
-// @DisplayName("testClassWithWrongFieldType")
-// @MethodSource("serializerFactoryProvider")
-// public void testClassWithWrongFieldType(SerializerFactory factory) throws Exception {
-// Column[] cols = new Column[] {
-// new Column("bitmaskCol", Bitmask.of(42), true),
-// new Column("shortCol", UUID, true)
-// };
-//
-// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-//
-// final Object key = TestObject.randomObject(rnd);
-// final Object val = TestObject.randomObject(rnd);
-//
-// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
-//
-// assertThrows(
-// SerializationException.class,
-// () -> serializer.serialize(key, val),
-// "Failed to write field [name=shortCol]"
-// );
-// }
-//
-// /**
-// *
-// */
-// @ParameterizedTest
-// @MethodSource("serializerFactoryProvider")
-// public void testClassWithPrivateConstructor(SerializerFactory factory) throws SerializationException {
-// Column[] cols = new Column[] {
-// new Column("pLongCol", LONG, false),
-// };
-//
-// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-//
-// final Object key = PrivateTestObject.randomObject(rnd);
-// final Object val = PrivateTestObject.randomObject(rnd);
-//
-// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
-//
-// byte[] bytes = serializer.serialize(key, val);
-//
-// Object key1 = serializer.deserializeKey(bytes);
-// Object val1 = serializer.deserializeValue(bytes);
-//
-// assertTrue(key.getClass().isInstance(key1));
-// assertTrue(val.getClass().isInstance(val1));
-//
-// assertEquals(key, key);
-// assertEquals(val, val1);
-// }
-//
-// /**
-// *
-// */
-// @ParameterizedTest
-// @DisplayName("testClassWithNoDefaultConstructor")
-// @MethodSource("serializerFactoryProvider")
-// public void testClassWithNoDefaultConstructor(SerializerFactory factory) throws SerializationException {
-// Column[] cols = new Column[] {
-// new Column("pLongCol", LONG, false),
-// };
-//
-// SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
-//
-// final Object key = WrongTestObject.randomObject(rnd);
-// final Object val = WrongTestObject.randomObject(rnd);
-//
-// Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
-//
-// byte[] bytes = serializer.serialize(key, val);
-//
-// Object key1 = serializer.deserializeKey(bytes);
-// Object val1 = serializer.deserializeValue(bytes);
-//
-// assertTrue(key.getClass().isInstance(key1));
-// assertTrue(val.getClass().isInstance(val1));
-//
-// assertEquals(key, key);
-// assertEquals(val, val1);
-// }
+ /**
+ * @throws SerializationException If serialization failed.
+ */
+ @ParameterizedTest
+ @MethodSource("serializerFactoryProvider")
+ public void testComplexType(SerializerFactory factory) throws SerializationException {
+ Column[] cols = new Column[] {
+ new Column("pByteCol", BYTE, false),
+ new Column("pShortCol", SHORT, false),
+ new Column("pIntCol", INTEGER, false),
+ new Column("pLongCol", LONG, false),
+ new Column("pFloatCol", FLOAT, false),
+ new Column("pDoubleCol", DOUBLE, false),
+
+ new Column("byteCol", BYTE, true),
+ new Column("shortCol", SHORT, true),
+ new Column("intCol", INTEGER, true),
+ new Column("longCol", LONG, true),
+ new Column("floatCol", FLOAT, true),
+ new Column("doubleCol", DOUBLE, true),
+
+ new Column("uuidCol", UUID, true),
+ new Column("bitmaskCol", Bitmask.of(42), true),
+ new Column("stringCol", STRING, true),
+ new Column("bytesCol", BYTES, true),
+ };
+
+ SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+
+ final Object key = TestObject.randomObject(rnd);
+ final Object val = TestObject.randomObject(rnd);
+
+ Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+
+ byte[] bytes = serializer.serialize(key, val);
+
+ // Try different order.
+ Object restoredVal = serializer.deserializeValue(bytes);
+ Object restoredKey = serializer.deserializeKey(bytes);
+
+ assertTrue(key.getClass().isInstance(restoredKey));
+ assertTrue(val.getClass().isInstance(restoredVal));
+
+ assertEquals(key, restoredKey);
+ assertEquals(val, restoredVal);
+ }
+
+ /**
+ *
+ */
+ @ParameterizedTest
+ @MethodSource("serializerFactoryProvider")
+ public void testClassWithIncorrectBitmaskSize(SerializerFactory factory) {
+ Column[] cols = new Column[] {
+ new Column("pLongCol", LONG, false),
+ new Column("bitmaskCol", Bitmask.of(9), true),
+ };
+
+ SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+
+ final Object key = TestObject.randomObject(rnd);
+ final Object val = TestObject.randomObject(rnd);
+
+ Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+
+ assertThrows(
+ SerializationException.class,
+ () -> serializer.serialize(key, val),
+ "Failed to write field [name=bitmaskCol]"
+ );
+ }
+
+ /**
+ *
+ */
+ @ParameterizedTest
+ @MethodSource("serializerFactoryProvider")
+ public void testClassWithWrongFieldType(SerializerFactory factory) {
+ Column[] cols = new Column[] {
+ new Column("bitmaskCol", Bitmask.of(42), true),
+ new Column("shortCol", UUID, true)
+ };
+
+ SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+
+ final Object key = TestObject.randomObject(rnd);
+ final Object val = TestObject.randomObject(rnd);
+
+ Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+
+ assertThrows(
+ SerializationException.class,
+ () -> serializer.serialize(key, val),
+ "Failed to write field [name=shortCol]"
+ );
+ }
+
+ /**
+ *
+ */
+ @ParameterizedTest
+ @MethodSource("serializerFactoryProvider")
+ public void testClassWithPrivateConstructor(SerializerFactory factory) throws SerializationException {
+ Column[] cols = new Column[] {
+ new Column("pLongCol", LONG, false),
+ };
+
+ SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+
+ final Object key = PrivateTestObject.randomObject(rnd);
+ final Object val = PrivateTestObject.randomObject(rnd);
+
+ Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+
+ byte[] bytes = serializer.serialize(key, val);
+
+ Object key1 = serializer.deserializeKey(bytes);
+ Object val1 = serializer.deserializeValue(bytes);
+
+ assertTrue(key.getClass().isInstance(key1));
+ assertTrue(val.getClass().isInstance(val1));
+
+ assertEquals(key, key);
+ assertEquals(val, val1);
+ }
+
+ /**
+ *
+ */
+ @ParameterizedTest
+ @MethodSource("serializerFactoryProvider")
+ public void testClassWithNoDefaultConstructor(SerializerFactory factory) throws SerializationException {
+ Column[] cols = new Column[] {
+ new Column("pLongCol", LONG, false),
+ };
+
+ SchemaDescriptor schema = new SchemaDescriptor(1, new Columns(cols), new Columns(cols.clone()));
+
+ final Object key = WrongTestObject.randomObject(rnd);
+ final Object val = WrongTestObject.randomObject(rnd);
+
+ Serializer serializer = factory.create(schema, key.getClass(), val.getClass());
+
+ byte[] bytes = serializer.serialize(key, val);
+
+ Object key1 = serializer.deserializeKey(bytes);
+ Object val1 = serializer.deserializeValue(bytes);
+
+ assertTrue(key.getClass().isInstance(key1));
+ assertTrue(val.getClass().isInstance(val1));
+
+ assertEquals(key, key);
+ assertEquals(val, val1);
+ }
/**
* Generate random key-value pair of given types and