ignite-1353: removed redundant sets and maps from portable API implementation
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e77e1c74 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e77e1c74 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e77e1c74 Branch: refs/heads/ignite-1353 Commit: e77e1c743ee5e6618767b636b920d7043b4898f0 Parents: abadcf2 Author: Denis Magda <[email protected]> Authored: Thu Sep 3 11:34:16 2015 +0300 Committer: Denis Magda <[email protected]> Committed: Thu Sep 3 11:34:16 2015 +0300 ---------------------------------------------------------------------- .../portable/PortableClassDescriptor.java | 77 +++++++++------- .../internal/portable/PortableContext.java | 79 ++++++----------- .../internal/portable/PortableWriterExImpl.java | 92 ++++++-------------- .../GridPortableMarshallerSelfTest.java | 15 ++-- 4 files changed, 104 insertions(+), 159 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/e77e1c74/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 b75e3c9..a2b4b74 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 @@ -19,10 +19,13 @@ package org.apache.ignite.internal.portable; import java.io.Externalizable; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.sql.Timestamp; import java.util.ArrayList; @@ -36,6 +39,8 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.processors.cache.CacheObjectImpl; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.marshaller.MarshallerExclusions; +import org.apache.ignite.marshaller.optimized.OptimizedMarshaller; +import org.apache.ignite.marshaller.portable.PortableMarshaller; import org.apache.ignite.portable.PortableException; import org.apache.ignite.portable.PortableIdMapper; import org.apache.ignite.portable.PortableMarshalAware; @@ -95,36 +100,10 @@ public class PortableClassDescriptor { private final boolean registered; /** */ - private final boolean excluded; + private final boolean useOptMarshaller; - /** - * @param ctx Context. - * @param cls Class. - * @param userType User type flag. - * @param typeId Type ID. - * @param typeName Type name. - * @param idMapper ID mapper. - * @param serializer Serializer. - * @param useTs Use timestamp flag. - * @param metaDataEnabled Metadata enabled flag. - * @param keepDeserialized Keep deserialized flag. - * @throws PortableException In case of error. - */ - PortableClassDescriptor( - PortableContext ctx, - Class<?> cls, - boolean userType, - int typeId, - String typeName, - @Nullable PortableIdMapper idMapper, - @Nullable PortableSerializer serializer, - boolean useTs, - boolean metaDataEnabled, - boolean keepDeserialized - ) throws PortableException { - this(ctx, cls, userType, typeId, typeName, idMapper, serializer, useTs, metaDataEnabled, keepDeserialized, - true); - } + /** */ + private final boolean excluded; /** * @param ctx Context. @@ -138,6 +117,7 @@ public class PortableClassDescriptor { * @param metaDataEnabled Metadata enabled flag. * @param keepDeserialized Keep deserialized flag. * @param registered Whether typeId has been successfully registered by MarshallerContext or not. + * @param predefined Whether the class is predefined or not. * @throws PortableException In case of error. */ PortableClassDescriptor( @@ -151,7 +131,8 @@ public class PortableClassDescriptor { boolean useTs, boolean metaDataEnabled, boolean keepDeserialized, - boolean registered + boolean registered, + boolean predefined ) throws PortableException { assert ctx != null; assert cls != null; @@ -168,6 +149,8 @@ public class PortableClassDescriptor { excluded = MarshallerExclusions.isExcluded(cls); + useOptMarshaller = !predefined && initUseOptimizedMarshallerFlag(); + if (excluded) mode = Mode.EXCLUSION; else @@ -318,6 +301,14 @@ public class PortableClassDescriptor { } /** + * @return {@code true} if {@link OptimizedMarshaller} must be used instead of {@link PortableMarshaller} + * for object serialization and deserialization. + */ + public boolean useOptimizedMarshaller() { + return useOptMarshaller; + } + + /** * Checks whether the class values are explicitly excluded from marshalling. * * @return {@code true} if excluded, {@code false} otherwise. @@ -720,6 +711,32 @@ public class PortableClassDescriptor { } /** + * Determines whether to use {@link OptimizedMarshaller} for serialization or + * not. + * + * @return {@code true} if to use, {@code false} otherwise. + */ + private boolean initUseOptimizedMarshallerFlag() { + boolean use; + + try { + Method writeObj = cls.getDeclaredMethod("writeObject", ObjectOutputStream.class); + Method readObj = cls.getDeclaredMethod("readObject", ObjectInputStream.class); + + if (!Modifier.isStatic(writeObj.getModifiers()) && !Modifier.isStatic(readObj.getModifiers()) && + writeObj.getReturnType() == void.class && readObj.getReturnType() == void.class) + use = true; + else + use = false; + } + catch (NoSuchMethodException e) { + use = false; + } + + return use; + } + + /** * @param cls Class. * @return Mode. */ http://git-wip-us.apache.org/repos/asf/ignite/blob/e77e1c74/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java index 29c635e..24c39b7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableContext.java @@ -112,9 +112,6 @@ public class PortableContext implements Externalizable { private final Map<Integer, PortableClassDescriptor> predefinedTypes = new HashMap<>(); /** */ - private final Set<Class> predefinedClasses = new HashSet<>(); - - /** */ private final Map<String, Integer> predefinedTypeNames = new HashMap<>(); /** */ @@ -221,18 +218,18 @@ public class PortableContext implements Externalizable { registerPredefinedType(Date[].class, GridPortableMarshaller.DATE_ARR); registerPredefinedType(Object[].class, GridPortableMarshaller.OBJ_ARR); - registerPredefinedType(ArrayList.class, 0); - registerPredefinedType(LinkedList.class, 0); - registerPredefinedType(HashSet.class, 0); - registerPredefinedType(LinkedHashSet.class, 0); - registerPredefinedType(TreeSet.class, 0); - registerPredefinedType(ConcurrentSkipListSet.class, 0); + registerPredefinedType(ArrayList.class, GridPortableMarshaller.ARR_LIST); + registerPredefinedType(LinkedList.class, GridPortableMarshaller.LINKED_LIST); + registerPredefinedType(HashSet.class, GridPortableMarshaller.HASH_SET); + registerPredefinedType(LinkedHashSet.class, GridPortableMarshaller.LINKED_HASH_SET); + registerPredefinedType(TreeSet.class, GridPortableMarshaller.TREE_SET); + registerPredefinedType(ConcurrentSkipListSet.class, GridPortableMarshaller.CONC_SKIP_LIST_SET); - registerPredefinedType(HashMap.class, 0); - registerPredefinedType(LinkedHashMap.class, 0); - registerPredefinedType(TreeMap.class, 0); - registerPredefinedType(ConcurrentHashMap.class, 0); - registerPredefinedType(ConcurrentHashMap8.class, 0); + registerPredefinedType(HashMap.class, GridPortableMarshaller.HASH_MAP); + registerPredefinedType(LinkedHashMap.class, GridPortableMarshaller.LINKED_HASH_MAP); + registerPredefinedType(TreeMap.class, GridPortableMarshaller.TREE_MAP); + registerPredefinedType(ConcurrentHashMap.class, GridPortableMarshaller.CONC_HASH_MAP); + registerPredefinedType(ConcurrentHashMap8.class, GridPortableMarshaller.CONC_HASH_MAP); registerPredefinedType(GridMapEntry.class, 60); registerPredefinedType(IgniteBiTuple.class, 61); @@ -508,7 +505,10 @@ public class PortableContext implements Externalizable { null, useTs, metaDataEnabled, - keepDeserialized); + keepDeserialized, + true, /* registered */ + false /* predefined */ + ); PortableClassDescriptor old = descByCls.putIfAbsent(cls, desc); @@ -556,7 +556,9 @@ public class PortableContext implements Externalizable { useTs, metaDataEnabled, keepDeserialized, - registered); + registered, + false /* predefined */ + ); // perform put() instead of putIfAbsent() because "registered" flag may have been changed. userTypes.put(typeId, desc); @@ -611,31 +613,6 @@ public class PortableContext implements Externalizable { } /** - * @param cls Class. - * @return Type ID. - * @throws PortableException In case of error. - */ - public Type typeId(Class cls) throws PortableException { - String clsName = cls.getName(); - - if (predefinedClasses.contains(cls)) - return new Type(descByCls.get(cls).typeId(), true); - - if (marshCtx.isSystemType(clsName)) - return new Type(clsName.hashCode(), true); - - PortableClassDescriptor desc = descByCls.get(cls); - - boolean registered = desc != null && desc.registered(); - - if (!registered) - // forces to register the class and fill up all required data structures - desc = registerUserClassDescriptor(cls); - - return new Type(desc.typeId(), desc.registered()); - } - - /** * @param typeId Type ID. * @param fieldName Field name. * @return Field ID. @@ -716,10 +693,11 @@ public class PortableContext implements Externalizable { null, false, false, - false + false, + true, /* registered */ + true /* predefined */ ); - predefinedClasses.add(cls); predefinedTypeNames.put(typeName, id); predefinedTypes.put(id, desc); @@ -789,7 +767,10 @@ public class PortableContext implements Externalizable { serializer, useTs, metaDataEnabled, - keepDeserialized); + keepDeserialized, + true, /* registered */ + false /* predefined */ + ); fieldsMeta = desc.fieldsMeta(); @@ -882,16 +863,6 @@ public class PortableContext implements Externalizable { } /** - * Returns whether {@code cls} is predefined in the context or not. - * - * @param cls Class. - * @return {@code true} if predefined, {@code false} otherwise. - */ - public boolean isPredefinedClass(Class<?> cls) { - return predefinedClasses.contains(cls); - } - - /** * Returns instance of {@link OptimizedMarshaller}. * * @return Optimized marshaller. http://git-wip-us.apache.org/repos/asf/ignite/blob/e77e1c74/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java index 364d5f8..3152c4b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/portable/PortableWriterExImpl.java @@ -93,9 +93,6 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx private static final int INIT_CAP = 1024; /** */ - private static final ConcurrentHashMap<Class<?>, Boolean> useOptMarshCache = new ConcurrentHashMap<>(); - - /** */ private final PortableContext ctx; /** */ @@ -197,7 +194,19 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx void marshal(Object obj, boolean detached) throws PortableException { assert obj != null; - if (useOptimizedMarshaller(obj)) { + cls = obj.getClass(); + + PortableClassDescriptor desc = ctx.descriptorForClass(cls); + + if (desc == null) + throw new PortableException("Object is not portable: [class=" + cls + ']'); + + if (desc.excluded()) { + doWriteByte(NULL); + return; + } + + if (desc.useOptimizedMarshaller()) { writeByte(OPTM_MARSH); try { @@ -214,18 +223,6 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx return; } - cls = obj.getClass(); - - PortableClassDescriptor desc = ctx.descriptorForClass(cls); - - if (desc == null) - throw new PortableException("Object is not portable: [class=" + cls + ']'); - - if (desc.excluded()) { - doWriteByte(NULL); - return; - } - if (desc.getWriteReplaceMethod() != null) { Object replace; @@ -269,44 +266,6 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx desc.write(obj, this); } - /** - * Determines whether to use {@link org.apache.ignite.marshaller.optimized.OptimizedMarshaller} for serialization - * or not. - * - * @param obj Object to serialize. - * @return {@code true} if to use, {@code false} otherwise. - */ - private boolean useOptimizedMarshaller(Object obj) { - Class<?> cls = obj.getClass(); - - Boolean use = useOptMarshCache.get(cls); - - if (use != null) - return use; - - if (ctx.isPredefinedClass(cls)) - use = false; - else { - try { - Method writeObj = cls.getDeclaredMethod("writeObject", ObjectOutputStream.class); - Method readObj = cls.getDeclaredMethod("readObject", ObjectInputStream.class); - - if (!Modifier.isStatic(writeObj.getModifiers()) && !Modifier.isStatic(readObj.getModifiers()) && - writeObj.getReturnType() == void.class && readObj.getReturnType() == void.class) - use = true; - else - use = false; - - } catch (NoSuchMethodException e) { - use = false; - } - } - - useOptMarshCache.putIfAbsent(cls, use); - - return use; - } - /** * @param obj Object. * @return Handle. @@ -803,12 +762,12 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx if (tryWriteAsHandle(val)) return; - PortableContext.Type type = ctx.typeId(val.getClass().getComponentType()); + PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType()); doWriteByte(OBJ_ARR); - if (type.registered()) - doWriteInt(type.id()); + if (desc.registered()) + doWriteInt(desc.typeId()); else { doWriteInt(UNREGISTERED_TYPE_ID); doWriteString(val.getClass().getComponentType().getName()); @@ -887,12 +846,12 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx if (val == null) doWriteByte(NULL); else { - PortableContext.Type type = ctx.typeId(val.getClass()); + PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass()); doWriteByte(ENUM); - if (type.registered()) - doWriteInt(type.id()); + if (desc.registered()) + doWriteInt(desc.typeId()); else { doWriteInt(UNREGISTERED_TYPE_ID); doWriteString(val.getClass().getName()); @@ -911,12 +870,11 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx if (val == null) doWriteByte(NULL); else { - PortableContext.Type type = ctx.typeId(val.getClass().getComponentType()); - + PortableClassDescriptor desc = ctx.descriptorForClass(val.getClass().getComponentType()); doWriteByte(ENUM_ARR); - if (type.registered()) - doWriteInt(type.id()); + if (desc.registered()) + doWriteInt(desc.typeId()); else { doWriteInt(UNREGISTERED_TYPE_ID); doWriteString(val.getClass().getComponentType().getName()); @@ -937,12 +895,12 @@ public class PortableWriterExImpl implements PortableWriter, PortableRawWriterEx if (val == null) doWriteByte(NULL); else { - PortableContext.Type type = ctx.typeId(val); + PortableClassDescriptor desc = ctx.descriptorForClass(val); doWriteByte(CLASS); - if (type.registered()) - doWriteInt(type.id()); + if (desc.registered()) + doWriteInt(desc.typeId()); else { doWriteInt(UNREGISTERED_TYPE_ID); doWriteString(val.getClass().getName()); http://git-wip-us.apache.org/repos/asf/ignite/blob/e77e1c74/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java index 5f2b8d1..332a605 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/portable/GridPortableMarshallerSelfTest.java @@ -2249,20 +2249,19 @@ public class GridPortableMarshallerSelfTest extends GridCommonAbstractTest { PortableContext pCtx = initPortableContext(marsh); - Field field = pCtx.getClass().getDeclaredField("predefinedClasses"); + Field field = pCtx.getClass().getDeclaredField("predefinedTypeNames"); field.setAccessible(true); - Set<Class> value = (Set<Class>)field.get(pCtx); + Map<String, Integer> map = (Map<String, Integer>)field.get(pCtx); - assertTrue(value.size() > 0); + assertTrue(map.size() > 0); - for (Class pCls : value) { - PortableClassDescriptor desc = pCtx.descriptorForClass(pCls); + for (Map.Entry<String, Integer> entry : map.entrySet()) { + PortableClassDescriptor desc = pCtx.descriptorForTypeId(false, entry.getValue(), null); - assertEquals(desc.typeId(), pCtx.typeId(pCls).id()); - assertEquals(desc.typeId(), pCtx.typeId(pCls.getName())); - assertEquals(desc.typeId(), pCtx.typeId(pCtx.typeName(pCls.getName()))); + assertEquals(desc.typeId(), pCtx.typeId(desc.describedClass().getName())); + assertEquals(desc.typeId(), pCtx.typeId(pCtx.typeName(desc.describedClass().getName()))); } }
