IGNITE-141 - Marshallers refactoring

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

Branch: refs/heads/ignite-141
Commit: e9d99de8a042c378d24b579ab49d251f780a775c
Parents: 6a8b322
Author: Valentin Kulichenko <[email protected]>
Authored: Sat Feb 28 23:38:44 2015 -0800
Committer: Valentin Kulichenko <[email protected]>
Committed: Sat Feb 28 23:38:44 2015 -0800

----------------------------------------------------------------------
 .../apache/ignite/internal/IgniteKernal.java    |    8 +-
 .../optimized/OptimizedClassDescriptor.java     |   49 +-
 .../optimized/OptimizedMarshaller.java          |   26 +-
 .../optimized/OptimizedMarshallerIdMapper.java  |   33 +
 .../optimized/OptimizedMarshallerUtils.java     |   67 +-
 .../optimized/OptimizedObjectInputStream.java   |   16 +-
 .../optimized/OptimizedObjectOutputStream.java  |   18 +-
 .../marshaller/optimized/classnames.properties  | 1470 ++++++++++++++++++
 .../OptimizedObjectStreamSelfTest.java          |    6 +-
 9 files changed, 1597 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java 
b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 55bc1f8..2e517e8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -2793,11 +2793,15 @@ public class IgniteKernal implements IgniteEx, 
IgniteMXBean, Externalizable {
         /** {@inheritDoc} */
         @Override public void run() {
             try {
+                // TODO: IGNITE-141 - Remove debug
+                U.debug(">>> REGISTER: " + clsName);
+
                 String old = cache.putIfAbsent(typeId, clsName);
 
-                // TODO: IGNITE-141 - proper message
                 if (old != null && !old.equals(clsName))
-                    throw new IgniteException("Collision.");
+                    throw new IgniteException("Type ID collision acquired in 
OptimizedMarshaller. Use " +
+                        "OptimizedMarshallerIdMapper to resolve it [id=" + 
typeId + ", clsName1=" + clsName +
+                        "clsName2=" + old + ']');
             }
             catch (IgniteCheckedException e) {
                 throw U.convertException(e);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
index 7c3c205..e50cf7b 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedClassDescriptor.java
@@ -130,19 +130,22 @@ class OptimizedClassDescriptor {
     private static final int TYPE_SERIALIZABLE = 51;
 
     /** Class. */
-    private Class<?> cls;
+    private final Class<?> cls;
 
     /** Context. */
-    private MarshallerContext ctx;
+    private final MarshallerContext ctx;
+
+    /** ID mapper. */
+    private final OptimizedMarshallerIdMapper mapper;
+
+    /** Class name. */
+    private final String name;
 
     /** Type ID. */
-    private int typeId;
+    private final int typeId;
 
     /** Short ID. */
-    private short checksum;
-
-    /** Class name. */
-    private String name;
+    private final short checksum;
 
     /** Class type. */
     private int type;
@@ -157,7 +160,7 @@ class OptimizedClassDescriptor {
     private boolean isSerial;
 
     /** Excluded flag. */
-    private final boolean excluded;
+    private boolean excluded;
 
     /** {@code True} if descriptor is for {@link Class}. */
     private boolean isCls;
@@ -203,19 +206,32 @@ class OptimizedClassDescriptor {
      *
      * @param cls Class.
      * @param ctx Context.
+     * @param mapper ID mapper.
      * @throws IOException In case of error.
      */
     @SuppressWarnings("ForLoopReplaceableByForEach")
-    OptimizedClassDescriptor(Class<?> cls, MarshallerContext ctx) throws 
IOException {
+    OptimizedClassDescriptor(Class<?> cls, MarshallerContext ctx, 
OptimizedMarshallerIdMapper mapper)
+        throws IOException {
         this.cls = cls;
         this.ctx = ctx;
+        this.mapper = mapper;
 
-        // TODO: IGNITE-141 - resolve
-        typeId = cls.getName().hashCode();
+        name = cls.getName();
 
-        excluded = MarshallerExclusions.isExcluded(cls);
+        int typeId;
 
-        name = cls.getName();
+        if (mapper != null) {
+            typeId = mapper.typeId(name);
+
+            if (typeId == 0)
+                typeId = name.hashCode();
+        }
+        else
+            typeId = name.hashCode();
+
+        this.typeId = typeId;
+
+        excluded = MarshallerExclusions.isExcluded(cls);
 
         if (!excluded) {
             Class<?> parent;
@@ -777,8 +793,7 @@ class OptimizedClassDescriptor {
                 break;
 
             case TYPE_CLS:
-                // TODO: IGNITE-141 - Do not acquire descriptor?
-                OptimizedClassDescriptor desc = 
OptimizedMarshallerUtils.classDescriptor((Class<?>)obj, ctx);
+                OptimizedClassDescriptor desc = 
OptimizedMarshallerUtils.classDescriptor((Class<?>)obj, ctx, mapper);
 
                 out.writeInt(desc.typeId());
 
@@ -901,8 +916,8 @@ class OptimizedClassDescriptor {
                 return in.readDate();
 
             case TYPE_CLS:
-                // TODO: IGNITE-141 - Do not acquire descriptor?
-                return OptimizedMarshallerUtils.classDescriptor(in.readInt(), 
in.classLoader(), ctx).describedClass();
+                return OptimizedMarshallerUtils.classDescriptor(in.readInt(), 
in.classLoader(), ctx, mapper).
+                    describedClass();
 
             case TYPE_EXTERNALIZABLE:
                 verifyChecksum(in.readShort());

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
index f107c08..4779eb6 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshaller.java
@@ -79,6 +79,9 @@ public class OptimizedMarshaller extends AbstractMarshaller {
     /** Whether or not to require an object to be serializable in order to be 
marshalled. */
     private boolean requireSer = true;
 
+    /** ID mapper. */
+    private OptimizedMarshallerIdMapper mapper;
+
     /**
      * Creates new marshaller will all defaults.
      *
@@ -110,6 +113,15 @@ public class OptimizedMarshaller extends 
AbstractMarshaller {
     }
 
     /**
+     * Sets ID mapper.
+     *
+     * @param mapper ID mapper.
+     */
+    public void setIdMapper(OptimizedMarshallerIdMapper mapper) {
+        this.mapper = mapper;
+    }
+
+    /**
      * Specifies size of cached object streams used by marshaller. Object 
streams are cached for
      * performance reason to avoid costly recreation for every serialization 
routine. If {@code 0} (default),
      * pool is not used and each thread has its own cached object stream which 
it keeps reusing.
@@ -137,8 +149,7 @@ public class OptimizedMarshaller extends AbstractMarshaller 
{
         try {
             objOut = OptimizedObjectStreamRegistry.out();
 
-            objOut.context(ctx);
-            objOut.requireSerializable(requireSer);
+            objOut.context(ctx, mapper, requireSer);
 
             objOut.out().outputStream(out);
 
@@ -159,8 +170,7 @@ public class OptimizedMarshaller extends AbstractMarshaller 
{
         try {
             objOut = OptimizedObjectStreamRegistry.out();
 
-            objOut.context(ctx);
-            objOut.requireSerializable(requireSer);
+            objOut.context(ctx, mapper, requireSer);
 
             objOut.writeObject(obj);
 
@@ -175,6 +185,7 @@ public class OptimizedMarshaller extends AbstractMarshaller 
{
     }
 
     /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
     @Override public <T> T unmarshal(InputStream in, @Nullable ClassLoader 
clsLdr) throws IgniteCheckedException {
         assert in != null;
 
@@ -183,8 +194,7 @@ public class OptimizedMarshaller extends AbstractMarshaller 
{
         try {
             objIn = OptimizedObjectStreamRegistry.in();
 
-            objIn.context(ctx);
-            objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr);
+            objIn.context(ctx, mapper, clsLdr != null ? clsLdr : dfltClsLdr);
 
             objIn.in().inputStream(in);
 
@@ -204,6 +214,7 @@ public class OptimizedMarshaller extends AbstractMarshaller 
{
     }
 
     /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
     @Override public <T> T unmarshal(byte[] arr, @Nullable ClassLoader clsLdr) 
throws IgniteCheckedException {
         assert arr != null;
 
@@ -212,8 +223,7 @@ public class OptimizedMarshaller extends AbstractMarshaller 
{
         try {
             objIn = OptimizedObjectStreamRegistry.in();
 
-            objIn.context(ctx);
-            objIn.classLoader(clsLdr != null ? clsLdr : dfltClsLdr);
+            objIn.context(ctx, mapper, clsLdr != null ? clsLdr : dfltClsLdr);
 
             objIn.in().bytes(arr, arr.length);
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerIdMapper.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerIdMapper.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerIdMapper.java
new file mode 100644
index 0000000..e4e2627
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerIdMapper.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.marshaller.optimized;
+
+/**
+ * ID mapper.
+ */
+public interface OptimizedMarshallerIdMapper {
+    /**
+     * Gets type ID for provided class name.
+     * <p>
+     * If {@code 0} is returned, hash code of class name will be used.
+     *
+     * @param clsName Class name.
+     * @return Type ID.
+     */
+    public int typeId(String clsName);
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
index 031e876..01cc348 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerUtils.java
@@ -17,13 +17,7 @@
 
 package org.apache.ignite.marshaller.optimized;
 
-import org.apache.ignite.internal.processors.cache.*;
-import org.apache.ignite.internal.processors.cache.distributed.*;
-import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.*;
-import org.apache.ignite.internal.processors.cache.transactions.*;
-import org.apache.ignite.internal.processors.cache.version.*;
 import org.apache.ignite.internal.util.*;
-import org.apache.ignite.internal.util.lang.*;
 import org.apache.ignite.internal.util.typedef.*;
 import org.apache.ignite.internal.util.typedef.internal.*;
 import org.apache.ignite.lang.*;
@@ -57,38 +51,8 @@ class OptimizedMarshallerUtils {
     /** UTF-8 character name. */
     static final Charset UTF_8 = Charset.forName("UTF-8");
 
-    /** Predefined classes. */
-    private static final Class[] PREDEFINED = new Class[] {
-        byte[].class,
-        Boolean.class,
-        Integer.class,
-        String.class,
-        UUID.class,
-        ArrayList.class,
-        LinkedList.class,
-        HashSet.class,
-        HashMap.class,
-
-        GridDhtPartitionMap.class,
-        GridDhtPartitionFullMap.class,
-        GridCacheMvccCandidate.class,
-        GridCacheVersion.class,
-        IgniteTxEntry.class,
-        IgnitePredicate[].class,
-        IgniteExternalizableExpiryPolicy.class,
-        IgniteTxKey.class,
-        GridCacheReturn.class,
-        GridTuple4.class,
-        GridCacheEntryInfo.class,
-        GridLeanMap.class
-    };
-
-    /** Predefined class names. */
-    private static final String[] PREDEFINED_NAMES = new String[] {
-        "org.apache.ignite.internal.GridTopic$T7",
-        "org.apache.ignite.internal.util.lang.GridFunc$37",
-        "org.apache.ignite.internal.util.GridLeanMap$Map3"
-    };
+    /** Classnames file path. */
+    private static final String CLS_NAMES_FILE = 
"org/apache/ignite/marshaller/optimized/classnames.properties";
 
     /** Class descriptors by class. */
     private static final ConcurrentMap<Class, OptimizedClassDescriptor> 
DESC_BY_CLS = new ConcurrentHashMap8<>(256);
@@ -98,17 +62,20 @@ class OptimizedMarshallerUtils {
         new ConcurrentHashMap8<>(256);
 
     static {
-        for (Class cls : PREDEFINED)
-            CLS_BY_ID.put(cls.getName().hashCode(), F.t(cls, true));
-
         try {
-            for (String clsName : PREDEFINED_NAMES) {
-                Class cls = U.forName(clsName, 
OptimizedMarshallerUtils.class.getClassLoader());
+            ClassLoader ldr = OptimizedMarshallerUtils.class.getClassLoader();
+
+            BufferedReader rdr = new BufferedReader(new 
InputStreamReader(ldr.getResourceAsStream(CLS_NAMES_FILE)));
+
+            String clsName;
+
+            while ((clsName = rdr.readLine()) != null) {
+                Class cls = U.forName(clsName, ldr);
 
                 CLS_BY_ID.put(cls.getName().hashCode(), F.t(cls, true));
             }
         }
-        catch (ClassNotFoundException e) {
+        catch (IOException | ClassNotFoundException e) {
             throw new IllegalStateException(e);
         }
     }
@@ -124,14 +91,16 @@ class OptimizedMarshallerUtils {
      *
      * @param cls Class.
      * @param ctx Context.
+     * @param mapper ID mapper.
      * @return Descriptor.
      * @throws IOException In case of error.
      */
-    static OptimizedClassDescriptor classDescriptor(Class cls, 
MarshallerContext ctx) throws IOException {
+    static OptimizedClassDescriptor classDescriptor(Class cls, 
MarshallerContext ctx,
+        OptimizedMarshallerIdMapper mapper) throws IOException {
         OptimizedClassDescriptor desc = DESC_BY_CLS.get(cls);
 
         if (desc == null) {
-            desc = new OptimizedClassDescriptor(cls, ctx);
+            desc = new OptimizedClassDescriptor(cls, ctx, mapper);
 
             if (CLS_BY_ID.putIfAbsent(desc.typeId(), F.t(cls, false)) == null)
                 ctx.registerClass(desc.typeId(), cls.getName());
@@ -151,11 +120,13 @@ class OptimizedMarshallerUtils {
      * @param id ID.
      * @param ldr Class loader.
      * @param ctx Context.
+     * @param mapper ID mapper.
      * @return Descriptor.
      * @throws IOException In case of error.
      * @throws ClassNotFoundException If class was not found.
      */
-    static OptimizedClassDescriptor classDescriptor(int id, ClassLoader ldr, 
MarshallerContext ctx)
+    static OptimizedClassDescriptor classDescriptor(int id, ClassLoader ldr, 
MarshallerContext ctx,
+        OptimizedMarshallerIdMapper mapper)
         throws IOException, ClassNotFoundException {
         Class cls = CLS_BY_ID.get(id).get1();
 
@@ -172,7 +143,7 @@ class OptimizedMarshallerUtils {
                 cls = old.get1();
         }
 
-        return classDescriptor(cls, ctx);
+        return classDescriptor(cls, ctx, mapper);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
index ad10638..50e5551 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectInputStream.java
@@ -48,6 +48,9 @@ class OptimizedObjectInputStream extends ObjectInputStream {
     private MarshallerContext ctx;
 
     /** */
+    private OptimizedMarshallerIdMapper mapper;
+
+    /** */
     private ClassLoader clsLdr;
 
     /** */
@@ -78,15 +81,12 @@ class OptimizedObjectInputStream extends ObjectInputStream {
 
     /**
      * @param ctx Context.
-     */
-    void context(MarshallerContext ctx) {
-        this.ctx = ctx;
-    }
-
-    /**
+     * @param mapper ID mapper.
      * @param clsLdr Class loader.
      */
-    void classLoader(ClassLoader clsLdr) {
+    void context(MarshallerContext ctx, OptimizedMarshallerIdMapper mapper, 
ClassLoader clsLdr) {
+        this.ctx = ctx;
+        this.mapper = mapper;
         this.clsLdr = clsLdr;
     }
 
@@ -149,7 +149,7 @@ class OptimizedObjectInputStream extends ObjectInputStream {
             case OBJECT:
                 int typeId = readInt();
 
-                OptimizedClassDescriptor desc = 
OptimizedMarshallerUtils.classDescriptor(typeId, clsLdr, ctx);
+                OptimizedClassDescriptor desc = 
OptimizedMarshallerUtils.classDescriptor(typeId, clsLdr, ctx, mapper);
 
                 curCls = desc.describedClass();
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e9d99de8/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
index fdcb78d..1e250d8 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/marshaller/optimized/OptimizedObjectOutputStream.java
@@ -50,6 +50,9 @@ class OptimizedObjectOutputStream extends ObjectOutputStream {
     private MarshallerContext ctx;
 
     /** */
+    private OptimizedMarshallerIdMapper mapper;
+
+    /** */
     private boolean requireSer;
 
     /** */
@@ -74,15 +77,12 @@ class OptimizedObjectOutputStream extends 
ObjectOutputStream {
 
     /**
      * @param ctx Context.
-     */
-    void context(MarshallerContext ctx) {
-        this.ctx = ctx;
-    }
-
-    /**
+     * @param mapper ID mapper.
      * @param requireSer Require {@link Serializable} flag.
      */
-    void requireSerializable(boolean requireSer) {
+    void context(MarshallerContext ctx, OptimizedMarshallerIdMapper mapper, 
boolean requireSer) {
+        this.ctx = ctx;
+        this.mapper = mapper;
         this.requireSer = requireSer;
     }
 
@@ -152,7 +152,7 @@ class OptimizedObjectOutputStream extends 
ObjectOutputStream {
         else {
             Class<?> cls = obj.getClass();
 
-            OptimizedClassDescriptor desc = classDescriptor(cls, ctx);
+            OptimizedClassDescriptor desc = classDescriptor(cls, ctx, mapper);
 
             if (desc.excluded()) {
                 writeByte(NULL);
@@ -176,7 +176,7 @@ class OptimizedObjectOutputStream extends 
ObjectOutputStream {
             if (obj0 != obj) {
                 obj = obj0;
 
-                desc = classDescriptor(obj.getClass(), ctx);
+                desc = classDescriptor(obj.getClass(), ctx, mapper);
             }
 
             if (handle >= 0) {

Reply via email to