You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/11/24 12:35:23 UTC

[2/3] ignite git commit: IGNITE-1956: WIP.

IGNITE-1956: WIP.


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

Branch: refs/heads/ignite-1956
Commit: 701758d7b958e3c9529c072eeb43f1f3643a73c3
Parents: fe16b19
Author: vozerov-gridgain <vo...@gridgain.com>
Authored: Tue Nov 24 13:46:16 2015 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Tue Nov 24 13:46:16 2015 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/IgniteBinary.java    |   4 +-
 .../internal/portable/BinaryEnumObjectImpl.java | 109 ++++++++++++++-
 .../internal/portable/BinaryWriteMode.java      |   3 +
 .../internal/portable/BinaryWriterExImpl.java   |  17 +++
 .../portable/PortableClassDescriptor.java       |  13 +-
 .../ignite/internal/portable/PortableUtils.java | 134 ++++++++++++++++++-
 .../portable/CacheObjectBinaryProcessor.java    |   8 ++
 .../CacheObjectBinaryProcessorImpl.java         |  12 ++
 .../cache/portable/IgniteBinaryImpl.java        |  12 ++
 .../processors/cacheobject/NoOpBinary.java      |   5 +
 10 files changed, 302 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
index af2c0ba..e7d77e7 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteBinary.java
@@ -359,8 +359,8 @@ public interface IgniteBinary {
      * Create enum object.
      *
      * @param typeName Type name.
-     * @param ordinal Ordinal.
+     * @param ord Ordinal.
      * @return Enum object.
      */
-    public BinaryObject buildEnum(String typeName, int ordinal);
+    public BinaryObject buildEnum(String typeName, int ord);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
index ddbb8d6..e97ef93 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryEnumObjectImpl.java
@@ -1,13 +1,35 @@
+/*
+ * 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.binary.BinaryObject;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.binary.BinaryType;
+import org.apache.ignite.internal.util.typedef.internal.SB;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
 
 /**
- * Created by vozerov on 11/24/2015.
+ * Binary enum object.
  */
 public class BinaryEnumObjectImpl implements BinaryObject, Externalizable {
     /** Context. */
@@ -16,6 +38,9 @@ public class BinaryEnumObjectImpl implements BinaryObject, Externalizable {
     /** Type ID. */
     private int typeId;
 
+    /** Raw data. */
+    private String clsName;
+
     /** Ordinal. */
     private int ord;
 
@@ -31,17 +56,25 @@ public class BinaryEnumObjectImpl implements BinaryObject, Externalizable {
      *
      * @param ctx Context.
      * @param typeId Type ID.
+     * @param clsName Class name.
      * @param ord Ordinal.
      */
-    public BinaryEnumObjectImpl(PortableContext ctx, int typeId, int ord) {
+    public BinaryEnumObjectImpl(PortableContext ctx, int typeId, @Nullable String clsName, int ord) {
         assert ctx != null;
-        assert typeId != 0;
 
         this.ctx = ctx;
         this.typeId = typeId;
+        this.clsName = clsName;
         this.ord = ord;
     }
 
+    /**
+     * @return Class name.
+     */
+    @Nullable public String className() {
+        return clsName;
+    }
+
     /** {@inheritDoc} */
     @Override public int typeId() {
         return typeId;
@@ -49,7 +82,7 @@ public class BinaryEnumObjectImpl implements BinaryObject, Externalizable {
 
     /** {@inheritDoc} */
     @Override public BinaryType type() throws BinaryObjectException {
-        return ctx.metadata(typeId);
+        return ctx.metadata(typeId());
     }
 
     /** {@inheritDoc} */
@@ -63,8 +96,9 @@ public class BinaryEnumObjectImpl implements BinaryObject, Externalizable {
     }
 
     /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
     @Override public <T> T deserialize() throws BinaryObjectException {
-        Class cls = ctx.descriptorForTypeId(true, typeId, null).describedClass();
+        Class cls = PortableUtils.resolveClass(ctx, typeId, clsName, null);
 
         return BinaryEnumCache.get(cls, ord);
     }
@@ -79,5 +113,70 @@ public class BinaryEnumObjectImpl implements BinaryObject, Externalizable {
         return ord;
     }
 
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        return 31 * typeId + ord;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object obj) {
+        if (obj != null && (obj instanceof BinaryEnumObjectImpl)) {
+            BinaryEnumObjectImpl other = (BinaryEnumObjectImpl)obj;
+
+            return typeId == other.typeId && ord == other.ord;
+        }
 
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        // 1. Try deserializing the object.
+        try {
+            Object val = deserialize();
+
+            return new SB().a(val).toString();
+        }
+        catch (Exception e) {
+            // No-op.
+        }
+
+        // 2. Try getting meta.
+        BinaryType type;
+
+        try {
+            type = type();
+        }
+        catch (Exception e) {
+            type = null;
+        }
+
+        if (type != null) {
+            return type.typeName() + "[ordinal=" + ord  + ']';
+        }
+        else {
+            if (typeId == GridPortableMarshaller.UNREGISTERED_TYPE_ID)
+                return "BinaryEnum[clsName=" + clsName + ", ordinal=" + ord + ']';
+            else
+                return "BinaryEnum[typeId=" + typeId + ", ordinal=" + ord + ']';
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject(ctx);
+
+        out.writeInt(typeId);
+        out.writeObject(clsName);
+        out.writeInt(ord);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        ctx = (PortableContext)in.readObject();
+
+        typeId = in.readInt();
+        clsName = (String)in.readObject();
+        ord = in.readInt();
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java
index a26b741..bd73ad0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriteMode.java
@@ -141,6 +141,9 @@ public enum BinaryWriteMode {
     /** */
     ENUM(GridPortableMarshaller.ENUM),
 
+    /** Portable enum. */
+    PORTABLE_ENUM(GridPortableMarshaller.ENUM),
+
     /** */
     ENUM_ARR(GridPortableMarshaller.ENUM_ARR),
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
index ec47f57..be10849 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/BinaryWriterExImpl.java
@@ -803,6 +803,23 @@ public class BinaryWriterExImpl implements BinaryWriter, BinaryRawWriterEx, Obje
     }
 
     /**
+     * @param val Value.
+     */
+    void doWritePortableEnum(BinaryEnumObjectImpl val) {
+        assert val != null;
+
+        int typeId = val.typeId();
+
+        out.unsafeEnsure(1 + 4);
+
+        out.unsafeWriteByte(ENUM);
+        out.unsafeWriteInt(typeId);
+
+        if (typeId == UNREGISTERED_TYPE_ID)
+            doWriteString(val.className());
+    }
+
+    /**
      * @param val Array.
      */
     void doWriteEnumArray(@Nullable Object[] val) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
index a206b8b..2e9c57e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableClassDescriptor.java
@@ -161,8 +161,12 @@ public class PortableClassDescriptor {
 
         if (excluded)
             mode = BinaryWriteMode.EXCLUSION;
-        else
-            mode = serializer != null ? BinaryWriteMode.PORTABLE : PortableUtils.mode(cls);
+        else {
+            if (cls == BinaryEnumObjectImpl.class)
+                mode = BinaryWriteMode.PORTABLE_ENUM;
+            else
+                mode = serializer != null ? BinaryWriteMode.PORTABLE : PortableUtils.mode(cls);
+        }
 
         switch (mode) {
             case P_BYTE:
@@ -541,6 +545,11 @@ public class PortableClassDescriptor {
 
                 break;
 
+            case PORTABLE_ENUM:
+                writer.doWritePortableEnum((BinaryEnumObjectImpl)obj);
+
+                break;
+
             case ENUM_ARR:
                 writer.doWriteEnumArray((Object[])obj);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
index e186760..dd0790e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableUtils.java
@@ -1320,6 +1320,37 @@ public class PortableUtils {
     }
 
     /**
+     * Read plain type.
+     *
+     * @param in Input stream.
+     * @return Plain type.
+     */
+    private static PlainType doReadPlainType(PortableInputStream in) {
+        int typeId = in.readInt();
+
+        if (typeId != UNREGISTERED_TYPE_ID)
+            return new PlainType(typeId, null);
+        else {
+            String clsName = doReadClassName(in);
+
+            return new PlainType(UNREGISTERED_TYPE_ID, clsName);
+        }
+    }
+
+    /**
+     * @param in Input stream.
+     * @return Class name.
+     */
+    private static String doReadClassName(PortableInputStream in) {
+        byte flag = in.readByte();
+
+        if (flag != STRING)
+            throw new BinaryObjectException("Failed to read class name [position=" + (in.position() - 1) + ']');
+
+        return doReadString(in);
+    }
+
+    /**
      * @param typeId Type id.
      * @return Value.
      */
@@ -1333,13 +1364,41 @@ public class PortableUtils {
         if (typeId != UNREGISTERED_TYPE_ID)
             cls = ctx.descriptorForTypeId(true, typeId, ldr).describedClass();
         else {
-            byte flag = in.readByte();
+            String clsName = doReadClassName(in);
 
-            if (flag != STRING)
-                throw new BinaryObjectException("No class definition for typeId: " + typeId);
+            try {
+                cls = U.forName(clsName, ldr);
+            }
+            catch (ClassNotFoundException e) {
+                throw new BinaryInvalidTypeException("Failed to load the class: " + clsName, e);
+            }
 
-            String clsName = doReadString(in);
+            // forces registering of class by type id, at least locally
+            ctx.descriptorForClass(cls);
+        }
 
+        return cls;
+    }
+
+    /**
+     * Resolve the class.
+     *
+     * @param ctx Portable context.
+     * @param typeId Type ID.
+     * @param clsName Class name.
+     * @param ldr Class loaded.
+     * @return Resovled class.
+     */
+    public static Class resolveClass(PortableContext ctx, int typeId, @Nullable String clsName,
+        @Nullable ClassLoader ldr) {
+        Class cls;
+
+        if (typeId == OBJECT_TYPE_ID)
+            return Object.class;
+
+        if (typeId != UNREGISTERED_TYPE_ID)
+            cls = ctx.descriptorForTypeId(true, typeId, ldr).describedClass();
+        else {
             try {
                 cls = U.forName(clsName, ldr);
             }
@@ -1355,6 +1414,44 @@ public class PortableUtils {
     }
 
     /**
+     * Read portable enum.
+     *
+     * @param in Input stream.
+     * @param ctx Portable context.
+     * @param type Plain type.
+     * @return Enum.
+     */
+    private static BinaryEnumObjectImpl doReadPortableEnum(PortableInputStream in, PortableContext ctx,
+        PlainType type) {
+        return new BinaryEnumObjectImpl(ctx, type.typeId, type.clsName, in.readInt());
+    }
+
+    /**
+     * Read portable enum array.
+     *
+     * @param in Input stream.
+     * @param ctx Portable context.
+     * @param type Plain type.
+     * @return Enum array.
+     */
+    private static Object[] doReadPortableEnumArray(PortableInputStream in, PortableContext ctx, PlainType type) {
+        int len = in.readInt();
+
+        Object[] arr = (Object[]) Array.newInstance(BinaryObject.class, len);
+
+        for (int i = 0; i < len; i++) {
+            byte flag = in.readByte();
+
+            if (flag == NULL)
+                arr[i] = null;
+            else
+                arr[i] = doReadPortableEnum(in, ctx, type);
+        }
+
+        return arr;
+    }
+
+    /**
      * Having target class in place we simply read ordinal and create final representation.
      *
      * @param cls Enum class.
@@ -1595,10 +1692,10 @@ public class PortableUtils {
                 return doReadPortableObject(in, ctx);
 
             case ENUM:
-                return doReadEnum(in, doReadClass(in, ctx, ldr));
+                return doReadPortableEnum(in, ctx, doReadPlainType(in));
 
             case ENUM_ARR:
-                return doReadEnumArray(in, ctx, ldr, doReadClass(in, ctx, ldr));
+                return doReadPortableEnumArray(in, ctx, doReadPlainType(in));
 
             case CLASS:
                 return doReadClass(in, ctx, ldr);
@@ -1844,4 +1941,29 @@ public class PortableUtils {
     public static int positionForHandle(PortableInputStream in) {
         return in.position() - 1;
     }
+
+    /**
+     * Plain type.
+     */
+    private static class PlainType {
+        /** Type ID. */
+        private final int typeId;
+
+        /** Class name. */
+        private final String clsName;
+
+        /**
+         * Constructor.
+         *
+         * @param typeId Type ID.
+         * @param clsName Class name.
+         */
+        public PlainType(int typeId, @Nullable String clsName) {
+            assert typeId != UNREGISTERED_TYPE_ID && clsName == null ||
+                typeId == UNREGISTERED_TYPE_ID && clsName != null;
+
+            this.typeId = typeId;
+            this.clsName = clsName;
+        }
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java
index 82d87b9..7ef4b91 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessor.java
@@ -84,6 +84,14 @@ public interface CacheObjectBinaryProcessor extends IgniteCacheObjectProcessor {
     public Collection<BinaryType> metadata() throws IgniteException;
 
     /**
+     * @param typeName Type name.
+     * @param ord ordinal.
+     * @return Enum object.
+     * @throws IgniteException If failed.
+     */
+    public BinaryObject buildEnum(String typeName, int ord) throws IgniteException;
+
+    /**
      * @return Portables interface.
      * @throws IgniteException If failed.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java
index b5ad1f0..4bff81a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/CacheObjectBinaryProcessorImpl.java
@@ -30,6 +30,7 @@ import org.apache.ignite.cluster.ClusterTopologyException;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.portable.BinaryEnumObjectImpl;
 import org.apache.ignite.internal.portable.BinaryMetadata;
 import org.apache.ignite.internal.portable.BinaryMetadataHandler;
 import org.apache.ignite.internal.portable.BinaryObjectImpl;
@@ -536,6 +537,17 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
     }
 
     /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, int ord) throws IgniteException {
+        typeName = PortableContext.typeName(typeName);
+
+        int typeId = portableCtx.typeId(typeName);
+
+        updateMetadata(typeId, typeName, null, null, true);
+
+        return new BinaryEnumObjectImpl(portableCtx, typeId, null, ord);
+    }
+
+    /** {@inheritDoc} */
     @Override public IgniteBinary binary() throws IgniteException {
         return portables;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java
index 72f4d24..517362e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/portable/IgniteBinaryImpl.java
@@ -142,6 +142,18 @@ public class IgniteBinaryImpl implements IgniteBinary {
         }
     }
 
+    /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, int ord) {
+        guard();
+
+        try {
+            return proc.buildEnum(typeName, ord);
+        }
+        finally {
+            unguard();
+        }
+    }
+
     /**
      * @return Portable processor.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/701758d7/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
index 5bbc194..c8a6448 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cacheobject/NoOpBinary.java
@@ -69,6 +69,11 @@ public class NoOpBinary implements IgniteBinary {
     }
 
     /** {@inheritDoc} */
+    @Override public BinaryObject buildEnum(String typeName, int ord) {
+        throw unsupported();
+    }
+
+    /** {@inheritDoc} */
     private BinaryObjectException unsupported() {
         return new BinaryObjectException("Binary marshaller is not configured.");
     }