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:09 UTC

[10/12] ignite git commit: Merge branch 'ignite-1282-micro' into ignite-1917

Merge branch 'ignite-1282-micro' into ignite-1917

Conflicts:
	modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
	modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
	modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
	modules/core/src/test/java/org/apache/ignite/internal/portable/BinaryMarshallerSelfTest.java


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

Branch: refs/heads/ignite-1917
Commit: d30500334b496cbc578144c985612f0b2a7a086d
Parents: 3f2320e 3edc0ed
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Mon Nov 16 11:08:22 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Mon Nov 16 11:08:22 2015 +0300

----------------------------------------------------------------------
 .../internal/portable/BinaryFieldAccessor.java  | 805 +++++++++++++++++++
 .../internal/portable/BinaryReaderExImpl.java   |  72 ++
 .../internal/portable/BinaryWriterExImpl.java   | 243 +++---
 .../portable/PortableClassDescriptor.java       | 579 ++-----------
 .../PortableThreadLocalMemoryAllocator.java     | 162 ----
 .../ignite/internal/portable/PortableUtils.java | 105 +++
 .../streams/PortableHeapOutputStream.java       |  51 +-
 .../streams/PortableMemoryAllocator.java        |  67 +-
 .../streams/PortableMemoryAllocatorChunk.java   | 115 +++
 .../streams/PortableSimpleMemoryAllocator.java  |  66 --
 .../portable/BinaryMarshallerSelfTest.java      |  30 +-
 11 files changed, 1338 insertions(+), 957 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d3050033/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryReaderExImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/d3050033/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
index 6cb18fb,74f8bee..9cf7fd1
--- 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
@@@ -141,6 -146,18 +140,18 @@@ public class BinaryWriterExImpl impleme
      /** ID mapper. */
      private BinaryIdMapper idMapper;
  
+     private static final ThreadLocal<TLSContext> TLS_CTX = new ThreadLocal<TLSContext>() {
+         @Override protected TLSContext initialValue() {
+             return new TLSContext();
+         }
+     };
+ 
+     private static class TLSContext {
+ 
+         public PortableMemoryAllocatorChunk chunk = PortableMemoryAllocator.INSTANCE.chunk();
+         public SchemaHolder schema = new SchemaHolder();
+     }
 -
++    
      /**
       * @param ctx Context.
       */
@@@ -334,16 -347,7 +342,16 @@@
       * @param userType User type flag.
       */
      public void postWrite(boolean userType) {
 +        short flags = userType ? PortableUtils.FLAG_USR_TYP : 0;
 +
 +        boolean useCompactFooter = ctx.isCompactFooter() && userType;
 +
 +        if (useCompactFooter)
 +            flags |= PortableUtils.FLAG_COMPACT_FOOTER;
-         
-         if (schema != null) {
++
+         if (fieldCnt != 0) {
 +            flags |= PortableUtils.FLAG_HAS_SCHEMA;
 +
              // Write schema ID.
              out.writeInt(start + SCHEMA_ID_POS, schemaId);
  
@@@ -1734,40 -1783,21 +1788,29 @@@
      public void writeFieldId(int fieldId) {
          int fieldOff = out.position() - start;
  
-         if (schema == null) {
-             schema = SCHEMA.get();
- 
-             if (schema == null) {
-                 schema = new SchemaHolder();
- 
-                 SCHEMA.set(schema);
-             }
-         }
- 
-         schemaId = PortableUtils.updateSchemaId(schemaId, fieldId);
- 
-         schema.push(fieldId, fieldOff);
+         // 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 = PortableUtils.updateSchemaId(schemaId, fieldId)        schema.push(fieldId, fieldOff);
  
 -        schemaId = schemaId0;
 +        fieldCnt++;
 +    }
  
 -        schema.push(fieldId, fieldOff);
 +    /**
 +     * @return Current schema ID.
 +     */
 +    public int schemaId() {
 +        return schemaId;
 +    }
  
 -        fieldCnt++;
 +    /**
 +     * @return Current writer's schema.
 +     */
 +    public PortableSchema currentSchema() {
 +        PortableSchema.Builder builder = PortableSchema.Builder.newBuilder();
 +
 +        if (schema != null)
 +            schema.build(builder, fieldCnt);
 +
 +        return builder.build();
      }
  
      /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/d3050033/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 8543ce6,4762e81..98728cc
--- 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
@@@ -224,12 -206,12 +224,12 @@@ public class PortableClassDescriptor 
                  break;
  
              case OBJECT:
 -                assert idMapper != null;
 -
                  ctor = constructor(cls);
-                 fields = new ArrayList<>();
-                 stableFieldsMeta = metaDataEnabled ? new HashMap<String, Integer>() : null;
+                 ArrayList<BinaryFieldAccessor> fields0 = new ArrayList<>();
+                 fieldsMeta = metaDataEnabled ? new HashMap<String, String>() : null;
  
 +                PortableSchema.Builder schemaBuilder = PortableSchema.Builder.newBuilder();
 +
                  Collection<String> names = new HashSet<>();
                  Collection<Integer> ids = new HashSet<>();
  
@@@ -250,20 -232,18 +250,22 @@@
                              if (!ids.add(fieldId))
                                  throw new BinaryObjectException("Duplicate field ID: " + name);
  
-                             FieldInfo fieldInfo = new FieldInfo(f, fieldId);
+                             BinaryFieldAccessor fieldInfo = BinaryFieldAccessor.create(f, fieldId);
  
-                             fields.add(fieldInfo);
+                             fields0.add(fieldInfo);
  
 +                            schemaBuilder.addField(fieldId);
 +
                              if (metaDataEnabled)
-                                 stableFieldsMeta.put(name, fieldInfo.fieldMode().typeId());
 -                                fieldsMeta.put(name, fieldInfo.mode().typeName());
++                                stableFieldsMeta.put(name, fieldInfo.mode().typeId());
                          }
                      }
                  }
