You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2015/11/02 18:21:59 UTC

[11/29] ignite git commit: Merge branch ignite-1282 into ignite-950-new

Merge branch ignite-1282 into ignite-950-new


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

Branch: refs/heads/ignite-950-new
Commit: 71d18bb4d33032b140227be35aea99543621af0b
Parents: f957ed4 fd640d7
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Mon Nov 2 19:39:51 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Mon Nov 2 19:39:51 2015 +0300

----------------------------------------------------------------------
 .../internal/portable/IgniteObjectImpl.java     |  33 +-
 .../portable/PortablePositionReadable.java      |   8 +
 .../internal/portable/PortablePrimitives.java   | 755 ++++---------------
 .../ignite/internal/portable/PortableUtils.java |  15 +
 .../builder/IgniteObjectBuilderImpl.java        |   2 +-
 .../portable/builder/PortableBuilderReader.java |  41 +-
 .../streams/PortableAbstractInputStream.java    |  18 +
 .../streams/PortableHeapInputStream.java        |   5 +
 .../streams/PortableOffheapInputStream.java     |   5 +
 .../PlatformBigEndianInputStreamImpl.java       |   5 +
 .../memory/PlatformInputStreamImpl.java         |  10 +
 .../src/impl/portable/portable_reader_impl.cpp  |  44 --
 12 files changed, 261 insertions(+), 680 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/71d18bb4/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectImpl.java
