ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sboi...@apache.org
Subject [08/14] ignite git commit: Merge remote-tracking branch 'remotes/apache-git/master' into ignite-1273
Date Tue, 01 Sep 2015 13:40:55 GMT
http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/GridPortableMarshaller.java
----------------------------------------------------------------------

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

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

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

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

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

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
index f704fe4,0000000..1472d56
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderEnum.java
@@@ -1,115 -1,0 +1,116 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
- import org.apache.ignite.internal.portable.*;
- import org.apache.ignite.internal.util.typedef.internal.*;
- import org.apache.ignite.portable.*;
++import org.apache.ignite.internal.portable.GridPortableMarshaller;
++import org.apache.ignite.internal.portable.PortableWriterExImpl;
++import org.apache.ignite.internal.util.typedef.internal.U;
++import org.apache.ignite.portable.PortableInvalidClassException;
 +
 +/**
 + *
 + */
 +public class PortableBuilderEnum implements PortableBuilderSerializationAware {
 +    /** */
 +    private final int ordinal;
 +
 +    /** */
 +    private final int typeId;
 +
 +    /** */
 +    private final String clsName;
 +
 +    /**
 +     * @param typeId Type ID.
 +     * @param anEnum Enum instance.
 +     */
 +    public PortableBuilderEnum(int typeId, Enum anEnum) {
 +        ordinal = anEnum.ordinal();
 +        this.typeId = typeId;
 +        clsName = null;
 +    }
 +
 +    /**
 +     * @param reader PortableBuilderReader.
 +     */
 +    public PortableBuilderEnum(PortableBuilderReader reader) {
 +        int typeId = reader.readInt();
 +
 +        if (typeId == GridPortableMarshaller.UNREGISTERED_TYPE_ID) {
 +            clsName = reader.readString();
 +
 +            Class cls;
 +
 +            try {
 +                // TODO: IGNITE-1272 - Is class loader needed here?
 +                cls = U.forName(reader.readString(), null);
 +            }
 +            catch (ClassNotFoundException e) {
 +                throw new PortableInvalidClassException("Failed to load the class: " + clsName, e);
 +            }
 +
 +            this.typeId = reader.portableContext().descriptorForClass(cls).typeId();
 +        }
 +        else {
 +            this.typeId = typeId;
 +            this.clsName = null;
 +        }
 +
 +        ordinal = reader.readInt();
 +    }
 +
 +    /**
 +     * @return Ordinal.
 +     */
 +    public int getOrdinal() {
 +        return ordinal;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        writer.writeByte(GridPortableMarshaller.ENUM);
 +
 +        if (typeId == GridPortableMarshaller.UNREGISTERED_TYPE_ID) {
 +            writer.writeInt(GridPortableMarshaller.UNREGISTERED_TYPE_ID);
 +            writer.writeString(clsName);
 +        }
 +        else
 +            writer.writeInt(typeId);
 +
 +        writer.writeInt(ordinal);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean equals(Object o) {
 +        if (o == null || getClass() != o.getClass())
 +            return false;
 +
 +        PortableBuilderEnum that = (PortableBuilderEnum)o;
 +
 +        return ordinal == that.ordinal && typeId == that.typeId;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int hashCode() {
 +        int result = ordinal;
 +
 +        result = 31 * result + typeId;
 +
 +        return result;
 +    }
- }
++}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
index 90996de,0000000..b2e4c0d
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderImpl.java
@@@ -1,521 -1,0 +1,537 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
++import java.util.Collections;
++import java.util.HashMap;
++import java.util.LinkedHashMap;
++import java.util.Map;
++import java.util.Set;
++import org.apache.ignite.internal.processors.cache.portable.CacheObjectPortableProcessorImpl;
++import org.apache.ignite.internal.util.GridArgumentCheck;
++import org.apache.ignite.internal.util.typedef.internal.U;
++import org.apache.ignite.portable.PortableBuilder;
++import org.apache.ignite.portable.PortableException;
++import org.apache.ignite.portable.PortableInvalidClassException;
++import org.apache.ignite.portable.PortableMetadata;
++import org.apache.ignite.portable.PortableObject;
++import org.jetbrains.annotations.Nullable;
 +import org.apache.ignite.internal.portable.*;
 +import org.apache.ignite.internal.processors.cache.portable.*;
 +import org.apache.ignite.internal.util.*;
 +import org.apache.ignite.internal.util.typedef.internal.*;
 +import org.apache.ignite.portable.*;
 +
- import org.jetbrains.annotations.*;
- 
- import java.util.*;
- 
- import static org.apache.ignite.internal.portable.GridPortableMarshaller.*;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.CLS_NAME_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.DFLT_HDR_LEN;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.HASH_CODE_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.RAW_DATA_OFF_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.TOTAL_LEN_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.TYPE_ID_POS;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.UNREGISTERED_TYPE_ID;
 +
 +/**
 + *
 + */
 +public class PortableBuilderImpl implements PortableBuilder {
 +    /** */
 +    private static final Object REMOVED_FIELD_MARKER = new Object();
 +
 +    /** */
 +    private final PortableContext ctx;
 +
 +    /** */
 +    private final int typeId;
 +
 +    /** May be null. */
 +    private String typeName;
 +
 +    /** May be null. */
 +    private String clsNameToWrite;
 +
 +    /** */
 +    private boolean registeredType = true;
 +
 +    /** */
 +    private Map<String, Object> assignedVals;
 +
 +    /** */
 +    private Map<Integer, Object> readCache;
 +
 +    /** Position of object in source array, or -1 if object is not created from PortableObject. */
 +    private final int start;
 +
 +    /** Total header length */
 +    private final int hdrLen;
 +
 +    /**
 +     * Context of PortableObject reading process. Or {@code null} if object is not created from PortableObject.
 +     */
 +    private final PortableBuilderReader reader;
 +
 +    /** */
 +    private int hashCode;
 +
 +    /**
 +     * @param clsName Class name.
 +     * @param ctx Portable context.
 +     */
 +    public PortableBuilderImpl(PortableContext ctx, String clsName) {
 +        this(ctx, ctx.typeId(clsName), PortableContext.typeName(clsName));
 +    }
 +
 +    /**
 +     * @param typeId Type ID.
 +     * @param ctx Portable context.
 +     */
 +    public PortableBuilderImpl(PortableContext ctx, int typeId) {
 +        this(ctx, typeId, null);
 +    }
 +
 +    /**
 +     * @param typeName Type name.
 +     * @param ctx Context.
 +     * @param typeId Type id.
 +     */
 +    public PortableBuilderImpl(PortableContext ctx, int typeId, String typeName) {
 +        this.typeId = typeId;
 +        this.typeName = typeName;
 +        this.ctx = ctx;
 +
 +        start = -1;
 +        reader = null;
 +        hdrLen = DFLT_HDR_LEN;
 +
 +        readCache = Collections.emptyMap();
 +    }
 +
 +    /**
 +     * @param obj Object to wrap.
 +     */
 +    public PortableBuilderImpl(PortableObjectImpl obj) {
 +        this(new PortableBuilderReader(obj), obj.start());
 +
 +        reader.registerObject(this);
 +    }
 +
 +    /**
 +     * @param reader ctx
 +     * @param start Start.
 +     */
 +    PortableBuilderImpl(PortableBuilderReader reader, int start) {
 +        this.reader = reader;
 +        this.start = start;
 +
 +        int typeId = reader.readIntAbsolute(start + TYPE_ID_POS);
 +        ctx = reader.portableContext();
 +        hashCode = reader.readIntAbsolute(start + HASH_CODE_POS);
 +
 +        if (typeId == UNREGISTERED_TYPE_ID) {
 +            int mark = reader.position();
 +
 +            reader.position(start + CLS_NAME_POS);
 +
 +            clsNameToWrite = reader.readString();
 +
 +            Class cls;
 +
 +            try {
 +                // TODO: IGNITE-1272 - Is class loader needed here?
 +                cls = U.forName(clsNameToWrite, null);
 +            }
 +            catch (ClassNotFoundException e) {
 +                throw new PortableInvalidClassException("Failed to load the class: " + clsNameToWrite, e);
 +            }
 +
 +            this.typeId = ctx.descriptorForClass(cls).typeId();
 +
 +            registeredType = false;
 +
 +            hdrLen = reader.position() - mark;
 +
 +            reader.position(mark);
 +        }
 +        else {
 +            this.typeId = typeId;
 +            hdrLen = DFLT_HDR_LEN;
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public PortableObject build() {
 +        try (PortableWriterExImpl writer = new PortableWriterExImpl(ctx, 0, typeId, false)) {
 +
 +            PortableBuilderSerializer serializationCtx = new PortableBuilderSerializer();
 +
 +            serializationCtx.registerObjectWriting(this, 0);
 +
 +            serializeTo(writer, serializationCtx);
 +
 +            byte[] arr = writer.array();
 +
 +            return new PortableObjectImpl(ctx, arr, 0);
 +        }
 +    }
 +
 +    /**
 +     * @param writer Writer.
 +     * @param serializer Serializer.
 +     */
 +    void serializeTo(PortableWriterExImpl writer, PortableBuilderSerializer serializer) {
 +        writer.doWriteByte(GridPortableMarshaller.OBJ);
 +        writer.doWriteBoolean(true);
 +        writer.doWriteInt(registeredType ? typeId : UNREGISTERED_TYPE_ID);
 +        writer.doWriteInt(hashCode);
 +
 +        // Length and raw offset.
 +        writer.reserve(8);
 +
 +        if (!registeredType)
 +            writer.writeString(clsNameToWrite);
 +
 +        Set<Integer> remainsFlds = null;
 +
 +        if (reader != null) {
 +            Map<Integer, Object> assignedFldsById;
 +
 +            if (assignedVals != null) {
 +                assignedFldsById = U.newHashMap(assignedVals.size());
 +
 +                for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
 +                    int fldId = ctx.fieldId(typeId, entry.getKey());
 +
 +                    assignedFldsById.put(fldId, entry.getValue());
 +                }
 +
 +                remainsFlds = assignedFldsById.keySet();
 +            }
 +            else
 +                assignedFldsById = Collections.emptyMap();
 +
 +            int rawOff = start + reader.readIntAbsolute(start + RAW_DATA_OFF_POS);
 +
 +            reader.position(start + hdrLen);
 +
 +            int cpStart = -1;
 +
 +            while (reader.position() < rawOff) {
 +                int fldId = reader.readInt();
 +
 +                int len = reader.readInt();
 +
 +                if (assignedFldsById.containsKey(fldId)) {
 +                    if (cpStart >= 0) {
 +                        writer.write(reader.array(), cpStart, reader.position() - 4 - 4 - cpStart);
 +
 +                        cpStart = -1;
 +                    }
 +
 +                    Object assignedVal = assignedFldsById.remove(fldId);
 +
 +                    reader.skip(len);
 +
 +                    if (assignedVal != REMOVED_FIELD_MARKER) {
 +                        writer.writeInt(fldId);
 +
 +                        int lenPos = writer.reserveAndMark(4);
 +
 +                        serializer.writeValue(writer, assignedVal);
 +
 +                        writer.writeDelta(lenPos);
 +                    }
 +                }
 +                else {
 +                    int type = len != 0 ? reader.readByte(0) : 0;
 +
 +                    if (len != 0 && !PortableUtils.isPlainArrayType(type) && PortableUtils.isPlainType(type)) {
 +                        if (cpStart < 0)
 +                            cpStart = reader.position() - 4 - 4;
 +
 +                        reader.skip(len);
 +                    }
 +                    else {
 +                        if (cpStart >= 0) {
 +                            writer.write(reader.array(), cpStart, reader.position() - 4 - cpStart);
 +
 +                            cpStart = -1;
 +                        }
 +                        else
 +                            writer.writeInt(fldId);
 +
 +                        Object val;
 +
 +                        if (len == 0)
 +                            val = null;
 +                        else if (readCache == null) {
 +                            int savedPos = reader.position();
 +
 +                            val = reader.parseValue();
 +
 +                            assert reader.position() == savedPos + len;
 +                        }
 +                        else {
 +                            val = readCache.get(fldId);
 +
 +                            reader.skip(len);
 +                        }
 +
 +                        int lenPos = writer.reserveAndMark(4);
 +
 +                        serializer.writeValue(writer, val);
 +
 +                        writer.writeDelta(lenPos);
 +                    }
 +                }
 +            }
 +
 +            if (cpStart >= 0)
 +                writer.write(reader.array(), cpStart, reader.position() - cpStart);
 +        }
 +
 +        if (assignedVals != null && (remainsFlds == null || !remainsFlds.isEmpty())) {
 +            boolean metadataEnabled = ctx.isMetaDataEnabled(typeId);
 +
 +            PortableMetadata metadata = null;
 +
 +            if (metadataEnabled)
 +                metadata = ctx.metaData(typeId);
 +
 +            Map<String, String> newFldsMetadata = null;
 +
 +            for (Map.Entry<String, Object> entry : assignedVals.entrySet()) {
 +                Object val = entry.getValue();
 +
 +                if (val == REMOVED_FIELD_MARKER)
 +                    continue;
 +
 +                String name = entry.getKey();
 +
 +                int fldId = ctx.fieldId(typeId, name);
 +
 +                if (remainsFlds != null && !remainsFlds.contains(fldId))
 +                    continue;
 +
 +                writer.writeInt(fldId);
 +
 +                int lenPos = writer.reserveAndMark(4);
 +
 +                serializer.writeValue(writer, val);
 +
 +                writer.writeDelta(lenPos);
 +
 +                if (metadataEnabled) {
 +                    String oldFldTypeName = metadata == null ? null : metadata.fieldTypeName(name);
 +
 +                    String newFldTypeName;
 +
 +                    if (val instanceof PortableValueWithType)
 +                        newFldTypeName = ((PortableValueWithType)val).typeName();
 +                    else {
 +                        byte type = PortableUtils.typeByClass(val.getClass());
 +
 +                        newFldTypeName = CacheObjectPortableProcessorImpl.fieldTypeName(type);
 +                    }
 +
 +                    if (oldFldTypeName == null) {
 +                        // It's a new field, we have to add it to metadata.
 +
 +                        if (newFldsMetadata == null)
 +                            newFldsMetadata = new HashMap<>();
 +
 +                        newFldsMetadata.put(name, newFldTypeName);
 +                    }
 +                    else {
 +                        if (!"Object".equals(oldFldTypeName) && !oldFldTypeName.equals(newFldTypeName)) {
 +                            throw new PortableException(
 +                                "Wrong value has been set [" +
 +                                    "typeName=" + (typeName == null ? metadata.typeName() : typeName) +
 +                                    ", fieldName=" + name +
 +                                    ", fieldType=" + oldFldTypeName +
 +                                    ", assignedValueType=" + newFldTypeName +
 +                                    ", assignedValue=" + (((PortableValueWithType)val).value()) + ']'
 +                            );
 +                        }
 +                    }
 +                }
 +            }
 +
 +            if (newFldsMetadata != null) {
 +                String typeName = this.typeName;
 +
 +                if (typeName == null)
 +                    typeName = metadata.typeName();
 +
 +                ctx.updateMetaData(typeId, typeName, newFldsMetadata);
 +            }
 +        }
 +
 +        writer.writeRawOffsetIfNeeded();
 +
 +        if (reader != null) {
 +            int rawOff = reader.readIntAbsolute(start + RAW_DATA_OFF_POS);
 +            int len = reader.readIntAbsolute(start + TOTAL_LEN_POS);
 +
 +            if (rawOff < len)
 +                writer.write(reader.array(), rawOff, len - rawOff);
 +        }
 +
 +        writer.writeLength();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public PortableBuilderImpl hashCode(int hashCode) {
 +        this.hashCode = hashCode;
 +
 +        return this;
 +    }
 +
 +    /**
 +     *
 +     */
 +    private void ensureReadCacheInit() {
 +        if (readCache == null) {
 +            Map<Integer, Object> readCache = new HashMap<>();
 +
 +            int pos = start + hdrLen;
 +            int end = start + reader.readIntAbsolute(start + RAW_DATA_OFF_POS);
 +
 +            while (pos < end) {
 +                int fieldId = reader.readIntAbsolute(pos);
 +
 +                pos += 4;
 +
 +                int len = reader.readIntAbsolute(pos);
 +
 +                pos += 4;
 +
 +                Object val = reader.getValueQuickly(pos, len);
 +
 +                readCache.put(fieldId, val);
 +
 +                pos += len;
 +            }
 +
 +            this.readCache = readCache;
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public <F> F getField(String name) {
 +        Object val;
 +
 +        if (assignedVals != null && assignedVals.containsKey(name)) {
 +            val = assignedVals.get(name);
 +
 +            if (val == REMOVED_FIELD_MARKER)
 +                return null;
 +        }
 +        else {
 +            ensureReadCacheInit();
 +
 +            int fldId = ctx.fieldId(typeId, name);
 +
 +            val = readCache.get(fldId);
 +        }
 +
 +        return (F)PortableUtils.unwrapLazy(val);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public PortableBuilder setField(String name, Object val) {
 +        GridArgumentCheck.notNull(val, name);
 +
 +        if (assignedVals == null)
 +            assignedVals = new LinkedHashMap<>();
 +
 +        Object oldVal = assignedVals.put(name, val);
 +
 +        if (oldVal instanceof PortableValueWithType) {
 +            ((PortableValueWithType)oldVal).value(val);
 +
 +            assignedVals.put(name, oldVal);
 +        }
 +
 +        return this;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public <T> PortableBuilder setField(String name, @Nullable T val, Class<? super T> type) {
 +        if (assignedVals == null)
 +            assignedVals = new LinkedHashMap<>();
 +
 +        //int fldId = ctx.fieldId(typeId, fldName);
 +
 +        assignedVals.put(name, new PortableValueWithType(PortableUtils.typeByClass(type), val));
 +
 +        return this;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public PortableBuilder setField(String name, @Nullable PortableBuilder builder) {
 +        if (builder == null)
 +            return setField(name, null, Object.class);
 +        else
 +            return setField(name, (Object)builder);
 +    }
 +
 +    /**
 +     * Removes field from portable object.
 +     *
 +     * @param name Field name.
 +     * @return {@code this} instance for chaining.
 +     */
 +    @Override public PortableBuilderImpl removeField(String name) {
 +        if (assignedVals == null)
 +            assignedVals = new LinkedHashMap<>();
 +
 +        assignedVals.put(name, REMOVED_FIELD_MARKER);
 +
 +        return this;
 +    }
 +
 +    /**
 +     * Creates builder initialized by specified portable object.
 +     *
 +     * @param obj Portable object to initialize builder.
 +     * @return New builder.
 +     */
 +    public static PortableBuilderImpl wrap(PortableObject obj) {
 +        PortableObjectImpl heapObj;
 +
 +        if (obj instanceof PortableObjectOffheapImpl)
 +            heapObj = (PortableObjectImpl)((PortableObjectOffheapImpl)obj).heapCopy();
 +        else
 +            heapObj = (PortableObjectImpl)obj;
 +
 +        return new PortableBuilderImpl(heapObj);
 +    }
 +
 +    /**
 +     * @return Object start position in source array.
 +     */
 +    int start() {
 +        return start;
 +    }
 +
 +    /**
 +     * @return Object type id.
 +     */
 +    public int typeId() {
 +        return typeId;
 +    }
- }
++}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
index ac76460,0000000..45355d7
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderReader.java
@@@ -1,793 -1,0 +1,800 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
- import org.apache.ignite.internal.portable.*;
- import org.apache.ignite.portable.*;
- 
- import java.sql.*;
++import java.sql.Timestamp;
 +import java.util.Date;
- import java.util.*;
- 
- import static java.nio.charset.StandardCharsets.*;
- import static org.apache.ignite.internal.portable.GridPortableMarshaller.*;
++import java.util.HashMap;
++import java.util.Map;
++import org.apache.ignite.internal.portable.GridPortableMarshaller;
++import org.apache.ignite.internal.portable.PortableContext;
++import org.apache.ignite.internal.portable.PortableObjectImpl;
++import org.apache.ignite.internal.portable.PortablePrimitives;
++import org.apache.ignite.internal.portable.PortableReaderExImpl;
++import org.apache.ignite.internal.portable.PortableUtils;
++import org.apache.ignite.internal.portable.PortableWriterExImpl;
++import org.apache.ignite.portable.PortableException;
++
++import static java.nio.charset.StandardCharsets.UTF_8;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.NULL;
++import static org.apache.ignite.internal.portable.GridPortableMarshaller.STRING;
 +
 +/**
 + *
 + */
 +class PortableBuilderReader {
 +    /** */
 +    private static final PortablePrimitives PRIM = PortablePrimitives.get();
 +
 +    /** */
 +    private final Map<Integer, PortableBuilderImpl> objMap = new HashMap<>();
 +
 +    /** */
 +    private final PortableContext ctx;
 +
 +    /** */
 +    private final PortableReaderExImpl reader;
 +
 +    /** */
 +    private byte[] arr;
 +
 +    /** */
 +    private int pos;
 +
 +    /**
 +     * @param objImpl Portable object
 +     */
 +    PortableBuilderReader(PortableObjectImpl objImpl) {
 +        ctx = objImpl.context();
 +        arr = objImpl.array();
 +        pos = objImpl.start();
 +
 +        // TODO: IGNITE-1272 - Is class loader needed here?
 +        reader = new PortableReaderExImpl(portableContext(), arr, pos, null);
 +    }
 +
 +    /**
 +     * @return Portable context.
 +     */
 +    public PortableContext portableContext() {
 +        return ctx;
 +    }
 +
 +    /**
 +     * @param obj Mutable portable object.
 +     */
 +    public void registerObject(PortableBuilderImpl obj) {
 +        objMap.put(obj.start(), obj);
 +    }
 +
 +    /**
 +     * @return Read int value.
 +     */
 +    public int readInt() {
 +        int res = readInt(0);
 +
 +        pos += 4;
 +
 +        return res;
 +    }
 +
 +    /**
 +     * @return Read int value.
 +     */
 +    public byte readByte() {
 +        return arr[pos++];
 +    }
 +
 +    /**
 +     * @return Read boolean value.
 +     */
 +    public boolean readBoolean() {
 +        return readByte() == 1;
 +    }
 +
 +    /**
 +     * @return Read int value.
 +     */
 +    public byte readByte(int off) {
 +        return arr[pos + off];
 +    }
 +
 +    /**
 +     * @param off Offset related to {@link #pos}
 +     * @return Read int value.
 +     */
 +    public int readInt(int off) {
 +        return PRIM.readInt(arr, pos + off);
 +    }
 +
 +    /**
 +     * @param pos Position in the source array.
 +     * @return Read int value.
 +     */
 +    public int readIntAbsolute(int pos) {
 +        return PRIM.readInt(arr, pos);
 +    }
 +
 +    /**
 +     * @return Read length of array.
 +     */
 +    public int readLength() {
 +        return PRIM.readInt(arr, pos);
 +    }
 +
 +    /**
 +     * Read string length.
 +     *
 +     * @return String length.
 +     */
 +    public int readStringLength() {
 +        boolean utf = PRIM.readBoolean(arr, pos);
 +
 +        int arrLen = PRIM.readInt(arr, pos + 1);
 +
 +        return 1 + (utf ? arrLen : arrLen << 1);
 +    }
 +
 +    /**
 +     * Reads string.
 +     *
 +     * @return String.
 +     */
 +    public String readString() {
 +        byte flag = readByte();
 +
 +        if (flag == NULL)
 +            return null;
 +
 +        if (flag != STRING)
 +            throw new PortableException("Failed to deserialize String.");
 +
 +        boolean convert = readBoolean();
 +        int len = readInt();
 +
 +        String str;
 +
 +        if (convert) {
 +            str = new String(arr, pos, len, UTF_8);
 +
 +            pos += len;
 +        }
 +        else {
 +            str = String.valueOf(PRIM.readCharArray(arr, pos, len));
 +
 +            pos += len << 1;
 +        }
 +
 +        return str;
 +    }
 +
 +    /**
 +     *
 +     */
 +    public void skipValue() {
 +        byte type = arr[pos++];
 +
 +        int len;
 +
 +        switch (type) {
 +            case GridPortableMarshaller.NULL:
 +                return;
 +
 +            case GridPortableMarshaller.OBJ:
 +                pos += readInt(GridPortableMarshaller.TOTAL_LEN_POS - 1) - 1;
 +
 +                return;
 +
 +            case GridPortableMarshaller.BOOLEAN:
 +            case GridPortableMarshaller.BYTE:
 +                len = 1;
 +                break;
 +
 +            case GridPortableMarshaller.CHAR:
 +            case GridPortableMarshaller.SHORT:
 +                len = 2;
 +
 +                break;
 +
 +            case GridPortableMarshaller.HANDLE:
 +            case GridPortableMarshaller.FLOAT:
 +            case GridPortableMarshaller.INT:
 +                len = 4;
 +
 +                break;
 +
 +            case GridPortableMarshaller.ENUM:
 +                //skipping type id and ordinal value
 +                len = 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.LONG:
 +            case GridPortableMarshaller.DOUBLE:
 +                len = 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.BYTE_ARR:
 +            case GridPortableMarshaller.BOOLEAN_ARR:
 +                len = 4 + readLength();
 +
 +                break;
 +
 +            case GridPortableMarshaller.STRING:
 +                len = 4 + readStringLength();
 +
 +                break;
 +
 +            case GridPortableMarshaller.DECIMAL:
 +                len = /** scale */ 4  + /** mag len */ 4  + /** mag bytes count */ readInt(4);
 +
 +                break;
 +
 +            case GridPortableMarshaller.UUID:
 +                len = 8 + 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.DATE:
 +                len = 8 + 4;
 +
 +                break;
 +
 +            case GridPortableMarshaller.CHAR_ARR:
 +            case GridPortableMarshaller.SHORT_ARR:
 +                len = 4 + readLength() * 2;
 +
 +                break;
 +
 +            case GridPortableMarshaller.INT_ARR:
 +            case GridPortableMarshaller.FLOAT_ARR:
 +                len = 4 + readLength() * 4;
 +
 +                break;
 +
 +            case GridPortableMarshaller.LONG_ARR:
 +            case GridPortableMarshaller.DOUBLE_ARR:
 +                len = 4 + readLength() * 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.DECIMAL_ARR:
 +            case GridPortableMarshaller.DATE_ARR:
 +            case GridPortableMarshaller.OBJ_ARR:
 +            case GridPortableMarshaller.ENUM_ARR:
 +            case GridPortableMarshaller.UUID_ARR:
 +            case GridPortableMarshaller.STRING_ARR: {
 +                int size = readInt();
 +
 +                for (int i = 0; i < size; i++)
 +                    skipValue();
 +
 +                return;
 +            }
 +
 +            case GridPortableMarshaller.COL: {
 +                int size = readInt();
 +
 +                pos++; // skip collection type
 +
 +                for (int i = 0; i < size; i++)
 +                    skipValue();
 +
 +                return;
 +            }
 +
 +            case GridPortableMarshaller.MAP: {
 +                int size = readInt();
 +
 +                pos++; // skip collection type
 +
 +                for (int i = 0; i < size; i++) {
 +                    skipValue(); // skip key.
 +                    skipValue(); // skip value.
 +                }
 +
 +                return;
 +            }
 +
 +            case GridPortableMarshaller.MAP_ENTRY:
 +                skipValue();
 +                skipValue();
 +
 +                return;
 +
 +            case GridPortableMarshaller.PORTABLE_OBJ:
 +                len = readInt() + 4;
 +
 +                break;
 +
 +            default:
 +                throw new PortableException("Invalid flag value: " + type);
 +        }
 +
 +        pos += len;
 +    }
 +
 +    /**
 +     * @param pos Position.
 +     * @param len Length.
 +     * @return Object.
 +     */
 +    public Object getValueQuickly(int pos, int len) {
 +        byte type = arr[pos];
 +
 +        switch (type) {
 +            case GridPortableMarshaller.NULL:
 +                return null;
 +
 +            case GridPortableMarshaller.HANDLE: {
 +                int objStart = pos - readIntAbsolute(pos + 1);
 +
 +                PortableBuilderImpl res = objMap.get(objStart);
 +
 +                if (res == null) {
 +                    res = new PortableBuilderImpl(this, objStart);
 +
 +                    objMap.put(objStart, res);
 +                }
 +
 +                return res;
 +            }
 +
 +            case GridPortableMarshaller.OBJ: {
 +                PortableBuilderImpl res = objMap.get(pos);
 +
 +                if (res == null) {
 +                    res = new PortableBuilderImpl(this, pos);
 +
 +                    objMap.put(pos, res);
 +                }
 +
 +                return res;
 +            }
 +
 +            case GridPortableMarshaller.BYTE:
 +                return arr[pos + 1];
 +
 +            case GridPortableMarshaller.SHORT:
 +                return PRIM.readShort(arr, pos + 1);
 +
 +            case GridPortableMarshaller.INT:
 +                return PRIM.readInt(arr, pos + 1);
 +
 +            case GridPortableMarshaller.LONG:
 +                return PRIM.readLong(arr, pos + 1);
 +
 +            case GridPortableMarshaller.FLOAT:
 +                return PRIM.readFloat(arr, pos + 1);
 +
 +            case GridPortableMarshaller.DOUBLE:
 +                return PRIM.readDouble(arr, pos + 1);
 +
 +            case GridPortableMarshaller.CHAR:
 +                return PRIM.readChar(arr, pos + 1);
 +
 +            case GridPortableMarshaller.BOOLEAN:
 +                return arr[pos + 1] != 0;
 +
 +            case GridPortableMarshaller.DECIMAL:
 +            case GridPortableMarshaller.STRING:
 +            case GridPortableMarshaller.UUID:
 +            case GridPortableMarshaller.DATE:
 +                return new PortablePlainLazyValue(this, pos, len);
 +
 +            case GridPortableMarshaller.BYTE_ARR:
 +            case GridPortableMarshaller.SHORT_ARR:
 +            case GridPortableMarshaller.INT_ARR:
 +            case GridPortableMarshaller.LONG_ARR:
 +            case GridPortableMarshaller.FLOAT_ARR:
 +            case GridPortableMarshaller.DOUBLE_ARR:
 +            case GridPortableMarshaller.CHAR_ARR:
 +            case GridPortableMarshaller.BOOLEAN_ARR:
 +            case GridPortableMarshaller.DECIMAL_ARR:
 +            case GridPortableMarshaller.DATE_ARR:
 +            case GridPortableMarshaller.UUID_ARR:
 +            case GridPortableMarshaller.STRING_ARR:
 +            case GridPortableMarshaller.ENUM_ARR:
 +            case GridPortableMarshaller.OBJ_ARR:
 +            case GridPortableMarshaller.COL:
 +            case GridPortableMarshaller.MAP:
 +            case GridPortableMarshaller.MAP_ENTRY:
 +                return new LazyCollection(pos);
 +
 +            case GridPortableMarshaller.ENUM: {
 +                if (len == 1) {
 +                    assert readByte(pos) == GridPortableMarshaller.NULL;
 +
 +                    return null;
 +                }
 +
 +                int mark = position();
 +                position(pos + 1);
 +
 +                PortableBuilderEnum builderEnum = new PortableBuilderEnum(this);
 +
 +                position(mark);
 +
 +                return builderEnum;
 +            }
 +
 +            case GridPortableMarshaller.PORTABLE_OBJ: {
 +                int size = readIntAbsolute(pos + 1);
 +
 +                int start = readIntAbsolute(pos + 4 + size);
 +
 +                PortableObjectImpl portableObj = new PortableObjectImpl(ctx, arr, pos + 4 + start);
 +
 +                return new PortablePlainPortableObject(portableObj);
 +            }
 +
 +            default:
 +                throw new PortableException("Invalid flag value: " + type);
 +        }
 +    }
 +
 +    /**
 +     * @return Parsed value.
 +     */
 +    public Object parseValue() {
 +        int valPos = pos;
 +
 +        byte type = arr[pos++];
 +
 +        int plainLazyValLen;
 +
 +        boolean modifiableLazyVal = false;
 +
 +        switch (type) {
 +            case GridPortableMarshaller.NULL:
 +                return null;
 +
 +            case GridPortableMarshaller.HANDLE: {
 +                int objStart = pos - 1 - readInt();
 +
 +                PortableBuilderImpl res = objMap.get(objStart);
 +
 +                if (res == null) {
 +                    res = new PortableBuilderImpl(this, objStart);
 +
 +                    objMap.put(objStart, res);
 +                }
 +
 +                return res;
 +            }
 +
 +            case GridPortableMarshaller.OBJ: {
 +                pos--;
 +
 +                PortableBuilderImpl res = objMap.get(pos);
 +
 +                if (res == null) {
 +                    res = new PortableBuilderImpl(this, pos);
 +
 +                    objMap.put(pos, res);
 +                }
 +
 +                pos += readInt(GridPortableMarshaller.TOTAL_LEN_POS);
 +
 +                return res;
 +            }
 +
 +            case GridPortableMarshaller.BYTE:
 +                return arr[pos++];
 +
 +            case GridPortableMarshaller.SHORT: {
 +                Object res = PRIM.readShort(arr, pos);
 +                pos += 2;
 +                return res;
 +            }
 +
 +            case GridPortableMarshaller.INT:
 +                return readInt();
 +
 +            case GridPortableMarshaller.LONG:
 +                plainLazyValLen = 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.FLOAT:
 +                plainLazyValLen = 4;
 +
 +                break;
 +
 +            case GridPortableMarshaller.DOUBLE:
 +                plainLazyValLen = 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.CHAR:
 +                plainLazyValLen = 2;
 +
 +                break;
 +
 +            case GridPortableMarshaller.BOOLEAN:
 +                return arr[pos++] != 0;
 +
 +            case GridPortableMarshaller.DECIMAL:
 +                plainLazyValLen = /** scale */ 4  + /** mag len */ 4  + /** mag bytes count */ readInt(4);
 +
 +                break;
 +
 +            case GridPortableMarshaller.STRING:
 +                plainLazyValLen = 4 + readStringLength();
 +
 +                break;
 +
 +            case GridPortableMarshaller.UUID:
 +                plainLazyValLen = 8 + 8;
 +
 +                break;
 +
 +            case GridPortableMarshaller.DATE:
 +                plainLazyValLen = 8 + 4;
 +
 +                break;
 +
 +            case GridPortableMarshaller.BYTE_ARR:
 +                plainLazyValLen = 4 + readLength();
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.SHORT_ARR:
 +                plainLazyValLen = 4 + readLength() * 2;
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.INT_ARR:
 +                plainLazyValLen = 4 + readLength() * 4;
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.LONG_ARR:
 +                plainLazyValLen = 4 + readLength() * 8;
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.FLOAT_ARR:
 +                plainLazyValLen = 4 + readLength() * 4;
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.DOUBLE_ARR:
 +                plainLazyValLen = 4 + readLength() * 8;
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.CHAR_ARR:
 +                plainLazyValLen = 4 + readLength() * 2;
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.BOOLEAN_ARR:
 +                plainLazyValLen = 4 + readLength();
 +                modifiableLazyVal = true;
 +
 +                break;
 +
 +            case GridPortableMarshaller.OBJ_ARR:
 +                return new PortableObjectArrayLazyValue(this);
 +
 +            case GridPortableMarshaller.DATE_ARR: {
 +                int size = readInt();
 +
 +                Date[] res = new Date[size];
 +
 +                for (int i = 0; i < res.length; i++) {
 +                    byte flag = arr[pos++];
 +
 +                    if (flag == GridPortableMarshaller.NULL) continue;
 +
 +                    if (flag != GridPortableMarshaller.DATE)
 +                        throw new PortableException("Invalid flag value: " + flag);
 +
 +                    long time = PRIM.readLong(arr, pos);
 +
 +                    pos += 8;
 +
 +                    if (ctx.isUseTimestamp()) {
 +                        Timestamp ts = new Timestamp(time);
 +
 +                        ts.setNanos(ts.getNanos() + readInt());
 +
 +                        res[i] = ts;
 +                    }
 +                    else {
 +                        res[i] = new Date(time);
 +
 +                        pos += 4;
 +                    }
 +                }
 +
 +                return res;
 +            }
 +
 +            case GridPortableMarshaller.UUID_ARR:
 +            case GridPortableMarshaller.STRING_ARR:
 +            case GridPortableMarshaller.DECIMAL_ARR: {
 +                int size = readInt();
 +
 +                for (int i = 0; i < size; i++) {
 +                    byte flag = arr[pos++];
 +
 +                    if (flag == GridPortableMarshaller.UUID)
 +                        pos += 8 + 8;
 +                    else if (flag == GridPortableMarshaller.STRING)
 +                        pos += 4 + readStringLength();
 +                    else if (flag == GridPortableMarshaller.DECIMAL) {
 +                        pos += 4; // scale value
 +                        pos += 4 + readLength();
 +                    }
 +                    else
 +                        assert flag == GridPortableMarshaller.NULL;
 +                }
 +
 +                return new PortableModifiableLazyValue(this, valPos, pos - valPos);
 +            }
 +
 +            case GridPortableMarshaller.COL: {
 +                int size = readInt();
 +                byte colType = arr[pos++];
 +
 +                switch (colType) {
 +                    case GridPortableMarshaller.USER_COL:
 +                    case GridPortableMarshaller.ARR_LIST:
 +                        return new PortableLazyArrayList(this, size);
 +
 +                    case GridPortableMarshaller.LINKED_LIST:
 +                        return new PortableLazyLinkedList(this, size);
 +
 +                    case GridPortableMarshaller.HASH_SET:
 +                    case GridPortableMarshaller.LINKED_HASH_SET:
 +                    case GridPortableMarshaller.TREE_SET:
 +                    case GridPortableMarshaller.CONC_SKIP_LIST_SET:
 +                        return new PortableLazySet(this, size);
 +                }
 +
 +                throw new PortableException("Unknown collection type: " + colType);
 +            }
 +
 +            case GridPortableMarshaller.MAP:
 +                return PortableLazyMap.parseMap(this);
 +
 +            case GridPortableMarshaller.ENUM:
 +                return new PortableBuilderEnum(this);
 +
 +            case GridPortableMarshaller.ENUM_ARR:
 +                return new PortableEnumArrayLazyValue(this);
 +
 +            case GridPortableMarshaller.MAP_ENTRY:
 +                return new PortableLazyMapEntry(this);
 +
 +            case GridPortableMarshaller.PORTABLE_OBJ: {
 +                int size = readInt();
 +
 +                pos += size;
 +
 +                int start = readInt();
 +
 +                PortableObjectImpl portableObj = new PortableObjectImpl(ctx, arr,
 +                    pos - 4 - size + start);
 +
 +                return new PortablePlainPortableObject(portableObj);
 +            }
 +
 +
 +            default:
 +                throw new PortableException("Invalid flag value: " + type);
 +        }
 +
 +        PortableAbstractLazyValue res;
 +
 +        if (modifiableLazyVal)
 +            res = new PortableModifiableLazyValue(this, valPos, 1 + plainLazyValLen);
 +        else
 +            res = new PortablePlainLazyValue(this, valPos, 1 + plainLazyValLen);
 +
 +        pos += plainLazyValLen;
 +
 +        return res;
 +    }
 +
 +    /**
 +     * @return Array.
 +     */
 +    public byte[] array() {
 +        return arr;
 +    }
 +
 +    /**
 +     * @return Position of reader.
 +     */
 +    public int position() {
 +        return pos;
 +    }
 +
 +    /**
 +     * @param pos New pos.
 +     */
 +    public void position(int pos) {
 +        this.pos = pos;
 +    }
 +
 +    /**
 +     * @param n Number of bytes to skip.
 +     */
 +    public void skip(int n) {
 +        pos += n;
 +    }
 +
 +    /**
 +     * @return Reader.
 +     */
 +    PortableReaderExImpl reader() {
 +        return reader;
 +    }
 +
 +    /**
 +     *
 +     */
 +    private class LazyCollection implements PortableLazyValue {
 +        /** */
 +        private final int valOff;
 +
 +        /** */
 +        private Object col;
 +
 +        /**
 +         * @param valOff Value.
 +         */
 +        protected LazyCollection(int valOff) {
 +            this.valOff = valOff;
 +        }
 +
 +        /**
 +         * @return Object.
 +         */
 +        private Object wrappedCollection() {
 +            if (col == null) {
 +                position(valOff);
 +
 +                col = parseValue();
 +            }
 +
 +            return col;
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +            ctx.writeValue(writer, wrappedCollection());
 +        }
 +
 +        /** {@inheritDoc} */
 +        @Override public Object value() {
 +            return PortableUtils.unwrapLazy(wrappedCollection());
 +        }
 +    }
- }
++}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java
index 6d1092b,0000000..2d9c961
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableBuilderSerializer.java
@@@ -1,211 -1,0 +1,214 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
- import org.apache.ignite.internal.portable.*;
++import org.apache.ignite.internal.portable.GridPortableMarshaller;
++import org.apache.ignite.internal.portable.PortableObjectEx;
++import org.apache.ignite.internal.portable.PortableUtils;
++import org.apache.ignite.internal.portable.PortableWriterExImpl;
 +import org.apache.ignite.internal.util.*;
 +import org.apache.ignite.portable.*;
 +
 +import java.util.*;
 +
 +/**
 + *
 + */
 +class PortableBuilderSerializer {
 +    /** */
 +    private final Map<PortableBuilderImpl, Integer> objToPos = new IdentityHashMap<>();
 +
 +    /** */
 +    private Map<PortableObject, PortableBuilderImpl> portableObjToWrapper;
 +
 +    /**
 +     * @param obj Mutable object.
 +     * @param posInResArr Object position in the array.
 +     */
 +    public void registerObjectWriting(PortableBuilderImpl obj, int posInResArr) {
 +        objToPos.put(obj, posInResArr);
 +    }
 +
 +    /**
 +     * @param writer Writer.
 +     * @param val Value.
 +     */
 +    public void writeValue(PortableWriterExImpl writer, Object val) {
 +        if (val == null) {
 +            writer.writeByte(GridPortableMarshaller.NULL);
 +
 +            return;
 +        }
 +
 +        if (val instanceof PortableBuilderSerializationAware) {
 +            ((PortableBuilderSerializationAware)val).writeTo(writer, this);
 +
 +            return;
 +        }
 +
 +        if (val instanceof PortableObjectEx) {
 +            if (portableObjToWrapper == null)
 +                portableObjToWrapper = new IdentityHashMap<>();
 +
 +            PortableBuilderImpl wrapper = portableObjToWrapper.get(val);
 +
 +            if (wrapper == null) {
 +                wrapper = PortableBuilderImpl.wrap((PortableObject)val);
 +
 +                portableObjToWrapper.put((PortableObject)val, wrapper);
 +            }
 +
 +            val = wrapper;
 +        }
 +
 +        if (val instanceof PortableBuilderImpl) {
 +            PortableBuilderImpl obj = (PortableBuilderImpl)val;
 +
 +            Integer posInResArr = objToPos.get(obj);
 +
 +            if (posInResArr == null) {
 +                objToPos.put(obj, writer.outputStream().position());
 +
 +                obj.serializeTo(writer.newWriter(obj.typeId()), this);
 +            }
 +            else {
 +                int handle = writer.outputStream().position() - posInResArr;
 +
 +                writer.writeByte(GridPortableMarshaller.HANDLE);
 +                writer.writeInt(handle);
 +            }
 +
 +            return;
 +        }
 +
 +        if (val.getClass().isEnum()) {
 +            writer.writeByte(GridPortableMarshaller.ENUM);
 +            writer.writeInt(writer.context().typeId(val.getClass().getName()));
 +            writer.writeInt(((Enum)val).ordinal());
 +
 +            return;
 +        }
 +
 +        if (val instanceof Collection) {
 +            Collection<?> c = (Collection<?>)val;
 +
 +            writer.writeByte(GridPortableMarshaller.COL);
 +            writer.writeInt(c.size());
 +
 +            byte colType;
 +
 +            if (c instanceof GridConcurrentSkipListSet)
 +                colType = GridPortableMarshaller.CONC_SKIP_LIST_SET;
 +            else
 +                colType = writer.context().collectionType(c.getClass());
 +
 +
 +            writer.writeByte(colType);
 +
 +            for (Object obj : c)
 +                writeValue(writer, obj);
 +
 +            return;
 +        }
 +
 +        if (val instanceof Map) {
 +            Map<?, ?> map = (Map<?, ?>)val;
 +
 +            writer.writeByte(GridPortableMarshaller.MAP);
 +            writer.writeInt(map.size());
 +
 +            writer.writeByte(writer.context().mapType(map.getClass()));
 +
 +            for (Map.Entry<?, ?> entry : map.entrySet()) {
 +                writeValue(writer, entry.getKey());
 +                writeValue(writer, entry.getValue());
 +            }
 +
 +            return;
 +        }
 +
 +        Byte flag = PortableUtils.PLAIN_CLASS_TO_FLAG.get(val.getClass());
 +
 +        if (flag != null) {
 +            PortableUtils.writePlainObject(writer, val);
 +
 +            return;
 +        }
 +
 +        if (val instanceof Object[]) {
 +            int compTypeId = writer.context().typeId(((Object[])val).getClass().getComponentType().getName());
 +
 +            if (val instanceof PortableBuilderEnum[]) {
 +                writeArray(writer, GridPortableMarshaller.ENUM_ARR, (Object[])val, compTypeId);
 +
 +                return;
 +            }
 +
 +            if (((Object[])val).getClass().getComponentType().isEnum()) {
 +                Enum[] enumArr = (Enum[])val;
 +
 +                writer.writeByte(GridPortableMarshaller.ENUM_ARR);
 +                writer.writeInt(compTypeId);
 +                writer.writeInt(enumArr.length);
 +
 +                for (Enum anEnum : enumArr)
 +                    writeValue(writer, anEnum);
 +
 +                return;
 +            }
 +
 +            writeArray(writer, GridPortableMarshaller.OBJ_ARR, (Object[])val, compTypeId);
 +
 +            return;
 +        }
 +
 +        writer.doWriteObject(val, false);
 +    }
 +
 +    /**
 +     * @param writer Writer.
 +     * @param elementType Element type.
 +     * @param arr The array.
 +     * @param compTypeId Component type ID.
 +     */
 +    public void writeArray(PortableWriterExImpl writer, byte elementType, Object[] arr, int compTypeId) {
 +        writer.writeByte(elementType);
 +        writer.writeInt(compTypeId);
 +        writer.writeInt(arr.length);
 +
 +        for (Object obj : arr)
 +            writeValue(writer, obj);
 +    }
 +
 +    /**
 +     * @param writer Writer.
 +     * @param elementType Element type.
 +     * @param arr The array.
 +     * @param clsName Component class name.
 +     */
 +    public void writeArray(PortableWriterExImpl writer, byte elementType, Object[] arr, String clsName) {
 +        writer.writeByte(elementType);
 +        writer.writeInt(GridPortableMarshaller.UNREGISTERED_TYPE_ID);
 +        writer.writeString(clsName);
 +        writer.writeInt(arr.length);
 +
 +        for (Object obj : arr)
 +            writeValue(writer, obj);
 +    }
 +
- }
++}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
index 419dd8e,0000000..d864a6e
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableEnumArrayLazyValue.java
@@@ -1,112 -1,0 +1,114 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
- import org.apache.ignite.internal.portable.*;
- import org.apache.ignite.internal.util.typedef.internal.*;
- import org.apache.ignite.portable.*;
++import org.apache.ignite.internal.portable.GridPortableMarshaller;
++import org.apache.ignite.internal.portable.PortableWriterExImpl;
++import org.apache.ignite.internal.util.typedef.internal.U;
++import org.apache.ignite.portable.PortableException;
++import org.apache.ignite.portable.PortableInvalidClassException;
 +
 +/**
 + *
 + */
 +class PortableEnumArrayLazyValue extends PortableAbstractLazyValue {
 +    /** */
 +    private final int len;
 +
 +    /** */
 +    private final int compTypeId;
 +
 +    /** */
 +    private final String clsName;
 +
 +    /**
 +     * @param reader Reader.
 +     */
 +    protected PortableEnumArrayLazyValue(PortableBuilderReader reader) {
 +        super(reader, reader.position() - 1);
 +
 +        int typeId = reader.readInt();
 +
 +        if (typeId == GridPortableMarshaller.UNREGISTERED_TYPE_ID) {
 +            clsName = reader.readString();
 +
 +            Class cls;
 +
 +            try {
 +                // TODO: IGNITE-1272 - Is class loader needed here?
 +                cls = U.forName(reader.readString(), null);
 +            }
 +            catch (ClassNotFoundException e) {
 +                throw new PortableInvalidClassException("Failed to load the class: " + clsName, e);
 +            }
 +
 +            compTypeId = reader.portableContext().descriptorForClass(cls).typeId();
 +        }
 +        else {
 +            compTypeId = typeId;
 +            clsName = null;
 +        }
 +
 +        int size = reader.readInt();
 +
 +        for (int i = 0; i < size; i++)
 +            reader.skipValue();
 +
 +        len = reader.position() - valOff;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected Object init() {
 +        reader.position(valOff + 1);
 +
 +        //skipping component type id
 +        reader.readInt();
 +
 +        int size = reader.readInt();
 +
 +        PortableBuilderEnum[] res = new PortableBuilderEnum[size];
 +
 +        for (int i = 0; i < size; i++) {
 +            byte flag = reader.readByte();
 +
 +            if (flag == GridPortableMarshaller.NULL)
 +                continue;
 +
 +            if (flag != GridPortableMarshaller.ENUM)
 +                throw new PortableException("Invalid flag value: " + flag);
 +
 +            res[i] = new PortableBuilderEnum(reader);
 +        }
 +
 +        return res;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        if (val != null) {
 +            if (clsName != null)
 +                ctx.writeArray(writer, GridPortableMarshaller.ENUM_ARR, (Object[])val, clsName);
 +            else
 +                ctx.writeArray(writer, GridPortableMarshaller.ENUM_ARR, (Object[])val, compTypeId);
 +
 +            return;
 +        }
 +
 +        writer.write(reader.array(), valOff, len);
 +    }
- }
++}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyArrayList.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyArrayList.java
index 510d04c,0000000..a08cfdd
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyArrayList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyArrayList.java
@@@ -1,163 -1,0 +1,166 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
 +import org.apache.ignite.internal.portable.*;
 +
- import java.util.*;
++import java.util.AbstractList;
++import java.util.ArrayList;
++import java.util.Collection;
++import java.util.List;
 +
 +/**
 + *
 + */
 +class PortableLazyArrayList extends AbstractList<Object> implements PortableBuilderSerializationAware {
 +    /** */
 +    private final PortableBuilderReader reader;
 +
 +    /** */
 +    private final int off;
 +
 +    /** */
 +    private List<Object> delegate;
 +
 +    /**
 +     * @param reader Reader.
 +     * @param size Size,
 +     */
 +    PortableLazyArrayList(PortableBuilderReader reader, int size) {
 +        this.reader = reader;
 +        off = reader.position() - 1/* flag */ - 4/* size */ - 1/* col type */;
 +
 +        assert size >= 0;
 +
 +        for (int i = 0; i < size; i++)
 +            reader.skipValue();
 +    }
 +
 +    /**
 +     *
 +     */
 +    private void ensureDelegateInit() {
 +        if (delegate == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */);
 +
 +            delegate = new ArrayList<>(size);
 +
 +            for (int i = 0; i < size; i++)
 +                delegate.add(reader.parseValue());
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object get(int idx) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.get(idx));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean add(Object o) {
 +        ensureDelegateInit();
 +
 +        return delegate.add(o);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void add(int idx, Object element) {
 +        ensureDelegateInit();
 +
 +        delegate.add(idx, element);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object set(int idx, Object element) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.set(idx, element));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object remove(int idx) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.remove(idx));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void clear() {
 +        if (delegate == null)
 +            delegate = new ArrayList<>();
 +        else
 +            delegate.clear();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean addAll(int idx, Collection<?> c) {
 +        return delegate.addAll(idx, c);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected void removeRange(int fromIdx, int toIdx) {
 +        ensureDelegateInit();
 +
 +        delegate.subList(fromIdx, toIdx).clear();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int size() {
 +        if (delegate == null)
 +            return reader.readIntAbsolute(off + 1);
 +
 +        return delegate.size();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        if (delegate == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */;
 +
 +            writer.write(reader.array(), off, hdrSize);
 +
 +            reader.position(off + hdrSize);
 +
 +            for (int i = 0; i < size; i++) {
 +                Object o = reader.parseValue();
 +
 +                ctx.writeValue(writer, o);
 +            }
 +        }
 +        else {
 +            writer.writeByte(GridPortableMarshaller.COL);
 +            writer.writeInt(delegate.size());
 +
 +            byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */];
 +            writer.writeByte(colType);
 +
 +            int oldPos = reader.position();
 +
 +            for (Object o : delegate)
 +                ctx.writeValue(writer, o);
 +
 +            // PortableBuilderImpl might have been written. It could override reader's position.
 +            reader.position(oldPos);
 +        }
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyLinkedList.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyLinkedList.java
index 0cbc0fb,0000000..f793d7a
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyLinkedList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyLinkedList.java
@@@ -1,212 -1,0 +1,217 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
 +import org.apache.ignite.internal.portable.*;
 +
- import java.util.*;
++import java.util.AbstractList;
++import java.util.Collection;
++import java.util.Iterator;
++import java.util.LinkedList;
++import java.util.List;
++import java.util.ListIterator;
 +
 +/**
 + *
 + */
 +class PortableLazyLinkedList extends AbstractList<Object> implements PortableBuilderSerializationAware {
 +    /** */
 +    private final PortableBuilderReader reader;
 +
 +    /** */
 +    private final int off;
 +
 +    /** */
 +    private List<Object> delegate;
 +
 +    /**
 +     * @param reader Reader.
 +     * @param size Size,
 +     */
 +    PortableLazyLinkedList(PortableBuilderReader reader, int size) {
 +        this.reader = reader;
 +        off = reader.position() - 1/* flag */ - 4/* size */ - 1/* col type */;
 +
 +        assert size >= 0;
 +
 +        for (int i = 0; i < size; i++)
 +            reader.skipValue();
 +    }
 +
 +    /**
 +     *
 +     */
 +    private void ensureDelegateInit() {
 +        if (delegate == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */);
 +
 +            delegate = new LinkedList<>();
 +
 +            for (int i = 0; i < size; i++)
 +                delegate.add(reader.parseValue());
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object get(int idx) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.get(idx));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean add(Object o) {
 +        ensureDelegateInit();
 +
 +        return delegate.add(o);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void add(int idx, Object element) {
 +        ensureDelegateInit();
 +
 +        delegate.add(idx, element);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object set(int idx, Object element) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.set(idx, element));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object remove(int idx) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.remove(idx));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void clear() {
 +        if (delegate == null)
 +            delegate = new LinkedList<>();
 +        else
 +            delegate.clear();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean addAll(int idx, Collection<?> c) {
 +        ensureDelegateInit();
 +
 +        return delegate.addAll(idx, c);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected void removeRange(int fromIdx, int toIdx) {
 +        ensureDelegateInit();
 +
 +        delegate.subList(fromIdx, toIdx).clear();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int size() {
 +        if (delegate == null)
 +            return reader.readIntAbsolute(off + 1);
 +
 +        return delegate.size();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public ListIterator<Object> listIterator(final int idx) {
 +        ensureDelegateInit();
 +
 +        return new ListIterator<Object>() {
 +            /** */
 +            private final ListIterator<Object> delegate = PortableLazyLinkedList.super.listIterator(idx);
 +
 +            @Override public boolean hasNext() {
 +                return delegate.hasNext();
 +            }
 +
 +            @Override public Object next() {
 +                return PortableUtils.unwrapLazy(delegate.next());
 +            }
 +
 +            @Override public boolean hasPrevious() {
 +                return delegate.hasPrevious();
 +            }
 +
 +            @Override public Object previous() {
 +                return PortableUtils.unwrapLazy(delegate.previous());
 +            }
 +
 +            @Override public int nextIndex() {
 +                return delegate.nextIndex();
 +            }
 +
 +            @Override public int previousIndex() {
 +                return delegate.previousIndex();
 +            }
 +
 +            @Override public void remove() {
 +                delegate.remove();
 +            }
 +
 +            @Override public void set(Object o) {
 +                delegate.set(o);
 +            }
 +
 +            @Override public void add(Object o) {
 +                delegate.add(o);
 +            }
 +        };
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Iterator<Object> iterator() {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazyIterator(super.iterator());
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        if (delegate == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */;
 +            writer.write(reader.array(), off, hdrSize);
 +
 +            reader.position(off + hdrSize);
 +
 +            for (int i = 0; i < size; i++) {
 +                Object o = reader.parseValue();
 +
 +                ctx.writeValue(writer, o);
 +            }
 +        }
 +        else {
 +            writer.writeByte(GridPortableMarshaller.COL);
 +            writer.writeInt(delegate.size());
 +
 +            byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */];
 +            writer.writeByte(colType);
 +
 +            for (Object o : delegate)
 +                ctx.writeValue(writer, o);
 +        }
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMap.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMap.java
index 90d5195,0000000..12cbfd6
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMap.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMap.java
@@@ -1,216 -1,0 +1,220 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
 +import org.apache.ignite.internal.portable.*;
 +
- import org.jetbrains.annotations.*;
- 
- import java.util.*;
++import java.util.AbstractMap;
++import java.util.AbstractSet;
++import java.util.Iterator;
++import java.util.LinkedHashMap;
++import java.util.Map;
++import java.util.Set;
++import org.jetbrains.annotations.Nullable;
 +
 +/**
 + *
 + */
 +class PortableLazyMap extends AbstractMap<Object, Object> implements PortableBuilderSerializationAware {
 +    /** */
 +    private final PortableBuilderReader reader;
 +
 +    /** */
 +    private final int off;
 +
 +    /** */
 +    private Map<Object, Object> delegate;
 +
 +    /**
 +     * @param reader Reader.
 +     * @param off Offset.
 +     */
 +    private PortableLazyMap(PortableBuilderReader reader, int off) {
 +        this.reader = reader;
 +        this.off = off;
 +    }
 +
 +    /**
 +     * @param reader Reader.
 +     * @return PortableLazyMap.
 +     */
 +    @Nullable public static PortableLazyMap parseMap(PortableBuilderReader reader) {
 +        int off = reader.position() - 1;
 +
 +        int size = reader.readInt();
 +
 +        reader.skip(1); // map type.
 +
 +        for (int i = 0; i < size; i++) {
 +            reader.skipValue(); // skip key
 +            reader.skipValue(); // skip value
 +        }
 +
 +        return new PortableLazyMap(reader, off);
 +    }
 +
 +    /**
 +     *
 +     */
 +    private void ensureDelegateInit() {
 +        if (delegate == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */);
 +
 +            delegate = new LinkedHashMap<>();
 +
 +            for (int i = 0; i < size; i++)
 +                delegate.put(PortableUtils.unwrapLazy(reader.parseValue()), reader.parseValue());
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        if (delegate == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */;
 +            writer.write(reader.array(), off, hdrSize);
 +
 +            reader.position(off + hdrSize);
 +
 +            for (int i = 0; i < size; i++) {
 +                ctx.writeValue(writer, reader.parseValue()); // key
 +                ctx.writeValue(writer, reader.parseValue()); // value
 +            }
 +        }
 +        else {
 +            writer.writeByte(GridPortableMarshaller.MAP);
 +            writer.writeInt(delegate.size());
 +
 +            byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */];
 +
 +            writer.writeByte(colType);
 +
 +            for (Entry<Object, Object> entry : delegate.entrySet()) {
 +                ctx.writeValue(writer, entry.getKey());
 +                ctx.writeValue(writer, entry.getValue());
 +            }
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public int size() {
 +        if (delegate == null)
 +            return reader.readIntAbsolute(off + 1);
 +
 +        return delegate.size();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean containsKey(Object key) {
 +        ensureDelegateInit();
 +
 +        return delegate.containsKey(key);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public boolean containsValue(Object val) {
 +        return values().contains(val);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Set<Object> keySet() {
 +        ensureDelegateInit();
 +
 +        return delegate.keySet();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void clear() {
 +        if (delegate == null)
 +            delegate = new LinkedHashMap<>();
 +        else
 +            delegate.clear();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object get(Object key) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.get(key));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object put(Object key, Object val) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.put(key, val));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object remove(Object key) {
 +        ensureDelegateInit();
 +
 +        return PortableUtils.unwrapLazy(delegate.remove(key));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Set<Entry<Object, Object>> entrySet() {
 +        ensureDelegateInit();
 +
 +        return new AbstractSet<Entry<Object, Object>>() {
 +            @Override public boolean contains(Object o) {
 +                throw new UnsupportedOperationException();
 +            }
 +
 +            @Override public Iterator<Entry<Object, Object>> iterator() {
 +                return new Iterator<Entry<Object, Object>>() {
 +                    /** */
 +                    private final Iterator<Entry<Object, Object>> itr = delegate.entrySet().iterator();
 +
 +                    @Override public boolean hasNext() {
 +                        return itr.hasNext();
 +                    }
 +
 +                    @Override public Entry<Object, Object> next() {
 +                        Entry<Object, Object> res = itr.next();
 +
 +                        final Object val = res.getValue();
 +
 +                        if (val instanceof PortableLazyValue) {
 +                            return new SimpleEntry<Object, Object>(res.getKey(), val) {
 +                                private static final long serialVersionUID = 0L;
 +
 +                                @Override public Object getValue() {
 +                                    return ((PortableLazyValue)val).value();
 +                                }
 +                            };
 +                        }
 +
 +                        return res;
 +                    }
 +
 +                    @Override public void remove() {
 +                        itr.remove();
 +                    }
 +                };
 +            }
 +
 +            @Override public int size() {
 +                return delegate.size();
 +            }
 +        };
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMapEntry.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMapEntry.java
index 53fc8d7,0000000..bd027f5
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazyMapEntry.java
@@@ -1,68 -1,0 +1,68 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
 +import org.apache.ignite.internal.portable.*;
 +
- import java.util.*;
++import java.util.Map;
 +
 +/**
 + *
 + */
 +class PortableLazyMapEntry implements Map.Entry<Object, Object>, PortableBuilderSerializationAware {
 +    /** */
 +    private final Object key;
 +
 +    /** */
 +    private Object val;
 +
 +    /**
 +     * @param reader GridMutablePortableReader
 +     */
 +    PortableLazyMapEntry(PortableBuilderReader reader) {
 +        key = reader.parseValue();
 +        val = reader.parseValue();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object getKey() {
 +        return PortableUtils.unwrapLazy(key);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object getValue() {
 +        return PortableUtils.unwrapLazy(val);
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Object setValue(Object val) {
 +        Object res = getValue();
 +
 +        this.val = val;
 +
 +        return res;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        writer.writeByte(GridPortableMarshaller.MAP_ENTRY);
 +
 +        ctx.writeValue(writer, key);
 +        ctx.writeValue(writer, val);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/979043dd/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazySet.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazySet.java
index 1e889e3,0000000..16772af
mode 100644,000000..100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazySet.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/builder/PortableLazySet.java
@@@ -1,90 -1,0 +1,92 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one or more
 + * contributor license agreements.  See the NOTICE file distributed with
 + * this work for additional information regarding copyright ownership.
 + * The ASF licenses this file to You under the Apache License, Version 2.0
 + * (the "License"); you may not use this file except in compliance with
 + * the License.  You may obtain a copy of the License at
 + *
 + *      http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing, software
 + * distributed under the License is distributed on an "AS IS" BASIS,
 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 + * See the License for the specific language governing permissions and
 + * limitations under the License.
 + */
 +
 +package org.apache.ignite.internal.portable.builder;
 +
- import org.apache.ignite.internal.portable.*;
- import org.apache.ignite.internal.util.typedef.internal.*;
- 
- import java.util.*;
++import java.util.Collection;
++import java.util.Set;
++import org.apache.ignite.internal.portable.GridPortableMarshaller;
++import org.apache.ignite.internal.portable.PortableUtils;
++import org.apache.ignite.internal.portable.PortableWriterExImpl;
++import org.apache.ignite.internal.util.typedef.internal.U;
 +
 +/**
 + *
 + */
 +class PortableLazySet extends PortableAbstractLazyValue {
 +    /** */
 +    private final int off;
 +
 +    /**
 +     * @param reader Reader.
 +     * @param size Size.
 +     */
 +    PortableLazySet(PortableBuilderReader reader, int size) {
 +        super(reader, reader.position() - 1);
 +
 +        off = reader.position() - 1/* flag */ - 4/* size */ - 1/* col type */;
 +
 +        assert size >= 0;
 +
 +        for (int i = 0; i < size; i++)
 +            reader.skipValue();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public void writeTo(PortableWriterExImpl writer, PortableBuilderSerializer ctx) {
 +        if (val == null) {
 +            int size = reader.readIntAbsolute(off + 1);
 +
 +            int hdrSize = 1 /* flag */ + 4 /* size */ + 1 /* col type */;
 +            writer.write(reader.array(), off, hdrSize);
 +
 +            reader.position(off + hdrSize);
 +
 +            for (int i = 0; i < size; i++) {
 +                Object o = reader.parseValue();
 +
 +                ctx.writeValue(writer, o);
 +            }
 +        }
 +        else {
 +            Collection<Object> c = (Collection<Object>)val;
 +
 +            writer.writeByte(GridPortableMarshaller.COL);
 +            writer.writeInt(c.size());
 +
 +            byte colType = reader.array()[off + 1 /* flag */ + 4 /* size */];
 +            writer.writeByte(colType);
 +
 +            for (Object o : c)
 +                ctx.writeValue(writer, o);
 +        }
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override protected Object init() {
 +        int size = reader.readIntAbsolute(off + 1);
 +
 +        reader.position(off + 1/* flag */ + 4/* size */ + 1/* col type */);
 +
 +        Set<Object> res = U.newLinkedHashSet(size);
 +
 +        for (int i = 0; i < size; i++)
 +            res.add(PortableUtils.unwrapLazy(reader.parseValue()));
 +
 +        return res;
 +    }
- }
++}


Mime
View raw message