--
++                
+                 fields = fields0.toArray(new BinaryFieldAccessor[fields0.size()]);
 -
++                
 +                stableSchemas = Collections.singleton(schemaBuilder.build());
- 
++                
                  break;
  
              default:
@@@ -723,12 -682,24 +725,22 @@@
          if (writer.tryWriteAsHandle(obj))
              return false;
  
-         PortableUtils.writeHeader(
-             writer,
-             registered ? typeId : GridPortableMarshaller.UNREGISTERED_TYPE_ID,
-             obj instanceof CacheObjectImpl ? 0 : obj.hashCode(),
-             registered ? null : cls.getName()
-         );
+         if (registered) {
+             PortableUtils.writeHeader(
+                 writer,
 -                userType,
+                 typeId,
+                 obj instanceof CacheObjectImpl ? 0 : obj.hashCode(),
+                 null
+             );
+         }
+         else {
+             PortableUtils.writeHeader(
+                 writer,
 -                userType,
+                 GridPortableMarshaller.UNREGISTERED_TYPE_ID,
+                 obj instanceof CacheObjectImpl ? 0 : obj.hashCode(),
+                 cls.getName()
+             );
+         }
  
          return true;
      }
@@@ -794,651 -764,155 +806,154 @@@
  
          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.OBJECT_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 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 OBJECT_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 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 OBJECT_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());
+     enum Mode {
+         /** Primitive byte. */
 -        P_BYTE("byte"),
++        P_BYTE(GridPortableMarshaller.BYTE),
  
-                     break;
+         /** Primitive boolean. */
 -        P_BOOLEAN("boolean"),
++        P_BOOLEAN(GridPortableMarshaller.BOOLEAN),
  
-                 case PORTABLE:
-                 case EXTERNALIZABLE:
-                 case OBJECT:
-                     val = reader.readObject(id);
+         /** Primitive short. */
 -        P_SHORT("short"),
++        P_SHORT(GridPortableMarshaller.SHORT),
  
-                     break;
+         /** Primitive char. */
 -        P_CHAR("char"),
++        P_CHAR(GridPortableMarshaller.CHAR),
  
-                 case CLASS:
-                     val = reader.readClass(id);
+         /** Primitive int. */
 -        P_INT("int"),
++        P_INT(GridPortableMarshaller.INT),
  
-                     break;
+         /** Primitive long. */
 -        P_LONG("long"),
++        P_LONG(GridPortableMarshaller.LONG),
  
-                 default:
-                     assert false : "Invalid mode: " + mode;
-             }
+         /** Primitive float. */
 -        P_FLOAT("float"),
++        P_FLOAT(GridPortableMarshaller.FLOAT),
  
