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/12/16 15:25:28 UTC
[ignite-3] branch ignite-13618-javapoet updated: WIP. Fix
generator. Fix styles.
This is an automated email from the ASF dual-hosted git repository.
amashenkov pushed a commit to branch ignite-13618-javapoet
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/ignite-13618-javapoet by this push:
new 0b13416 WIP. Fix generator. Fix styles.
0b13416 is described below
commit 0b13416bb28c608cd6093c278426b00ce695693e
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Wed Dec 16 18:25:08 2020 +0300
WIP.
Fix generator. Fix styles.
---
.../schema/marshaller/AbstractSerializer.java | 104 ++++++++
.../internal/schema/marshaller/BinaryMode.java | 20 +-
.../{MarshallerUtil.java => CompilerUtils.java} | 289 ++++++++++-----------
.../internal/schema/marshaller/MarshallerUtil.java | 272 +------------------
.../schema/marshaller/SerializationException.java | 2 +-
.../internal/schema/marshaller/Serializer.java | 2 +
.../schema/marshaller/SerializerFactory.java | 2 +-
.../IdentityObjectMarshallerExprGenerator.java | 22 +-
.../generator/MarshallerCodeGenerator.java | 47 ++++
...tor.java => ObjectMarshallerCodeGenerator.java} | 74 +++---
.../marshaller/generator/SerializerGenerator.java | 159 ++++++++----
...pr.java => TupleColumnAccessCodeGenerator.java} | 157 ++++++++---
.../marshaller/reflection/FieldAccessor.java | 154 ++++++++++-
.../marshaller/reflection/JavaSerializer.java | 148 -----------
.../ignite/internal/util/IgniteUnsafeUtils.java | 273 -------------------
.../benchmarks/SerializerBenchmarkTest.java | 10 +-
.../schema/marshaller/JavaSerializerTest.java | 6 +-
17 files changed, 734 insertions(+), 1007 deletions(-)
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/AbstractSerializer.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/AbstractSerializer.java
new file mode 100644
index 0000000..86e4355
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/AbstractSerializer.java
@@ -0,0 +1,104 @@
+/*
+ * 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.Objects;
+import org.apache.ignite.internal.schema.ByteBufferTuple;
+import org.apache.ignite.internal.schema.SchemaDescriptor;
+import org.apache.ignite.internal.schema.Tuple;
+import org.apache.ignite.internal.schema.TupleAssembler;
+import org.apache.ignite.internal.util.Pair;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Base serializer class.
+ */
+public abstract class AbstractSerializer implements Serializer {
+ /** Schema descriptor. */
+ protected final SchemaDescriptor schema;
+
+ /**
+ * Constructor.
+ * @param schema Schema descriptor.
+ */
+ protected AbstractSerializer(SchemaDescriptor schema) {
+ this.schema = schema;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte[] serialize(Object key, Object val) throws SerializationException {
+ final TupleAssembler assembler = createAssembler(Objects.requireNonNull(key), val);
+
+ return serialize0(assembler, key, val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object deserializeKey(byte[] data) throws SerializationException {
+ final Tuple tuple = new ByteBufferTuple(schema, data);
+
+ return deserializeKey0(tuple);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object deserializeValue(byte[] data) throws SerializationException {
+ final Tuple tuple = new ByteBufferTuple(schema, data);
+
+ return deserializeValue0(tuple);
+ }
+
+ /** {@inheritDoc} */
+ public <K, V> Pair<K, V> deserialize(byte[] data) throws SerializationException {
+ final Tuple tuple = new ByteBufferTuple(schema, data);
+
+ return new Pair<>((K)deserializeKey0(tuple), (V)deserializeValue0(tuple));
+ }
+
+ /**
+ * Tuple assembler factory method.
+ */
+ protected abstract TupleAssembler createAssembler(Object key, @Nullable Object val);
+
+ /**
+ * Internal serialization method.
+ *
+ * @param asm Tuple assembler.
+ * @param keyObj Key object.
+ * @param valObj Value object.
+ * @return Serialized pair.
+ * @throws SerializationException If failed.
+ */
+ protected abstract byte[] serialize0(TupleAssembler asm, Object keyObj, Object valObj) throws SerializationException;
+
+ /**
+ * Extract key object from tuple.
+ *
+ * @param tuple Tuple.
+ * @return Deserialized key object.
+ * @throws SerializationException If failed.
+ */
+ protected abstract Object deserializeKey0(Tuple tuple) throws SerializationException;
+
+ /**
+ * Extract value object from tuple.
+ *
+ * @param tuple Tuple.
+ * @return Deserialized value object.
+ * @throws SerializationException If failed.
+ */
+ protected abstract Object deserializeValue0(Tuple tuple) throws SerializationException;
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/BinaryMode.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/BinaryMode.java
index db5a77f..6a0c6ab 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/BinaryMode.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/BinaryMode.java
@@ -41,34 +41,34 @@ public enum BinaryMode {
/** Primitive int. */
P_DOUBLE(NativeTypeSpec.DOUBLE),
- /** */
+ /** Boxed byte. */
BYTE(NativeTypeSpec.BYTE),
- /** */
+ /** Boxed short. */
SHORT(NativeTypeSpec.SHORT),
- /** */
+ /** Boxed int. */
INT(NativeTypeSpec.INTEGER),
- /** */
+ /** Boxed long. */
LONG(NativeTypeSpec.LONG),
- /** */
+ /** Boxed float. */
FLOAT(NativeTypeSpec.FLOAT),
- /** */
+ /** Boxed double. */
DOUBLE(NativeTypeSpec.DOUBLE),
- /** */
+ /** String. */
STRING(NativeTypeSpec.STRING),
- /** */
+ /** Uuid. */
UUID(NativeTypeSpec.UUID),
- /** */
+ /** Raw byte array. */
BYTE_ARR(NativeTypeSpec.BYTES),
- /** */
+ /** BitSet.*/
BITSET(NativeTypeSpec.BITMASK);
/** Natove type spec. */
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/CompilerUtils.java
similarity index 60%
copy from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/MarshallerUtil.java
copy to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/CompilerUtils.java
index 4f36129..0edaf68 100644
--- 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/CompilerUtils.java
@@ -26,14 +26,16 @@ import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
-import java.util.BitSet;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.Set;
-import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
@@ -41,112 +43,38 @@ import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
-import org.apache.ignite.internal.schema.NativeType;
-import org.apache.ignite.internal.schema.TupleAssembler;
-import org.apache.ignite.internal.util.ObjectFactory;
import org.jetbrains.annotations.Nullable;
/**
- * Marshaller utility class.
+ * Compiler utility class.
*/
-public final class MarshallerUtil {
+public final class CompilerUtils {
/**
- * Calculates size for serialized value of varlen type.
- *
- * @param val Field value.
- * @param type Mapped type.
- * @return Serialized value size.
+ * @return Creates classloader for dynamically loaded in-memory classes.
*/
- 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);
- }
+ public static ClassLoader dynamicClassLoader() {
+ return AccessController.doPrivileged(new PrivilegedAction<>() {
+ @Override public ClassLoader run() {
+ return new MemoryClassLoader(new ConcurrentHashMap<>(), ClassLoader.getSystemClassLoader());
+ }
+ });
}
/**
- * Gets binary read/write mode for given class.
+ * Compiles code and load compiled classes.
*
- * @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 static <T> ObjectFactory<T> factoryForClass(Class<T> type) {
- if (mode(type) == null)
- return new ObjectFactory<>(type);
- else
- return null;
- }
-
- /**
- * Stub.
+ * @param javafile Java file representation.
+ * @return Classloader with compiled classes.
*/
- private MarshallerUtil() {
- }
-
public static ClassLoader compileCode(JavaFile javafile) {
- return compileCode(javafile, null);
- }
-
- public static ClassLoader compileCode(JavaFile javafile, Map<String, byte[]> classes) {
final JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- Map<String, byte[]> classes = classLoader instanceof MemoryClassLoader ?
+ ConcurrentHashMap<String, byte[]> classes = classLoader instanceof MemoryClassLoader ?
((MemoryClassLoader)classLoader).classBytes : new ConcurrentHashMap<>();
try (final MemoryJavaFileManager fileManager = new MemoryJavaFileManager(cmp.getStandardFileManager(null, null, null), classes)) {
@@ -176,55 +104,124 @@ public final class MarshallerUtil {
}
}
+ /**
+ * @param iterables Iterables.
+ * @return Concated iterable.
+ */
+ private static <E> Iterable<E> concat(Iterable<? extends E>... iterables) {
+ return new Iterable<>() {
+ private final Iterator<Iterable<? extends E>> it = Arrays.asList(iterables).iterator();
+
+ /** {@inheritDoc} */
+ @Override public Iterator<E> iterator() {
+ return new Iterator<>() {
+ private Iterator<? extends E> curIt = Collections.emptyIterator();
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNext() {
+ if (curIt == null || !curIt.hasNext())
+ advance();
+
+ return curIt.hasNext();
+ }
+
+ /** Switches to next iterable. */
+ private void advance() {
+ while (it.hasNext() && !curIt.hasNext())
+ curIt = it.next().iterator();
+ }
+
+ /** {@inheritDoc} */
+ @Override public E next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ return curIt.next();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * In-memory java file manager.
+ */
private static class MemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> {
- private final Map<String, byte[]> classes;
+ /** Classes code. */
+ private final Map<String, byte[]> classesBytes;
- public MemoryJavaFileManager(JavaFileManager fileManager, Map<String, byte[]> classes) {
+ /**
+ * Constructor.
+ *
+ * @param fileManager Java file manager.
+ * @param classesBytes Classes code.
+ */
+ public MemoryJavaFileManager(JavaFileManager fileManager, Map<String, byte[]> classesBytes) {
super(fileManager);
-
- this.classes = classes;
+ this.classesBytes = classesBytes;
}
+ /**
+ * Java '.class' in-memory file.
+ */
private static class MemoryJavaFileObject extends SimpleJavaFileObject {
- private final byte[] bytes;
-
- public MemoryJavaFileObject(String className, byte[] bytes) {
+ /** Class code. */
+ private final byte[] classBytes;
+
+ /**
+ * Constructor.
+ *
+ * @param className Class name.
+ * @param classBytes Class code.
+ */
+ MemoryJavaFileObject(String className, byte[] classBytes) {
super(URI.create(className + Kind.CLASS.extension), Kind.CLASS);
- this.bytes = bytes;
+ this.classBytes = classBytes;
}
+ /** {@inheritDoc} */
@Override public InputStream openInputStream() {
- return new ByteArrayInputStream(bytes);
+ return new ByteArrayInputStream(classBytes);
}
}
/**
* A file object that stores Java bytecode into the classBytes map.
*/
- private class ClassOutputBuffer extends SimpleJavaFileObject {
+ private class JavaClassOutputFile extends SimpleJavaFileObject {
+ /** Class name. */
private final String classname;
- ClassOutputBuffer(String classname) {
+ /**
+ * Constructor.
+ *
+ * @param classname Class name.
+ */
+ JavaClassOutputFile(String classname) {
super(URI.create(classname), Kind.CLASS);
this.classname = classname;
}
+ /** {@inheritDoc} */
@Override public OutputStream openOutputStream() {
return new ByteArrayOutputStream() {
@Override public void close() throws IOException {
super.close();
- classes.put(classname, toByteArray());
+ classesBytes.put(classname, toByteArray());
}
};
}
}
- @Override public ClassLoader getClassLoader(Location location) {
- return new MemoryClassLoader(classes, super.getClassLoader(location));
- }
- @Override
- public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds,
+ /** {@inheritDoc} */
+ @Override public Iterable<JavaFileObject> list(Location location, String packageName,
+ Set<JavaFileObject.Kind> kinds,
boolean recurse) throws IOException {
final Iterable<JavaFileObject> it = super.list(location, packageName, kinds, recurse);
@@ -233,7 +230,10 @@ public final class MarshallerUtil {
Iterable<JavaFileObject> localClasses = new Iterable<>() {
@Override public Iterator<JavaFileObject> iterator() {
- return classes.keySet().stream().map(cn -> getJavaFileObjectByName(cn)).iterator();
+ return classesBytes.keySet().stream()
+ .filter(cn -> cn.startsWith(packageName))
+ .map(cn -> getJavaFileObjectByName(cn))
+ .filter(Objects::nonNull).iterator();
}
};
@@ -243,6 +243,7 @@ public final class MarshallerUtil {
return it;
}
+ /** {@inheritDoc} */
@Override public String inferBinaryName(Location location, JavaFileObject jfo) {
if (!(jfo instanceof MemoryJavaFileObject)) {
String result = super.inferBinaryName(location, jfo);
@@ -269,7 +270,9 @@ public final class MarshallerUtil {
return bn;
}
- @Override public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
+ /** {@inheritDoc} */
+ @Override public JavaFileObject getJavaFileForInput(Location location, String className,
+ JavaFileObject.Kind kind) throws IOException {
if (location == StandardLocation.CLASS_OUTPUT) {
JavaFileObject javaFileObject = getJavaFileObjectByName(className);
@@ -280,8 +283,9 @@ public final class MarshallerUtil {
return fileManager.getJavaFileForInput(location, className, kind);
}
+ /** {@inheritDoc} */
@Nullable private JavaFileObject getJavaFileObjectByName(String className) {
- final byte[] bytes = classes.get(className);
+ final byte[] bytes = classesBytes.get(className);
if (bytes != null)
return new MemoryJavaFileObject(className, bytes);
@@ -289,28 +293,41 @@ public final class MarshallerUtil {
return null;
}
+ /** {@inheritDoc} */
@Override public JavaFileObject getJavaFileForOutput(Location location,
String className,
JavaFileObject.Kind kind,
FileObject sibling) throws IOException {
if (kind == JavaFileObject.Kind.CLASS)
- return new ClassOutputBuffer(className);
+ return new JavaClassOutputFile(className);
else
return super.getJavaFileForOutput(location, className, kind, sibling);
}
}
+ /**
+ * Classloader for runtime compiled classes.
+ */
private static final class MemoryClassLoader extends URLClassLoader {
+ /** Empty array. */
private static final URL[] EMPTY_URLS = new URL[0];
- private final Map<String, byte[]> classBytes;
+ /** Classes code. */
+ private final ConcurrentHashMap<String, byte[]> classBytes;
- public MemoryClassLoader(Map<String, byte[]> classBytes, ClassLoader parent) {
+ /**
+ * Constructor.
+ *
+ * @param classBytes Classes code holder.
+ * @param parent Parent classloader.
+ */
+ MemoryClassLoader(ConcurrentHashMap<String, byte[]> classBytes, ClassLoader parent) {
super(EMPTY_URLS, parent);
this.classBytes = classBytes;
}
+ /** {@inheritDoc} */
@Override protected Class<?> findClass(String className) throws ClassNotFoundException {
byte[] buf = classBytes.get(className); // clear the bytes in map -- we don't need it anymore
@@ -321,49 +338,7 @@ public final class MarshallerUtil {
}
}
- public static <E> Iterable<E> concat(
- Iterable<? extends E> i1,
- Iterable<? extends E> i2) {
- return new Iterable<E>() {
- @Override public Iterator<E> iterator() {
- return new Iterator<E>() {
- Iterator<? extends E> listIterator = i1.iterator();
- Boolean checkedHasNext;
- E nextValue;
- private boolean startTheSecond;
-
- void theNext() {
- if (listIterator.hasNext()) {
- checkedHasNext = true;
- nextValue = listIterator.next();
- }
- else if (startTheSecond)
- checkedHasNext = false;
- else {
- startTheSecond = true;
- listIterator = i2.iterator();
- theNext();
- }
- }
-
- @Override public boolean hasNext() {
- if (checkedHasNext == null)
- theNext();
- return checkedHasNext;
- }
-
- @Override public E next() {
- if (!hasNext())
- throw new NoSuchElementException();
- checkedHasNext = null;
- return nextValue;
- }
-
- @Override public void remove() {
- listIterator.remove();
- }
- };
- }
- };
+ /** Stub. */
+ private CompilerUtils() {
}
}
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
index 4f36129..9361fa0 100644
--- 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
@@ -17,38 +17,11 @@
package org.apache.ignite.internal.schema.marshaller;
-import com.squareup.javapoet.JavaFile;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLClassLoader;
import java.util.BitSet;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
import java.util.UUID;
-import javax.tools.Diagnostic;
-import javax.tools.DiagnosticCollector;
-import javax.tools.FileObject;
-import javax.tools.ForwardingJavaFileManager;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.tools.JavaFileObject.Kind;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardLocation;
-import javax.tools.ToolProvider;
import org.apache.ignite.internal.schema.NativeType;
import org.apache.ignite.internal.schema.TupleAssembler;
import org.apache.ignite.internal.util.ObjectFactory;
-import org.jetbrains.annotations.Nullable;
/**
* Marshaller utility class.
@@ -124,246 +97,19 @@ public final class MarshallerUtil {
return null;
}
- public static <T> ObjectFactory<T> factoryForClass(Class<T> type) {
- if (mode(type) == null)
- return new ObjectFactory<>(type);
- else
- return null;
- }
-
/**
- * Stub.
+ * Creates object factory for class.
+ * @param tClass Target type.
+ * @return Object factory.
*/
- private MarshallerUtil() {
- }
-
- public static ClassLoader compileCode(JavaFile javafile) {
- return compileCode(javafile, null);
- }
-
- public static ClassLoader compileCode(JavaFile javafile, Map<String, byte[]> classes) {
- final JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();
-
- final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-
- Map<String, byte[]> classes = classLoader instanceof MemoryClassLoader ?
- ((MemoryClassLoader)classLoader).classBytes : new ConcurrentHashMap<>();
-
- try (final MemoryJavaFileManager fileManager = new MemoryJavaFileManager(cmp.getStandardFileManager(null, null, null), classes)) {
- DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
-
- JavaCompiler.CompilationTask task = cmp.getTask(null, fileManager, diagnostics, null, null, Collections.singletonList(javafile.toJavaFileObject()));
-
- if (task.call())
- return classLoader instanceof MemoryClassLoader ? classLoader :
- new MemoryClassLoader(classes, ClassLoader.getSystemClassLoader());
-
- // TODO: write to log.
- for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
- System.out.println(diagnostic.getCode());
- System.out.println(diagnostic.getKind());
- System.out.println(diagnostic.getPosition());
- System.out.println(diagnostic.getStartPosition());
- System.out.println(diagnostic.getEndPosition());
- System.out.println(diagnostic.getSource());
- System.out.println(diagnostic.getMessage(null));
- }
-
- throw new IllegalStateException("Failed to compile code:\n" + javafile.toString());
- }
- catch (IOException ex) {
- throw new IllegalStateException("Failed to compile code.", ex);
- }
- }
-
- private static class MemoryJavaFileManager extends ForwardingJavaFileManager<JavaFileManager> {
- private final Map<String, byte[]> classes;
-
- public MemoryJavaFileManager(JavaFileManager fileManager, Map<String, byte[]> classes) {
- super(fileManager);
-
- this.classes = classes;
- }
-
- private static class MemoryJavaFileObject extends SimpleJavaFileObject {
- private final byte[] bytes;
-
- public MemoryJavaFileObject(String className, byte[] bytes) {
- super(URI.create(className + Kind.CLASS.extension), Kind.CLASS);
- this.bytes = bytes;
- }
-
- @Override public InputStream openInputStream() {
- return new ByteArrayInputStream(bytes);
- }
- }
-
- /**
- * A file object that stores Java bytecode into the classBytes map.
- */
- private class ClassOutputBuffer extends SimpleJavaFileObject {
- private final String classname;
-
- ClassOutputBuffer(String classname) {
- super(URI.create(classname), Kind.CLASS);
- this.classname = classname;
- }
-
- @Override public OutputStream openOutputStream() {
- return new ByteArrayOutputStream() {
- @Override public void close() throws IOException {
- super.close();
-
- classes.put(classname, toByteArray());
- }
- };
- }
- }
-
- @Override public ClassLoader getClassLoader(Location location) {
- return new MemoryClassLoader(classes, super.getClassLoader(location));
- }
- @Override
- public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds,
- boolean recurse) throws IOException {
- final Iterable<JavaFileObject> it = super.list(location, packageName, kinds, recurse);
-
- if (location == StandardLocation.CLASS_PATH) {
- assert kinds.contains(JavaFileObject.Kind.CLASS);
-
- Iterable<JavaFileObject> localClasses = new Iterable<>() {
- @Override public Iterator<JavaFileObject> iterator() {
- return classes.keySet().stream().map(cn -> getJavaFileObjectByName(cn)).iterator();
- }
- };
-
- return concat(localClasses, it);
- }
- else
- return it;
- }
-
- @Override public String inferBinaryName(Location location, JavaFileObject jfo) {
- if (!(jfo instanceof MemoryJavaFileObject)) {
- String result = super.inferBinaryName(location, jfo);
- assert result != null;
- return result;
- }
-
- // A [Java]FileObject's "name" looks like this: "/orc/codehaus/commons/compiler/Foo.java".
- // A [Java]FileObject's "binary name" looks like "java.lang.annotation.Retention".
-
- String bn = jfo.getName();
- if (bn.startsWith("/"))
- bn = bn.substring(1);
-
- if (!bn.endsWith(jfo.getKind().extension)) {
- throw new AssertionError(
- "Name \"" + jfo.getName() + "\" does not match kind \"" + jfo.getKind() + "\""
- );
- }
- bn = bn.substring(0, bn.length() - jfo.getKind().extension.length());
-
- bn = bn.replace('/', '.');
-
- return bn;
- }
-
- @Override public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
- if (location == StandardLocation.CLASS_OUTPUT) {
- JavaFileObject javaFileObject = getJavaFileObjectByName(className);
-
- if (javaFileObject != null)
- return javaFileObject;
- }
-
- return fileManager.getJavaFileForInput(location, className, kind);
- }
-
- @Nullable private JavaFileObject getJavaFileObjectByName(String className) {
- final byte[] bytes = classes.get(className);
-
- if (bytes != null)
- return new MemoryJavaFileObject(className, bytes);
-
+ public static <T> ObjectFactory<T> factoryForClass(Class<T> tClass) {
+ if (mode(tClass) == null)
+ return new ObjectFactory<>(tClass);
+ else
return null;
- }
-
- @Override public JavaFileObject getJavaFileForOutput(Location location,
- String className,
- JavaFileObject.Kind kind,
- FileObject sibling) throws IOException {
- if (kind == JavaFileObject.Kind.CLASS)
- return new ClassOutputBuffer(className);
- else
- return super.getJavaFileForOutput(location, className, kind, sibling);
- }
}
- private static final class MemoryClassLoader extends URLClassLoader {
- private static final URL[] EMPTY_URLS = new URL[0];
-
- private final Map<String, byte[]> classBytes;
-
- public MemoryClassLoader(Map<String, byte[]> classBytes, ClassLoader parent) {
- super(EMPTY_URLS, parent);
-
- this.classBytes = classBytes;
- }
-
- @Override protected Class<?> findClass(String className) throws ClassNotFoundException {
- byte[] buf = classBytes.get(className); // clear the bytes in map -- we don't need it anymore
-
- if (buf != null)
- return defineClass(className, buf, 0, buf.length);
- else
- return super.findClass(className);
- }
- }
-
- public static <E> Iterable<E> concat(
- Iterable<? extends E> i1,
- Iterable<? extends E> i2) {
- return new Iterable<E>() {
- @Override public Iterator<E> iterator() {
- return new Iterator<E>() {
- Iterator<? extends E> listIterator = i1.iterator();
- Boolean checkedHasNext;
- E nextValue;
- private boolean startTheSecond;
-
- void theNext() {
- if (listIterator.hasNext()) {
- checkedHasNext = true;
- nextValue = listIterator.next();
- }
- else if (startTheSecond)
- checkedHasNext = false;
- else {
- startTheSecond = true;
- listIterator = i2.iterator();
- theNext();
- }
- }
-
- @Override public boolean hasNext() {
- if (checkedHasNext == null)
- theNext();
- return checkedHasNext;
- }
-
- @Override public E next() {
- if (!hasNext())
- throw new NoSuchElementException();
- checkedHasNext = null;
- return nextValue;
- }
-
- @Override public void remove() {
- listIterator.remove();
- }
- };
- }
- };
+ /** Stub. */
+ private MarshallerUtil() {
}
}
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 e690710..56a0cd6 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
@@ -27,7 +27,7 @@ public class SerializationException extends Exception {
* @param cause Cause.
*/
public SerializationException(Throwable cause) {
- // Used by serializers generated with Janino.
+ // Used by generated serializer.
super(cause);
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java
index 21a1560..a62400d 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/Serializer.java
@@ -34,9 +34,11 @@ public interface Serializer {
* @return Key object.
*/
Object deserializeKey(byte[] data) throws SerializationException;
+// <T> T deserializeKey(byte[] data) throws SerializationException;
/**
* @return Value object.
*/
Object deserializeValue(byte[] data) throws SerializationException;
+// <T> T deserializeValue(byte[] data) throws SerializationException;
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java
index ce88b18..63b4f73 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/SerializerFactory.java
@@ -29,7 +29,7 @@ public interface SerializerFactory {
/**
* @return Serializer factory back by code generator.
*/
- public static SerializerFactory createJaninoSerializerFactory() {
+ public static SerializerFactory createGeneratedSerializerFactory() {
return new SerializerGenerator();
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/IdentityObjectMarshallerExprGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/IdentityObjectMarshallerExprGenerator.java
index 9d292c7..5778a5a 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/IdentityObjectMarshallerExprGenerator.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/IdentityObjectMarshallerExprGenerator.java
@@ -24,32 +24,34 @@ import org.apache.ignite.internal.schema.marshaller.Serializer;
/**
* Generate {@link Serializer} method's bodies for simple types.
*/
-class IdentityObjectMarshallerExprGenerator extends MarshallerExprGenerator {
+class IdentityObjectMarshallerExprGenerator implements MarshallerCodeGenerator {
+ /** Tuple column accessor. */
+ private final TupleColumnAccessCodeGenerator columnAccessor;
+
/**
* Constructor.
*
- * @param aClass
- * @param tupleAccessorGen Object field access expression generators.
+ * @param columnAccessor Tuple column code generator.
*/
- IdentityObjectMarshallerExprGenerator(Class<?> aClass, TupleAccessorExpr tupleAccessorGen) {
- super(aClass, null /* no instantiation needed */, new TupleAccessorExpr[] {tupleAccessorGen});
+ IdentityObjectMarshallerExprGenerator(TupleColumnAccessCodeGenerator columnAccessor) {
+ this.columnAccessor = columnAccessor;
}
/** {@inheritDoc} */
- @Override boolean isSimpleType() {
+ @Override public boolean isSimpleType() {
return true;
}
/** {@inheritDoc} */
@Override public CodeBlock unmarshallObjectCode(String tupleExpr) {
return CodeBlock.builder()
- .add("return ").addStatement(tupleAccessors[0].read(tupleExpr))
+ .addStatement("return $L", columnAccessor.read(tupleExpr))
.build();
}
/** {@inheritDoc} */
@Override public CodeBlock marshallObjectCode(String asm, String objVar) {
- return tupleAccessors[0].write(asm, objVar);
+ return columnAccessor.write(asm, objVar);
}
/** {@inheritDoc} */
@@ -58,7 +60,7 @@ class IdentityObjectMarshallerExprGenerator extends MarshallerExprGenerator {
}
/** {@inheritDoc} */
- @Override public void staticHandlers(TypeSpec.Builder builder, CodeBlock.Builder staticBuilder) {
-
+ @Override public void initStaticHandlers(TypeSpec.Builder builder, CodeBlock.Builder staticBuilder) {
+ throw new UnsupportedOperationException("Static handlers are not applicable to simple types.");
}
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/MarshallerCodeGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/MarshallerCodeGenerator.java
new file mode 100644
index 0000000..bca3256
--- /dev/null
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/MarshallerCodeGenerator.java
@@ -0,0 +1,47 @@
+package org.apache.ignite.internal.schema.marshaller.generator;
+
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.TypeSpec;
+
+/**
+ * Marshaller code generator.
+ */
+interface MarshallerCodeGenerator {
+ /**
+ * @return {@code true} if it is simple object marshaller, {@code false} otherwise.
+ */
+ boolean isSimpleType();
+
+ /**
+ * @param tupleExpr Tuple to read from.
+ * @return Unmarshall object code.
+ */
+ CodeBlock unmarshallObjectCode(String tupleExpr);
+
+ /**
+ * @param asm Tuple assembler to write to.
+ * @param objVar Object to serialize.
+ * @return Marshall object code.
+ */
+ CodeBlock marshallObjectCode(String asm, String objVar);
+
+ /**
+ * @param objVar Object var.
+ * @param colIdx Column index.
+ * @return Object field value for given column.
+ */
+ CodeBlock getValueCode(String objVar, int colIdx);
+
+ /**
+ * @param classBuilder Class builder.
+ * @param staticInitBuilder Static initializer builder.
+ */
+ void initStaticHandlers(TypeSpec.Builder classBuilder, CodeBlock.Builder staticInitBuilder);
+
+ /**
+ * @return Marshaller target class.
+ */
+ default Class<?> getClazz() {
+ return null;
+ }
+}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/MarshallerExprGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/ObjectMarshallerCodeGenerator.java
similarity index 53%
rename from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/MarshallerExprGenerator.java
rename to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/ObjectMarshallerCodeGenerator.java
index 53be5ed..6a54d4d 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/MarshallerExprGenerator.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/ObjectMarshallerCodeGenerator.java
@@ -28,36 +28,40 @@ import org.apache.ignite.internal.schema.marshaller.MarshallerUtil;
import org.apache.ignite.internal.schema.marshaller.Serializer;
/**
- * Generate {@link Serializer} method's bodies.
+ * Generates {@link Serializer} methods code.
*/
-class MarshallerExprGenerator {
- /** Object factory regerence expression. */
- private final String factoryRefExpr;
+class ObjectMarshallerCodeGenerator implements MarshallerCodeGenerator {
+ /** Target object factory var. */
+ private final String objectFactoryVar;
+ /** Target class. */
private final Class<?> tClass;
+ /** Mapped columns. */
private final Columns columns;
/** Object field access expression generators. */
- protected TupleAccessorExpr[] tupleAccessors;
+ private final TupleColumnAccessCodeGenerator[] columnAccessessors;
/**
* Constructor.
*
- * @param tClass
- * @param factoryRefExpr Object factory regerence expression.
+ * @param tClass Target object class.
+ * @param objectFactoryVar Target object factory var.
+ * @param columns Column object is mapped to.
+ * @param firstColIdx Column index offset.
*/
- public MarshallerExprGenerator(Class<?> tClass, String factoryRefExpr, Columns columns, int firstColIdx) {
- this.factoryRefExpr = factoryRefExpr;
+ public ObjectMarshallerCodeGenerator(Class<?> tClass, String objectFactoryVar, Columns columns, int firstColIdx) {
+ this.objectFactoryVar = objectFactoryVar;
this.tClass = tClass;
this.columns = columns;
- tupleAccessors = new TupleAccessorExpr[this.columns.length()];
+ columnAccessessors = new TupleColumnAccessCodeGenerator[this.columns.length()];
try {
for (int i = 0; i < columns.length(); i++) {
final Field field = tClass.getDeclaredField(columns.column(i).name());
- tupleAccessors[i] = TupleAccessorExpr.createAccessor(MarshallerUtil.mode(field.getType()), i + firstColIdx);
+ columnAccessessors[i] = TupleColumnAccessCodeGenerator.createAccessor(MarshallerUtil.mode(field.getType()), i + firstColIdx);
}
}
catch (NoSuchFieldException ex) {
@@ -65,60 +69,56 @@ class MarshallerExprGenerator {
}
}
- public MarshallerExprGenerator(Class<?> tClass, Object expr, TupleAccessorExpr[] tupleAccessorExprs) {
- this.factoryRefExpr = null;
- this.tClass = tClass;
- columns = null;
- this.tupleAccessors = tupleAccessorExprs;
+ /** {@inheritDoc} */
+ @Override public Class<?> getClazz() {
+ return tClass;
}
- /**
- * @return {@code true} if it is simple object marshaller, {@code false} otherwise.
- */
- boolean isSimpleType() {
+ /** {@inheritDoc} */
+ @Override public boolean isSimpleType() {
return false;
}
- Class<?> getClazz() {
- return tClass;
- }
-
- public CodeBlock unmarshallObjectCode(String tupleExpr) {
+ /** {@inheritDoc} */
+ @Override public CodeBlock unmarshallObjectCode(String tupleExpr) {
final CodeBlock.Builder builder = CodeBlock.builder()
- .add("Object obj = ").add(factoryRefExpr).addStatement(".create()");
+ .addStatement("$T obj = ($T)$L.create()", tClass, tClass, objectFactoryVar);
- for (int i = 0; i < tupleAccessors.length; i++)
- builder.addStatement("FIELD_HANDLE_$L.set(obj, $L)", tupleAccessors[i].colIdx, tupleAccessors[i].read(tupleExpr).toString());
+ for (int i = 0; i < columnAccessessors.length; i++)
+ builder.addStatement("FIELD_HANDLE_$L.set(obj, $L)", columnAccessessors[i].columnIdx(), columnAccessessors[i].read(tupleExpr).toString());
builder.addStatement("return obj");
return builder.build();
}
- public CodeBlock getValueCode(String objVar, int i) {
- return CodeBlock.of("FIELD_HANDLE_$L.get($L)", tupleAccessors[i].colIdx, objVar);
+ /** {@inheritDoc} */
+ @Override public CodeBlock getValueCode(String objVar, int i) {
+ return CodeBlock.of("FIELD_HANDLE_$L.get($L)", columnAccessessors[i].columnIdx(), objVar);
}
- public CodeBlock marshallObjectCode(String asm, String objVar) {
+ /** {@inheritDoc} */
+ @Override public CodeBlock marshallObjectCode(String asm, String objVar) {
final CodeBlock.Builder builder = CodeBlock.builder();
- for (int i = 0; i < tupleAccessors.length; i++)
- builder.addStatement(tupleAccessors[i].write(asm, getValueCode(objVar, i).toString()).toString());
+ for (int i = 0; i < columnAccessessors.length; i++)
+ builder.add(columnAccessessors[i].write(asm, getValueCode(objVar, i).toString()));
return builder.build();
}
- public void staticHandlers(TypeSpec.Builder builder, CodeBlock.Builder staticBuilder) {
- for (int i = 0; i < tupleAccessors.length; i++) {
+ /** {@inheritDoc} */
+ @Override public void initStaticHandlers(TypeSpec.Builder builder, CodeBlock.Builder staticBuilder) {
+ for (int i = 0; i < columnAccessessors.length; i++) {
builder.addField(FieldSpec.builder(
VarHandle.class,
- CodeBlock.of("FIELD_HANDLE_$L", tupleAccessors[i].colIdx).toString(),
+ CodeBlock.of("FIELD_HANDLE_$L", columnAccessessors[i].columnIdx()).toString(),
Modifier.PRIVATE,
Modifier.FINAL,
Modifier.STATIC)
.build());
staticBuilder.addStatement("FIELD_HANDLE_$L = lookup.unreflectVarHandle($T.class.getDeclaredField($S))",
- tupleAccessors[i].colIdx, tClass, columns.column(i).name());
+ columnAccessessors[i].columnIdx(), tClass, columns.column(i).name());
}
}
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/SerializerGenerator.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/SerializerGenerator.java
index 42786bf..c43406b 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/SerializerGenerator.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/SerializerGenerator.java
@@ -26,6 +26,7 @@ import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.InvocationTargetException;
+import java.util.Objects;
import javax.annotation.processing.Generated;
import javax.lang.model.element.Modifier;
import org.apache.ignite.internal.schema.ByteBufferTuple;
@@ -34,22 +35,23 @@ import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.schema.Tuple;
import org.apache.ignite.internal.schema.TupleAssembler;
import org.apache.ignite.internal.schema.marshaller.BinaryMode;
+import org.apache.ignite.internal.schema.marshaller.CompilerUtils;
import org.apache.ignite.internal.schema.marshaller.MarshallerUtil;
import org.apache.ignite.internal.schema.marshaller.SerializationException;
import org.apache.ignite.internal.schema.marshaller.Serializer;
import org.apache.ignite.internal.schema.marshaller.SerializerFactory;
import org.apache.ignite.internal.util.ObjectFactory;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
- * {@link Serializer} code generator backed with Janino.
+ * {@link Serializer} code generator.
*/
public class SerializerGenerator implements SerializerFactory {
-
+ /** Serializer package name. */
public static final String SERIALIZER_PACKAGE_NAME = "org.apache.ignite.internal.schema.marshaller";
- public static final String SERIALIZER_CLASS_NAME_PREFIX = "JaninoSerializerForSchema_";
+ /** Serializer package name prefix. */
+ public static final String SERIALIZER_CLASS_NAME_PREFIX = "SerializerForSchema_";
/** {@inheritDoc} */
@Override public Serializer create(
@@ -57,26 +59,26 @@ public class SerializerGenerator implements SerializerFactory {
Class<?> keyClass,
Class<?> valClass
) {
- // Generate Serializer code.
final String className = SERIALIZER_CLASS_NAME_PREFIX + schema.version();
+ try {
+ // Generate Serializer code.
+ JavaFile javaFile = generateSerializerClassCode(className, schema, keyClass, valClass);
- JavaFile javaFile = generateSerializerClassCode(className, schema, keyClass, valClass);
-
- //TODO: pass code to logger on trace level.
- System.out.println(javaFile.toString());
-
- final ClassLoader loader = MarshallerUtil.compileCode(javaFile);
+ //TODO: pass code to logger on trace level.
+// System.out.println(javaFile.toString());
- try {
- final Class<?> aClass = loader.loadClass(javaFile.packageName + '.' + className);
+ // Compile.
+ ClassLoader loader = CompilerUtils.compileCode(javaFile);
- return (Serializer)aClass
+ // Instantiate serializer.
+ return (Serializer)loader.loadClass(javaFile.packageName + '.' + className)
.getDeclaredConstructor(SchemaDescriptor.class, Class.class, Class.class)
.newInstance(schema, keyClass, valClass);
}
catch (InstantiationException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
- throw new IllegalStateException(e);
+ throw new IllegalStateException("Failed to create serializer for key-value pair: schemaVer=" + schema.version() +
+ ", keyClass=" + keyClass.getSimpleName() + ", valueClass=" + valClass.getSimpleName(), e);
}
}
@@ -84,15 +86,17 @@ public class SerializerGenerator implements SerializerFactory {
* Generates serializer code.
*
* @param className Serializer class name.
+ * @param schema Schema descriptor.
+ * @param keyClass Key class.
* @param valClass Value class.
- * @return Generated class code.
+ * @return Generated java file representation.
*/
private JavaFile generateSerializerClassCode(String className, SchemaDescriptor schema, Class<?> keyClass,
Class<?> valClass) {
try {
- // Build field accessor generators.
- final MarshallerExprGenerator keyMarsh = createObjectMarshaller(keyClass, "keyFactory", schema.keyColumns(), 0);
- final MarshallerExprGenerator valMarsh = createObjectMarshaller(valClass, "valFactory", schema.valueColumns(), schema.keyColumns().length());
+ // Build code generators.
+ final MarshallerCodeGenerator keyMarsh = createObjectMarshaller(keyClass, "keyFactory", schema.keyColumns(), 0);
+ final MarshallerCodeGenerator valMarsh = createObjectMarshaller(valClass, "valFactory", schema.valueColumns(), schema.keyColumns().length());
final TypeSpec.Builder classBuilder = TypeSpec.classBuilder(className)
.addSuperinterface(Serializer.class)
@@ -115,14 +119,14 @@ public class SerializerGenerator implements SerializerFactory {
.addStatement("this.valFactory = $T.factoryForClass(valClass)", MarshallerUtil.class)
.build()
)
- .addMethod(generateHelpersMetod(schema, keyMarsh, valMarsh))
+ .addMethod(generateTupleAsseblerFactoryMethod(schema, keyMarsh, valMarsh))
.addMethod(generateSerializeMethod(keyMarsh, valMarsh))
.addMethod(generateDeserializeKeyMethod(keyMarsh))
.addMethod(generateDeserializeValueMethod(valMarsh));
return JavaFile
.builder(SERIALIZER_PACKAGE_NAME, classBuilder.build())
- .addStaticImport(TupleAccessorExpr.class, "*")
+ .addStaticImport(TupleColumnAccessCodeGenerator.class, "*")
.addStaticImport(MethodHandles.class, "Lookup")
.skipJavaLangImports(true)
.indent(" ")
@@ -134,34 +138,65 @@ public class SerializerGenerator implements SerializerFactory {
}
}
- private void initFieldHandlers(MarshallerExprGenerator keyMarsh, MarshallerExprGenerator valMarsh,
- TypeSpec.Builder classBuilder) {
+ /**
+ * @param keyMarsh Key marshaller code generator.
+ * @param valMarsh Value marshaller code generator.
+ * @param classBuilder Serializer class builder.
+ */
+ private void initFieldHandlers(
+ MarshallerCodeGenerator keyMarsh,
+ MarshallerCodeGenerator valMarsh,
+ TypeSpec.Builder classBuilder
+ ) {
if (keyMarsh.isSimpleType() && valMarsh.isSimpleType())
- return;
+ return; // No field hanlders needed for simple types.
final CodeBlock.Builder staticInitBuilder = CodeBlock.builder()
.addStatement("$T.Lookup lookup", MethodHandles.class)
.beginControlFlow("try");
if (!keyMarsh.isSimpleType()) {
- staticInitBuilder.addStatement("lookup = $T.privateLookupIn($T.class, $T.lookup())", MethodHandles.class, keyMarsh.getClazz(), MethodHandles.class);
- keyMarsh.staticHandlers(classBuilder, staticInitBuilder);
+ staticInitBuilder.addStatement(
+ "lookup = $T.privateLookupIn($T.class, $T.lookup())",
+ MethodHandles.class,
+ Objects.requireNonNull(keyMarsh.getClazz()),
+ MethodHandles.class
+ );
+
+ keyMarsh.initStaticHandlers(classBuilder, staticInitBuilder);
}
if (!valMarsh.isSimpleType()) {
- staticInitBuilder.addStatement("lookup = $T.privateLookupIn($T.class, $T.lookup())", MethodHandles.class, valMarsh.getClazz(), MethodHandles.class);
- valMarsh.staticHandlers(classBuilder, staticInitBuilder);
+ staticInitBuilder.addStatement(
+ "lookup = $T.privateLookupIn($T.class, $T.lookup())",
+ MethodHandles.class,
+ Objects.requireNonNull(valMarsh.getClazz()),
+ MethodHandles.class
+ );
+
+ valMarsh.initStaticHandlers(classBuilder, staticInitBuilder);
}
- staticInitBuilder.nextControlFlow("catch ($T | $T ex)", ReflectiveOperationException.class, SecurityException.class)
+ staticInitBuilder
+ .nextControlFlow(
+ "catch ($T | $T ex)",
+ ReflectiveOperationException.class,
+ SecurityException.class
+ )
.addStatement("throw new $T(ex)", IllegalStateException.class)
.endControlFlow();
classBuilder.addStaticBlock(staticInitBuilder.build());
}
- private MethodSpec generateHelpersMetod(SchemaDescriptor schema, MarshallerExprGenerator keyMarsh,
- MarshallerExprGenerator valMarsh) {
+ /**
+ * @param schema Schema descriptor.
+ * @param keyMarsh Key marshaller code generator.
+ * @param valMarsh Value marshaller code generator.
+ * @return Tuple accembler factory method spec.
+ */
+ private MethodSpec generateTupleAsseblerFactoryMethod(SchemaDescriptor schema, MarshallerCodeGenerator keyMarsh,
+ MarshallerCodeGenerator valMarsh) {
final MethodSpec.Builder builder = MethodSpec
.methodBuilder("createAssembler")
.addModifiers(Modifier.PRIVATE)
@@ -169,8 +204,8 @@ public class SerializerGenerator implements SerializerFactory {
.addParameter(Object.class, "val")
.returns(TupleAssembler.class)
- .addStatement("int nonNullVarlenKeys = 0; int nonNullVarlenValues = 0")
- .addStatement("int nonNullVarlenKeysSize = 0; int nonNullVarlenValuesSize = 0")
+ .addStatement("int varlenKeyCols = 0; int varlenValueCols = 0")
+ .addStatement("int varlenKeyColsSize = 0; int varlenValueColsSize = 0")
.addStatement("$T keyCols = schema.keyColumns()", Columns.class)
.addStatement("$T valCols = schema.valueColumns()", Columns.class);
@@ -185,8 +220,8 @@ public class SerializerGenerator implements SerializerFactory {
block.addStatement("fVal = $L", keyMarsh.getValueCode("key", i).toString());
block.beginControlFlow("if (fVal != null)")
- .addStatement("nonNullVarlenKeysSize += $T.getValueSize(fVal, keyCols.column($L).type())", MarshallerUtil.class, i)
- .addStatement("nonNullVarlenKeys++")
+ .addStatement("varlenKeyColsSize += $T.getValueSize(fVal, keyCols.column($L).type())", MarshallerUtil.class, i)
+ .addStatement("varlenKeyCols++")
.endControlFlow();
}
block.unindent();
@@ -208,8 +243,8 @@ public class SerializerGenerator implements SerializerFactory {
block.addStatement("fVal = $L", valMarsh.getValueCode("val", i).toString());
block.beginControlFlow("if (fVal != null)")
- .addStatement("nonNullVarlenValuesSize += $T.getValueSize(fVal, valCols.column($L).type())", MarshallerUtil.class, i)
- .addStatement("nonNullVarlenValues++")
+ .addStatement("varlenValueColsSize += $T.getValueSize(fVal, valCols.column($L).type())", MarshallerUtil.class, i)
+ .addStatement("varlenValueCols++")
.endControlFlow();
}
block.unindent();
@@ -220,15 +255,19 @@ public class SerializerGenerator implements SerializerFactory {
.addCode("}\n");
}
- builder.addStatement("int size = $T.tupleSize(keyCols, nonNullVarlenKeys, nonNullVarlenKeysSize," +
- "valCols, nonNullVarlenValues, nonNullVarlenValuesSize)", TupleAssembler.class);
+ builder.addStatement("int size = $T.tupleSize(keyCols, varlenKeyCols, varlenKeyColsSize," +
+ "valCols, varlenValueCols, varlenValueColsSize)", TupleAssembler.class);
- builder.addStatement("return new $T(schema, size, nonNullVarlenKeys, nonNullVarlenValues)", TupleAssembler.class);
+ builder.addStatement("return new $T(schema, size, varlenKeyCols, varlenValueCols)", TupleAssembler.class);
return builder.build();
}
- @NotNull private MethodSpec generateDeserializeValueMethod(MarshallerExprGenerator valMarsh) {
+ /**
+ * @param valMarsh Value marshaller code generator.
+ * @return Deserialize value method spec.
+ */
+ private MethodSpec generateDeserializeValueMethod(MarshallerCodeGenerator valMarsh) {
return MethodSpec
.methodBuilder("deserializeValue")
.addAnnotation(Override.class)
@@ -246,7 +285,11 @@ public class SerializerGenerator implements SerializerFactory {
.endControlFlow().build();
}
- @NotNull private MethodSpec generateDeserializeKeyMethod(MarshallerExprGenerator keyMarsh) {
+ /**
+ * @param keyMarsh Key marshaller code generator.
+ * @return Deserialize key method spec.
+ */
+ private MethodSpec generateDeserializeKeyMethod(MarshallerCodeGenerator keyMarsh) {
return MethodSpec
.methodBuilder("deserializeKey")
.addAnnotation(Override.class)
@@ -264,8 +307,12 @@ public class SerializerGenerator implements SerializerFactory {
.endControlFlow().build();
}
- @NotNull
- private MethodSpec generateSerializeMethod(MarshallerExprGenerator keyMarsh, MarshallerExprGenerator valMarsh) {
+ /**
+ * @param keyMarsh Key marshaller code generator.
+ * @param valMarsh Value marshaller code generator.
+ * @return Serialize method spec.
+ */
+ private MethodSpec generateSerializeMethod(MarshallerCodeGenerator keyMarsh, MarshallerCodeGenerator valMarsh) {
return MethodSpec.
methodBuilder("serialize")
.addAnnotation(Override.class)
@@ -288,25 +335,25 @@ public class SerializerGenerator implements SerializerFactory {
}
/**
- * Creates marshal/unmarshall expressions generator for object.
+ * Creates marshaller code generator for given class.
*
- * @param aClass Object class.
- * @param factoryRefExpr Factory reference expression.
- * @param columns Columns that aClass mapped to.
+ * @param tClass Target class.
+ * @param factoryRefVar Object factory variable.
+ * @param columns Columns that tClass mapped to.
* @param firstColIdx First column absolute index in schema.
- * @return Marshal/unmarshall expression generator.
+ * @return Marshaller code generator.
*/
- private MarshallerExprGenerator createObjectMarshaller(
- Class<?> aClass,
- @Nullable String factoryRefExpr,
+ private MarshallerCodeGenerator createObjectMarshaller(
+ Class<?> tClass,
+ @Nullable String factoryRefVar,
Columns columns,
int firstColIdx
) {
- BinaryMode mode = MarshallerUtil.mode(aClass);
+ BinaryMode mode = MarshallerUtil.mode(tClass);
- if (mode != null)
- return new IdentityObjectMarshallerExprGenerator(aClass, TupleAccessorExpr.createAccessor(mode, firstColIdx));
+ if (mode != null) // Simple type.
+ return new IdentityObjectMarshallerExprGenerator(TupleColumnAccessCodeGenerator.createAccessor(mode, firstColIdx));
else
- return new MarshallerExprGenerator(aClass, factoryRefExpr, columns, firstColIdx);
+ return new ObjectMarshallerCodeGenerator(tClass, factoryRefVar, columns, firstColIdx);
}
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/TupleAccessorExpr.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/TupleColumnAccessCodeGenerator.java
similarity index 55%
rename from modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/TupleAccessorExpr.java
rename to modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/TupleColumnAccessCodeGenerator.java
index ccca864..968f24c 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/TupleAccessorExpr.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/generator/TupleColumnAccessCodeGenerator.java
@@ -28,41 +28,71 @@ import org.apache.ignite.internal.schema.TupleAssembler;
import org.apache.ignite.internal.schema.marshaller.BinaryMode;
/**
- * Object field access expression generators.
+ * Tuple access code generator.
*/
-public class TupleAccessorExpr {
+public class TupleColumnAccessCodeGenerator {
+ /** Tuple method handler. */
public static final MethodHandle READ_BYTE;
+ /** Tuple method handler. */
public static final MethodHandle READ_SHORT;
+ /** Tuple method handler. */
public static final MethodHandle READ_INT;
+ /** Tuple method handler. */
public static final MethodHandle READ_LONG;
+ /** Tuple method handler. */
public static final MethodHandle READ_FLOAT;
+ /** Tuple method handler. */
public static final MethodHandle READ_DOUBLE;
+ /** Tuple method handler. */
public static final MethodHandle READ_BYTE_BOXED;
+ /** Tuple method handler. */
public static final MethodHandle READ_SHORT_BOXED;
+ /** Tuple method handler. */
public static final MethodHandle READ_INT_BOXED;
+ /** Tuple method handler. */
public static final MethodHandle READ_LONG_BOXED;
+ /** Tuple method handler. */
public static final MethodHandle READ_FLOAT_BOXED;
+ /** Tuple method handler. */
public static final MethodHandle READ_DOUBLE_BOXED;
+ /** Tuple method handler. */
public static final MethodHandle READ_UUID;
+ /** Tuple method handler. */
public static final MethodHandle READ_BITSET;
+ /** Tuple method handler. */
public static final MethodHandle READ_STRING;
+ /** Tuple method handler. */
public static final MethodHandle READ_BYTE_ARR;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_NULL;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_BYTE;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_SHORT;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_INT;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_LONG;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_FLOAT;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_DOUBLE;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_UUID;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_BITSET;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_STRING;
+ /** Tuple assembler method handler. */
public static final MethodHandle WRITE_BYTE_ARR;
+ /**
+ * Initializes static handlers.
+ */
static {
try {
- MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Tuple.class, MethodHandles.lookup());
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
READ_BYTE = lookup.findVirtual(Tuple.class, "byteValue", MethodType.methodType(byte.class, int.class));
READ_SHORT = lookup.findVirtual(Tuple.class, "shortValue", MethodType.methodType(short.class, int.class));
@@ -81,7 +111,6 @@ public class TupleAccessorExpr {
READ_STRING = lookup.findVirtual(Tuple.class, "stringValue", MethodType.methodType(String.class, int.class));
READ_BYTE_ARR = lookup.findVirtual(Tuple.class, "bytesValue", MethodType.methodType(byte[].class, int.class));
- lookup = MethodHandles.privateLookupIn(TupleAssembler.class, MethodHandles.lookup());
WRITE_NULL = lookup.findVirtual(TupleAssembler.class, "appendNull", MethodType.methodType(void.class));
WRITE_BYTE = lookup.findVirtual(TupleAssembler.class, "appendByte", MethodType.methodType(void.class, byte.class));
WRITE_SHORT = lookup.findVirtual(TupleAssembler.class, "appendShort", MethodType.methodType(void.class, short.class));
@@ -97,76 +126,128 @@ public class TupleAccessorExpr {
catch (NoSuchMethodException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
-
}
- private final Class<?> rType;
-
- static TupleAccessorExpr createAccessor(BinaryMode mode, int colIdx) {
+ /**
+ * @param mode Binary mode.
+ * @param colIdx Column index in schema.
+ * @return Tuple column access code generator.
+ */
+ static TupleColumnAccessCodeGenerator createAccessor(BinaryMode mode, int colIdx) {
switch (mode) {
case P_BYTE:
- return new TupleAccessorExpr("READ_BYTE", "WRITE_BYTE", byte.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_BYTE", "WRITE_BYTE", byte.class, colIdx);
case P_SHORT:
- return new TupleAccessorExpr("READ_SHORT", "WRITE_SHORT", short.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_SHORT", "WRITE_SHORT", short.class, colIdx);
case P_INT:
- return new TupleAccessorExpr("READ_INT", "WRITE_INT", int.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_INT", "WRITE_INT", int.class, colIdx);
case P_LONG:
- return new TupleAccessorExpr("READ_LONG", "WRITE_LONG", long.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_LONG", "WRITE_LONG", long.class, colIdx);
case P_FLOAT:
- return new TupleAccessorExpr("READ_FLOAT", "WRITE_FLOAT", float.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_FLOAT", "WRITE_FLOAT", float.class, colIdx);
case P_DOUBLE:
- return new TupleAccessorExpr("READ_DOUBLE", "WRITE_DOUBLE", double.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_DOUBLE", "WRITE_DOUBLE", double.class, colIdx);
case BYTE:
- return new TupleAccessorExpr("READ_BYTE_BOXED", "WRITE_BYTE", Byte.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_BYTE_BOXED", "WRITE_BYTE", Byte.class, byte.class, colIdx);
case SHORT:
- return new TupleAccessorExpr("READ_SHORT_BOXED", "WRITE_SHORT", Short.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_SHORT_BOXED", "WRITE_SHORT", Short.class, short.class, colIdx);
case INT:
- return new TupleAccessorExpr("READ_INT_BOXED", "WRITE_INT", Integer.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_INT_BOXED", "WRITE_INT", Integer.class, int.class, colIdx);
case LONG:
- return new TupleAccessorExpr("READ_LONG_BOXED", "WRITE_LONG", Long.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_LONG_BOXED", "WRITE_LONG", Long.class, long.class, colIdx);
case FLOAT:
- return new TupleAccessorExpr("READ_FLOAT_BOXED", "WRITE_FLOAT", Float.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_FLOAT_BOXED", "WRITE_FLOAT", Float.class, float.class, colIdx);
case DOUBLE:
- return new TupleAccessorExpr("READ_DOUBLE_BOXED", "WRITE_DOUBLE", Double.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_DOUBLE_BOXED", "WRITE_DOUBLE", Double.class, double.class, colIdx);
case STRING:
- return new TupleAccessorExpr("READ_STRING", "WRITE_STRING", String.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_STRING", "WRITE_STRING", String.class, colIdx);
case UUID:
- return new TupleAccessorExpr("READ_UUID", "WRITE_UUID", UUID.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_UUID", "WRITE_UUID", UUID.class, colIdx);
case BYTE_ARR:
- return new TupleAccessorExpr("READ_BYTE_ARR", "WRITE_BYTE_ARR", byte[].class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_BYTE_ARR", "WRITE_BYTE_ARR", byte[].class, colIdx);
case BITSET:
- return new TupleAccessorExpr("READ_BITSET", "WRITE_BITSET", BitSet.class, colIdx);
+ return new TupleColumnAccessCodeGenerator("READ_BITSET", "WRITE_BITSET", BitSet.class, colIdx);
}
throw new IllegalStateException("Unsupported binary mode: " + mode);
}
- private final String readExpr;
- private final String writeExpr;
- final int colIdx;
+ /** Reader handle name. */
+ private final String readHandleName;
+
+ /** Writer handle name. */
+ private final String writeHandleName;
+
+ /** Mapped value type. */
+ private final Class<?> mappedType;
+
+ /** Write method argument type. */
+ private final Class<?> writeArgType;
- private TupleAccessorExpr(String readExpr, String writeExpr, Class<?> rType, int colIdx) {
- this.readExpr = readExpr;
- this.writeExpr = writeExpr;
+ /** Column index in schema. */
+ private final int colIdx;
+
+ /**
+ * Constructor.
+ *
+ * @param readHandleName Reader handle name.
+ * @param writeHandleName Writer handle name.
+ * @param mappedType Mapped value type.
+ * @param colIdx Column index in schema.
+ */
+ TupleColumnAccessCodeGenerator(String readHandleName, String writeHandleName, Class<?> mappedType, int colIdx) {
+ this(readHandleName, writeHandleName, mappedType, mappedType, colIdx);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param readHandleName Reader handle name.
+ * @param writeHandleName Writer handle name.
+ * @param mappedType Mapped value type.
+ * @param writeArgType Write method argument type.
+ * @param colIdx Column index in schema.
+ */
+ TupleColumnAccessCodeGenerator(String readHandleName, String writeHandleName, Class<?> mappedType,
+ Class<?> writeArgType, int colIdx) {
+ this.readHandleName = readHandleName;
+ this.writeHandleName = writeHandleName;
this.colIdx = colIdx;
- this.rType = rType;
+ this.mappedType = mappedType;
+ this.writeArgType = writeArgType;
+ }
+
+ /**
+ * @return Column index in schema.
+ */
+ public int columnIdx() {
+ return colIdx;
}
+ /**
+ * @param tuple Tuple.
+ * @return Code that reads column value from tuple.
+ */
public CodeBlock read(String tuple) {
- return CodeBlock.of("($T)$T.$L.invoke($L, $L)", rType, TupleAccessorExpr.class, readExpr, tuple, colIdx);
+ return CodeBlock.of("($T)$T.$L.invoke($L, $L)", mappedType, TupleColumnAccessCodeGenerator.class, readHandleName, tuple, colIdx);
}
+ /**
+ * @param asmVar Tuple assembler var.
+ * @param valExpr Value expression.
+ * @return Code that writes value to tuple column.
+ */
public CodeBlock write(String asmVar, String valExpr) {
- if (rType.isPrimitive())
- return CodeBlock.of("$T.$L.invoke($L, $L)", TupleAccessorExpr.class, writeExpr, asmVar, valExpr);
+ if (mappedType.isPrimitive())
+ return CodeBlock.builder().addStatement("$T.$L.invokeExact($L, ($T)$L)", TupleColumnAccessCodeGenerator.class, writeHandleName, asmVar, writeArgType, valExpr).build();
else {
return CodeBlock.builder()
.add("{\n").indent()
- .addStatement("$T fVal", rType)
- .beginControlFlow("if((fVal = ($T)$L) == null)", rType, valExpr)
- .addStatement("$T.WRITE_NULL.invoke($L)", TupleAccessorExpr.class, asmVar)
+ .addStatement("$T fVal", mappedType)
+ .beginControlFlow("if((fVal = ($T)$L) == null)", mappedType, valExpr)
+ .addStatement("$T.WRITE_NULL.invokeExact($L)", TupleColumnAccessCodeGenerator.class, asmVar)
.nextControlFlow("else")
- .addStatement("$T.$L.invoke($L, fVal)", TupleAccessorExpr.class, writeExpr, asmVar)
+ .addStatement("$T.$L.invokeExact($L, ($T)fVal)", TupleColumnAccessCodeGenerator.class, writeHandleName, asmVar, writeArgType)
.endControlFlow()
.unindent()
.add("}\n")
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/FieldAccessor.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/FieldAccessor.java
index 812b02e..6cad0d0 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/FieldAccessor.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/FieldAccessor.java
@@ -20,7 +20,9 @@ package org.apache.ignite.internal.schema.marshaller.reflection;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.reflect.Field;
+import java.util.BitSet;
import java.util.Objects;
+import java.util.UUID;
import org.apache.ignite.internal.schema.Column;
import org.apache.ignite.internal.schema.Columns;
import org.apache.ignite.internal.schema.Tuple;
@@ -148,6 +150,150 @@ public abstract class FieldAccessor {
}
/**
+ * Reads value object from tuple.
+ *
+ * @param reader Reader.
+ * @param colIdx Column index.
+ * @param mode Binary read mode.
+ * @return Read value object.
+ */
+ private static Object readRefValue(Tuple reader, int colIdx, BinaryMode mode) {
+ assert reader != null;
+ assert colIdx >= 0;
+
+ Object val = null;
+
+ switch (mode) {
+ case BYTE:
+ val = reader.byteValueBoxed(colIdx);
+
+ break;
+
+ case SHORT:
+ val = reader.shortValueBoxed(colIdx);
+
+ break;
+
+ case INT:
+ val = reader.intValueBoxed(colIdx);
+
+ break;
+
+ case LONG:
+ val = reader.longValueBoxed(colIdx);
+
+ break;
+
+ case FLOAT:
+ val = reader.floatValueBoxed(colIdx);
+
+ break;
+
+ case DOUBLE:
+ val = reader.doubleValueBoxed(colIdx);
+
+ break;
+
+ case STRING:
+ val = reader.stringValue(colIdx);
+
+ break;
+
+ case UUID:
+ val = reader.uuidValue(colIdx);
+
+ break;
+
+ case BYTE_ARR:
+ val = reader.bytesValue(colIdx);
+
+ break;
+
+ case BITSET:
+ val = reader.bitmaskValue(colIdx);
+
+ break;
+
+ default:
+ assert false : "Invalid mode: " + mode;
+ }
+
+ return val;
+ }
+
+ /**
+ * Writes reference value to tuple.
+ *
+ * @param val Value object.
+ * @param writer Writer.
+ * @param mode Write binary mode.
+ */
+ private static void writeRefObject(Object val, TupleAssembler writer, BinaryMode mode) {
+ assert writer != null;
+
+ if (val == null) {
+ writer.appendNull();
+
+ return;
+ }
+
+ switch (mode) {
+ case BYTE:
+ writer.appendByte((Byte)val);
+
+ break;
+
+ case SHORT:
+ writer.appendShort((Short)val);
+
+ break;
+
+ case INT:
+ writer.appendInt((Integer)val);
+
+ break;
+
+ case LONG:
+ writer.appendLong((Long)val);
+
+ break;
+
+ case FLOAT:
+ writer.appendFloat((Float)val);
+
+ break;
+
+ case DOUBLE:
+ writer.appendDouble((Double)val);
+
+ break;
+
+ case STRING:
+ writer.appendString((String)val);
+
+ break;
+
+ case UUID:
+ writer.appendUuid((UUID)val);
+
+ break;
+
+ case BYTE_ARR:
+ writer.appendBytes((byte[])val);
+
+ break;
+
+ case BITSET:
+ writer.appendBitmask((BitSet)val);
+
+ break;
+
+ default:
+ assert false : "Invalid mode: " + mode;
+ }
+ }
+
+ /**
* Protected constructor.
*
* @param varHandle Field.
@@ -265,7 +411,7 @@ public abstract class FieldAccessor {
/** {@inheritDoc} */
@Override protected void write0(Object obj, TupleAssembler writer) {
- JavaSerializer.writeRefObject(Objects.requireNonNull(obj, "Null values are not supported."), writer, mode);
+ writeRefObject(obj, writer, mode);
}
/** {@inheritDoc} */
@@ -275,7 +421,7 @@ public abstract class FieldAccessor {
/** {@inheritDoc} */
@Override public Object read(Tuple reader) {
- return JavaSerializer.readRefValue(reader, colIdx, mode);
+ return readRefValue(reader, colIdx, mode);
}
/** {@inheritDoc} */
@@ -486,12 +632,12 @@ public abstract class FieldAccessor {
return;
}
- JavaSerializer.writeRefObject(val, writer, mode);
+ writeRefObject(val, writer, mode);
}
/** {@inheritDoc} */
@Override public void read0(Object obj, Tuple reader) {
- Object val = JavaSerializer.readRefValue(reader, colIdx, mode);
+ Object val = readRefValue(reader, colIdx, mode);
varHandle.set(obj, val);
}
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/JavaSerializer.java b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/JavaSerializer.java
index 4bbb630..5e63e33 100644
--- a/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/JavaSerializer.java
+++ b/modules/commons/src/main/java/org/apache/ignite/internal/schema/marshaller/reflection/JavaSerializer.java
@@ -17,14 +17,11 @@
package org.apache.ignite.internal.schema.marshaller.reflection;
-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.SchemaDescriptor;
import org.apache.ignite.internal.schema.Tuple;
import org.apache.ignite.internal.schema.TupleAssembler;
-import org.apache.ignite.internal.schema.marshaller.BinaryMode;
import org.apache.ignite.internal.schema.marshaller.SerializationException;
import org.apache.ignite.internal.schema.marshaller.Serializer;
@@ -34,151 +31,6 @@ import static org.apache.ignite.internal.schema.marshaller.MarshallerUtil.getVal
* Reflection based (de)serializer.
*/
public class JavaSerializer implements Serializer {
-
- /**
- * Reads value object from tuple.
- *
- * @param reader Reader.
- * @param colIdx Column index.
- * @param mode Binary read mode.
- * @return Read value object.
- */
- static Object readRefValue(Tuple reader, int colIdx, BinaryMode mode) {
- assert reader != null;
- assert colIdx >= 0;
-
- Object val = null;
-
- switch (mode) {
- case BYTE:
- val = reader.byteValueBoxed(colIdx);
-
- break;
-
- case SHORT:
- val = reader.shortValueBoxed(colIdx);
-
- break;
-
- case INT:
- val = reader.intValueBoxed(colIdx);
-
- break;
-
- case LONG:
- val = reader.longValueBoxed(colIdx);
-
- break;
-
- case FLOAT:
- val = reader.floatValueBoxed(colIdx);
-
- break;
-
- case DOUBLE:
- val = reader.doubleValueBoxed(colIdx);
-
- break;
-
- case STRING:
- val = reader.stringValue(colIdx);
-
- break;
-
- case UUID:
- val = reader.uuidValue(colIdx);
-
- break;
-
- case BYTE_ARR:
- val = reader.bytesValue(colIdx);
-
- break;
-
- case BITSET:
- val = reader.bitmaskValue(colIdx);
-
- break;
-
- default:
- assert false : "Invalid mode: " + mode;
- }
-
- return val;
- }
-
- /**
- * Writes reference value to tuple.
- *
- * @param val Value object.
- * @param writer Writer.
- * @param mode Write binary mode.
- */
- static void writeRefObject(Object val, TupleAssembler writer, BinaryMode mode) {
- assert writer != null;
-
- if (val == null) {
- writer.appendNull();
-
- return;
- }
-
- switch (mode) {
- case BYTE:
- writer.appendByte((Byte)val);
-
- break;
-
- case SHORT:
- writer.appendShort((Short)val);
-
- break;
-
- case INT:
- writer.appendInt((Integer)val);
-
- break;
-
- case LONG:
- writer.appendLong((Long)val);
-
- break;
-
- case FLOAT:
- writer.appendFloat((Float)val);
-
- break;
-
- case DOUBLE:
- writer.appendDouble((Double)val);
-
- break;
-
- case STRING:
- writer.appendString((String)val);
-
- break;
-
- case UUID:
- writer.appendUuid((UUID)val);
-
- break;
-
- case BYTE_ARR:
- writer.appendBytes((byte[])val);
-
- break;
-
- case BITSET:
- writer.appendBitmask((BitSet)val);
-
- break;
-
- default:
- assert false : "Invalid mode: " + mode;
- }
- }
-
/** Schema. */
private final SchemaDescriptor schema;
diff --git a/modules/commons/src/main/java/org/apache/ignite/internal/util/IgniteUnsafeUtils.java b/modules/commons/src/main/java/org/apache/ignite/internal/util/IgniteUnsafeUtils.java
deleted file mode 100644
index 74ea3a3..0000000
--- a/modules/commons/src/main/java/org/apache/ignite/internal/util/IgniteUnsafeUtils.java
+++ /dev/null
@@ -1,273 +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.util;
-
-import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import sun.misc.Unsafe;
-
-/**
- * Unsafe utility.
- */
-//TODO Move class to 'java-8' profile. Java9+ should use varhandles instead.
-public final class IgniteUnsafeUtils {
- /** Unsafe. */
- private static final Unsafe UNSAFE = unsafe();
-
- /**
- * @return Instance of Unsafe class.
- */
- private static Unsafe unsafe() {
- try {
- return Unsafe.getUnsafe();
- }
- catch (SecurityException ignored) {
- try {
- return AccessController.doPrivileged(
- new PrivilegedExceptionAction<Unsafe>() {
- @Override public Unsafe run() throws Exception {
- Field f = Unsafe.class.getDeclaredField("theUnsafe");
-
- f.setAccessible(true);
-
- return (Unsafe)f.get(null);
- }
- });
- }
- catch (PrivilegedActionException e) {
- throw new RuntimeException("Could not initialize intrinsics.", e.getCause());
- }
- }
- }
-
- /**
- * Returns object field offset.
- *
- * @param field Field.
- * @return Object field offset.
- */
- public static long objectFieldOffset(Field field) {
- return UNSAFE.objectFieldOffset(field);
- }
-
- /**
- * Gets boolean value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Boolean value from object field.
- */
- public static boolean getBooleanField(Object obj, long fieldOff) {
- return UNSAFE.getBoolean(obj, fieldOff);
- }
-
- /**
- * Stores boolean value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putBooleanField(Object obj, long fieldOff, boolean val) {
- UNSAFE.putBoolean(obj, fieldOff, val);
- }
-
- /**
- * Gets byte value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Byte value from object field.
- */
- public static byte getByteField(Object obj, long fieldOff) {
- return UNSAFE.getByte(obj, fieldOff);
- }
-
- /**
- * Stores byte value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putByteField(Object obj, long fieldOff, byte val) {
- UNSAFE.putByte(obj, fieldOff, val);
- }
-
- /**
- * Gets short value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Short value from object field.
- */
- public static short getShortField(Object obj, long fieldOff) {
- return UNSAFE.getShort(obj, fieldOff);
- }
-
- /**
- * Stores short value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putShortField(Object obj, long fieldOff, short val) {
- UNSAFE.putShort(obj, fieldOff, val);
- }
-
- /**
- * Gets char value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Char value from object field.
- */
- public static char getCharField(Object obj, long fieldOff) {
- return UNSAFE.getChar(obj, fieldOff);
- }
-
- /**
- * Stores char value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putCharField(Object obj, long fieldOff, char val) {
- UNSAFE.putChar(obj, fieldOff, val);
- }
-
- /**
- * Gets integer value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Integer value from object field.
- */
- public static int getIntField(Object obj, long fieldOff) {
- return UNSAFE.getInt(obj, fieldOff);
- }
-
- /**
- * Stores integer value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putIntField(Object obj, long fieldOff, int val) {
- UNSAFE.putInt(obj, fieldOff, val);
- }
-
- /**
- * Gets long value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Long value from object field.
- */
- public static long getLongField(Object obj, long fieldOff) {
- return UNSAFE.getLong(obj, fieldOff);
- }
-
- /**
- * Stores long value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putLongField(Object obj, long fieldOff, long val) {
- UNSAFE.putLong(obj, fieldOff, val);
- }
-
- /**
- * Gets float value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Float value from object field.
- */
- public static float getFloatField(Object obj, long fieldOff) {
- return UNSAFE.getFloat(obj, fieldOff);
- }
-
- /**
- * Stores float value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putFloatField(Object obj, long fieldOff, float val) {
- UNSAFE.putFloat(obj, fieldOff, val);
- }
-
- /**
- * Gets double value from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Double value from object field.
- */
- public static double getDoubleField(Object obj, long fieldOff) {
- return UNSAFE.getDouble(obj, fieldOff);
- }
-
- /**
- * Stores double value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putDoubleField(Object obj, long fieldOff, double val) {
- UNSAFE.putDouble(obj, fieldOff, val);
- }
-
- /**
- * Gets reference from object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @return Reference from object field.
- */
- public static Object getObjectField(Object obj, long fieldOff) {
- return UNSAFE.getObject(obj, fieldOff);
- }
-
- /**
- * Stores reference value into object field.
- *
- * @param obj Object.
- * @param fieldOff Field offset.
- * @param val Value.
- */
- public static void putObjectField(Object obj, long fieldOff, Object val) {
- UNSAFE.putObject(obj, fieldOff, val);
- }
-
- /**
- * Stub.
- */
- private IgniteUnsafeUtils() {
- }
-}
diff --git a/modules/commons/src/test/java/org/apache/ignite/internal/benchmarks/SerializerBenchmarkTest.java b/modules/commons/src/test/java/org/apache/ignite/internal/benchmarks/SerializerBenchmarkTest.java
index f574dec..1896573 100644
--- a/modules/commons/src/test/java/org/apache/ignite/internal/benchmarks/SerializerBenchmarkTest.java
+++ b/modules/commons/src/test/java/org/apache/ignite/internal/benchmarks/SerializerBenchmarkTest.java
@@ -27,7 +27,7 @@ import javax.lang.model.element.Modifier;
import org.apache.ignite.internal.schema.Column;
import org.apache.ignite.internal.schema.Columns;
import org.apache.ignite.internal.schema.SchemaDescriptor;
-import org.apache.ignite.internal.schema.marshaller.MarshallerUtil;
+import org.apache.ignite.internal.schema.marshaller.CompilerUtils;
import org.apache.ignite.internal.schema.marshaller.Serializer;
import org.apache.ignite.internal.schema.marshaller.SerializerFactory;
import org.apache.ignite.internal.util.Factory;
@@ -75,7 +75,7 @@ public class SerializerBenchmarkTest {
public int fieldsCount;
/** Serializer. */
- @Param({"Janino", "Java"})
+ @Param({"Generated", "Java"})
public String serializerName;
/**
@@ -94,7 +94,7 @@ public class SerializerBenchmarkTest {
*/
@Setup
public void init() throws Exception {
- Thread.currentThread().setContextClassLoader(MarshallerUtil.dynamicClassLoader());
+ Thread.currentThread().setContextClassLoader(CompilerUtils.dynamicClassLoader());
long seed = System.currentTimeMillis();
@@ -110,7 +110,7 @@ public class SerializerBenchmarkTest {
if ("Java".equals(serializerName))
serializer = SerializerFactory.createJavaSerializerFactory().create(schema, Long.class, valClass);
else
- serializer = SerializerFactory.createJaninoSerializerFactory().create(schema, Long.class, valClass);
+ serializer = SerializerFactory.createGeneratedSerializerFactory().create(schema, Long.class, valClass);
}
/**
@@ -182,7 +182,7 @@ public class SerializerBenchmarkTest {
final JavaFile javaFile = JavaFile.builder(packageName, classBuilder.build()).build();
- final ClassLoader loader = MarshallerUtil.compileCode(javaFile);
+ final ClassLoader loader = CompilerUtils.compileCode(javaFile);
try {
return loader.loadClass(packageName + '.' + className);
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 d10fdf7..7b41412 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
@@ -22,9 +22,7 @@ import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import java.util.Arrays;
import java.util.BitSet;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;
@@ -276,7 +274,7 @@ public class JavaSerializerTest {
public void testClassLoader(SerializerFactory factory) throws SerializationException {
final ClassLoader prevClassLoader = Thread.currentThread().getContextClassLoader();
try {
- Thread.currentThread().setContextClassLoader(MarshallerUtil.dynamicClassLoader());
+ Thread.currentThread().setContextClassLoader(CompilerUtils.dynamicClassLoader());
Column[] keyCols = new Column[] {
new Column("key", LONG, false)
@@ -395,7 +393,7 @@ public class JavaSerializerTest {
final JavaFile javaFile = JavaFile.builder(packageName, classBuilder.build()).build();
try {
- return MarshallerUtil.compileCode(javaFile).loadClass(packageName + '.' + className);
+ return CompilerUtils.compileCode(javaFile).loadClass(packageName + '.' + className);
}
catch (Exception ex) {
throw new IllegalStateException("Failed to compile/instantiate generated Serializer.", ex);