index 7b16b66,0000000..639435b
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/IgniteObjectImpl.java
@@@ -1,541 -1,0 +1,538 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable;
 +
 +import org.apache.ignite.IgniteCheckedException;
 +import org.apache.ignite.internal.GridDirectTransient;
 +import org.apache.ignite.internal.IgniteCodeGeneratingFail;
 +import org.apache.ignite.internal.portable.streams.PortableHeapInputStream;
 +import org.apache.ignite.internal.processors.cache.CacheObject;
 +import org.apache.ignite.internal.processors.cache.CacheObjectContext;
 +import org.apache.ignite.internal.processors.cache.KeyCacheObject;
 +import org.apache.ignite.internal.processors.cache.portable.CacheObjectPortableProcessorImpl;
 +import org.apache.ignite.internal.util.typedef.internal.U;
 +import org.apache.ignite.plugin.extensions.communication.Message;
 +import org.apache.ignite.plugin.extensions.communication.MessageReader;
 +import org.apache.ignite.plugin.extensions.communication.MessageWriter;
 +import org.apache.ignite.igniteobject.IgniteObjectException;
 +import org.apache.ignite.igniteobject.IgniteObjectMetadata;
 +import org.apache.ignite.igniteobject.IgniteObject;
 +import org.apache.ignite.portable.PortableField;
 +import org.jetbrains.annotations.Nullable;
 +
 +import java.io.Externalizable;
 +import java.io.IOException;
 +import java.io.ObjectInput;
 +import java.io.ObjectOutput;
 +import java.nio.ByteBuffer;
 +
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.BOOLEAN;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.BYTE;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.CHAR;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DOUBLE;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.FLOAT;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.INT;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.LONG;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.SHORT;
 +
 +/**
 + * Portable object implementation.
 + */
 +@IgniteCodeGeneratingFail // Fields arr and start should not be generated by MessageCodeGenerator.
 +public final class IgniteObjectImpl extends IgniteObjectEx implements Externalizable,
 +    Message, CacheObject, KeyCacheObject {
 +    /** */
 +    public static final byte TYPE_PORTABLE = 100;
 +
 +    /** */
 +    private static final long serialVersionUID = 0L;
 +
 +    /** */
-     private static final PortablePrimitives PRIM = PortablePrimitives.get();
- 
-     /** */
 +    @GridDirectTransient
 +    private PortableContext ctx;
 +
 +    /** */
 +    private byte[] arr;
 +
 +    /** */
 +    private int start;
 +
 +    /** */
 +    @GridDirectTransient
 +    private Object obj;
 +
 +    /** */
 +    @GridDirectTransient
 +    private boolean detachAllowed;
 +
 +    /**
 +     * For {@link Externalizable}.
 +     */
 +    public IgniteObjectImpl() {
 +        // No-op.
 +    }
 +
 +    /**
 +     * @param ctx Context.
 +     * @param arr Array.
 +     * @param start Start.
 +     */
 +    public IgniteObjectImpl(PortableContext ctx, byte[] arr, int start) {
 +        assert ctx != null;
 +        assert arr != null;
 +
 +        this.ctx = ctx;
 +        this.arr = arr;
 +        this.start = start;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public byte type() {
 +        return TYPE_PORTABLE;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean isPlatformType() {
 +        return false;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean internal() {
 +        return false;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
 +        Object obj0 = obj;
 +
 +        if (obj0 == null || cpy)
 +            obj0 = deserializeValue();
 +
 +        return (T)obj0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public byte[] valueBytes(CacheObjectContext ctx) throws IgniteCheckedException {
 +        if (detached())
 +            return array();
 +
 +        int len = length();
 +
 +        byte[] arr0 = new byte[len];
 +
 +        U.arrayCopy(arr, start, arr0, 0, len);
 +
 +        return arr0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public CacheObject prepareForCache(CacheObjectContext ctx) {
 +        if (detached())
 +            return this;
 +
 +        return (IgniteObjectImpl)detach();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void finishUnmarshal(CacheObjectContext ctx, ClassLoader ldr) throws IgniteCheckedException {
 +        this.ctx = ((CacheObjectPortableProcessorImpl)ctx.processor()).portableContext();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException {
 +        // No-op.
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int length() {
-         return PRIM.readInt(arr, start + GridPortableMarshaller.TOTAL_LEN_POS);
++        return PortablePrimitives.readInt(arr, start + GridPortableMarshaller.TOTAL_LEN_POS);
 +    }
 +
 +    /**
 +     * @return Detached portable object.
 +     */
 +    public IgniteObject detach() {
 +        if (!detachAllowed || detached())
 +            return this;
 +
 +        int len = length();
 +
 +        byte[] arr0 = new byte[len];
 +
 +        U.arrayCopy(arr, start, arr0, 0, len);
 +
 +        return new IgniteObjectImpl(ctx, arr0, 0);
 +    }
 +
 +    /**
 +     * @return Detached or not.
 +     */
 +    public boolean detached() {
 +        return start == 0 && length() == arr.length;
 +    }
 +
 +    /**
 +     * @return {@code True} if detach is allowed.
 +     */
 +    public boolean detachAllowed() {
 +        return true;
 +    }
 +
 +    /**
 +     * @param detachAllowed Detach allowed flag.
 +     */
 +    public void detachAllowed(boolean detachAllowed) {
 +        this.detachAllowed = detachAllowed;
 +    }
 +
 +    /**
 +     * @return Context.
 +     */
 +    public PortableContext context() {
 +        return ctx;
 +    }
 +
 +    /**
 +     * @param ctx Context.
 +     */
 +    public void context(PortableContext ctx) {
 +        this.ctx = ctx;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public byte[] array() {
 +        return arr;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int start() {
 +        return start;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public long offheapAddress() {
 +        return 0;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected boolean hasArray() {
 +        return true;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int typeId() {
-         return PRIM.readInt(arr, start + GridPortableMarshaller.TYPE_ID_POS);
++        return PortablePrimitives.readInt(arr, start + GridPortableMarshaller.TYPE_ID_POS);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Nullable @Override public IgniteObjectMetadata metaData() throws IgniteObjectException {
 +        if (ctx == null)
 +            throw new IgniteObjectException("PortableContext is not set for the object.");
 +
 +        return ctx.metaData(typeId());
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override public <F> F field(String fieldName) throws IgniteObjectException {
 +        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, arr, start, null);
 +
 +        return (F)reader.unmarshalField(fieldName);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override public <F> F field(int fieldId) throws IgniteObjectException {
 +        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, arr, start, null);
 +
 +        return (F)reader.unmarshalField(fieldId);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override protected <F> F fieldByOffset(int fieldOffset) {
 +        Object val;
 +
-         int schemaOffset = PRIM.readInt(arr, start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
-         int fieldPos = PRIM.readInt(arr, start + schemaOffset + fieldOffset);
++        int schemaOffset = PortablePrimitives.readInt(arr, start + GridPortableMarshaller.SCHEMA_OR_RAW_OFF_POS);
++        int fieldPos = PortablePrimitives.readInt(arr, start + schemaOffset + fieldOffset);
 +
 +        // Read header and try performing fast lookup for well-known types (the most common types go first).
-         byte hdr = PRIM.readByte(arr, fieldPos);
++        byte hdr = PortablePrimitives.readByte(arr, fieldPos);
 +
 +        switch (hdr) {
 +            case INT:
-                 val = PRIM.readInt(arr, fieldPos + 1);
++                val = PortablePrimitives.readInt(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case LONG:
-                 val = PRIM.readLong(arr, fieldPos + 1);
++                val = PortablePrimitives.readLong(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case BOOLEAN:
-                 val = PRIM.readBoolean(arr, fieldPos + 1);
++                val = PortablePrimitives.readBoolean(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case SHORT:
-                 val = PRIM.readShort(arr, fieldPos + 1);
++                val = PortablePrimitives.readShort(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case BYTE:
-                 val = PRIM.readByte(arr, fieldPos + 1);
++                val = PortablePrimitives.readByte(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case CHAR:
-                 val = PRIM.readChar(arr, fieldPos + 1);
++                val = PortablePrimitives.readChar(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case FLOAT:
-                 val = PRIM.readFloat(arr, fieldPos + 1);
++                val = PortablePrimitives.readFloat(arr, fieldPos + 1);
 +
 +                break;
 +
 +            case DOUBLE:
-                 val = PRIM.readDouble(arr, fieldPos + 1);
++                val = PortablePrimitives.readDouble(arr, fieldPos + 1);
 +
 +                break;
 +
 +//            case DECIMAL:
 +//                val = doReadDecimal();
 +//
 +//                break;
 +//
 +//            case STRING:
 +//                val = doReadString();
 +//
 +//                break;
 +//
 +//            case UUID:
 +//                val = doReadUuid();
 +//
 +//                break;
 +//
 +//            case DATE:
 +//                val = doReadDate();
 +//
 +//                break;
 +//
 +//            case TIMESTAMP:
 +//                val = doReadTimestamp();
 +//
 +//                break;
 +
 +            default: {
 +                // TODO: Pass absolute offset, not relative.
 +                IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, arr, start, null);
 +
 +                val = reader.unmarshalFieldByOffset(fieldOffset);
 +            }
 +        }
 +
 +        return (F)val;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override protected <F> F field(PortableReaderContext rCtx, String fieldName) {
 +        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx,
 +            new PortableHeapInputStream(arr),
 +            start,
 +            null,
 +            rCtx);
 +
 +        return (F)reader.unmarshalField(fieldName);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean hasField(String fieldName) {
 +        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, arr, start, null);
 +
 +        return reader.hasField(fieldName);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Nullable @Override public <T> T deserialize() throws IgniteObjectException {
 +        Object obj0 = obj;
 +
 +        if (obj0 == null)
 +            obj0 = deserializeValue();
 +
 +        return (T)obj0;
 +
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public IgniteObject clone() throws CloneNotSupportedException {
 +        return super.clone();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int hashCode() {
-         return PRIM.readInt(arr, start + GridPortableMarshaller.HASH_CODE_POS);
++        return PortablePrimitives.readInt(arr, start + GridPortableMarshaller.HASH_CODE_POS);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected int schemaId() {
-         return PRIM.readInt(arr, start + GridPortableMarshaller.SCHEMA_ID_POS);
++        return PortablePrimitives.readInt(arr, start + GridPortableMarshaller.SCHEMA_ID_POS);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected PortableSchema createSchema() {
 +        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, arr, start, null);
 +
 +        return reader.createSchema();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public PortableField fieldDescriptor(String fieldName) throws IgniteObjectException {
 +        int typeId = typeId();
 +
 +        PortableSchemaRegistry schemaReg = ctx.schemaRegistry(typeId);
 +
 +        int fieldId = ctx.userTypeIdMapper(typeId).fieldId(typeId, fieldName);
 +
 +        return new PortableFieldImpl(schemaReg, fieldId);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeExternal(ObjectOutput out) throws IOException {
 +        out.writeObject(ctx);
 +
 +        if (detachAllowed) {
 +            int len = length();
 +
 +            out.writeInt(len);
 +            out.write(arr, start, len);
 +            out.writeInt(0);
 +        }
 +        else {
 +            out.writeInt(arr.length);
 +            out.write(arr);
 +            out.writeInt(start);
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
 +        ctx = (PortableContext)in.readObject();
 +
 +        arr = new byte[in.readInt()];
 +
 +        in.readFully(arr);
 +
 +        start = in.readInt();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
 +        writer.setBuffer(buf);
 +
 +        if (!writer.isHeaderWritten()) {
 +            if (!writer.writeHeader(directType(), fieldsCount()))
 +                return false;
 +
 +            writer.onHeaderWritten();
 +        }
 +
 +        switch (writer.state()) {
 +            case 0:
 +                if (!writer.writeByteArray("arr",
 +                    arr,
 +                    detachAllowed ? start : 0,
 +                    detachAllowed ? length() : arr.length))
 +                    return false;
 +
 +                writer.incrementState();
 +
 +            case 1:
 +                if (!writer.writeInt("start", detachAllowed ? 0 : start))
 +                    return false;
 +
 +                writer.incrementState();
 +
 +        }
 +
 +        return true;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
 +        reader.setBuffer(buf);
 +
 +        if (!reader.beforeMessageRead())
 +            return false;
 +
 +        switch (reader.state()) {
 +            case 0:
 +                arr = reader.readByteArray("arr");
 +
 +                if (!reader.isLastRead())
 +                    return false;
 +
 +                reader.incrementState();
 +
 +            case 1:
 +                start = reader.readInt("start");
 +
 +                if (!reader.isLastRead())
 +                    return false;
 +
 +                reader.incrementState();
 +
 +        }
 +
 +        return true;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public byte directType() {
 +        return 113;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public byte fieldsCount() {
 +        return 3;
 +    }
 +
 +    /**
 +     * Runs value deserialization regardless of whether obj already has the deserialized value.
 +     * Will set obj if descriptor is configured to keep deserialized values.
 +     */
 +    private Object deserializeValue() {
 +        // TODO: IGNITE-1272 - Deserialize with proper class loader.
 +        IgniteObjectReaderExImpl reader = new IgniteObjectReaderExImpl(ctx, arr, start, null);
 +
 +        Object obj0 = reader.deserialize();
 +
 +        PortableClassDescriptor desc = reader.descriptor();
 +
 +        assert desc != null;
 +
 +        if (desc.keepDeserialized())
 +            obj = obj0;
 +
 +        return obj0;
 +    }
 +}

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

http://git-wip-us.apache.org/repos/asf/ignite/blob/71d18bb4/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/IgniteObjectBuilderImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/IgniteObjectBuilderImpl.java
index 7c167f3,0000000..2783f8a
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/IgniteObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/IgniteObjectBuilderImpl.java
@@@ -1,551 -1,0 +1,551 @@@
 +/*
 + * 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.builder;
 +
 +import java.util.Collections;
 +import java.util.HashMap;
 +import java.util.LinkedHashMap;
 +import java.util.Map;
 +import java.util.Set;
 +import org.apache.ignite.igniteobject.IgniteObject;
 +import org.apache.ignite.igniteobject.IgniteObjectBuilder;
 +import org.apache.ignite.igniteobject.IgniteObjectException;
 +import org.apache.ignite.igniteobject.IgniteObjectInvalidClassException;
 +import org.apache.ignite.igniteobject.IgniteObjectMetadata;
 +import org.apache.ignite.internal.portable.IgniteObjectImpl;
 +import org.apache.ignite.internal.portable.IgniteObjectOffheapImpl;
 +import org.apache.ignite.internal.portable.IgniteObjectWriterExImpl;
 +import org.apache.ignite.internal.portable.PortableContext;
 +import org.apache.ignite.internal.portable.PortableUtils;
 +import org.apache.ignite.internal.processors.cache.portable.CacheObjectPortableProcessorImpl;
 +import org.apache.ignite.internal.util.GridArgumentCheck;
 +import org.apache.ignite.internal.util.typedef.F;
 +import org.apache.ignite.internal.util.typedef.internal.U;
 +import org.apache.ignite.lang.IgniteBiTuple;
 +import org.jetbrains.annotations.Nullable;
 +
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.DFLT_HDR_LEN;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.HASH_CODE_POS;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.PROTO_VER_POS;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.TYPE_ID_POS;
 +import static org.apache.ignite.internal.portable.GridPortableMarshaller.UNREGISTERED_TYPE_ID;
 +
 +/**
 + *
 + */
 +public class IgniteObjectBuilderImpl implements IgniteObjectBuilder {
 +    /** */
 +    private static final Object REMOVED_FIELD_MARKER = new Object();
 +
 +    /** */
 +    private final PortableContext ctx;
 +
 +    /** */
 +    private final int typeId;
 +
 +    /** May be null. */
 +    private String typeName;
 +
 +    /** May be null. */
 +    private String clsNameToWrite;
 +
 +    /** */
 +    private boolean registeredType = true;
 +
 +    /** */
 +    private Map<String, Object> assignedVals;
 +
 +    /** */
 +    private Map<Integer, Object> readCache;
 +
 +    /** Position of object in source array, or -1 if object is not created from PortableObject. */
 +    private final int start;
 +
 +    /** Total header length */
 +    private final int hdrLen;
 +
 +    /**
 +     * Context of PortableObject reading process. Or {@code null} if object is not created from PortableObject.
 +     */
 +    private final PortableBuilderReader reader;
 +
 +    /** */
 +    private int hashCode;
 +
 +    /**
 +     * @param clsName Class name.
 +     * @param ctx Portable context.
 +     */
 +    public IgniteObjectBuilderImpl(PortableContext ctx, String clsName) {
 +        this(ctx, ctx.typeId(clsName), PortableContext.typeName(clsName));
 +    }
 +
 +    /**
 +     * @param typeId Type ID.
 +     * @param ctx Portable context.
 +     */
 +    public IgniteObjectBuilderImpl(PortableContext ctx, int typeId) {
 +        this(ctx, typeId, null);
 +    }
 +
 +    /**
 +     * @param typeName Type name.
 +     * @param ctx Context.
 +     * @param typeId Type id.
 +     */
 +    public IgniteObjectBuilderImpl(PortableContext ctx, int typeId, String typeName) {
 +        this.typeId = typeId;
 +        this.typeName = typeName;
 +        this.ctx = ctx;
 +
 +        start = -1;
 +        reader = null;
 +        hdrLen = DFLT_HDR_LEN;
 +
 +        readCache = Collections.emptyMap();
 +    }
 +
 +    /**
 +     * @param obj Object to wrap.
 +     */
 +    public IgniteObjectBuilderImpl(IgniteObjectImpl obj) {
 +        this(new PortableBuilderReader(obj), obj.start());
 +
 +        reader.registerObject(this);
 +    }
 +
 +    /**
 +     * @param reader ctx
 +     * @param start Start.
 +     */
 +    IgniteObjectBuilderImpl(PortableBuilderReader reader, int start) {
 +        this.reader = reader;
 +        this.start = start;
 +
-         byte ver = reader.readByteAbsolute(start + PROTO_VER_POS);
++        byte ver = reader.readBytePositioned(start + PROTO_VER_POS);
 +
 +        PortableUtils.checkProtocolVersion(ver);
 +
 +        int typeId = reader.readIntPositioned(start + TYPE_ID_POS);
 +        ctx = reader.portableContext();
 +        hashCode = reader.readIntPositioned(start + HASH_CODE_POS);
 +
 +        if (typeId == UNREGISTERED_TYPE_ID) {
 +            int mark = reader.position();
 +
 +            reader.position(start + DFLT_HDR_LEN);
 +
 +            clsNameToWrite = reader.readString();
 +
 +            Class cls;
 +
 +            try {
 +                // TODO: IGNITE-1272 - Is class loader needed here?
 +                cls = U.forName(clsNameToWrite, null);
 +            }
 +            catch (ClassNotFoundException e) {
 +                throw new IgniteObjectInvalidClassException("Failed to load the class: " + clsNameToWrite, e);
 +            }
 +
 +            this.typeId = ctx.descriptorForClass(cls).typeId();
 +
 +            registeredType = false;
 +
 +            hdrLen = reader.position() - mark;
 +
 +            reader.position(mark);
 +        }
 +        else {
 +            this.typeId = typeId;
 +            hdrLen = DFLT_HDR_LEN;
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public IgniteObject build() {
 +        try (IgniteObjectWriterExImpl writer = new IgniteObjectWriterExImpl(ctx, typeId, false)) {
 +
 +            PortableBuilderSerializer serializationCtx = new PortableBuilderSerializer();
 +
 +            serializationCtx.registerObjectWriting(this, 0);
 +
 +            serializeTo(writer, serializationCtx);
 +
 +            byte[] arr = writer.array();
 +
 +            return new IgniteObjectImpl(ctx, arr, 0);
 +        }
 +    }
 +
 +    /**
 +     * @param writer Writer.
 +     * @param serializer Serializer.
 +     */
 +    void serializeTo(IgniteObjectWriterExImpl writer, PortableBuilderSerializer serializer) {
 +        PortableUtils.writeHeader(writer,
 +            true,
 +            registeredType ? typeId : UNREGISTERED_TYPE_ID,
 +            hashCode,
 +            registeredType ? null : clsNameToWrite);
 +
 +        Set<Integer> remainsFlds = null;
 +
 +        if (reader != null) {
 +            Map<Integer, Object> assignedFldsById;
 +
 +            if (assignedVals != null) {
 +                assignedFldsById = U.newHashMap(assignedVals.size());
 +
 +                for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
 +                    int fldId = ctx.fieldId(typeId, entry.getKey());
 +
 +                    assignedFldsById.put(fldId, entry.getValue());
 +                }
 +
 +                remainsFlds = assignedFldsById.keySet();
 +            }
 +            else
 +                assignedFldsById = Collections.emptyMap();
 +
 +            // Get footer details.
 +            IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start);
 +
 +            int footerPos = footer.get1();
 +            int footerEnd = footer.get2();
 +
 +            // Get raw position.
 +            int rawPos = PortableUtils.rawOffsetAbsolute(reader, start);
 +
 +            // Position reader on data.
 +            reader.position(start + hdrLen);
 +
 +            while (reader.position() < rawPos) {
 +                int fieldId = reader.readIntPositioned(footerPos);
 +                int fieldLen = fieldPositionAndLength(footerPos, footerEnd, rawPos).get2();
 +
 +                footerPos += 8;
 +
 +                if (assignedFldsById.containsKey(fieldId)) {
 +                    Object assignedVal = assignedFldsById.remove(fieldId);
 +
 +                    reader.skip(fieldLen);
 +
 +                    if (assignedVal != REMOVED_FIELD_MARKER) {
 +                        writer.writeFieldId(fieldId);
 +
 +                        serializer.writeValue(writer, assignedVal);
 +                    }
 +                }
 +                else {
 +                    int type = fieldLen != 0 ? reader.readByte(0) : 0;
 +
 +                    if (fieldLen != 0 && !PortableUtils.isPlainArrayType(type) && PortableUtils.isPlainType(type)) {
 +                        writer.writeFieldId(fieldId);
 +                        writer.write(reader.array(), reader.position(), fieldLen);
 +
 +                        reader.skip(fieldLen);
 +                    }
 +                    else {
 +                        writer.writeFieldId(fieldId);
 +
 +                        Object val;
 +
 +                        if (fieldLen == 0)
 +                            val = null;
 +                        else if (readCache == null) {
 +                            int savedPos = reader.position();
 +
 +                            val = reader.parseValue();
 +
 +                            assert reader.position() == savedPos + fieldLen;
 +                        }
 +                        else {
 +                            val = readCache.get(fieldId);
 +
 +                            reader.skip(fieldLen);
 +                        }
 +
 +                        serializer.writeValue(writer, val);
 +                    }
 +                }
 +            }
 +        }
 +
 +        if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
 +            boolean metadataEnabled = ctx.isMetaDataEnabled(typeId);
 +
 +            IgniteObjectMetadata metadata = null;
 +
 +            if (metadataEnabled)
 +                metadata = ctx.metaData(typeId);
 +
 +            Map<String, String> newFldsMetadata = null;
 +
 +            for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
 +                Object val = entry.getValue();
 +
 +                if (val == REMOVED_FIELD_MARKER)
 +                    continue;
 +
 +                String name = entry.getKey();
 +
 +                int fldId = ctx.fieldId(typeId, name);
 +
 +                if (remainsFlds != null && !remainsFlds.contains(fldId))
 +                    continue;
 +
 +                writer.writeFieldId(fldId);
 +
 +                serializer.writeValue(writer, val);
 +
 +                if (metadataEnabled) {
 +                    String oldFldTypeName = metadata == null ? null : metadata.fieldTypeName(name);
 +
 +                    String newFldTypeName;
 +
 +                    if (val instanceof PortableValueWithType)
 +                        newFldTypeName = ((PortableValueWithType)val).typeName();
 +                    else {
 +                        byte type = PortableUtils.typeByClass(val.getClass());
 +
 +                        newFldTypeName = CacheObjectPortableProcessorImpl.fieldTypeName(type);
 +                    }
 +
 +                    if (oldFldTypeName == null) {
 +                        // It's a new field, we have to add it to metadata.
 +
 +                        if (newFldsMetadata == null)
 +                            newFldsMetadata = new HashMap<>();
 +
 +                        newFldsMetadata.put(name, newFldTypeName);
 +                    }
 +                    else {
 +                        if (!"Object".equals(oldFldTypeName) && !oldFldTypeName.equals(newFldTypeName)) {
 +                            throw new IgniteObjectException(
 +                                "Wrong value has been set [" +
 +                                    "typeName=" + (typeName == null ? metadata.typeName() : typeName) +
 +                                    ", fieldName=" + name +
 +                                    ", fieldType=" + oldFldTypeName +
 +                                    ", assignedValueType=" + newFldTypeName +
 +                                    ", assignedValue=" + (((PortableValueWithType)val).value()) + ']'
 +                            );
 +                        }
 +                    }
 +                }
 +            }
 +
 +            if (newFldsMetadata != null) {
 +                String typeName = this.typeName;
 +
 +                if (typeName == null)
 +                    typeName = metadata.typeName();
 +
 +                ctx.updateMetaData(typeId, typeName, newFldsMetadata);
 +            }
 +        }
 +
 +        if (reader != null) {
 +            // Write raw data if any.
 +            int rawOff = PortableUtils.rawOffsetAbsolute(reader, start);
 +            int footerStart = PortableUtils.footerStartAbsolute(reader, start);
 +
 +            if (rawOff < footerStart) {
 +                writer.rawWriter();
 +
 +                writer.write(reader.array(), rawOff, footerStart - rawOff);
 +            }
 +
 +            // Shift reader to the end of the object.
 +            reader.position(start + PortableUtils.length(reader, start));
 +        }
 +
 +        writer.postWrite(true);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public IgniteObjectBuilderImpl hashCode(int hashCode) {
 +        this.hashCode = hashCode;
 +
 +        return this;
 +    }
 +
 +    /**
 +     * Get field position and length.
 +     *
 +     * @param footerPos Field position inside the footer (absolute).
 +     * @param footerEnd Footer end (absolute).
 +     * @param rawPos Raw data position (absolute).
 +     * @return Tuple with field position and length.
 +     */
 +    private IgniteBiTuple<Integer, Integer> fieldPositionAndLength(int footerPos, int footerEnd, int rawPos) {
 +        int fieldOffset = reader.readIntPositioned(footerPos + 4);
 +        int fieldPos = start + fieldOffset;
 +
 +        // Get field length.
 +        int fieldLen;
 +
 +        if (footerPos + 8 == footerEnd)
 +            // This is the last field, compare to raw offset.
 +            fieldLen = rawPos - fieldPos;
 +        else {
 +            // Field is somewhere in the middle, get difference with the next offset.
 +            int nextFieldOffset = reader.readIntPositioned(footerPos + 8 + 4);
 +
 +            fieldLen = nextFieldOffset - fieldOffset;
 +        }
 +
 +        return F.t(fieldPos, fieldLen);
 +    }
 +
 +    /**
 +     * Initialize read cache if needed.
 +     */
 +    private void ensureReadCacheInit() {
 +        if (readCache == null) {
 +            Map<Integer, Object> readCache = new HashMap<>();
 +
 +            IgniteBiTuple<Integer, Integer> footer = PortableUtils.footerAbsolute(reader, start);
 +
 +            int footerPos = footer.get1();
 +            int footerEnd = footer.get2();
 +
 +            int rawPos = PortableUtils.rawOffsetAbsolute(reader, start);
 +
 +            while (footerPos < footerEnd) {
 +                int fieldId = reader.readIntPositioned(footerPos);
 +
 +                IgniteBiTuple<Integer, Integer> posAndLen = fieldPositionAndLength(footerPos, footerEnd, rawPos);
 +
 +                Object val = reader.getValueQuickly(posAndLen.get1(), posAndLen.get2());
 +
 +                readCache.put(fieldId, val);
 +
 +                // Shift current footer position.
 +                footerPos += 8;
 +            }
 +
 +            this.readCache = readCache;
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @SuppressWarnings("unchecked")
 +    @Override public <T> T getField(String name) {
 +        Object val;
 +
 +        if (assignedVals != null && assignedVals.containsKey(name)) {
 +            val = assignedVals.get(name);
 +
 +            if (val == REMOVED_FIELD_MARKER)
 +                return null;
 +        }
 +        else {
 +            ensureReadCacheInit();
 +
 +            int fldId = ctx.fieldId(typeId, name);
 +
 +            val = readCache.get(fldId);
 +        }
 +
 +        return (T)PortableUtils.unwrapLazy(val);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public IgniteObjectBuilder setField(String name, Object val) {
 +        GridArgumentCheck.notNull(val, name);
 +
 +        if (assignedVals == null)
 +            assignedVals = new LinkedHashMap<>();
 +
 +        Object oldVal = assignedVals.put(name, val);
 +
 +        if (oldVal instanceof PortableValueWithType) {
 +            ((PortableValueWithType)oldVal).value(val);
 +
 +            assignedVals.put(name, oldVal);
 +        }
 +
 +        return this;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public <T> IgniteObjectBuilder setField(String name, @Nullable T val, Class<? super T> type) {
 +        if (assignedVals == null)
 +            assignedVals = new LinkedHashMap<>();
 +
 +        //int fldId = ctx.fieldId(typeId, fldName);
 +
 +        assignedVals.put(name, new PortableValueWithType(PortableUtils.typeByClass(type), val));
 +
 +        return this;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public IgniteObjectBuilder setField(String name, @Nullable IgniteObjectBuilder builder) {
 +        if (builder == null)
 +            return setField(name, null, Object.class);
 +        else
 +            return setField(name, (Object)builder);
 +    }
 +
 +    /**
 +     * Removes field from portable object.
 +     *
 +     * @param name Field name.
 +     * @return {@code this} instance for chaining.
 +     */
 +    @Override public IgniteObjectBuilderImpl removeField(String name) {
 +        if (assignedVals == null)
 +            assignedVals = new LinkedHashMap<>();
 +
 +        assignedVals.put(name, REMOVED_FIELD_MARKER);
 +
 +        return this;
 +    }
 +
 +    /**
 +     * Creates builder initialized by specified portable object.
 +     *
 +     * @param obj Portable object to initialize builder.
 +     * @return New builder.
 +     */
 +    public static IgniteObjectBuilderImpl wrap(IgniteObject obj) {
 +        IgniteObjectImpl heapObj;
 +
 +        if (obj instanceof IgniteObjectOffheapImpl)
 +            heapObj = (IgniteObjectImpl)((IgniteObjectOffheapImpl)obj).heapCopy();
 +        else
 +            heapObj = (IgniteObjectImpl)obj;
 +
 +        return new IgniteObjectBuilderImpl(heapObj);
 +    }
 +
 +    /**
 +     * @return Object start position in source array.
 +     */
 +    int start() {
 +        return start;
 +    }
 +
 +    /**
 +     * @return Object type id.
 +     */
 +    public int typeId() {
 +        return typeId;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/71d18bb4/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
index cf8ad20,9645ced..abea3c0
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
@@@ -40,10 -40,7 +40,7 @@@ import static org.apache.ignite.interna
   */
  public class PortableBuilderReader implements PortablePositionReadable {
      /** */
-     private static final PortablePrimitives PRIM = PortablePrimitives.get();
- 
-     /** */
 -    private final Map<Integer, PortableBuilderImpl> objMap = new HashMap<>();
 +    private final Map<Integer, IgniteObjectBuilderImpl> objMap = new HashMap<>();
  
      /** */
      private final PortableContext ctx;
@@@ -636,9 -633,9 +633,9 @@@
                      if (flag == GridPortableMarshaller.NULL) continue;
  
                      if (flag != GridPortableMarshaller.DATE)
 -                        throw new PortableException("Invalid flag value: " + flag);
 +                        throw new IgniteObjectException("Invalid flag value: " + flag);
  
-                     long time = PRIM.readLong(arr, pos);
+                     long time = PortablePrimitives.readLong(arr, pos);
  
                      pos += 8;
  
@@@ -660,9 -657,9 +657,9 @@@
                          continue;
  
                      if (flag != GridPortableMarshaller.TIMESTAMP)
 -                        throw new PortableException("Invalid flag value: " + flag);
 +                        throw new IgniteObjectException("Invalid flag value: " + flag);
  
-                     long time = PRIM.readLong(arr, pos);
+                     long time = PortablePrimitives.readLong(arr, pos);
  
                      pos += 8;
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/71d18bb4/modules/core/src/main/java/org/apache/ignite/internal/portable/streams/PortableAbstractInputStream.java
----------------------------------------------------------------------