You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/11/16 09:51:01 UTC

[02/12] ignite git commit: IGNITE-1282: Optimized primitive field reads/writes.

IGNITE-1282: Optimized primitive field reads/writes.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4edc0620
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4edc0620
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4edc0620

Branch: refs/heads/ignite-1917
Commit: 4edc06208588b5fe4b9e85d73f361f4a05d43727
Parents: b48dc3a
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Fri Nov 13 15:47:02 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Fri Nov 13 15:47:02 2015 +0300

----------------------------------------------------------------------
 .../internal/portable/BinaryFieldAccessor.java  | 805 +++++++++++++++++++
 .../internal/portable/BinaryReaderExImpl.java   |  72 ++
 .../internal/portable/BinaryWriterExImpl.java   | 112 ++-
 .../portable/PortableClassDescriptor.java       | 546 +------------
 .../ignite/internal/portable/PortableUtils.java | 107 +++
 5 files changed, 1089 insertions(+), 553 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4edc0620/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java
new file mode 100644
index 0000000..8f33825
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryFieldAccessor.java
@@ -0,0 +1,805 @@
+/*
+ * 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.binary.BinaryObjectException;
+import org.apache.ignite.internal.util.GridUnsafe;
+import sun.misc.Unsafe;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Field accessor to speedup access.
+ */
+public abstract class BinaryFieldAccessor {
+    /** Field ID. */
+    protected final int id;
+
+    /** Mode. */
+    protected final PortableClassDescriptor.Mode mode;
+
+    /**
+     * Create accessor for the field.
+     *
+     * @param field Field.
+     * @param id FIeld ID.
+     * @return Accessor.
+     */
+    public static BinaryFieldAccessor create(Field field, int id) {
+        PortableClassDescriptor.Mode mode = PortableUtils.mode(field.getType());
+
+        switch (mode) {
+            case P_BYTE:
+                return new BytePrimitiveAccessor(field, id);
+
+            case P_BOOLEAN:
+                return new BooleanPrimitiveAccessor(field, id);
+
+            case P_SHORT:
+                return new ShortPrimitiveAccessor(field, id);
+
+            case P_CHAR:
+                return new CharPrimitiveAccessor(field, id);
+
+            case P_INT:
+                return new IntPrimitiveAccessor(field, id);
+
+            case P_LONG:
+                return new LongPrimitiveAccessor(field, id);
+
+            case P_FLOAT:
+                return new FloatPrimitiveAccessor(field, id);
+
+            case P_DOUBLE:
+                return new DoublePrimitiveAccessor(field, id);
+
+            default:
+                return new DefaultAccessor(field, id, mode);
+        }
+    }
+
+    /**
+     * Protected constructor.
+     *
+     * @param id Field ID.
+     * @param mode Mode;
+     */
+    protected BinaryFieldAccessor(int id, PortableClassDescriptor.Mode mode) {
+        assert id != 0;
+        assert mode != null;
+
+        this.id = id;
+        this.mode = mode;
+    }
+
+    /**
+     * Get mode.
+     *
+     * @return Mode.
+     */
+    public PortableClassDescriptor.Mode mode() {
+        return mode;
+    }
+
+    /**
+     * Write field.
+     *
+     * @param obj Object.
+     * @param writer Writer.
+     * @throws BinaryObjectException If failed.
+     */
+    public abstract void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException;
+
+    /**
+     * Read field.
+     *
+     * @param obj Object.
+     * @param reader Reader.
+     * @throws BinaryObjectException If failed.
+     */
+    public abstract void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException;
+
+    /**
+     * Base primitive field accessor.
+     */
+    private static abstract class AbstractPrimitiveAccessor extends BinaryFieldAccessor {
+        /** Unsafe instance. */
+        protected static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+        /** Offset. */
+        protected final long offset;
+
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         * @param id Field ID.
+         * @param mode Mode.
+         */
+        protected AbstractPrimitiveAccessor(Field field, int id, PortableClassDescriptor.Mode mode) {
+            super(id, mode);
+
+            assert field != null;
+
+            offset = UNSAFE.objectFieldOffset(field);
+        }
+    }
+
+    /**
+     * Byte field accessor.
+     */
+    private static class BytePrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public BytePrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_BYTE);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            byte val = UNSAFE.getByte(obj, offset);
+
+            writer.writeByteFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            byte val = reader.readBytePrimitive(id);
+
+            UNSAFE.putByte(obj, offset, val);
+        }
+    }
+
+    /**
+     * Boolean field accessor.
+     */
+    private static class BooleanPrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public BooleanPrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_BOOLEAN);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            boolean val = UNSAFE.getBoolean(obj, offset);
+
+            writer.writeBooleanFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            boolean val = reader.readBooleanPrimitive(id);
+
+            UNSAFE.putBoolean(obj, offset, val);
+        }
+    }
+
+    /**
+     * Short field accessor.
+     */
+    private static class ShortPrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public ShortPrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_SHORT);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            short val = UNSAFE.getShort(obj, offset);
+
+            writer.writeShortFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            short val = reader.readShortPrimitive(id);
+
+            UNSAFE.putShort(obj, offset, val);
+        }
+    }
+
+    /**
+     * Char field accessor.
+     */
+    private static class CharPrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public CharPrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_CHAR);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            char val = UNSAFE.getChar(obj, offset);
+
+            writer.writeCharFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            char val = reader.readCharPrimitive(id);
+
+            UNSAFE.putChar(obj, offset, val);
+        }
+    }
+
+    /**
+     * Int field accessor.
+     */
+    private static class IntPrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public IntPrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_INT);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            int val = UNSAFE.getInt(obj, offset);
+
+            writer.writeIntFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            int val = reader.readIntPrimitive(id);
+
+            UNSAFE.putInt(obj, offset, val);
+        }
+    }
+
+    /**
+     * Long field accessor.
+     */
+    private static class LongPrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public LongPrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_LONG);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            long val = UNSAFE.getLong(obj, offset);
+
+            writer.writeLongFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            long val = reader.readLongPrimitive(id);
+
+            UNSAFE.putLong(obj, offset, val);
+        }
+    }
+
+    /**
+     * Float field accessor.
+     */
+    private static class FloatPrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public FloatPrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_FLOAT);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            float val = UNSAFE.getFloat(obj, offset);
+
+            writer.writeFloatFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            float val = reader.readFloatPrimitive(id);
+
+            UNSAFE.putFloat(obj, offset, val);
+        }
+    }
+
+    /**
+     * Double field accessor.
+     */
+    private static class DoublePrimitiveAccessor extends AbstractPrimitiveAccessor {
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         */
+        public DoublePrimitiveAccessor(Field field, int id) {
+            super(field, id, PortableClassDescriptor.Mode.P_DOUBLE);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            writer.writeFieldId(id);
+
+            double val = UNSAFE.getDouble(obj, offset);
+
+            writer.writeDoubleFieldPrimitive(val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            double val = reader.readDoublePrimitive(id);
+
+            UNSAFE.putDouble(obj, offset, val);
+        }
+    }
+
+    /**
+     * Default accessor.
+     */
+    private static class DefaultAccessor extends BinaryFieldAccessor {
+        /** Target field. */
+        private final Field field;
+
+        /**
+         * Constructor.
+         *
+         * @param field Field.
+         * @param id Field ID.
+         * @param mode Mode.
+         */
+        public DefaultAccessor(Field field, int id, PortableClassDescriptor.Mode mode) {
+            super(id, mode);
+
+            assert field != null;
+
+            this.field = field;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
+            assert obj != null;
+            assert writer != null;
+
+            writer.writeFieldId(id);
+
+            Object val;
+
+            try {
+                val = field.get(obj);
+            }
+            catch (IllegalAccessException e) {
+                throw new BinaryObjectException("Failed to get value for field: " + field, e);
+            }
+
+            switch (mode) {
+                case BYTE:
+                    writer.writeByteField((Byte) val);
+
+                    break;
+
+                case SHORT:
+                    writer.writeShortField((Short) val);
+
+                    break;
+
+                case INT:
+                    writer.writeIntField((Integer) val);
+
+                    break;
+
+                case LONG:
+                    writer.writeLongField((Long)val);
+
+                    break;
+
+                case FLOAT:
+                    writer.writeFloatField((Float)val);
+
+                    break;
+
+                case DOUBLE:
+                    writer.writeDoubleField((Double)val);
+
+                    break;
+
+                case CHAR:
+                    writer.writeCharField((Character)val);
+
+                    break;
+
+                case BOOLEAN:
+                    writer.writeBooleanField((Boolean)val);
+
+                    break;
+
+                case DECIMAL:
+                    writer.writeDecimalField((BigDecimal)val);
+
+                    break;
+
+                case STRING:
+                    writer.writeStringField((String)val);
+
+                    break;
+
+                case UUID:
+                    writer.writeUuidField((UUID)val);
+
+                    break;
+
+                case DATE:
+                    writer.writeDateField((Date)val);
+
+                    break;
+
+                case TIMESTAMP:
+                    writer.writeTimestampField((Timestamp)val);
+
+                    break;
+
+                case BYTE_ARR:
+                    writer.writeByteArrayField((byte[])val);
+
+                    break;
+
+                case SHORT_ARR:
+                    writer.writeShortArrayField((short[])val);
+
+                    break;
+
+                case INT_ARR:
+                    writer.writeIntArrayField((int[])val);
+
+                    break;
+
+                case LONG_ARR:
+                    writer.writeLongArrayField((long[])val);
+
+                    break;
+
+                case FLOAT_ARR:
+                    writer.writeFloatArrayField((float[])val);
+
+                    break;
+
+                case DOUBLE_ARR:
+                    writer.writeDoubleArrayField((double[])val);
+
+                    break;
+
+                case CHAR_ARR:
+                    writer.writeCharArrayField((char[])val);
+
+                    break;
+
+                case BOOLEAN_ARR:
+                    writer.writeBooleanArrayField((boolean[])val);
+
+                    break;
+
+                case DECIMAL_ARR:
+                    writer.writeDecimalArrayField((BigDecimal[])val);
+
+                    break;
+
+                case STRING_ARR:
+                    writer.writeStringArrayField((String[])val);
+
+                    break;
+
+                case UUID_ARR:
+                    writer.writeUuidArrayField((UUID[])val);
+
+                    break;
+
+                case DATE_ARR:
+                    writer.writeDateArrayField((Date[])val);
+
+                    break;
+
+                case TIMESTAMP_ARR:
+                    writer.writeTimestampArrayField((Timestamp[])val);
+
+                    break;
+
+                case OBJ_ARR:
+                    writer.writeObjectArrayField((Object[])val);
+
+                    break;
+
+                case COL:
+                    writer.writeCollectionField((Collection<?>)val);
+
+                    break;
+
+                case MAP:
+                    writer.writeMapField((Map<?, ?>)val);
+
+                    break;
+
+                case MAP_ENTRY:
+                    writer.writeMapEntryField((Map.Entry<?, ?>)val);
+
+                    break;
+
+                case PORTABLE_OBJ:
+                    writer.writePortableObjectField((BinaryObjectImpl)val);
+
+                    break;
+
+                case ENUM:
+                    writer.writeEnumField((Enum<?>)val);
+
+                    break;
+
+                case ENUM_ARR:
+                    writer.writeEnumArrayField((Object[])val);
+
+                    break;
+
+                case PORTABLE:
+                case EXTERNALIZABLE:
+                case OBJECT:
+                    writer.writeObjectField(val);
+
+                    break;
+
+                case CLASS:
+                    writer.writeClassField((Class)val);
+
+                    break;
+
+                default:
+                    assert false : "Invalid mode: " + mode;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+            Object val = null;
+
+            switch (mode) {
+                case BYTE:
+                    val = reader.readByte(id);
+
+                    break;
+
+                case SHORT:
+                    val = reader.readShort(id);
+
+                    break;
+
+                case INT:
+                    val = reader.readInt(id);
+
+                    break;
+
+                case LONG:
+                    val = reader.readLong(id);
+
+                    break;
+
+                case FLOAT:
+                    val = reader.readFloat(id);
+
+                    break;
+
+                case DOUBLE:
+                    val = reader.readDouble(id);
+
+                    break;
+
+                case CHAR:
+                    val = reader.readChar(id);
+
+                    break;
+
+                case BOOLEAN:
+                    val = reader.readBoolean(id);
+
+                    break;
+
+                case DECIMAL:
+                    val = reader.readDecimal(id);
+
+                    break;
+
+                case STRING:
+                    val = reader.readString(id);
+
+                    break;
+
+                case UUID:
+                    val = reader.readUuid(id);
+
+                    break;
+
+                case DATE:
+                    val = reader.readDate(id);
+
+                    break;
+
+                case TIMESTAMP:
+                    val = reader.readTimestamp(id);
+
+                    break;
+
+                case BYTE_ARR:
+                    val = reader.readByteArray(id);
+
+                    break;
+
+                case SHORT_ARR:
+                    val = reader.readShortArray(id);
+
+                    break;
+
+                case INT_ARR:
+                    val = reader.readIntArray(id);
+
+                    break;
+
+                case LONG_ARR:
+                    val = reader.readLongArray(id);
+
+                    break;
+
+                case FLOAT_ARR:
+                    val = reader.readFloatArray(id);
+
+                    break;
+
+                case DOUBLE_ARR:
+                    val = reader.readDoubleArray(id);
+
+                    break;
+
+                case CHAR_ARR:
+                    val = reader.readCharArray(id);
+
+                    break;
+
+                case BOOLEAN_ARR:
+                    val = reader.readBooleanArray(id);
+
+                    break;
+
+                case DECIMAL_ARR:
+                    val = reader.readDecimalArray(id);
+
+                    break;
+
+                case STRING_ARR:
+                    val = reader.readStringArray(id);
+
+                    break;
+
+                case UUID_ARR:
+                    val = reader.readUuidArray(id);
+
+                    break;
+
+                case DATE_ARR:
+                    val = reader.readDateArray(id);
+
+                    break;
+
+                case TIMESTAMP_ARR:
+                    val = reader.readTimestampArray(id);
+
+                    break;
+
+                case OBJ_ARR:
+                    val = reader.readObjectArray(id);
+
+                    break;
+
+                case COL:
+                    val = reader.readCollection(id, null);
+
+                    break;
+
+                case MAP:
+                    val = reader.readMap(id, null);
+
+                    break;
+
+                case MAP_ENTRY:
+                    val = reader.readMapEntry(id);
+
+                    break;
+
+                case PORTABLE_OBJ:
+                    val = reader.readPortableObject(id);
+
+                    break;
+
+                case ENUM:
+                    val = reader.readEnum(id, field.getType());
+
+                    break;
+
+                case ENUM_ARR:
+                    val = reader.readEnumArray(id, field.getType().getComponentType());
+
+                    break;
+
+                case PORTABLE:
+                case EXTERNALIZABLE:
+                case OBJECT:
+                    val = reader.readObject(id);
+
+                    break;
+
+                case CLASS:
+                    val = reader.readClass(id);
+
+                    break;
+
+                default:
+                    assert false : "Invalid mode: " + mode;
+            }
+
+            try {
+                if (val != null || !field.getType().isPrimitive())
+                    field.set(obj, val);
+            }
+            catch (IllegalAccessException e) {
+                throw new BinaryObjectException("Failed to set value for field: " + field, e);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4edc0620/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
index 669ba01..d384da2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
@@ -328,6 +328,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    byte readBytePrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(BYTE) == Flag.NORMAL ? in.readByte() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Byte readByte(int fieldId) throws BinaryObjectException {
@@ -344,6 +353,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    short readShortPrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(SHORT) == Flag.NORMAL ? in.readShort() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Short readShort(int fieldId) throws BinaryObjectException {
@@ -360,6 +378,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    int readIntPrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(INT) == Flag.NORMAL ? in.readInt() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Integer readInt(int fieldId) throws BinaryObjectException {
@@ -376,6 +403,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    long readLongPrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(LONG) == Flag.NORMAL ? in.readLong() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Long readLong(int fieldId) throws BinaryObjectException {
@@ -392,6 +428,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    float readFloatPrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(FLOAT) == Flag.NORMAL ? in.readFloat() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Float readFloat(int fieldId) throws BinaryObjectException {
@@ -408,6 +453,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    double readDoublePrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(DOUBLE) == Flag.NORMAL ? in.readDouble() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Double readDouble(int fieldId) throws BinaryObjectException {
@@ -424,6 +478,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    char readCharPrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(CHAR) == Flag.NORMAL ? in.readChar() : 0;
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Character readChar(int fieldId) throws BinaryObjectException {
@@ -440,6 +503,15 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Obje
     /**
      * @param fieldId Field ID.
      * @return Value.
+     * @throws BinaryObjectException If failed.
+     */
+    boolean readBooleanPrimitive(int fieldId) throws BinaryObjectException {
+        return hasField(fieldId) && checkFlag(BOOLEAN) == Flag.NORMAL && in.readBoolean();
+    }
+
+    /**
+     * @param fieldId Field ID.
+     * @return Value.
      * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
      */
     @Nullable Boolean readBoolean(int fieldId) throws BinaryObjectException {

http://git-wip-us.apache.org/repos/asf/ignite/blob/4edc0620/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
index cedf1c8..a91d2da 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
@@ -967,13 +967,19 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     /**
      * @param val Value.
      */
+    void writeByteFieldPrimitive(byte val) {
+        doWriteByte(BYTE);
+        doWriteByte(val);
+    }
+
+    /**
+     * @param val Value.
+     */
     void writeByteField(@Nullable Byte val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(BYTE);
-            doWriteByte(val);
-        }
+        else
+            writeByteFieldPrimitive(val);
     }
 
     /**
@@ -986,13 +992,27 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     /**
      * @param val Value.
      */
+    void writeShortFieldPrimitive(short val) {
+        doWriteByte(SHORT);
+        doWriteShort(val);
+    }
+
+    /**
+     * @param val Value.
+     */
     void writeShortField(@Nullable Short val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(SHORT);
-            doWriteShort(val);
-        }
+        else
+            writeShortFieldPrimitive(val);
+    }
+
+    /**
+     * @param val Value.
+     */
+    void writeIntFieldPrimitive(int val) {
+        doWriteByte(INT);
+        doWriteInt(val);
     }
 
     /**
@@ -1001,10 +1021,16 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     void writeIntField(@Nullable Integer val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(INT);
-            doWriteInt(val);
-        }
+        else
+            writeIntFieldPrimitive(val);
+    }
+
+    /**
+     * @param val Value.
+     */
+    void writeLongFieldPrimitive(long val) {
+        doWriteByte(LONG);
+        doWriteLong(val);
     }
 
     /**
@@ -1013,10 +1039,16 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     void writeLongField(@Nullable Long val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(LONG);
-            doWriteLong(val);
-        }
+        else
+            writeLongFieldPrimitive(val);
+    }
+
+    /**
+     * @param val Value.
+     */
+    void writeFloatFieldPrimitive(float val) {
+        doWriteByte(FLOAT);
+        doWriteFloat(val);
     }
 
     /**
@@ -1025,10 +1057,16 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     void writeFloatField(@Nullable Float val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(FLOAT);
-            doWriteFloat(val);
-        }
+        else
+            writeFloatFieldPrimitive(val);
+    }
+
+    /**
+     * @param val Value.
+     */
+    void writeDoubleFieldPrimitive(double val) {
+        doWriteByte(DOUBLE);
+        doWriteDouble(val);
     }
 
     /**
@@ -1037,10 +1075,16 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     void writeDoubleField(@Nullable Double val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(DOUBLE);
-            doWriteDouble(val);
-        }
+        else
+            writeDoubleFieldPrimitive(val);
+    }
+
+    /**
+     * @param val Value.
+     */
+    void writeCharFieldPrimitive(char val) {
+        doWriteByte(CHAR);
+        doWriteChar(val);
     }
 
     /**
@@ -1049,10 +1093,16 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     void writeCharField(@Nullable Character val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(CHAR);
-            doWriteChar(val);
-        }
+        else
+            writeCharFieldPrimitive(val);
+    }
+
+    /**
+     * @param val Value.
+     */
+    void writeBooleanFieldPrimitive(boolean val) {
+        doWriteByte(BOOLEAN);
+        doWriteBoolean(val);
     }
 
     /**
@@ -1061,10 +1111,8 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     void writeBooleanField(@Nullable Boolean val) {
         if (val == null)
             doWriteByte(NULL);
-        else {
-            doWriteByte(BOOLEAN);
-            doWriteBoolean(val);
-        }
+        else
+            writeBooleanFieldPrimitive(val);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/4edc0620/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git 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
index e589e97..0916444 100644
--- 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
@@ -83,7 +83,7 @@ public class PortableClassDescriptor {
     private final Constructor<?> ctor;
 
     /** */
-    private final FieldInfo[] fields;
+    private final BinaryFieldAccessor[] fields;
 
     /** */
     private final Method writeReplaceMtd;
@@ -153,7 +153,7 @@ public class PortableClassDescriptor {
         if (excluded)
             mode = Mode.EXCLUSION;
         else
-            mode = serializer != null ? Mode.PORTABLE : mode(cls);
+            mode = serializer != null ? Mode.PORTABLE : PortableUtils.mode(cls);
 
         switch (mode) {
             case BYTE:
@@ -209,7 +209,7 @@ public class PortableClassDescriptor {
                 assert idMapper != null;
 
                 ctor = constructor(cls);
-                ArrayList<FieldInfo> fields0 = new ArrayList<>();
+                ArrayList<BinaryFieldAccessor> fields0 = new ArrayList<>();
                 fieldsMeta = metaDataEnabled ? new HashMap<String, String>() : null;
 
                 Collection<String> names = new HashSet<>();
@@ -232,17 +232,17 @@ public class PortableClassDescriptor {
                             if (!ids.add(fieldId))
                                 throw new BinaryObjectException("Duplicate field ID: " + name);
 
-                            FieldInfo fieldInfo = new FieldInfo(f, fieldId);
+                            BinaryFieldAccessor fieldInfo = BinaryFieldAccessor.create(f, fieldId);
 
                             fields0.add(fieldInfo);
 
                             if (metaDataEnabled)
-                                fieldsMeta.put(name, fieldInfo.fieldMode().typeName());
+                                fieldsMeta.put(name, fieldInfo.mode().typeName());
                         }
                     }
                 }
 
-                fields = fields0.toArray(new FieldInfo[fields0.size()]);
+                fields = fields0.toArray(new BinaryFieldAccessor[fields0.size()]);
 
                 break;
 
@@ -582,7 +582,7 @@ public class PortableClassDescriptor {
             case OBJECT:
                 if (writeHeader(obj, writer)) {
                     try {
-                        for (FieldInfo info : fields)
+                        for (BinaryFieldAccessor info : fields)
                             info.write(obj, writer);
 
                         writer.postWrite(userType);
@@ -642,7 +642,7 @@ public class PortableClassDescriptor {
 
                 reader.setHandler(res);
 
-                for (FieldInfo info : fields)
+                for (BinaryFieldAccessor info : fields)
                     info.read(res, reader);
 
                 break;
@@ -754,528 +754,32 @@ public class PortableClassDescriptor {
         return use;
     }
 
-    /**
-     * @param cls Class.
-     * @return Mode.
-     */
-    @SuppressWarnings("IfMayBeConditional")
-    private static Mode mode(Class<?> cls) {
-        assert cls != null;
-
-        if (cls == byte.class || cls == Byte.class)
-            return Mode.BYTE;
-        else if (cls == short.class || cls == Short.class)
-            return Mode.SHORT;
-        else if (cls == int.class || cls == Integer.class)
-            return Mode.INT;
-        else if (cls == long.class || cls == Long.class)
-            return Mode.LONG;
-        else if (cls == float.class || cls == Float.class)
-            return Mode.FLOAT;
-        else if (cls == double.class || cls == Double.class)
-            return Mode.DOUBLE;
-        else if (cls == char.class || cls == Character.class)
-            return Mode.CHAR;
-        else if (cls == boolean.class || cls == Boolean.class)
-            return Mode.BOOLEAN;
-        else if (cls == BigDecimal.class)
-            return Mode.DECIMAL;
-        else if (cls == String.class)
-            return Mode.STRING;
-        else if (cls == UUID.class)
-            return Mode.UUID;
-        else if (cls == Date.class)
-            return Mode.DATE;
-        else if (cls == Timestamp.class)
-            return Mode.TIMESTAMP;
-        else if (cls == byte[].class)
-            return Mode.BYTE_ARR;
-        else if (cls == short[].class)
-            return Mode.SHORT_ARR;
-        else if (cls == int[].class)
-            return Mode.INT_ARR;
-        else if (cls == long[].class)
-            return Mode.LONG_ARR;
-        else if (cls == float[].class)
-            return Mode.FLOAT_ARR;
-        else if (cls == double[].class)
-            return Mode.DOUBLE_ARR;
-        else if (cls == char[].class)
-            return Mode.CHAR_ARR;
-        else if (cls == boolean[].class)
-            return Mode.BOOLEAN_ARR;
-        else if (cls == BigDecimal[].class)
-            return Mode.DECIMAL_ARR;
-        else if (cls == String[].class)
-            return Mode.STRING_ARR;
-        else if (cls == UUID[].class)
-            return Mode.UUID_ARR;
-        else if (cls == Date[].class)
-            return Mode.DATE_ARR;
-        else if (cls == Timestamp[].class)
-            return Mode.TIMESTAMP_ARR;
-        else if (cls.isArray())
-            return cls.getComponentType().isEnum() ? Mode.ENUM_ARR : Mode.OBJ_ARR;
-        else if (cls == BinaryObjectImpl.class)
-            return Mode.PORTABLE_OBJ;
-        else if (Binarylizable.class.isAssignableFrom(cls))
-            return Mode.PORTABLE;
-        else if (Externalizable.class.isAssignableFrom(cls))
-            return Mode.EXTERNALIZABLE;
-        else if (Map.Entry.class.isAssignableFrom(cls))
-            return Mode.MAP_ENTRY;
-        else if (Collection.class.isAssignableFrom(cls))
-            return Mode.COL;
-        else if (Map.class.isAssignableFrom(cls))
-            return Mode.MAP;
-        else if (cls == BinaryObjectImpl.class)
-            return Mode.PORTABLE_OBJ;
-        else if (cls.isEnum())
-            return Mode.ENUM;
-        else if (cls == Class.class)
-            return Mode.CLASS;
-        else
-            return Mode.OBJECT;
-    }
-
     /** */
-    private static class FieldInfo {
-        /** */
-        private final Field field;
-
-        /** */
-        private final int id;
-
-        /** */
-        private final Mode mode;
-
-        /**
-         * @param field Field.
-         * @param id Field ID.
-         */
-        private FieldInfo(Field field, int id) {
-            assert field != null;
-
-            this.field = field;
-            this.id = id;
-
-            Class<?> type = field.getType();
-
-            mode = mode(type);
-        }
-
-        /**
-         * @return Field mode.
-         */
-        public Mode fieldMode() {
-            return mode;
-        }
-
-        /**
-         * @param obj Object.
-         * @param writer Writer.
-         * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
-         */
-        public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
-            assert obj != null;
-            assert writer != null;
-
-            writer.writeFieldId(id);
-
-            Object val;
-
-            try {
-                val = field.get(obj);
-            }
-            catch (IllegalAccessException e) {
-                throw new BinaryObjectException("Failed to get value for field: " + field, e);
-            }
-
-            switch (mode) {
-                case BYTE:
-                    writer.writeByteField((Byte)val);
-
-                    break;
-
-                case SHORT:
-                    writer.writeShortField((Short)val);
-
-                    break;
-
-                case INT:
-                    writer.writeIntField((Integer)val);
-
-                    break;
-
-                case LONG:
-                    writer.writeLongField((Long)val);
-
-                    break;
-
-                case FLOAT:
-                    writer.writeFloatField((Float)val);
-
-                    break;
-
-                case DOUBLE:
-                    writer.writeDoubleField((Double)val);
-
-                    break;
-
-                case CHAR:
-                    writer.writeCharField((Character)val);
-
-                    break;
-
-                case BOOLEAN:
-                    writer.writeBooleanField((Boolean)val);
-
-                    break;
-
-                case DECIMAL:
-                    writer.writeDecimalField((BigDecimal)val);
-
-                    break;
-
-                case STRING:
-                    writer.writeStringField((String)val);
-
-                    break;
-
-                case UUID:
-                    writer.writeUuidField((UUID)val);
-
-                    break;
-
-                case DATE:
-                    writer.writeDateField((Date)val);
-
-                    break;
-
-                case TIMESTAMP:
-                    writer.writeTimestampField((Timestamp)val);
-
-                    break;
-
-                case BYTE_ARR:
-                    writer.writeByteArrayField((byte[])val);
-
-                    break;
-
-                case SHORT_ARR:
-                    writer.writeShortArrayField((short[])val);
-
-                    break;
-
-                case INT_ARR:
-                    writer.writeIntArrayField((int[])val);
-
-                    break;
-
-                case LONG_ARR:
-                    writer.writeLongArrayField((long[])val);
-
-                    break;
-
-                case FLOAT_ARR:
-                    writer.writeFloatArrayField((float[])val);
-
-                    break;
-
-                case DOUBLE_ARR:
-                    writer.writeDoubleArrayField((double[])val);
-
-                    break;
-
-                case CHAR_ARR:
-                    writer.writeCharArrayField((char[])val);
-
-                    break;
-
-                case BOOLEAN_ARR:
-                    writer.writeBooleanArrayField((boolean[])val);
-
-                    break;
-
-                case DECIMAL_ARR:
-                    writer.writeDecimalArrayField((BigDecimal[])val);
-
-                    break;
-
-                case STRING_ARR:
-                    writer.writeStringArrayField((String[])val);
-
-                    break;
-
-                case UUID_ARR:
-                    writer.writeUuidArrayField((UUID[])val);
-
-                    break;
-
-                case DATE_ARR:
-                    writer.writeDateArrayField((Date[])val);
-
-                    break;
-
-                case TIMESTAMP_ARR:
-                    writer.writeTimestampArrayField((Timestamp[])val);
-
-                    break;
-
-                case OBJ_ARR:
-                    writer.writeObjectArrayField((Object[])val);
-
-                    break;
-
-                case COL:
-                    writer.writeCollectionField((Collection<?>)val);
-
-                    break;
-
-                case MAP:
-                    writer.writeMapField((Map<?, ?>)val);
-
-                    break;
-
-                case MAP_ENTRY:
-                    writer.writeMapEntryField((Map.Entry<?, ?>)val);
-
-                    break;
-
-                case PORTABLE_OBJ:
-                    writer.writePortableObjectField((BinaryObjectImpl)val);
-
-                    break;
-
-                case ENUM:
-                    writer.writeEnumField((Enum<?>)val);
-
-                    break;
-
-                case ENUM_ARR:
-                    writer.writeEnumArrayField((Object[])val);
-
-                    break;
-
-                case PORTABLE:
-                case EXTERNALIZABLE:
-                case OBJECT:
-                    writer.writeObjectField(val);
-
-                    break;
-
-                case CLASS:
-                    writer.writeClassField((Class)val);
-
-                    break;
-
-                default:
-                    assert false : "Invalid mode: " + mode;
-            }
-        }
-
-        /**
-         * @param obj Object.
-         * @param reader Reader.
-         * @throws org.apache.ignite.binary.BinaryObjectException In case of error.
-         */
-        public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
-            Object val = null;
-
-            switch (mode) {
-                case BYTE:
-                    val = reader.readByte(id);
-
-                    break;
-
-                case SHORT:
-                    val = reader.readShort(id);
-
-                    break;
-
-                case INT:
-                    val = reader.readInt(id);
-
-                    break;
-
-                case LONG:
-                    val = reader.readLong(id);
-
-                    break;
-
-                case FLOAT:
-                    val = reader.readFloat(id);
-
-                    break;
-
-                case DOUBLE:
-                    val = reader.readDouble(id);
-
-                    break;
-
-                case CHAR:
-                    val = reader.readChar(id);
-
-                    break;
-
-                case BOOLEAN:
-                    val = reader.readBoolean(id);
-
-                    break;
-
-                case DECIMAL:
-                    val = reader.readDecimal(id);
-
-                    break;
-
-                case STRING:
-                    val = reader.readString(id);
-
-                    break;
-
-                case UUID:
-                    val = reader.readUuid(id);
-
-                    break;
-
-                case DATE:
-                    val = reader.readDate(id);
-
-                    break;
-
-                case TIMESTAMP:
-                    val = reader.readTimestamp(id);
-
-                    break;
-
-                case BYTE_ARR:
-                    val = reader.readByteArray(id);
-
-                    break;
-
-                case SHORT_ARR:
-                    val = reader.readShortArray(id);
-
-                    break;
-
-                case INT_ARR:
-                    val = reader.readIntArray(id);
-
-                    break;
-
-                case LONG_ARR:
-                    val = reader.readLongArray(id);
-
-                    break;
-
-                case FLOAT_ARR:
-                    val = reader.readFloatArray(id);
-
-                    break;
-
-                case DOUBLE_ARR:
-                    val = reader.readDoubleArray(id);
-
-                    break;
-
-                case CHAR_ARR:
-                    val = reader.readCharArray(id);
-
-                    break;
-
-                case BOOLEAN_ARR:
-                    val = reader.readBooleanArray(id);
-
-                    break;
-
-                case DECIMAL_ARR:
-                    val = reader.readDecimalArray(id);
-
-                    break;
-
-                case STRING_ARR:
-                    val = reader.readStringArray(id);
-
-                    break;
-
-                case UUID_ARR:
-                    val = reader.readUuidArray(id);
-
-                    break;
-
-                case DATE_ARR:
-                    val = reader.readDateArray(id);
-
-                    break;
-
-                case TIMESTAMP_ARR:
-                    val = reader.readTimestampArray(id);
-
-                    break;
-
-                case OBJ_ARR:
-                    val = reader.readObjectArray(id);
-
-                    break;
-
-                case COL:
-                    val = reader.readCollection(id, null);
-
-                    break;
-
-                case MAP:
-                    val = reader.readMap(id, null);
-
-                    break;
-
-                case MAP_ENTRY:
-                    val = reader.readMapEntry(id);
-
-                    break;
-
-                case PORTABLE_OBJ:
-                    val = reader.readPortableObject(id);
-
-                    break;
-
-                case ENUM:
-                    val = reader.readEnum(id, field.getType());
-
-                    break;
+    enum Mode {
+        /** Primitive byte. */
+        P_BYTE("byte"),
 
-                case ENUM_ARR:
-                    val = reader.readEnumArray(id, field.getType().getComponentType());
+        /** Primitive boolean. */
+        P_BOOLEAN("boolean"),
 
-                    break;
+        /** Primitive short. */
+        P_SHORT("short"),
 
-                case PORTABLE:
-                case EXTERNALIZABLE:
-                case OBJECT:
-                    val = reader.readObject(id);
+        /** Primitive char. */
+        P_CHAR("char"),
 
-                    break;
+        /** Primitive int. */
+        P_INT("int"),
 
-                case CLASS:
-                    val = reader.readClass(id);
+        /** Primitive long. */
+        P_LONG("long"),
 
-                    break;
+        /** Primitive float. */
+        P_FLOAT("float"),
 
-                default:
-                    assert false : "Invalid mode: " + mode;
-            }
+        /** Primitive int. */
+        P_DOUBLE("double"),
 
-            try {
-                if (val != null || !field.getType().isPrimitive())
-                    field.set(obj, val);
-            }
-            catch (IllegalAccessException e) {
-                throw new BinaryObjectException("Failed to set value for field: " + field, e);
-            }
-        }
-    }
-
-    /** */
-    enum Mode {
         /** */
         BYTE("byte"),
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4edc0620/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
----------------------------------------------------------------------
diff --git 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
index fe97e7e..7d76658 100644
--- 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
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.portable;
 
+import org.apache.ignite.binary.Binarylizable;
 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;
@@ -26,6 +27,7 @@ import org.apache.ignite.binary.BinaryObject;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
+import java.io.Externalizable;
 import java.math.BigDecimal;
 import java.sql.Timestamp;
 import java.util.Collection;
@@ -698,4 +700,109 @@ public class PortableUtils {
 
         return res;
     }
+
+    /**
+     * @param cls Class.
+     * @return Mode.
+     */
+    @SuppressWarnings("IfMayBeConditional")
+    public static PortableClassDescriptor.Mode mode(Class<?> cls) {
+        assert cls != null;
+
+        /** Primitives. */
+        if (cls == byte.class)
+            return PortableClassDescriptor.Mode.P_BYTE;
+        else if (cls == boolean.class)
+            return PortableClassDescriptor.Mode.P_BOOLEAN;
+        else if (cls == short.class)
+            return PortableClassDescriptor.Mode.P_SHORT;
+        else if (cls == char.class)
+            return PortableClassDescriptor.Mode.P_CHAR;
+        else if (cls == int.class)
+            return PortableClassDescriptor.Mode.P_INT;
+        else if (cls == long.class)
+            return PortableClassDescriptor.Mode.P_LONG;
+        else if (cls == float.class)
+            return PortableClassDescriptor.Mode.P_FLOAT;
+        else if (cls == double.class)
+            return PortableClassDescriptor.Mode.P_DOUBLE;
+
+        /** Boxed primitives. */
+        else if (cls == Byte.class)
+            return PortableClassDescriptor.Mode.BYTE;
+        else if (cls == Boolean.class)
+            return PortableClassDescriptor.Mode.BOOLEAN;
+        else if (cls == Short.class)
+            return PortableClassDescriptor.Mode.SHORT;
+        else if (cls == Character.class)
+            return PortableClassDescriptor.Mode.CHAR;
+        else if (cls == Integer.class)
+            return PortableClassDescriptor.Mode.INT;
+        else if (cls == Long.class)
+            return PortableClassDescriptor.Mode.LONG;
+        else if (cls == Float.class)
+            return PortableClassDescriptor.Mode.FLOAT;
+        else if (cls == Double.class)
+            return PortableClassDescriptor.Mode.DOUBLE;
+
+        /** The rest types. */
+        else if (cls == BigDecimal.class)
+            return PortableClassDescriptor.Mode.DECIMAL;
+        else if (cls == String.class)
+            return PortableClassDescriptor.Mode.STRING;
+        else if (cls == UUID.class)
+            return PortableClassDescriptor.Mode.UUID;
+        else if (cls == Date.class)
+            return PortableClassDescriptor.Mode.DATE;
+        else if (cls == Timestamp.class)
+            return PortableClassDescriptor.Mode.TIMESTAMP;
+        else if (cls == byte[].class)
+            return PortableClassDescriptor.Mode.BYTE_ARR;
+        else if (cls == short[].class)
+            return PortableClassDescriptor.Mode.SHORT_ARR;
+        else if (cls == int[].class)
+            return PortableClassDescriptor.Mode.INT_ARR;
+        else if (cls == long[].class)
+            return PortableClassDescriptor.Mode.LONG_ARR;
+        else if (cls == float[].class)
+            return PortableClassDescriptor.Mode.FLOAT_ARR;
+        else if (cls == double[].class)
+            return PortableClassDescriptor.Mode.DOUBLE_ARR;
+        else if (cls == char[].class)
+            return PortableClassDescriptor.Mode.CHAR_ARR;
+        else if (cls == boolean[].class)
+            return PortableClassDescriptor.Mode.BOOLEAN_ARR;
+        else if (cls == BigDecimal[].class)
+            return PortableClassDescriptor.Mode.DECIMAL_ARR;
+        else if (cls == String[].class)
+            return PortableClassDescriptor.Mode.STRING_ARR;
+        else if (cls == UUID[].class)
+            return PortableClassDescriptor.Mode.UUID_ARR;
+        else if (cls == Date[].class)
+            return PortableClassDescriptor.Mode.DATE_ARR;
+        else if (cls == Timestamp[].class)
+            return PortableClassDescriptor.Mode.TIMESTAMP_ARR;
+        else if (cls.isArray())
+            return cls.getComponentType().isEnum() ? PortableClassDescriptor.Mode.ENUM_ARR : PortableClassDescriptor.Mode.OBJ_ARR;
+        else if (cls == BinaryObjectImpl.class)
+            return PortableClassDescriptor.Mode.PORTABLE_OBJ;
+        else if (Binarylizable.class.isAssignableFrom(cls))
+            return PortableClassDescriptor.Mode.PORTABLE;
+        else if (Externalizable.class.isAssignableFrom(cls))
+            return PortableClassDescriptor.Mode.EXTERNALIZABLE;
+        else if (Map.Entry.class.isAssignableFrom(cls))
+            return PortableClassDescriptor.Mode.MAP_ENTRY;
+        else if (Collection.class.isAssignableFrom(cls))
+            return PortableClassDescriptor.Mode.COL;
+        else if (Map.class.isAssignableFrom(cls))
+            return PortableClassDescriptor.Mode.MAP;
+        else if (cls == BinaryObjectImpl.class)
+            return PortableClassDescriptor.Mode.PORTABLE_OBJ;
+        else if (cls.isEnum())
+            return PortableClassDescriptor.Mode.ENUM;
+        else if (cls == Class.class)
+            return PortableClassDescriptor.Mode.CLASS;
+        else
+            return PortableClassDescriptor.Mode.OBJECT;
+    }
 }
\ No newline at end of file