You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2015/10/30 16:52:45 UTC
[49/52] [abbrv] ignite git commit: IGNITE-950-new Fixed compilation.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c70a94/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectWriterExImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectWriterExImpl.java
index de2b810,0000000..5421bea
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectWriterExImpl.java
@@@ -1,1892 -1,0 +1,1855 @@@
+/*
+ * 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.portable;
+
+import org.apache.ignite.IgniteCheckedException;
++import org.apache.ignite.igniteobject.IgniteObjectIdMapper;
+import org.apache.ignite.internal.portable.streams.PortableHeapOutputStream;
+import org.apache.ignite.internal.portable.streams.PortableOutputStream;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.igniteobject.IgniteObjectException;
+import org.apache.ignite.igniteobject.IgniteObjectRawWriter;
+import org.apache.ignite.igniteobject.IgniteObjectWriter;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.Date;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLASS;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.COL;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DATE;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DATE_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DECIMAL;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DECIMAL_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.ENUM;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.ENUM_ARR;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLAGS_POS;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.MAP_ENTRY;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.OBJ_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.OPTM_MARSH;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.PORTABLE_OBJ;
- import static org.apache.ignite.internal.portable.GridPortableMarshaller.RAW_DATA_OFF_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.SCHEMA_ID_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.TIMESTAMP;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.TIMESTAMP_ARR;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.TOTAL_LEN_POS;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.UNREGISTERED_TYPE_ID;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID;
+import static org.apache.ignite.internal.portable.GridPortableMarshaller.UUID_ARR;
+
- /**
++/**
+ * Portable writer implementation.
+ */
+public class IgniteObjectWriterExImpl implements IgniteObjectWriter, IgniteObjectRawWriterEx, ObjectOutput {
+ /** Length: integer. */
+ private static final int LEN_INT = 4;
+
+ /** */
+ private static final int INIT_CAP = 1024;
+
- /** */
- private final PortableContext ctx;
++ /** FNV1 hash offset basis. */
++ private static final int FNV1_OFFSET_BASIS = 0x811C9DC5;
+
- /** */
- private final WriterContext wCtx;
++ /** FNV1 hash prime. */
++ private static final int FNV1_PRIME = 0x01000193;
++
++ /** Thread-local schema. */
++ private static final ThreadLocal<SchemaHolder> SCHEMA = new ThreadLocal<>();
+
+ /** */
- private final int start;
++ private final PortableContext ctx;
+
+ /** */
- private int mark;
++ private final int start;
+
+ /** */
+ private Class<?> cls;
+
+ /** */
+ private int typeId;
+
- /** */
- private boolean allowFields = true;
++ /** Raw offset position. */
++ private int rawOffPos;
+
+ /** */
+ private boolean metaEnabled;
+
+ /** */
+ private int metaHashSum;
+
- /**
- * @param ctx Context.
- * @param off Start offset.
- */
- IgniteObjectWriterExImpl(PortableContext ctx, int off) {
- this.ctx = ctx;
++ /** Handles. */
++ private Map<Object, Integer> handles;
+
- PortableOutputStream out = new PortableHeapOutputStream(off + INIT_CAP);
++ /** Output stream. */
++ private PortableOutputStream out;
+
- out.position(off);
++ /** Schema. */
++ private SchemaHolder schema;
+
- wCtx = new WriterContext(out, null);
++ /** Schema ID. */
++ private int schemaId;
+
- start = off;
- }
++ /** Amount of written fields. */
++ private int fieldCnt;
++
++ /** ID mapper. */
++ private IgniteObjectIdMapper idMapper;
+
+ /**
+ * @param ctx Context.
- * @param out Output stream.
- * @param off Start offset.
+ */
- IgniteObjectWriterExImpl(PortableContext ctx, PortableOutputStream out, int off) {
- this.ctx = ctx;
-
- wCtx = new WriterContext(out, null);
-
- start = off;
++ IgniteObjectWriterExImpl(PortableContext ctx) {
++ this(ctx, new PortableHeapOutputStream(INIT_CAP));
+ }
+
+ /**
+ * @param ctx Context.
- * @param off Start offset.
- * @param typeId Type ID.
++ * @param out Output stream.
+ */
- public IgniteObjectWriterExImpl(PortableContext ctx, int off, int typeId, boolean metaEnabled) {
- this(ctx, off);
++ IgniteObjectWriterExImpl(PortableContext ctx, PortableOutputStream out) {
++ this(ctx, out, new IdentityHashMap<Object, Integer>());
++ }
+
- this.typeId = typeId;
++ /**
++ * @param ctx Context.
++ * @param out Output stream.
++ * @param handles Handles.
++ */
++ private IgniteObjectWriterExImpl(PortableContext ctx, PortableOutputStream out, Map<Object, Integer> handles) {
++ this.ctx = ctx;
++ this.out = out;
++ this.handles = handles;
+
- this.metaEnabled = metaEnabled;
- }
++ start = out.position();
++ }
+
+ /**
+ * @param ctx Context.
- * @param wCtx Writer context.
++ * @param typeId Type ID.
+ */
- private IgniteObjectWriterExImpl(PortableContext ctx, WriterContext wCtx) {
- this.ctx = ctx;
- this.wCtx = wCtx;
++ public IgniteObjectWriterExImpl(PortableContext ctx, int typeId, boolean metaEnabled) {
++ this(ctx);
+
- start = wCtx.out.position();
++ this.typeId = typeId;
++ this.metaEnabled = metaEnabled;
+ }
+
+ /**
+ * Close the writer releasing resources if necessary.
+ */
+ @Override public void close() {
- wCtx.out.close();
++ out.close();
+ }
+
+ /**
+ * @return Meta data hash sum or {@code null} if meta data is disabled.
+ */
+ @Nullable Integer metaDataHashSum() {
+ return metaEnabled ? metaHashSum : null;
+ }
+
+ /**
+ * @param obj Object.
- * @param detached Detached or not.
- * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
++ * @throws IgniteObjectException In case of error.
++ */
++ void marshal(Object obj) throws IgniteObjectException {
++ marshal(obj, true);
++ }
++
++ /**
++ * @param obj Object.
++ * @param enableReplace Object replacing enabled flag.
++ * @throws IgniteObjectException In case of error.
+ */
- void marshal(Object obj, boolean detached) throws IgniteObjectException {
++ void marshal(Object obj, boolean enableReplace) throws IgniteObjectException {
+ assert obj != null;
+
+ cls = obj.getClass();
+
+ PortableClassDescriptor desc = ctx.descriptorForClass(cls);
+
+ if (desc == null)
+ throw new IgniteObjectException("Object is not portable: [class=" + cls + ']');
+
+ if (desc.excluded()) {
+ doWriteByte(NULL);
+ return;
+ }
+
+ if (desc.useOptimizedMarshaller()) {
+ writeByte(OPTM_MARSH);
+
+ try {
+ byte[] arr = ctx.optimizedMarsh().marshal(obj);
+
+ writeInt(arr.length);
+
+ write(arr);
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteObjectException("Failed to marshal object with optimized marshaller: " + obj, e);
+ }
+
+ return;
+ }
+
- if (desc.getWriteReplaceMethod() != null) {
- Object replace;
++ if (enableReplace && desc.getWriteReplaceMethod() != null) {
++ Object replacedObj;
+
+ try {
- replace = desc.getWriteReplaceMethod().invoke(obj);
++ replacedObj = desc.getWriteReplaceMethod().invoke(obj);
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof IgniteObjectException)
+ throw (IgniteObjectException)e.getTargetException();
+
+ throw new IgniteObjectException("Failed to execute writeReplace() method on " + obj, e);
+ }
+
- if (replace == null) {
++ if (replacedObj == null) {
+ doWriteByte(NULL);
+ return;
+ }
+
- if (cls != replace.getClass()) {
- cls = replace.getClass();
-
- desc = ctx.descriptorForClass(cls);
-
- if (desc == null)
- throw new IgniteObjectException("Object is not portable: [class=" + cls + ']');
- }
++ marshal(replacedObj, false);
+
- obj = replace;
++ return;
+ }
+
+ typeId = desc.typeId();
+
+ metaEnabled = ctx.isMetaDataEnabled(typeId);
+
- if (detached)
- wCtx.resetHandles();
-
+ desc.write(obj, this);
+ }
+
+ /**
+ * @param obj Object.
+ * @return Handle.
+ */
+ int handle(Object obj) {
+ assert obj != null;
+
- return wCtx.handle(obj);
++ Integer h = handles.get(obj);
++
++ if (h != null)
++ return out.position() - h;
++ else {
++ handles.put(obj, out.position());
++
++ return -1;
++ }
+ }
+
+ /**
+ * @return Array.
+ */
+ public byte[] array() {
- return wCtx.out.arrayCopy();
- }
-
- /**
- * @return Output stream.
- */
- public PortableOutputStream outputStream() {
- return wCtx.out;
++ return out.arrayCopy();
+ }
+
+ /**
+ * @return Stream current position.
+ */
+ int position() {
- return wCtx.out.position();
++ return out.position();
+ }
+
+ /**
+ * Sets new position.
+ *
+ * @param pos Position.
+ */
+ void position(int pos) {
- wCtx.out.position(pos);
++ out.position(pos);
+ }
+
- /**
++ /**
+ * @param bytes Number of bytes to reserve.
+ * @return Offset.
+ */
+ public int reserve(int bytes) {
- int pos = wCtx.out.position();
++ int pos = out.position();
+
- wCtx.out.position(pos + bytes);
++ out.position(pos + bytes);
+
+ return pos;
+ }
+
+ /**
- * @param bytes Number of bytes to reserve.
- * @return Offset.
++ * Perform post-write activity. This includes:
++ * - writing object length;
++ * - writing schema offset;
++ * - writing schema to the tail.
++ *
++ * @param userType User type flag.
+ */
- public int reserveAndMark(int bytes) {
- int off0 = reserve(bytes);
++ public void postWrite(boolean userType) {
++ if (schema != null) {
++ // Write schema ID.
++ out.writeInt(start + SCHEMA_ID_POS, schemaId);
+
- mark = wCtx.out.position();
++ // Write schema offset.
++ out.writeInt(start + SCHEMA_OR_RAW_OFF_POS, out.position() - start);
+
- return off0;
- }
++ // Write the schema.
++ schema.writeAndPop(this, fieldCnt);
+
- /**
- * @param off Offset.
- */
- public void writeDelta(int off) {
- wCtx.out.writeInt(off, wCtx.out.position() - mark);
- }
++ // Write raw offset if needed.
++ if (rawOffPos != 0)
++ out.writeInt(rawOffPos - start);
++ }
++ else {
++ // Write raw-only flag is needed.
++ int flags = (userType ? PortableUtils.FLAG_USR_TYP : 0) | PortableUtils.FLAG_RAW_ONLY;
+
- /**
- *
- */
- public void writeLength() {
- wCtx.out.writeInt(start + TOTAL_LEN_POS, wCtx.out.position() - start);
- }
++ out.writeShort(start + FLAGS_POS, (short)flags);
+
- /**
- *
- */
- public void writeRawOffsetIfNeeded() {
- if (allowFields)
- wCtx.out.writeInt(start + RAW_DATA_OFF_POS, wCtx.out.position() - start);
++ // If there are no schema, we are free to write raw offset to schema offset.
++ out.writeInt(start + SCHEMA_OR_RAW_OFF_POS, (rawOffPos == 0 ? out.position() : rawOffPos) - start);
++ }
++
++ // 5. Write length.
++ out.writeInt(start + TOTAL_LEN_POS, out.position() - start);
+ }
+
+ /**
+ * @param val Byte array.
+ */
+ public void write(byte[] val) {
+ assert val != null;
+
- wCtx.out.writeByteArray(val);
++ out.writeByteArray(val);
+ }
+
+ /**
+ * @param val Byte array.
+ * @param off Offset.
+ * @param len Length.
+ */
+ public void write(byte[] val, int off, int len) {
+ assert val != null;
+
- wCtx.out.write(val, off, len);
++ out.write(val, off, len);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteByte(byte val) {
- wCtx.out.writeByte(val);
++ out.writeByte(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteShort(short val) {
- wCtx.out.writeShort(val);
++ out.writeShort(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteInt(int val) {
- wCtx.out.writeInt(val);
++ out.writeInt(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteLong(long val) {
- wCtx.out.writeLong(val);
++ out.writeLong(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteFloat(float val) {
- wCtx.out.writeFloat(val);
++ out.writeFloat(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteDouble(double val) {
- wCtx.out.writeDouble(val);
++ out.writeDouble(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteChar(char val) {
- wCtx.out.writeChar(val);
++ out.writeChar(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ public void doWriteBoolean(boolean val) {
- wCtx.out.writeBoolean(val);
++ out.writeBoolean(val);
+ }
+
+ /**
+ * @param val String value.
+ */
+ public void doWriteDecimal(@Nullable BigDecimal val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(DECIMAL);
+
+ BigInteger intVal = val.unscaledValue();
+
+ if (intVal.signum() == -1) {
+ intVal = intVal.negate();
+
- wCtx.out.writeInt(val.scale() | 0x80000000);
++ out.writeInt(val.scale() | 0x80000000);
+ }
+ else
- wCtx.out.writeInt(val.scale());
++ out.writeInt(val.scale());
+
+ byte[] vals = intVal.toByteArray();
+
- wCtx.out.writeInt(vals.length);
- wCtx.out.writeByteArray(vals);
++ out.writeInt(vals.length);
++ out.writeByteArray(vals);
+ }
+ }
+
+ /**
+ * @param val String value.
+ */
+ public void doWriteString(@Nullable String val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(STRING);
+
+ if (ctx.isConvertString()) {
+ doWriteBoolean(true);
+
+ byte[] strArr = val.getBytes(UTF_8);
+
+ doWriteInt(strArr.length);
+
- wCtx.out.writeByteArray(strArr);
++ out.writeByteArray(strArr);
+ }
+ else {
+ doWriteBoolean(false);
+
+ char[] strArr = val.toCharArray();
+
+ doWriteInt(strArr.length);
+
- wCtx.out.writeCharArray(strArr);
++ out.writeCharArray(strArr);
+ }
+ }
+ }
+
+ /**
+ * @param uuid UUID.
+ */
+ public void doWriteUuid(@Nullable UUID uuid) {
+ if (uuid == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(UUID);
+ doWriteLong(uuid.getMostSignificantBits());
+ doWriteLong(uuid.getLeastSignificantBits());
+ }
+ }
+
+ /**
+ * @param date Date.
+ */
+ public void doWriteDate(@Nullable Date date) {
+ if (date == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(DATE);
+ doWriteLong(date.getTime());
+ }
+ }
+
- /**
- * @param ts Timestamp.
- */
- public void doWriteTimestamp(@Nullable Timestamp ts) {
- if (ts== null)
- doWriteByte(NULL);
- else {
- doWriteByte(TIMESTAMP);
- doWriteLong(ts.getTime());
- doWriteInt(ts.getNanos() % 1000000);
- }
- }
++ /**
++ * @param ts Timestamp.
++ */
++ public void doWriteTimestamp(@Nullable Timestamp ts) {
++ if (ts== null)
++ doWriteByte(NULL);
++ else {
++ doWriteByte(TIMESTAMP);
++ doWriteLong(ts.getTime());
++ doWriteInt(ts.getNanos() % 1000000);
++ }
++ }
+
+ /**
++ * Write object.
++ *
+ * @param obj Object.
- * @param detached Detached or not.
- * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
++ * @throws IgniteObjectException In case of error.
+ */
- public void doWriteObject(@Nullable Object obj, boolean detached) throws IgniteObjectException {
++ public void doWriteObject(@Nullable Object obj) throws IgniteObjectException {
+ if (obj == null)
+ doWriteByte(NULL);
+ else {
- WriterContext wCtx = detached ? new WriterContext(this.wCtx.out, this.wCtx.handles) : this.wCtx;
-
- IgniteObjectWriterExImpl writer = new IgniteObjectWriterExImpl(ctx, wCtx);
-
- writer.marshal(obj, detached);
++ IgniteObjectWriterExImpl writer = new IgniteObjectWriterExImpl(ctx, out, handles);
+
- if (detached)
- this.wCtx.out = wCtx.out;
++ writer.marshal(obj);
+ }
+ }
+
+ /**
+ * @param val Byte array.
+ */
+ void doWriteByteArray(@Nullable byte[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(BYTE_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeByteArray(val);
++ out.writeByteArray(val);
+ }
+ }
+
+ /**
+ * @param val Short array.
+ */
+ void doWriteShortArray(@Nullable short[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(SHORT_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeShortArray(val);
++ out.writeShortArray(val);
+ }
+ }
+
+ /**
+ * @param val Integer array.
+ */
+ void doWriteIntArray(@Nullable int[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(INT_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeIntArray(val);
++ out.writeIntArray(val);
+ }
+ }
+
+ /**
+ * @param val Long array.
+ */
+ void doWriteLongArray(@Nullable long[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(LONG_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeLongArray(val);
++ out.writeLongArray(val);
+ }
+ }
+
+ /**
+ * @param val Float array.
+ */
+ void doWriteFloatArray(@Nullable float[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(FLOAT_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeFloatArray(val);
++ out.writeFloatArray(val);
+ }
+ }
+
+ /**
+ * @param val Double array.
+ */
+ void doWriteDoubleArray(@Nullable double[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(DOUBLE_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeDoubleArray(val);
++ out.writeDoubleArray(val);
+ }
+ }
+
+ /**
+ * @param val Char array.
+ */
+ void doWriteCharArray(@Nullable char[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(CHAR_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeCharArray(val);
++ out.writeCharArray(val);
+ }
+ }
+
+ /**
+ * @param val Boolean array.
+ */
+ void doWriteBooleanArray(@Nullable boolean[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(BOOLEAN_ARR);
+ doWriteInt(val.length);
+
- wCtx.out.writeBooleanArray(val);
++ out.writeBooleanArray(val);
+ }
+ }
+
+ /**
+ * @param val Array of strings.
+ */
+ void doWriteDecimalArray(@Nullable BigDecimal[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(DECIMAL_ARR);
+ doWriteInt(val.length);
+
+ for (BigDecimal str : val)
+ doWriteDecimal(str);
+ }
+ }
+
+ /**
+ * @param val Array of strings.
+ */
+ void doWriteStringArray(@Nullable String[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(STRING_ARR);
+ doWriteInt(val.length);
+
+ for (String str : val)
+ doWriteString(str);
+ }
+ }
+
+ /**
+ * @param val Array of UUIDs.
+ */
+ void doWriteUuidArray(@Nullable UUID[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(UUID_ARR);
+ doWriteInt(val.length);
+
+ for (UUID uuid : val)
+ doWriteUuid(uuid);
+ }
+ }
+
+ /**
+ * @param val Array of dates.
+ */
+ void doWriteDateArray(@Nullable Date[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(DATE_ARR);
+ doWriteInt(val.length);
+
+ for (Date date : val)
+ doWriteDate(date);
+ }
+ }
+
+ /**
+ * @param val Array of timestamps.
+ */
+ void doWriteTimestampArray(@Nullable Timestamp[] val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ doWriteByte(TIMESTAMP_ARR);
+ doWriteInt(val.length);
+
+ for (Timestamp ts : val)
+ doWriteTimestamp(ts);
+ }
+ }
+
+ /**
+ * @param val Array of objects.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void doWriteObjectArray(@Nullable Object[] val) throws IgniteObjectException {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(val))
+ return;
+
+ PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType());
+
+ doWriteByte(OBJ_ARR);
+
+ if (desc.registered())
+ doWriteInt(desc.typeId());
+ else {
+ doWriteInt(UNREGISTERED_TYPE_ID);
+ doWriteString(val.getClass().getComponentType().getName());
+ }
+
+ doWriteInt(val.length);
+
+ for (Object obj : val)
- doWriteObject(obj, false);
++ doWriteObject(obj);
+ }
+ }
+
+ /**
+ * @param col Collection.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void doWriteCollection(@Nullable Collection<?> col) throws IgniteObjectException {
+ if (col == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(col))
+ return;
+
+ doWriteByte(COL);
+ doWriteInt(col.size());
+ doWriteByte(ctx.collectionType(col.getClass()));
+
+ for (Object obj : col)
- doWriteObject(obj, false);
++ doWriteObject(obj);
+ }
+ }
+
+ /**
+ * @param map Map.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void doWriteMap(@Nullable Map<?, ?> map) throws IgniteObjectException {
+ if (map == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(map))
+ return;
+
+ doWriteByte(MAP);
+ doWriteInt(map.size());
+ doWriteByte(ctx.mapType(map.getClass()));
+
+ for (Map.Entry<?, ?> e : map.entrySet()) {
- doWriteObject(e.getKey(), false);
- doWriteObject(e.getValue(), false);
++ doWriteObject(e.getKey());
++ doWriteObject(e.getValue());
+ }
+ }
+ }
+
+ /**
+ * @param e Map entry.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void doWriteMapEntry(@Nullable Map.Entry<?, ?> e) throws IgniteObjectException {
+ if (e == null)
+ doWriteByte(NULL);
+ else {
+ if (tryWriteAsHandle(e))
+ return;
+
+ doWriteByte(MAP_ENTRY);
- doWriteObject(e.getKey(), false);
- doWriteObject(e.getValue(), false);
++ doWriteObject(e.getKey());
++ doWriteObject(e.getValue());
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void doWriteEnum(@Nullable Enum<?> val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass());
+
+ doWriteByte(ENUM);
+
+ if (desc.registered())
+ doWriteInt(desc.typeId());
+ else {
+ doWriteInt(UNREGISTERED_TYPE_ID);
+ doWriteString(val.getClass().getName());
+ }
+
+ doWriteInt(val.ordinal());
+ }
+ }
+
+ /**
+ * @param val Array.
+ */
+ void doWriteEnumArray(@Nullable Object[] val) {
+ assert val == null || val.getClass().getComponentType().isEnum();
+
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType());
+ doWriteByte(ENUM_ARR);
+
+ if (desc.registered())
+ doWriteInt(desc.typeId());
+ else {
+ doWriteInt(UNREGISTERED_TYPE_ID);
+ doWriteString(val.getClass().getComponentType().getName());
+ }
+
+ doWriteInt(val.length);
+
+ // TODO: Denis: Redundant data for each element of the array.
+ for (Object o : val)
+ doWriteEnum((Enum<?>)o);
+ }
+ }
+
+ /**
+ * @param val Class.
+ */
+ void doWriteClass(@Nullable Class val) {
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ PortableClassDescriptor desc = ctx.descriptorForClass(val);
+
+ doWriteByte(CLASS);
+
+ if (desc.registered())
+ doWriteInt(desc.typeId());
+ else {
+ doWriteInt(UNREGISTERED_TYPE_ID);
+ doWriteString(val.getClass().getName());
+ }
+ }
+ }
+
+ /**
+ * @param po Portable object.
+ */
+ public void doWritePortableObject(@Nullable IgniteObjectImpl po) {
+ if (po == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(PORTABLE_OBJ);
+
+ byte[] poArr = po.array();
+
+ doWriteInt(poArr.length);
+
- wCtx.out.writeByteArray(poArr);
++ out.writeByteArray(poArr);
+
+ doWriteInt(po.start());
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeByteField(@Nullable Byte val) {
- doWriteInt(val != null ? 2 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(BYTE);
+ doWriteByte(val);
+ }
+ }
+
+ /**
+ * @param val Class.
+ */
+ void writeClassField(@Nullable Class val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteClass(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeShortField(@Nullable Short val) {
- doWriteInt(val != null ? 3 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(SHORT);
+ doWriteShort(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeIntField(@Nullable Integer val) {
- doWriteInt(val != null ? 5 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(INT);
+ doWriteInt(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeLongField(@Nullable Long val) {
- doWriteInt(val != null ? 9 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(LONG);
+ doWriteLong(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeFloatField(@Nullable Float val) {
- doWriteInt(val != null ? 5 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(FLOAT);
+ doWriteFloat(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeDoubleField(@Nullable Double val) {
- doWriteInt(val != null ? 9 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(DOUBLE);
+ doWriteDouble(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeCharField(@Nullable Character val) {
- doWriteInt(val != null ? 3 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(CHAR);
+ doWriteChar(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeBooleanField(@Nullable Boolean val) {
- doWriteInt(val != null ? 2 : 1);
-
+ if (val == null)
+ doWriteByte(NULL);
+ else {
+ doWriteByte(BOOLEAN);
+ doWriteBoolean(val);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeDecimalField(@Nullable BigDecimal val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteDecimal(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeStringField(@Nullable String val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteString(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeUuidField(@Nullable UUID val) {
- doWriteInt(val != null ? 17 : 1);
+ doWriteUuid(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeDateField(@Nullable Date val) {
- doWriteInt(val != null ? 9 : 1);
+ doWriteDate(val);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeTimestampField(@Nullable Timestamp val) {
- doWriteInt(val != null ? 13 : 1);
+ doWriteTimestamp(val);
+ }
+
+ /**
+ * @param obj Object.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void writeObjectField(@Nullable Object obj) throws IgniteObjectException {
- int lenPos = reserveAndMark(4);
-
- doWriteObject(obj, false);
-
- writeDelta(lenPos);
++ doWriteObject(obj);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeByteArrayField(@Nullable byte[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteByteArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeShortArrayField(@Nullable short[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteShortArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeIntArrayField(@Nullable int[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteIntArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeLongArrayField(@Nullable long[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteLongArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeFloatArrayField(@Nullable float[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteFloatArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeDoubleArrayField(@Nullable double[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteDoubleArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeCharArrayField(@Nullable char[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteCharArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeBooleanArrayField(@Nullable boolean[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteBooleanArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeDecimalArrayField(@Nullable BigDecimal[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteDecimalArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeStringArrayField(@Nullable String[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteStringArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeUuidArrayField(@Nullable UUID[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteUuidArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeDateArrayField(@Nullable Date[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteDateArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeTimestampArrayField(@Nullable Timestamp[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteTimestampArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void writeObjectArrayField(@Nullable Object[] val) throws IgniteObjectException {
- int lenPos = reserveAndMark(4);
-
+ doWriteObjectArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param col Collection.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void writeCollectionField(@Nullable Collection<?> col) throws IgniteObjectException {
- int lenPos = reserveAndMark(4);
-
+ doWriteCollection(col);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param map Map.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void writeMapField(@Nullable Map<?, ?> map) throws IgniteObjectException {
- int lenPos = reserveAndMark(4);
-
+ doWriteMap(map);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param e Map entry.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void writeMapEntryField(@Nullable Map.Entry<?, ?> e) throws IgniteObjectException {
- int lenPos = reserveAndMark(4);
-
+ doWriteMapEntry(e);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeEnumField(@Nullable Enum<?> val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteEnum(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param val Value.
+ */
+ void writeEnumArrayField(@Nullable Object[] val) {
- int lenPos = reserveAndMark(4);
-
+ doWriteEnumArray(val);
-
- writeDelta(lenPos);
+ }
+
+ /**
+ * @param po Portable object.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException In case of error.
+ */
+ void writePortableObjectField(@Nullable IgniteObjectImpl po) throws IgniteObjectException {
- int lenPos = reserveAndMark(4);
-
+ doWritePortableObject(po);
-
- writeDelta(lenPos);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByte(String fieldName, byte val) throws IgniteObjectException {
+ writeFieldId(fieldName, BYTE);
+ writeByteField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByte(byte val) throws IgniteObjectException {
+ doWriteByte(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShort(String fieldName, short val) throws IgniteObjectException {
+ writeFieldId(fieldName, SHORT);
+ writeShortField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShort(short val) throws IgniteObjectException {
+ doWriteShort(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeInt(String fieldName, int val) throws IgniteObjectException {
+ writeFieldId(fieldName, INT);
+ writeIntField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeInt(int val) throws IgniteObjectException {
+ doWriteInt(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLong(String fieldName, long val) throws IgniteObjectException {
+ writeFieldId(fieldName, LONG);
+ writeLongField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLong(long val) throws IgniteObjectException {
+ doWriteLong(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloat(String fieldName, float val) throws IgniteObjectException {
+ writeFieldId(fieldName, FLOAT);
+ writeFloatField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloat(float val) throws IgniteObjectException {
+ doWriteFloat(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDouble(String fieldName, double val) throws IgniteObjectException {
+ writeFieldId(fieldName, DOUBLE);
+ writeDoubleField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDouble(double val) throws IgniteObjectException {
+ doWriteDouble(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeChar(String fieldName, char val) throws IgniteObjectException {
+ writeFieldId(fieldName, CHAR);
+ writeCharField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeChar(char val) throws IgniteObjectException {
+ doWriteChar(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBoolean(String fieldName, boolean val) throws IgniteObjectException {
+ writeFieldId(fieldName, BOOLEAN);
+ writeBooleanField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBoolean(boolean val) throws IgniteObjectException {
+ doWriteBoolean(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDecimal(String fieldName, @Nullable BigDecimal val) throws IgniteObjectException {
+ writeFieldId(fieldName, DECIMAL);
+ writeDecimalField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDecimal(@Nullable BigDecimal val) throws IgniteObjectException {
+ doWriteDecimal(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeString(String fieldName, @Nullable String val) throws IgniteObjectException {
+ writeFieldId(fieldName, STRING);
+ writeStringField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeString(@Nullable String val) throws IgniteObjectException {
+ doWriteString(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeUuid(String fieldName, @Nullable UUID val) throws IgniteObjectException {
+ writeFieldId(fieldName, UUID);
+ writeUuidField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeUuid(@Nullable UUID val) throws IgniteObjectException {
+ doWriteUuid(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDate(String fieldName, @Nullable Date val) throws IgniteObjectException {
+ writeFieldId(fieldName, DATE);
+ writeDateField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDate(@Nullable Date val) throws IgniteObjectException {
+ doWriteDate(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeTimestamp(String fieldName, @Nullable Timestamp val) throws IgniteObjectException {
+ writeFieldId(fieldName, TIMESTAMP);
+ writeTimestampField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeTimestamp(@Nullable Timestamp val) throws IgniteObjectException {
+ doWriteTimestamp(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeObject(String fieldName, @Nullable Object obj) throws IgniteObjectException {
+ writeFieldId(fieldName, OBJ);
+ writeObjectField(obj);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeObject(@Nullable Object obj) throws IgniteObjectException {
- doWriteObject(obj, false);
++ doWriteObject(obj);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeObjectDetached(@Nullable Object obj) throws IgniteObjectException {
- doWriteObject(obj, true);
++ if (obj == null)
++ doWriteByte(NULL);
++ else {
++ IgniteObjectWriterExImpl writer = new IgniteObjectWriterExImpl(ctx, out, new IdentityHashMap<Object, Integer>());
++
++ writer.marshal(obj);
++ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByteArray(String fieldName, @Nullable byte[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, BYTE_ARR);
+ writeByteArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByteArray(@Nullable byte[] val) throws IgniteObjectException {
+ doWriteByteArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShortArray(String fieldName, @Nullable short[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, SHORT_ARR);
+ writeShortArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShortArray(@Nullable short[] val) throws IgniteObjectException {
+ doWriteShortArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeIntArray(String fieldName, @Nullable int[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, INT_ARR);
+ writeIntArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeIntArray(@Nullable int[] val) throws IgniteObjectException {
+ doWriteIntArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLongArray(String fieldName, @Nullable long[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, LONG_ARR);
+ writeLongArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLongArray(@Nullable long[] val) throws IgniteObjectException {
+ doWriteLongArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloatArray(String fieldName, @Nullable float[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, FLOAT_ARR);
+ writeFloatArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloatArray(@Nullable float[] val) throws IgniteObjectException {
+ doWriteFloatArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDoubleArray(String fieldName, @Nullable double[] val)
+ throws IgniteObjectException {
+ writeFieldId(fieldName, DOUBLE_ARR);
+ writeDoubleArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDoubleArray(@Nullable double[] val) throws IgniteObjectException {
+ doWriteDoubleArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeCharArray(String fieldName, @Nullable char[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, CHAR_ARR);
+ writeCharArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeCharArray(@Nullable char[] val) throws IgniteObjectException {
+ doWriteCharArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBooleanArray(String fieldName, @Nullable boolean[] val)
+ throws IgniteObjectException {
+ writeFieldId(fieldName, BOOLEAN_ARR);
+ writeBooleanArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBooleanArray(@Nullable boolean[] val) throws IgniteObjectException {
+ doWriteBooleanArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDecimalArray(String fieldName, @Nullable BigDecimal[] val)
+ throws IgniteObjectException {
+ writeFieldId(fieldName, DECIMAL_ARR);
+ writeDecimalArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDecimalArray(@Nullable BigDecimal[] val) throws IgniteObjectException {
+ doWriteDecimalArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeStringArray(String fieldName, @Nullable String[] val)
+ throws IgniteObjectException {
+ writeFieldId(fieldName, STRING_ARR);
+ writeStringArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeStringArray(@Nullable String[] val) throws IgniteObjectException {
+ doWriteStringArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeUuidArray(String fieldName, @Nullable UUID[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, UUID_ARR);
+ writeUuidArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeUuidArray(@Nullable UUID[] val) throws IgniteObjectException {
+ doWriteUuidArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDateArray(String fieldName, @Nullable Date[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, DATE_ARR);
+ writeDateArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDateArray(@Nullable Date[] val) throws IgniteObjectException {
+ doWriteDateArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeTimestampArray(String fieldName, @Nullable Timestamp[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, TIMESTAMP_ARR);
+ writeTimestampArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeTimestampArray(@Nullable Timestamp[] val) throws IgniteObjectException {
+ doWriteTimestampArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeObjectArray(String fieldName, @Nullable Object[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, OBJ_ARR);
+ writeObjectArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeObjectArray(@Nullable Object[] val) throws IgniteObjectException {
+ doWriteObjectArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> void writeCollection(String fieldName, @Nullable Collection<T> col)
+ throws IgniteObjectException {
+ writeFieldId(fieldName, COL);
+ writeCollectionField(col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> void writeCollection(@Nullable Collection<T> col) throws IgniteObjectException {
+ doWriteCollection(col);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <K, V> void writeMap(String fieldName, @Nullable Map<K, V> map)
+ throws IgniteObjectException {
+ writeFieldId(fieldName, MAP);
+ writeMapField(map);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <K, V> void writeMap(@Nullable Map<K, V> map) throws IgniteObjectException {
+ doWriteMap(map);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T extends Enum<?>> void writeEnum(String fieldName, T val) throws IgniteObjectException {
+ writeFieldId(fieldName, ENUM);
+ writeEnumField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T extends Enum<?>> void writeEnum(T val) throws IgniteObjectException {
+ doWriteEnum(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T extends Enum<?>> void writeEnumArray(String fieldName, T[] val) throws IgniteObjectException {
+ writeFieldId(fieldName, ENUM_ARR);
+ writeEnumArrayField(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T extends Enum<?>> void writeEnumArray(T[] val) throws IgniteObjectException {
+ doWriteEnumArray(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteObjectRawWriter rawWriter() {
- if (allowFields) {
- wCtx.out.writeInt(start + RAW_DATA_OFF_POS, wCtx.out.position() - start);
-
- allowFields = false;
- }
++ if (rawOffPos == 0)
++ rawOffPos = out.position();
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override public PortableOutputStream out() {
- return wCtx.out;
++ return out;
+ }
+
+ /** {@inheritDoc} */
++ @SuppressWarnings("NullableProblems")
+ @Override public void writeBytes(String s) throws IOException {
+ int len = s.length();
+
+ writeInt(len);
+
+ for (int i = 0; i < len; i++)
+ writeByte(s.charAt(i));
+ }
+
+ /** {@inheritDoc} */
++ @SuppressWarnings("NullableProblems")
+ @Override public void writeChars(String s) throws IOException {
+ int len = s.length();
+
+ writeInt(len);
+
+ for (int i = 0; i < len; i++)
+ writeChar(s.charAt(i));
+ }
+
+ /** {@inheritDoc} */
++ @SuppressWarnings("NullableProblems")
+ @Override public void writeUTF(String s) throws IOException {
+ writeString(s);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByte(int v) throws IOException {
- doWriteByte((byte)v);
++ doWriteByte((byte) v);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShort(int v) throws IOException {
- doWriteShort((short)v);
++ doWriteShort((short) v);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeChar(int v) throws IOException {
- doWriteChar((char)v);
++ doWriteChar((char) v);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void write(int b) throws IOException {
- doWriteByte((byte)b);
++ doWriteByte((byte) b);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void flush() throws IOException {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public int reserveInt() {
+ return reserve(LEN_INT);
+ }
+
- /** {@inheritDoc} */
++ /** {@inheritDoc} */
+ @Override public void writeInt(int pos, int val) throws IgniteObjectException {
- wCtx.out.writeInt(pos, val);
++ out.writeInt(pos, val);
+ }
+
+ /**
+ * @param fieldName Field name.
+ * @throws org.apache.ignite.igniteobject.IgniteObjectException If fields are not allowed.
+ */
+ private void writeFieldId(String fieldName, byte fieldType) throws IgniteObjectException {
+ A.notNull(fieldName, "fieldName");
+
- if (!allowFields)
++ if (rawOffPos != 0)
+ throw new IgniteObjectException("Individual field can't be written after raw writer is acquired " +
+ "via rawWriter() method. Consider fixing serialization logic for class: " + cls.getName());
+
- int id = ctx.fieldId(typeId, fieldName);
++ if (idMapper == null)
++ idMapper = ctx.userTypeIdMapper(typeId);
++
++ int id = idMapper.fieldId(typeId, fieldName);
++
++ writeFieldId(id);
+
+ if (metaEnabled)
+ metaHashSum = 31 * metaHashSum + (id + fieldType);
++ }
++
++ /**
++ * Write field ID.
++ * @param fieldId Field ID.
++ */
++ public void writeFieldId(int fieldId) {
++ int fieldOff = out.position() - start;
+
- doWriteInt(id);
++ if (schema == null) {
++ schema = SCHEMA.get();
++
++ if (schema == null) {
++ schema = new SchemaHolder();
++
++ SCHEMA.set(schema);
++ }
++
++ // Initialize offset when the first field is written.
++ schemaId = FNV1_OFFSET_BASIS;
++ }
++
++ // Advance schema hash.
++ int schemaId0 = schemaId ^ (fieldId & 0xFF);
++ schemaId0 = schemaId0 * FNV1_PRIME;
++ schemaId0 = schemaId0 ^ ((fieldId >> 8) & 0xFF);
++ schemaId0 = schemaId0 * FNV1_PRIME;
++ schemaId0 = schemaId0 ^ ((fieldId >> 16) & 0xFF);
++ schemaId0 = schemaId0 * FNV1_PRIME;
++ schemaId0 = schemaId0 ^ ((fieldId >> 24) & 0xFF);
++ schemaId0 = schemaId0 * FNV1_PRIME;
++
++ schemaId = schemaId0;
++
++ schema.push(fieldId, fieldOff);
++
++ fieldCnt++;
+ }
+
- /**
- * Attempts to write the object as a handle.
- *
- * @param obj Object to write.
- * @return {@code true} if the object has been written as a handle.
- */
- boolean tryWriteAsHandle(Object obj) {
- int handle = handle(obj);
++ /**
++ * Attempts to write the object as a handle.
++ *
++ * @param obj Object to write.
++ * @return {@code true} if the object has been written as a handle.
++ */
++ boolean tryWriteAsHandle(Object obj) {
++ int handle = handle(obj);
+
- if (handle >= 0) {
- doWriteByte(GridPortableMarshaller.HANDLE);
- doWriteInt(handle);
++ if (handle >= 0) {
++ doWriteByte(GridPortableMarshaller.HANDLE);
++ doWriteInt(handle);
+
- return true;
- }
++ return true;
++ }
+
- return false;
- }
++ return false;
++ }
+
+ /**
+ * Create new writer with same context.
++ *
+ * @param typeId type
+ * @return New writer.
+ */
+ public IgniteObjectWriterExImpl newWriter(int typeId) {
- IgniteObjectWriterExImpl res = new IgniteObjectWriterExImpl(ctx, wCtx);
++ IgniteObjectWriterExImpl res = new IgniteObjectWriterExImpl(ctx, out, handles);
+
+ res.typeId = typeId;
+
+ return res;
+ }
+
+ /**
+ * @return Portable context.
+ */
+ public PortableContext context() {
+ return ctx;
+ }
+
- /** */
- private static class WriterContext {
- /** */
- private Map<Object, Integer> handles = new IdentityHashMap<>();
++ /**
++ * Schema holder.
++ */
++ private static class SchemaHolder {
++ /** Grow step. */
++ private static final int GROW_STEP = 16;
++
++ /** Maximum stable size. */
++ private static final int MAX_SIZE = 256;
++
++ /** Data. */
++ private int[] data;
+
- /** Output stream. */
- private PortableOutputStream out;
++ /** Index. */
++ private int idx;
+
+ /**
+ * Constructor.
- *
- * @param out Output stream.
- * @param handles Handles.
+ */
- private WriterContext(PortableOutputStream out, Map<Object, Integer> handles) {
- this.out = out;
- this.handles = handles == null ? new IdentityHashMap<Object, Integer>() : handles;
++ public SchemaHolder() {
++ data = new int[GROW_STEP];
+ }
+
+ /**
- * @param obj Object.
- * @return Handle.
++ * Push another frame.
++ *
++ * @param id Field ID.
++ * @param off Field offset.
+ */
- private int handle(Object obj) {
- assert obj != null;
-
- Integer h = handles.get(obj);
++ public void push(int id, int off) {
++ if (idx == data.length) {
++ int[] data0 = new int[data.length + GROW_STEP];
+
- if (h != null)
- return out.position() - h;
- else {
- handles.put(obj, out.position());
++ System.arraycopy(data, 0, data0, 0, data.length);
+
- return -1;
++ data = data0;
+ }
++
++ data[idx] = id;
++ data[idx + 1] = off;
++
++ idx += 2;
+ }
+
+ /**
++ * Write collected frames and pop them.
+ *
++ * @param writer Writer.
++ * @param cnt Count.
+ */
- private void resetHandles() {
- handles = new IdentityHashMap<>();
++ public void writeAndPop(PortableWriterExImpl writer, int cnt) {
++ int startIdx = idx - cnt * 2;
++
++ assert startIdx >= 0;
++
++ for (int idx0 = startIdx; idx0 < idx;) {
++ writer.writeInt(data[idx0++]);
++ writer.writeInt(data[idx0++]);
++ }
++
++ idx = startIdx;
++
++ // Shrink data array if needed.
++ if (idx == 0 && data.length > MAX_SIZE)
++ data = new int[MAX_SIZE];
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c70a94/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
index 2470837,9f7f0c6..4cad80b
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
@@@ -17,6 -17,18 +17,14 @@@
package org.apache.ignite.internal.portable;
+ import org.apache.ignite.IgniteCheckedException;
+ import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
+ import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.marshaller.MarshallerExclusions;
+ import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+ import org.apache.ignite.marshaller.portable.PortableMarshaller;
-import org.apache.ignite.portable.PortableException;
-import org.apache.ignite.portable.PortableIdMapper;
-import org.apache.ignite.portable.PortableMarshalAware;
-import org.apache.ignite.portable.PortableSerializer;
+ import org.jetbrains.annotations.Nullable;
+
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInputStream;
@@@ -61,8 -62,11 +69,11 @@@ public class PortableClassDescriptor
private final Class<?> cls;
/** */
- private final PortableSerializer serializer;
+ private final IgniteObjectSerializer serializer;
+ /** ID mapper. */
+ private final PortableIdMapper idMapper;
+
/** */
private final Mode mode;
@@@ -513,14 -527,13 +534,13 @@@
if (serializer != null)
serializer.writePortable(obj, writer);
else
- ((PortableMarshalAware)obj).writePortable(writer);
+ ((IgniteObjectMarshalAware)obj).writePortable(writer);
- writer.writeRawOffsetIfNeeded();
- writer.writeLength();
+ writer.postWrite(userType);
- if (obj.getClass() != PortableMetaDataImpl.class
+ if (obj.getClass() != IgniteObjectMetaDataImpl.class
&& ctx.isMetaDataChanged(typeId, writer.metaDataHashSum())) {
- PortableMetaDataCollector metaCollector = new PortableMetaDataCollector(typeName);
+ IgniteObjectMetaDataCollector metaCollector = new IgniteObjectMetaDataCollector(typeName);
if (serializer != null)
serializer.writePortable(obj, metaCollector);
@@@ -539,10 -554,10 +561,10 @@@
((Externalizable)obj).writeExternal(writer);
}
catch (IOException e) {
- throw new PortableException("Failed to write Externalizable object: " + obj, e);
+ throw new IgniteObjectException("Failed to write Externalizable object: " + obj, e);
}
- writer.writeLength();
+ writer.postWrite(userType);
}
break;
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c70a94/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
index 471781c,e61cba7..3b32e67
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java
@@@ -81,10 -80,13 +103,13 @@@ public class PortableContext implement
private static final long serialVersionUID = 0L;
/** */
+ private static final ClassLoader dfltLdr = U.gridClassLoader();
+
+ /** */
- static final PortableIdMapper DFLT_ID_MAPPER = new IdMapperWrapper(null);
+ static final IgniteObjectIdMapper DFLT_ID_MAPPER = new IdMapperWrapper(null);
/** */
- static final PortableIdMapper BASIC_CLS_ID_MAPPER = new BasicClassIdMapper();
+ static final IgniteObjectIdMapper BASIC_CLS_ID_MAPPER = new BasicClassIdMapper();
/** */
static final char[] LOWER_CASE_CHARS;
@@@ -124,10 -126,10 +149,10 @@@
private final Map<Class<? extends Map>, Byte> mapTypes = new HashMap<>();
/** */
- private final Map<Integer, IgniteObjectIdMapper> mappers = new ConcurrentHashMap8<>(0);
- private final ConcurrentMap<Integer, PortableIdMapper> mappers = new ConcurrentHashMap8<>(0);
++ private final ConcurrentMap<Integer, IgniteObjectIdMapper> mappers = new ConcurrentHashMap8<>(0);
/** */
- private final Map<String, PortableIdMapper> typeMappers = new ConcurrentHashMap8<>(0);
+ private final Map<String, IgniteObjectIdMapper> typeMappers = new ConcurrentHashMap8<>(0);
/** */
private Map<Integer, Boolean> metaEnabled = new HashMap<>(0);
@@@ -475,10 -471,18 +505,18 @@@
desc = descByCls.get(cls);
}
catch (ClassNotFoundException e) {
+ // Class might have been loaded by default class loader.
+ if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null)
+ return desc;
+
- throw new PortableInvalidClassException(e);
+ throw new IgniteObjectInvalidClassException(e);
}
catch (IgniteCheckedException e) {
+ // Class might have been loaded by default class loader.
+ if (userType && !ldr.equals(dfltLdr) && (desc = descriptorForTypeId(true, typeId, dfltLdr)) != null)
+ return desc;
+
- throw new PortableException("Failed resolve class for ID: " + typeId, e);
+ throw new IgniteObjectException("Failed resolve class for ID: " + typeId, e);
}
if (desc == null) {
@@@ -537,7 -541,7 +575,7 @@@
String typeName = typeName(cls.getName());
- IgniteObjectIdMapper idMapper = idMapper(typeName);
- PortableIdMapper idMapper = userTypeIdMapper(typeName);
++ IgniteObjectIdMapper idMapper = userTypeIdMapper(typeName);
int typeId = idMapper.typeId(typeName);
@@@ -630,8 -639,8 +673,8 @@@
* @param typeId Type ID.
* @return Instance of ID mapper.
*/
- public IgniteObjectIdMapper idMapper(int typeId) {
- public PortableIdMapper userTypeIdMapper(int typeId) {
- PortableIdMapper idMapper = mappers.get(typeId);
++ public IgniteObjectIdMapper userTypeIdMapper(int typeId) {
+ IgniteObjectIdMapper idMapper = mappers.get(typeId);
if (idMapper != null)
return idMapper;
@@@ -646,8 -655,8 +689,8 @@@
* @param typeName Type name.
* @return Instance of ID mapper.
*/
- private IgniteObjectIdMapper idMapper(String typeName) {
- private PortableIdMapper userTypeIdMapper(String typeName) {
- PortableIdMapper idMapper = typeMappers.get(typeName);
++ private IgniteObjectIdMapper userTypeIdMapper(String typeName) {
+ IgniteObjectIdMapper idMapper = typeMappers.get(typeName);
return idMapper != null ? idMapper : DFLT_ID_MAPPER;
}
@@@ -907,10 -966,26 +1000,26 @@@
}
/**
+ * Undeployment callback invoked when class loader is being undeployed.
+ *
+ * Some marshallers may want to clean their internal state that uses the undeployed class loader somehow.
+ *
+ * @param ldr Class loader being undeployed.
+ */
+ public void onUndeploy(ClassLoader ldr) {
+ for (Class<?> cls : descByCls.keySet()) {
+ if (ldr.equals(cls.getClassLoader()))
+ descByCls.remove(cls);
+ }
+
+ U.clearClassCache(ldr);
+ }
+
+ /**
*/
- private static class IdMapperWrapper implements PortableIdMapper {
+ private static class IdMapperWrapper implements IgniteObjectIdMapper {
/** */
- private final PortableIdMapper mapper;
+ private final IgniteObjectIdMapper mapper;
/**
* @param mapper Custom ID mapper.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c70a94/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
index bf1c3b6,51fc407..cfe7efe
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
@@@ -20,18 -20,19 +20,19 @@@ package org.apache.ignite.internal.port
import java.util.HashMap;
import java.util.Map;
import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.igniteobject.IgniteObject;
+ import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.portable.PortableObject;
import org.jetbrains.annotations.Nullable;
/**
- * Reader context.
- */
+ * Reader context.
+ */
class PortableReaderContext {
/** */
- private Map<Integer, Object> oHandles;
+ private Object oHandles;
/** */
- private Map<Integer, PortableObject> poHandles;
+ private Map<Integer, IgniteObject> poHandles;
/**
* @param handle Handle.
http://git-wip-us.apache.org/repos/asf/ignite/blob/b5c70a94/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
index d6b526d,eafcbd1..e0e6d21
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
@@@ -18,9 -18,11 +18,11 @@@
package org.apache.ignite.internal.portable;
import org.apache.ignite.internal.portable.builder.PortableLazyValue;
+ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
+ import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.portable.PortableException;
-import org.apache.ignite.portable.PortableObject;
+import org.apache.ignite.igniteobject.IgniteObjectException;
+import org.apache.ignite.igniteobject.IgniteObject;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
@@@ -92,6 -94,47 +94,47 @@@ public class PortableUtils
/** Portable classes. */
private static final Collection<Class<?>> PORTABLE_CLS = new HashSet<>();
+ /** Flag: user type. */
+ public static final short FLAG_USR_TYP = 0x1;
+
+ /** Flag: only raw data exists. */
+ public static final short FLAG_RAW_ONLY = 0x2;
+
+ /**
+ * Write flags.
+ *
+ * @param writer Writer.
+ * @param userType User type flag.
+ */
- public static void writeFlags(PortableWriterExImpl writer, boolean userType) {
++ public static void writeFlags(IgniteObjectWriterExImpl writer, boolean userType) {
+ short val = 0;
+
+ if (userType)
+ val |= FLAG_USR_TYP;
+
+ writer.doWriteShort(val);
+ }
+
+ /**
+ * Check if user type flag is set.
+ *
+ * @param flags Flags.
+ * @return {@code True} if set.
+ */
+ public static boolean isUserType(short flags) {
+ return (flags & FLAG_USR_TYP) == FLAG_USR_TYP;
+ }
+
+ /**
+ * Check if raw-only flag is set.
+ *
+ * @param flags Flags.
+ * @return {@code True} if set.
+ */
+ public static boolean isRawOnly(short flags) {
+ return (flags & FLAG_RAW_ONLY) == FLAG_RAW_ONLY;
+ }
+
/**
*
*/
@@@ -485,6 -528,120 +528,120 @@@
*/
public static void checkProtocolVersion(byte protoVer) {
if (PROTO_VER != protoVer)
- throw new PortableException("Unsupported protocol version: " + protoVer);
+ throw new IgniteObjectException("Unsupported protocol version: " + protoVer);
}
+
+ /**
+ * Write portable header.
+ *
+ * @param writer Writer.
+ * @param usrTyp User type flag.
+ * @param typeId Type ID.
+ * @param hashCode Hash code.
+ * @param clsName Class name (optional).
+ * @return Position where length should be written.
+ */
- public static int writeHeader(PortableWriterExImpl writer, boolean usrTyp, int typeId, int hashCode,
++ public static int writeHeader(IgniteObjectWriterExImpl writer, boolean usrTyp, int typeId, int hashCode,
+ @Nullable String clsName) {
+ writer.doWriteByte(GridPortableMarshaller.OBJ);
+ writer.doWriteByte(GridPortableMarshaller.PROTO_VER);
+
+ PortableUtils.writeFlags(writer, usrTyp);
+
+ writer.doWriteInt(typeId);
+ writer.doWriteInt(hashCode);
+
+ int reserved = writer.reserve(12);
+
+ if (clsName != null)
+ writer.doWriteString(clsName);
+
+ return reserved;
+ }
+
+ /**
+ * Get portable object length.
+ *
+ * @param in Input stream.
+ * @param start Start position.
+ * @return Length.
+ */
+ public static int length(PortablePositionReadable in, int start) {
+ return in.readIntPositioned(start + GridPortableMarshaller.TOTAL_LEN_POS);
+ }
+
+ /**
+ * Get footer start of the object.
+ *
+ * @param in Input stream.
+ * @param start Object start position inside the stream.
+ * @return Footer start.
+ */
+ public static int footerStartRelative(PortablePositionReadable in, int start) {
+ short flags = in.readShortPositioned(start + GridPortableMarshaller.FLAGS_POS);
+
+ if (PortableUtils.isRawOnly(flags))
+ // No schema, footer start equals to object end.
+ return length(in, start);
+ else
+ // Schema exists, use offset.
+ return in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
+ }
+
+ /**
+ * Get object's footer.
+ *
+ * @param in Input stream.
+ * @param start Start position.
+ * @return Footer start.
+ */
+ public static int footerStartAbsolute(PortablePositionReadable in, int start) {
+ return footerStartRelative(in, start) + start;
+ }
+
+ /**
+ * Get object's footer.
+ *
+ * @param in Input stream.
+ * @param start Start position.
+ * @return Footer.
+ */
+ public static IgniteBiTuple<Integer, Integer> footerAbsolute(PortablePositionReadable in, int start) {
+ int footerStart = footerStartRelative(in, start);
+ int footerEnd = length(in, start);
+
+ // Take in count possible raw offset.
+ if ((((footerEnd - footerStart) >> 2) & 0x1) == 0x1)
+ footerEnd -= 4;
+
+ return F.t(start + footerStart, start + footerEnd);
+ }
+
+ /**
+ * Get raw offset of the object.
+ *
+ * @param in Input stream.
+ * @param start Object start position inside the stream.
+ * @return Raw offset.
+ */
+ public static int rawOffsetAbsolute(PortablePositionReadable in, int start) {
+ int len = length(in, start);
+
+ short flags = in.readShortPositioned(start + GridPortableMarshaller.FLAGS_POS);
+
+ if (PortableUtils.isRawOnly(flags))
+ // No schema, raw offset is located on schema offset position.
+ return start + in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
+ else {
+ // Schema exists.
+ int schemaOff = in.readIntPositioned(start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
+
+ if ((((len - schemaOff) >> 2) & 0x1) == 0x0)
+ // Even amount of records in schema => no raw offset.
+ return start + schemaOff;
+ else
+ // Odd amount of records in schema => raw offset is the very last 4 bytes in object.
+ return start + in.readIntPositioned(start + len - 4);
+ }
+ }
}