-             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 {
+         /** Primitive int. */
 -        P_DOUBLE("double"),
 -
++        P_DOUBLE(GridPortableMarshaller.DOUBLE),
++        
          /** */
 -        BYTE("byte"),
 +        BYTE(GridPortableMarshaller.BYTE),
  
          /** */
 -        SHORT("short"),
 +        SHORT(GridPortableMarshaller.SHORT),
  
          /** */
 -        INT("int"),
 +        INT(GridPortableMarshaller.INT),
  
          /** */
 -        LONG("long"),
 +        LONG(GridPortableMarshaller.LONG),
  
          /** */
 -        FLOAT("float"),
 +        FLOAT(GridPortableMarshaller.FLOAT),
  
          /** */
 -        DOUBLE("double"),
 +        DOUBLE(GridPortableMarshaller.DOUBLE),
  
          /** */
 -        CHAR("char"),
 +        CHAR(GridPortableMarshaller.CHAR),
  
          /** */
 -        BOOLEAN("boolean"),
 +        BOOLEAN(GridPortableMarshaller.BOOLEAN),
  
          /** */
 -        DECIMAL("decimal"),
 +        DECIMAL(GridPortableMarshaller.DECIMAL),
  
          /** */
 -        STRING("String"),
 +        STRING(GridPortableMarshaller.STRING),
  
          /** */
 -        UUID("UUID"),
 +        UUID(GridPortableMarshaller.UUID),
  
          /** */
 -        DATE("Date"),
 +        DATE(GridPortableMarshaller.DATE),
  
          /** */
 -        TIMESTAMP("Timestamp"),
 +        TIMESTAMP(GridPortableMarshaller.TIMESTAMP),
  
          /** */
 -        BYTE_ARR("byte[]"),
 +        BYTE_ARR(GridPortableMarshaller.BYTE_ARR),
  
          /** */
 -        SHORT_ARR("short[]"),
 +        SHORT_ARR(GridPortableMarshaller.SHORT_ARR),
  
          /** */
 -        INT_ARR("int[]"),
 +        INT_ARR(GridPortableMarshaller.INT_ARR),
  
          /** */
 -        LONG_ARR("long[]"),
 +        LONG_ARR(GridPortableMarshaller.LONG_ARR),
  
          /** */
 -        FLOAT_ARR("float[]"),
 +        FLOAT_ARR(GridPortableMarshaller.FLOAT_ARR),
  
          /** */
 -        DOUBLE_ARR("double[]"),
 +        DOUBLE_ARR(GridPortableMarshaller.DOUBLE_ARR),
  
          /** */
 -        CHAR_ARR("char[]"),
 +        CHAR_ARR(GridPortableMarshaller.CHAR_ARR),
  
          /** */
 -        BOOLEAN_ARR("boolean[]"),
 +        BOOLEAN_ARR(GridPortableMarshaller.BOOLEAN_ARR),
  
          /** */
 -        DECIMAL_ARR("decimal[]"),
 +        DECIMAL_ARR(GridPortableMarshaller.DECIMAL_ARR),
  
          /** */
 -        STRING_ARR("String[]"),
 +        STRING_ARR(GridPortableMarshaller.STRING_ARR),
  
          /** */
 -        UUID_ARR("UUID[]"),
 +        UUID_ARR(GridPortableMarshaller.UUID_ARR),
  
          /** */
 -        DATE_ARR("Date[]"),
 +        DATE_ARR(GridPortableMarshaller.DATE_ARR),
  
          /** */
 -        TIMESTAMP_ARR("Timestamp[]"),
 +        TIMESTAMP_ARR(GridPortableMarshaller.TIMESTAMP_ARR),
  
          /** */
 -        OBJ_ARR("Object[]"),
 +        OBJECT_ARR(GridPortableMarshaller.OBJ_ARR),
  
          /** */
 -        COL("Collection"),
 +        COL(GridPortableMarshaller.COL),
  
          /** */
 -        MAP("Map"),
 +        MAP(GridPortableMarshaller.MAP),
  
          /** */
 -        MAP_ENTRY("Entry"),
 +        MAP_ENTRY(GridPortableMarshaller.MAP_ENTRY),
  
          /** */
 -        PORTABLE_OBJ("Object"),
 +        PORTABLE_OBJ(GridPortableMarshaller.OBJ),
  
          /** */
 -        ENUM("Enum"),
 +        ENUM(GridPortableMarshaller.ENUM),
  
          /** */
 -        ENUM_ARR("Enum[]"),
 +        ENUM_ARR(GridPortableMarshaller.ENUM_ARR),
  
          /** */
 -        CLASS("Class"),
 +        CLASS(GridPortableMarshaller.CLASS),
  
          /** */
 -        PORTABLE("Object"),
 +        PORTABLE(GridPortableMarshaller.PORTABLE_OBJ),
  
          /** */
 -        EXTERNALIZABLE("Object"),
 +        EXTERNALIZABLE(GridPortableMarshaller.OBJ),
  
          /** */
 -        OBJECT("Object"),
 +        OBJECT(GridPortableMarshaller.OBJ),
  
          /** */
 -        EXCLUSION("Exclusion");
 +        EXCLUSION(GridPortableMarshaller.OBJ);
  
          /** */
 -        private final String typeName;
 +        private final int typeId;
  
          /**
 -         * @param typeName Type name.
 +         * @param typeId Type ID.
           */
 -        Mode(String typeName) {
 -            this.typeName = typeName;
 +        Mode(int typeId) {
 +            this.typeId = typeId;
          }
  
          /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/d3050033/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 95ef9591,a6a7238..669bcaf
--- 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
@@@ -837,70 -702,105 +839,173 @@@ public class PortableUtils 
      }
  
      /**
 +     * Merge old and new metas.
 +     *
 +     * @param oldMeta Old meta.
 +     * @param newMeta New meta.
 +     * @return New meta if old meta was null, old meta if no changes detected, merged meta otherwise.
 +     * @throws BinaryObjectException If merge failed due to metadata conflict.
 +     */
 +    public static BinaryMetadata mergeMetadata(@Nullable BinaryMetadata oldMeta, BinaryMetadata newMeta) {
 +        assert newMeta != null;
 +
 +        if (oldMeta == null)
 +            return newMeta;
 +        else {
 +            assert oldMeta.typeId() == newMeta.typeId();
 +
 +            // Check type name.
 +            if (!F.eq(oldMeta.typeName(), newMeta.typeName())) {
 +                throw new BinaryObjectException(
 +                    "Two portable types have duplicate type ID [" + "typeId=" + oldMeta.typeId() +
 +                        ", typeName1=" + oldMeta.typeName() + ", typeName2=" + newMeta.typeName() + ']'
 +                );
 +            }
 +
 +            // Check affinity field names.
 +            if (!F.eq(oldMeta.affinityKeyFieldName(), newMeta.affinityKeyFieldName())) {
 +                throw new BinaryObjectException(
 +                    "Binary type has different affinity key fields [" + "typeName=" + newMeta.typeName() +
 +                        ", affKeyFieldName1=" + oldMeta.affinityKeyFieldName() +
 +                        ", affKeyFieldName2=" + newMeta.affinityKeyFieldName() + ']'
 +                );
 +            }
 +
 +            // Check and merge fields.
 +            boolean changed = false;
 +
 +            Map<String, Integer> mergedFields = new HashMap<>(oldMeta.fieldsMap());
 +            Map<String, Integer> newFields = newMeta.fieldsMap();
 +
 +            for (Map.Entry<String, Integer> newField : newFields.entrySet()) {
 +                Integer oldFieldType = mergedFields.put(newField.getKey(), newField.getValue());
 +
 +                if (oldFieldType == null)
 +                    changed = true;
 +                else if (!F.eq(oldFieldType, newField.getValue())) {
 +                    throw new BinaryObjectException(
 +                        "Binary type has different field types [" + "typeName=" + oldMeta.typeName() +
 +                            ", fieldName=" + newField.getKey() +
 +                            ", fieldTypeName1=" + PortableUtils.fieldTypeName(oldFieldType) +
 +                            ", fieldTypeName2=" + PortableUtils.fieldTypeName(newField.getValue()) + ']'
 +                    );
 +                }
 +            }
 +
 +            // Check and merge schemas.
 +            Collection<PortableSchema> mergedSchemas = new HashSet<>(oldMeta.schemas());
 +
 +            for (PortableSchema newSchema : newMeta.schemas()) {
 +                if (mergedSchemas.add(newSchema))
 +                    changed = true;
 +            }
 +
 +            // Return either old meta if no changes detected, or new merged meta.
 +            return changed ? new BinaryMetadata(oldMeta.typeId(), oldMeta.typeName(), mergedFields,
 +                oldMeta.affinityKeyFieldName(), mergedSchemas) : oldMeta;
 +        }
 +    }
++
++    /**
+      * @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.isEnum())
+             return PortableClassDescriptor.Mode.ENUM;
+         else if (cls == Class.class)
+             return PortableClassDescriptor.Mode.CLASS;
+         else
+             return PortableClassDescriptor.Mode.OBJECT;
+     }
  }