You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/08/26 05:06:46 UTC

[35/50] [abbrv] ignite git commit: ignite-1258: portable objects API support in Ignite

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
new file mode 100644
index 0000000..270ba9f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectEx.java
@@ -0,0 +1,213 @@
+/*
+ * 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.*;
+import org.apache.ignite.internal.util.offheap.unsafe.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.portable.*;
+
+import org.jetbrains.annotations.*;
+
+import java.math.*;
+import java.util.*;
+
+/**
+ * Internal portable object interface.
+ */
+public abstract class PortableObjectEx implements PortableObject {
+    /**
+     * @return Length.
+     */
+    public abstract int length();
+
+    /**
+     * @return Object start.
+     */
+    public abstract int start();
+
+    /**
+     * @return {@code True} if object is array based.
+     */
+    protected abstract boolean hasArray();
+
+    /**
+     * @return Object array if object is array based, otherwise {@code null}.
+     */
+    public abstract byte[] array();
+
+    /**
+     * @return Object offheap address is object is offheap based, otherwise 0.
+     */
+    public abstract long offheapAddress();
+
+    /**
+     * @param ctx Reader context.
+     * @param fieldName Field name.
+     * @return Field name.
+     */
+    @Nullable protected abstract <F> F field(PortableReaderContext ctx, String fieldName);
+
+    /** {@inheritDoc} */
+    @Override public PortableObject clone() throws CloneNotSupportedException {
+        return (PortableObject)super.clone();
+    }
+
+    /** {@inheritDoc} */
+    public boolean equals(Object other) {
+        if (other == this)
+            return true;
+
+        if (other == null)
+            return false;
+
+        if (!(other instanceof PortableObjectEx))
+            return false;
+
+        PortableObjectEx otherPo = (PortableObjectEx)other;
+
+        if (length() != otherPo.length() || typeId() != otherPo.typeId())
+            return false;
+
+        if (hasArray()) {
+            if (otherPo.hasArray()) {
+                int len = length();
+                int end = start() + len;
+
+                byte[] arr = array();
+                byte[] otherArr = otherPo.array();
+
+                for (int i = start(), j = otherPo.start(); i < end; i++, j++) {
+                    if (arr[i] != otherArr[j])
+                        return false;
+                }
+
+                return true;
+            }
+            else {
+                assert otherPo.offheapAddress() > 0;
+
+                return GridUnsafeMemory.compare(otherPo.offheapAddress() + otherPo.start(), array());
+            }
+        }
+        else {
+            assert offheapAddress() > 0;
+
+            if (otherPo.hasArray())
+                return GridUnsafeMemory.compare(offheapAddress() + start(), otherPo.array());
+            else {
+                assert otherPo.offheapAddress() > 0;
+
+                return GridUnsafeMemory.compare(offheapAddress() + start(),
+                    otherPo.offheapAddress() + otherPo.start(),
+                    length());
+            }
+        }
+    }
+
+    /**
+     * @param ctx Reader context.
+     * @param handles Handles for already traversed objects.
+     * @return String representation.
+     */
+    private String toString(PortableReaderContext ctx, IdentityHashMap<PortableObject, Integer> handles) {
+        int idHash = System.identityHashCode(this);
+
+        PortableMetadata meta;
+
+        try {
+            meta = metaData();
+        }
+        catch (PortableException ignore) {
+            meta = null;
+        }
+
+        if (meta == null)
+            return "PortableObject [hash=" + idHash + ", typeId=" + typeId() + ']';
+
+        handles.put(this, idHash);
+
+        SB buf = new SB(meta.typeName());
+
+        if (meta.fields() != null) {
+            buf.a(" [hash=").a(idHash);
+
+            for (String name : meta.fields()) {
+                Object val = field(ctx, name);
+
+                buf.a(", ").a(name).a('=');
+
+                if (val instanceof byte[])
+                    buf.a(Arrays.toString((byte[]) val));
+                else if (val instanceof short[])
+                    buf.a(Arrays.toString((short[])val));
+                else if (val instanceof int[])
+                    buf.a(Arrays.toString((int[])val));
+                else if (val instanceof long[])
+                    buf.a(Arrays.toString((long[])val));
+                else if (val instanceof float[])
+                    buf.a(Arrays.toString((float[])val));
+                else if (val instanceof double[])
+                    buf.a(Arrays.toString((double[])val));
+                else if (val instanceof char[])
+                    buf.a(Arrays.toString((char[])val));
+                else if (val instanceof boolean[])
+                    buf.a(Arrays.toString((boolean[]) val));
+                else if (val instanceof BigDecimal[])
+                    buf.a(Arrays.toString((BigDecimal[])val));
+                else {
+                    if (val instanceof PortableObjectEx) {
+                        PortableObjectEx po = (PortableObjectEx)val;
+
+                        Integer idHash0 = handles.get(val);
+
+                        if (idHash0 != null) {  // Circular reference.
+                            PortableMetadata meta0 = po.metaData();
+
+                            assert meta0 != null;
+
+                            buf.a(meta0.typeName()).a(" [hash=").a(idHash0).a(", ...]");
+                        }
+                        else
+                            buf.a(po.toString(ctx, handles));
+                    }
+                    else
+                        buf.a(val);
+                }
+            }
+
+            buf.a(']');
+        }
+
+        return buf.toString();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        try {
+            PortableReaderContext ctx = new PortableReaderContext();
+
+            ctx.setPortableHandler(start(), this);
+
+            return toString(ctx, new IdentityHashMap<PortableObject, Integer>());
+        }
+        catch (PortableException e) {
+            throw new IgniteException("Failed to create string representation of portable object.", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
new file mode 100644
index 0000000..f3dfd50
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectImpl.java
@@ -0,0 +1,383 @@
+/*
+ * 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.*;
+import org.apache.ignite.internal.*;
+import org.apache.ignite.internal.portable.streams.*;
+import org.apache.ignite.internal.processors.cache.*;
+import org.apache.ignite.internal.processors.cache.portable.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.plugin.extensions.communication.*;
+import org.apache.ignite.portable.*;
+
+import org.jetbrains.annotations.*;
+
+import java.io.*;
+import java.nio.*;
+
+/**
+ * Portable object implementation.
+ */
+@IgniteCodeGeneratingFail // Fields arr and start should not be generated by MessageCodeGenerator.
+public final class PortableObjectImpl extends PortableObjectEx 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 PortableObjectImpl() {
+        // No-op.
+    }
+
+    /**
+     * @param ctx Context.
+     * @param arr Array.
+     * @param start Start.
+     */
+    public PortableObjectImpl(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 internal() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
+        return (T)this;
+    }
+
+    /** {@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 (PortableObjectImpl)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 Detached portable object.
+     */
+    public PortableObject detach() {
+        if (!detachAllowed || detached())
+            return this;
+
+        int len = length();
+
+        byte[] arr0 = new byte[len];
+
+        U.arrayCopy(arr, start, arr0, 0, len);
+
+        return new PortableObjectImpl(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 + 2);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public PortableMetadata metaData() throws PortableException {
+        if (ctx == null)
+            throw new PortableException("PortableContext is not set for the object.");
+
+        return ctx.metaData(typeId());
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override public <F> F field(String fieldName) throws PortableException {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx, arr, start, null);
+
+        return (F)reader.unmarshal(fieldName);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override protected <F> F field(PortableReaderContext rCtx, String fieldName) {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
+            new PortableHeapInputStream(arr),
+            start,
+            null,
+            rCtx);
+
+        return (F)reader.unmarshal(fieldName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean hasField(String fieldName) {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx, arr, start, null);
+
+        return reader.hasField(fieldName);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override public <T> T deserialize() throws PortableException {
+        Object obj0 = obj;
+
+        if (obj0 == null) {
+            // TODO: IGNITE-1272 - Deserialize with proper class loader.
+            PortableReaderExImpl reader = new PortableReaderExImpl(ctx, arr, start, null);
+
+            obj0 = reader.deserialize();
+
+            PortableClassDescriptor desc = reader.descriptor();
+
+            assert desc != null;
+
+            if (desc.keepDeserialized())
+                obj = obj0;
+        }
+
+        return (T)obj0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public PortableObject clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return PRIM.readInt(arr, start + 6);
+    }
+
+    /** {@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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
new file mode 100644
index 0000000..40655ba
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableObjectOffheapImpl.java
@@ -0,0 +1,238 @@
+/*
+ * 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.*;
+import org.apache.ignite.internal.portable.streams.*;
+import org.apache.ignite.internal.processors.cache.*;
+import org.apache.ignite.internal.util.*;
+import org.apache.ignite.internal.util.typedef.internal.*;
+import org.apache.ignite.plugin.extensions.communication.*;
+import org.apache.ignite.portable.*;
+
+import org.jetbrains.annotations.*;
+import sun.misc.*;
+
+import java.io.*;
+import java.nio.*;
+
+/**
+ *  Portable object implementation over offheap memory
+ */
+public class PortableObjectOffheapImpl extends PortableObjectEx implements Externalizable, CacheObject {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+    /** */
+    private final PortableContext ctx;
+
+    /** */
+    private final long ptr;
+
+    /** */
+    private final int start;
+
+    /** */
+    private final int size;
+
+    /**
+     * For {@link Externalizable} (not supported).
+     */
+    public PortableObjectOffheapImpl() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @param ctx Context.
+     * @param ptr Memory address.
+     * @param start Object start.
+     * @param size Memory size.
+     */
+    public PortableObjectOffheapImpl(PortableContext ctx, long ptr, int start, int size) {
+        this.ctx = ctx;
+        this.ptr = ptr;
+        this.start = start;
+        this.size = size;
+    }
+
+    /**
+     * @return Heap-based copy.
+     */
+    public PortableObject heapCopy() {
+        return new PortableObjectImpl(ctx, U.copyMemory(ptr, size), start);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int typeId() {
+        return UNSAFE.getInt(ptr + start + 2);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int length() {
+        return UNSAFE.getInt(ptr + start + GridPortableMarshaller.TOTAL_LEN_POS);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return UNSAFE.getInt(ptr + start + 6);
+    }
+
+    /** {@inheritDoc} */
+    @Override public int start() {
+        return start;
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte[] array() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long offheapAddress() {
+        return ptr;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean hasArray() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public PortableMetadata metaData() throws PortableException {
+        if (ctx == null)
+            throw new PortableException("PortableContext is not set for the object.");
+
+        return ctx.metaData(typeId());
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override public <F> F field(String fieldName) throws PortableException {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
+            new PortableOffheapInputStream(ptr, size, false),
+            start,
+            null);
+
+        return (F)reader.unmarshal(fieldName);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override protected <F> F field(PortableReaderContext rCtx, String fieldName) {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
+            new PortableOffheapInputStream(ptr, size, false),
+            start,
+            null,
+            rCtx);
+
+        return (F)reader.unmarshal(fieldName);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean hasField(String fieldName) {
+        PortableReaderExImpl reader = new PortableReaderExImpl(ctx,
+            new PortableOffheapInputStream(ptr, size, false),
+            start,
+            null);
+
+        return reader.hasField(fieldName);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override public <T> T deserialize() throws PortableException {
+        // TODO: IGNITE-1272 - Deserialize with proper class loader.
+        PortableReaderExImpl reader = new PortableReaderExImpl(
+            ctx,
+            new PortableOffheapInputStream(ptr, size, false),
+            start,
+            null);
+
+        return (T)reader.deserialize();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("CloneDoesntCallSuperClone")
+    @Override public PortableObject clone() throws CloneNotSupportedException {
+        return heapCopy();
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte type() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Nullable @Override public <T> T value(CacheObjectContext ctx, boolean cpy) {
+        return (T)this;
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte[] valueBytes(CacheObjectContext ctx) throws IgniteCheckedException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public CacheObject prepareForCache(CacheObjectContext ctx) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void finishUnmarshal(CacheObjectContext ctx, ClassLoader ldr) throws IgniteCheckedException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void prepareMarshal(CacheObjectContext ctx) throws IgniteCheckedException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte directType() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte fieldsCount() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        throw new UnsupportedOperationException(); // To make sure it is not marshalled.
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        throw new UnsupportedOperationException(); // To make sure it is not marshalled.
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainLazyValue.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainLazyValue.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainLazyValue.java
new file mode 100644
index 0000000..73cc19e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainLazyValue.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+/**
+ *
+ */
+class PortablePlainLazyValue extends PortableAbstractLazyValue {
+    /** */
+    protected final int len;
+
+    /**
+     * @param reader Reader
+     * @param valOff Offset
+     * @param len Length.
+     */
+    protected PortablePlainLazyValue(PortableBuilderReader reader, int valOff, int len) {
+        super(reader, valOff);
+
+        this.len = len;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Object init() {
+        return reader.reader().unmarshal(valOff);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
+        writer.write(reader.array(), valOff, len);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainPortableObject.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainPortableObject.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainPortableObject.java
new file mode 100644
index 0000000..1679303
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePlainPortableObject.java
@@ -0,0 +1,50 @@
+/*
+ * 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.portable.*;
+
+/**
+ *
+ */
+public class PortablePlainPortableObject implements PortableLazyValue {
+    /** */
+    private final PortableObject portableObj;
+
+    /**
+     * @param portableObj Portable object.
+     */
+    public PortablePlainPortableObject(PortableObject portableObj) {
+        this.portableObj = portableObj;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Object value() {
+        return portableObj;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
+        PortableObject val = portableObj;
+
+        if (val instanceof PortableObjectOffheapImpl)
+            val = ((PortableObjectOffheapImpl)val).heapCopy();
+
+        writer.doWritePortableObject((PortableObjectImpl)val);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
new file mode 100644
index 0000000..10f3479
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortablePrimitives.java
@@ -0,0 +1,773 @@
+/*
+ * 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.internal.util.*;
+
+import sun.misc.*;
+
+import static java.nio.ByteOrder.*;
+
+/**
+ * Primitives writer.
+ */
+abstract class PortablePrimitives {
+    /** */
+    private static final PortablePrimitives INSTANCE =
+        nativeOrder() == LITTLE_ENDIAN ? new UnsafePrimitives() : new BytePrimitives();
+
+    /**
+     * @return Primitives writer.
+     */
+    static PortablePrimitives get() {
+        return INSTANCE;
+    }
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeByte(byte[] arr, int off, byte val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract byte readByte(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeShort(byte[] arr, int off, short val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract short readShort(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeInt(byte[] arr, int off, int val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract int readInt(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeLong(byte[] arr, int off, long val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract long readLong(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeFloat(byte[] arr, int off, float val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract float readFloat(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeDouble(byte[] arr, int off, double val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract double readDouble(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeChar(byte[] arr, int off, char val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract char readChar(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeBoolean(byte[] arr, int off, boolean val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract boolean readBoolean(byte[] arr, int off);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeByteArray(byte[] arr, int off, byte[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract byte[] readByteArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeShortArray(byte[] arr, int off, short[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract short[] readShortArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeIntArray(byte[] arr, int off, int[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract int[] readIntArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeLongArray(byte[] arr, int off, long[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract long[] readLongArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeFloatArray(byte[] arr, int off, float[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract float[] readFloatArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeDoubleArray(byte[] arr, int off, double[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract double[] readDoubleArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeCharArray(byte[] arr, int off, char[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract char[] readCharArray(byte[] arr, int off, int len);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @param val Value.
+     */
+    abstract void writeBooleanArray(byte[] arr, int off, boolean[] val);
+
+    /**
+     * @param arr Array.
+     * @param off Offset.
+     * @return Value.
+     */
+    abstract boolean[] readBooleanArray(byte[] arr, int off, int len);
+
+    /** */
+    private static class UnsafePrimitives extends PortablePrimitives {
+        /** */
+        private static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+        /** */
+        private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
+
+        /** */
+        private static final long SHORT_ARR_OFF = UNSAFE.arrayBaseOffset(short[].class);
+
+        /** */
+        private static final long INT_ARR_OFF = UNSAFE.arrayBaseOffset(int[].class);
+
+        /** */
+        private static final long LONG_ARR_OFF = UNSAFE.arrayBaseOffset(long[].class);
+
+        /** */
+        private static final long FLOAT_ARR_OFF = UNSAFE.arrayBaseOffset(float[].class);
+
+        /** */
+        private static final long DOUBLE_ARR_OFF = UNSAFE.arrayBaseOffset(double[].class);
+
+        /** */
+        private static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class);
+
+        /** */
+        private static final long BOOLEAN_ARR_OFF = UNSAFE.arrayBaseOffset(boolean[].class);
+
+        /** {@inheritDoc} */
+        @Override void writeByte(byte[] arr, int off, byte val) {
+            UNSAFE.putByte(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override byte readByte(byte[] arr, int off) {
+            return UNSAFE.getByte(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeShort(byte[] arr, int off, short val) {
+            UNSAFE.putShort(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override short readShort(byte[] arr, int off) {
+            return UNSAFE.getShort(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeInt(byte[] arr, int off, int val) {
+            UNSAFE.putInt(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override int readInt(byte[] arr, int off) {
+            return UNSAFE.getInt(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeLong(byte[] arr, int off, long val) {
+            UNSAFE.putLong(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override long readLong(byte[] arr, int off) {
+            return UNSAFE.getLong(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeFloat(byte[] arr, int off, float val) {
+            UNSAFE.putFloat(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override float readFloat(byte[] arr, int off) {
+            return UNSAFE.getFloat(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeDouble(byte[] arr, int off, double val) {
+            UNSAFE.putDouble(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override double readDouble(byte[] arr, int off) {
+            return UNSAFE.getDouble(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeChar(byte[] arr, int off, char val) {
+            UNSAFE.putChar(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override char readChar(byte[] arr, int off) {
+            return UNSAFE.getChar(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeBoolean(byte[] arr, int off, boolean val) {
+            UNSAFE.putBoolean(arr, BYTE_ARR_OFF + off, val);
+        }
+
+        /** {@inheritDoc} */
+        @Override boolean readBoolean(byte[] arr, int off) {
+            return UNSAFE.getBoolean(arr, BYTE_ARR_OFF + off);
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeByteArray(byte[] arr, int off, byte[] val) {
+            UNSAFE.copyMemory(val, BYTE_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length);
+        }
+
+        /** {@inheritDoc} */
+        @Override byte[] readByteArray(byte[] arr, int off, int len) {
+            byte[] arr0 = new byte[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, BYTE_ARR_OFF, len);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeShortArray(byte[] arr, int off, short[] val) {
+            UNSAFE.copyMemory(val, SHORT_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length << 1);
+        }
+
+        /** {@inheritDoc} */
+        @Override short[] readShortArray(byte[] arr, int off, int len) {
+            short[] arr0 = new short[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, SHORT_ARR_OFF, len << 1);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeIntArray(byte[] arr, int off, int[] val) {
+            UNSAFE.copyMemory(val, INT_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length << 2);
+        }
+
+        /** {@inheritDoc} */
+        @Override int[] readIntArray(byte[] arr, int off, int len) {
+            int[] arr0 = new int[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, INT_ARR_OFF, len << 2);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeLongArray(byte[] arr, int off, long[] val) {
+            UNSAFE.copyMemory(val, LONG_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length << 3);
+        }
+
+        /** {@inheritDoc} */
+        @Override long[] readLongArray(byte[] arr, int off, int len) {
+            long[] arr0 = new long[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, LONG_ARR_OFF, len << 3);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeFloatArray(byte[] arr, int off, float[] val) {
+            UNSAFE.copyMemory(val, FLOAT_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length << 2);
+        }
+
+        /** {@inheritDoc} */
+        @Override float[] readFloatArray(byte[] arr, int off, int len) {
+            float[] arr0 = new float[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, FLOAT_ARR_OFF, len << 2);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeDoubleArray(byte[] arr, int off, double[] val) {
+            UNSAFE.copyMemory(val, DOUBLE_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length << 3);
+        }
+
+        /** {@inheritDoc} */
+        @Override double[] readDoubleArray(byte[] arr, int off, int len) {
+            double[] arr0 = new double[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, DOUBLE_ARR_OFF, len << 3);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeCharArray(byte[] arr, int off, char[] val) {
+            UNSAFE.copyMemory(val, CHAR_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length << 1);
+        }
+
+        /** {@inheritDoc} */
+        @Override char[] readCharArray(byte[] arr, int off, int len) {
+            char[] arr0 = new char[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, CHAR_ARR_OFF, len << 1);
+
+            return arr0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeBooleanArray(byte[] arr, int off, boolean[] val) {
+            UNSAFE.copyMemory(val, BOOLEAN_ARR_OFF, arr, BYTE_ARR_OFF + off, val.length);
+        }
+
+        /** {@inheritDoc} */
+        @Override boolean[] readBooleanArray(byte[] arr, int off, int len) {
+            boolean[] arr0 = new boolean[len];
+
+            UNSAFE.copyMemory(arr, BYTE_ARR_OFF + off, arr0, BOOLEAN_ARR_OFF, len);
+
+            return arr0;
+        }
+    }
+
+    /** */
+    private static class BytePrimitives extends PortablePrimitives {
+        /** {@inheritDoc} */
+        @Override void writeByte(byte[] arr, int off, byte val) {
+            arr[off] = val;
+        }
+
+        /** {@inheritDoc} */
+        @Override byte readByte(byte[] arr, int off) {
+            return arr[off];
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeShort(byte[] arr, int off, short val) {
+            arr[off++] = (byte)(val & 0xff);
+            arr[off] = (byte)((val >>> 8) & 0xff);
+        }
+
+        /** {@inheritDoc} */
+        @Override short readShort(byte[] arr, int off) {
+            short val = 0;
+
+            val |= (arr[off++] & 0xff);
+            val |= (arr[off] & 0xff) << 8;
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeInt(byte[] arr, int off, int val) {
+            arr[off++] = (byte)(val & 0xff);
+            arr[off++] = (byte)((val >>> 8) & 0xff);
+            arr[off++] = (byte)((val >>> 16) & 0xff);
+            arr[off] = (byte)((val >>> 24) & 0xff);
+        }
+
+        /** {@inheritDoc} */
+        @Override int readInt(byte[] arr, int off) {
+            int val = 0;
+
+            val |= (arr[off++] & 0xff);
+            val |= (arr[off++] & 0xff) << 8;
+            val |= (arr[off++] & 0xff) << 16;
+            val |= (arr[off] & 0xff) << 24;
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeLong(byte[] arr, int off, long val) {
+            arr[off++] = (byte)(val & 0xffL);
+            arr[off++] = (byte)((val >>> 8) & 0xffL);
+            arr[off++] = (byte)((val >>> 16) & 0xffL);
+            arr[off++] = (byte)((val >>> 24) & 0xffL);
+            arr[off++] = (byte)((val >>> 32) & 0xffL);
+            arr[off++] = (byte)((val >>> 40) & 0xffL);
+            arr[off++] = (byte)((val >>> 48) & 0xffL);
+            arr[off] = (byte)((val >>> 56) & 0xffL);
+        }
+
+        /** {@inheritDoc} */
+        @Override long readLong(byte[] arr, int off) {
+            long val = 0;
+
+            val |= (arr[off++] & 0xffL);
+            val |= (arr[off++] & 0xffL) << 8;
+            val |= (arr[off++] & 0xffL) << 16;
+            val |= (arr[off++] & 0xffL) << 24;
+            val |= (arr[off++] & 0xffL) << 32;
+            val |= (arr[off++] & 0xffL) << 40;
+            val |= (arr[off++] & 0xffL) << 48;
+            val |= (arr[off] & 0xffL) << 56;
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeFloat(byte[] arr, int off, float val) {
+            writeInt(arr, off, Float.floatToIntBits(val));
+        }
+
+        /** {@inheritDoc} */
+        @Override float readFloat(byte[] arr, int off) {
+            return Float.intBitsToFloat(readInt(arr, off));
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeDouble(byte[] arr, int off, double val) {
+            writeLong(arr, off, Double.doubleToLongBits(val));
+        }
+
+        /** {@inheritDoc} */
+        @Override double readDouble(byte[] arr, int off) {
+            return Double.longBitsToDouble(readLong(arr, off));
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeChar(byte[] arr, int off, char val) {
+            arr[off++] = (byte)(val & 0xff);
+            arr[off] = (byte)((val >>> 8) & 0xff);
+        }
+
+        /** {@inheritDoc} */
+        @Override char readChar(byte[] arr, int off) {
+            char val = 0;
+
+            val |= (arr[off++] & 0xff);
+            val |= (arr[off] & 0xff) << 8;
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeBoolean(byte[] arr, int off, boolean val) {
+            arr[off] = (byte)(val ? 1 : 0);
+        }
+
+        /** {@inheritDoc} */
+        @Override boolean readBoolean(byte[] arr, int off) {
+            return arr[off] != 0;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeByteArray(byte[] arr, int off, byte[] val) {
+            for (byte b : val)
+                arr[off++] = b;
+        }
+
+        /** {@inheritDoc} */
+        @Override byte[] readByteArray(byte[] arr, int off, int len) {
+            byte[] val = new byte[len];
+
+            for (int i = 0; i < len; i++)
+                val[i] = arr[off++];
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeShortArray(byte[] arr, int off, short[] val) {
+            for (short s : val) {
+                writeShort(arr, off, s);
+
+                off += 2;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override short[] readShortArray(byte[] arr, int off, int len) {
+            short[] val = new short[len];
+
+            for (int i = 0; i < len; i++) {
+                val[i] = readShort(arr, off);
+
+                off += 2;
+            }
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeIntArray(byte[] arr, int off, int[] val) {
+            for (int i : val) {
+                writeInt(arr, off, i);
+
+                off += 4;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override int[] readIntArray(byte[] arr, int off, int len) {
+            int[] val = new int[len];
+
+            for (int i = 0; i < len; i++) {
+                val[i] = readInt(arr, off);
+
+                off += 4;
+            }
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeLongArray(byte[] arr, int off, long[] val) {
+            for (long l : val) {
+                writeLong(arr, off, l);
+
+                off += 8;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override long[] readLongArray(byte[] arr, int off, int len) {
+            long[] val = new long[len];
+
+            for (int i = 0; i < len; i++) {
+                val[i] = readLong(arr, off);
+
+                off += 8;
+            }
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeFloatArray(byte[] arr, int off, float[] val) {
+            for (float f : val) {
+                writeFloat(arr, off, f);
+
+                off += 4;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override float[] readFloatArray(byte[] arr, int off, int len) {
+            float[] val = new float[len];
+
+            for (int i = 0; i < len; i++) {
+                val[i] = readFloat(arr, off);
+
+                off += 4;
+            }
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeDoubleArray(byte[] arr, int off, double[] val) {
+            for (double d : val) {
+                writeDouble(arr, off, d);
+
+                off += 8;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override double[] readDoubleArray(byte[] arr, int off, int len) {
+            double[] val = new double[len];
+
+            for (int i = 0; i < len; i++) {
+                val[i] = readDouble(arr, off);
+
+                off += 8;
+            }
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeCharArray(byte[] arr, int off, char[] val) {
+            for (char c : val) {
+                writeChar(arr, off, c);
+
+                off += 2;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override char[] readCharArray(byte[] arr, int off, int len) {
+            char[] val = new char[len];
+
+            for (int i = 0; i < len; i++) {
+                val[i] = readChar(arr, off);
+
+                off += 2;
+            }
+
+            return val;
+        }
+
+        /** {@inheritDoc} */
+        @Override void writeBooleanArray(byte[] arr, int off, boolean[] val) {
+            for (boolean b : val)
+                writeBoolean(arr, off++, b);
+        }
+
+        /** {@inheritDoc} */
+        @Override boolean[] readBooleanArray(byte[] arr, int off, int len) {
+            boolean[] val = new boolean[len];
+
+            for (int i = 0; i < len; i++)
+                val[i] = readBoolean(arr, off++);
+
+            return val;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawReaderEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawReaderEx.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawReaderEx.java
new file mode 100644
index 0000000..2abce7f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawReaderEx.java
@@ -0,0 +1,33 @@
+/*
+ * 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.portable.*;
+
+import org.jetbrains.annotations.*;
+
+/**
+ * Extended reader interface.
+ */
+public interface PortableRawReaderEx extends PortableRawReader {
+    /**
+     * @return Object.
+     * @throws PortableException In case of error.
+     */
+    @Nullable public Object readObjectDetached() throws PortableException;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawWriterEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawWriterEx.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawWriterEx.java
new file mode 100644
index 0000000..d3e65f0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableRawWriterEx.java
@@ -0,0 +1,44 @@
+/*
+ * 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.internal.portable.streams.*;
+import org.apache.ignite.portable.*;
+
+import org.jetbrains.annotations.*;
+
+/**
+ * Extended writer interface.
+ */
+public interface PortableRawWriterEx extends PortableRawWriter, AutoCloseable {
+    /**
+     * @param obj Object to write.
+     * @throws PortableException In case of error.
+     */
+    public void writeObjectDetached(@Nullable Object obj) throws PortableException;
+
+    /**
+     * @return Output stream.
+     */
+    public PortableOutputStream out();
+
+    /**
+     * Cleans resources.
+     */
+    @Override public void close();
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/878dcd92/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
new file mode 100644
index 0000000..704305a
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableReaderContext.java
@@ -0,0 +1,83 @@
+/*
+ * 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.internal.util.typedef.internal.*;
+import org.apache.ignite.portable.*;
+
+import org.jetbrains.annotations.*;
+
+import java.util.*;
+
+/**
+ * Reader context.
+ */
+class PortableReaderContext {
+    /** */
+    private Map<Integer, Object> oHandles;
+
+    /** */
+    private Map<Integer, PortableObject> poHandles;
+
+    /**
+     * @param handle Handle.
+     * @param obj Object.
+     */
+    void setObjectHandler(int handle, Object obj) {
+        assert obj != null;
+
+        if (oHandles == null)
+            oHandles = new HashMap<>(3, 1.0f);
+
+        oHandles.put(handle, obj);
+    }
+
+    /**
+     * @param handle Handle.
+     * @param po Portable object.
+     */
+    void setPortableHandler(int handle, PortableObject po) {
+        assert po != null;
+
+        if (poHandles == null)
+            poHandles = new HashMap<>(3, 1.0f);
+
+        poHandles.put(handle, po);
+    }
+
+    /**
+     * @param handle Handle.
+     * @return Object.
+     */
+    @Nullable Object getObjectByHandle(int handle) {
+        return oHandles != null ? oHandles.get(handle) : null;
+    }
+
+    /**
+     * @param handle Handle.
+     * @return Object.
+     */
+    @Nullable PortableObject getPortableByHandle(int handle) {
+        return poHandles != null ? poHandles.get(handle) : null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(PortableReaderContext.class, this);
+    }
+}