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);
+ }
+}