You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/04/14 15:08:48 UTC
[09/14] ignite git commit: IGNITE-4938 De-pub of OptimizedMarshaller
- take 1
IGNITE-4938 De-pub of OptimizedMarshaller - take 1
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/faa8681a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/faa8681a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/faa8681a
Branch: refs/heads/ignite-4938
Commit: faa8681ab35e2332a7b16210492468495eb9518e
Parents: 5c48260
Author: Alexander Paschenko <al...@gmail.com>
Authored: Mon Apr 10 19:47:17 2017 +0300
Committer: Alexander Paschenko <al...@gmail.com>
Committed: Mon Apr 10 19:47:18 2017 +0300
----------------------------------------------------------------------
examples/config/filesystem/example-igfs.xml | 5 +-
.../MemcacheRestExampleNodeStartup.java | 7 -
.../optimized/OptimizedMarshallerAopTest.java | 1 +
modules/clients/src/test/config/jdbc-config.xml | 6 -
.../apache/ignite/IgniteSystemProperties.java | 2 +-
.../apache/ignite/internal/IgniteKernal.java | 2 +-
.../internal/binary/BinaryClassDescriptor.java | 2 +-
.../ignite/internal/binary/BinaryContext.java | 59 +-
.../GridClientOptimizedMarshaller.java | 2 +-
.../GridClientZipOptimizedMarshaller.java | 3 +-
.../optimized/OptimizedClassDescriptor.java | 1141 +++++++++
.../optimized/OptimizedFieldType.java | 50 +
.../optimized/OptimizedMarshaller.java | 313 +++
.../optimized/OptimizedMarshallerIdMapper.java | 33 +
.../optimized/OptimizedMarshallerUtils.java | 551 +++++
.../optimized/OptimizedObjectInputStream.java | 1231 ++++++++++
.../optimized/OptimizedObjectOutputStream.java | 875 +++++++
.../OptimizedObjectStreamRegistry.java | 244 ++
.../marshaller/optimized/package-info.java | 22 +
.../apache/ignite/marshaller/Marshaller.java | 2 -
.../ignite/marshaller/jdk/JdkMarshaller.java | 4 +-
.../optimized/OptimizedClassDescriptor.java | 1141 ---------
.../optimized/OptimizedFieldType.java | 50 -
.../optimized/OptimizedMarshaller.java | 313 ---
.../optimized/OptimizedMarshallerIdMapper.java | 33 -
.../optimized/OptimizedMarshallerUtils.java | 551 -----
.../optimized/OptimizedObjectInputStream.java | 1231 ----------
.../optimized/OptimizedObjectOutputStream.java | 875 -------
.../OptimizedObjectStreamRegistry.java | 244 --
.../marshaller/optimized/package-info.java | 22 -
.../resources/META-INF/classnames.properties | 2 +-
modules/core/src/test/config/example-cache.xml | 5 +-
modules/core/src/test/config/igfs-loopback.xml | 2 +-
modules/core/src/test/config/igfs-shmem.xml | 2 +-
.../src/test/config/spring-start-nodes-attr.xml | 2 +-
.../core/src/test/config/spring-start-nodes.xml | 2 +-
.../config/websession/example-cache-base.xml | 5 +-
.../IgniteExternalizableAbstractTest.java | 2 +-
...dbcPojoStoreOptimizedMarshallerSelfTest.java | 31 -
...ptimizedMarshallerWithSqlEscapeSelfTest.java | 28 -
.../apache/ignite/igfs/IgfsPathSelfTest.java | 2 +-
.../internal/GridLifecycleAwareSelfTest.java | 2 +-
.../managers/GridManagerStopSelfTest.java | 2 +-
.../GridDiscoveryManagerAttributesSelfTest.java | 4 +-
.../OptimizedMarshallerEnumSelfTest.java | 87 +
.../OptimizedMarshallerNodeFailoverTest.java | 357 +++
.../OptimizedMarshallerPooledSelfTest.java | 44 +
.../optimized/OptimizedMarshallerSelfTest.java | 283 +++
...arshallerSerialPersistentFieldsSelfTest.java | 114 +
.../optimized/OptimizedMarshallerTest.java | 790 +++++++
.../OptimizedObjectStreamSelfTest.java | 2157 ++++++++++++++++++
.../TestTcpDiscoveryIpFinderAdapter.java | 43 +
.../marshaller/optimized/package-info.java | 22 +
.../CacheStartupInDeploymentModesTest.java | 38 -
.../cache/GridCacheEntryMemorySizeSelfTest.java | 2 +-
...ridCacheStoreManagerDeserializationTest.java | 2 +-
.../cache/GridCacheVersionSelfTest.java | 2 +-
.../distributed/CacheAffinityEarlyTest.java | 7 +-
.../CacheGetFutureHangsSelfTest.java | 7 +-
.../IgniteCacheCreatePutMultiNodeSelfTest.java | 2 +-
.../distributed/IgniteCacheCreatePutTest.java | 2 +-
.../near/GridCacheNearTxForceKeyTest.java | 2 +-
.../CacheEntryProcessorNonSerializableTest.java | 4 +-
.../igfs/IgfsAbstractBaseSelfTest.java | 2 +-
.../processors/igfs/IgfsFileInfoSelfTest.java | 9 +-
.../service/ClosureServiceClientsNodesTest.java | 4 +-
...ent2ClassLoadersOptimizedMarshallerTest.java | 2 +-
...mentClassLoadingOptimizedMarshallerTest.java | 2 +-
...namicProxySerializationMultiJvmSelfTest.java | 14 -
.../GridMarshallerPerformanceTest.java | 10 +-
.../OptimizedMarshallerEnumSelfTest.java | 87 -
.../OptimizedMarshallerNodeFailoverTest.java | 357 ---
.../OptimizedMarshallerPooledSelfTest.java | 44 -
.../optimized/OptimizedMarshallerSelfTest.java | 283 ---
...arshallerSerialPersistentFieldsSelfTest.java | 114 -
.../optimized/OptimizedMarshallerTest.java | 790 -------
.../OptimizedObjectStreamSelfTest.java | 2157 ------------------
.../TestTcpDiscoveryIpFinderAdapter.java | 43 -
.../marshaller/optimized/package-info.java | 22 -
.../IgniteMessagingWithClientTest.java | 2 +-
...pClientDiscoveryMarshallerCheckSelfTest.java | 2 +-
.../TcpDiscoveryMarshallerCheckSelfTest.java | 2 +-
.../configvariations/ConfigVariations.java | 15 +-
.../junits/IgniteTestResources.java | 4 +-
.../testsuites/IgniteBinaryBasicTestSuite.java | 14 +-
.../ignite/testsuites/IgniteCacheTestSuite.java | 6 +-
...teBasicConfigVariationsFullApiTestSuite.java | 2 +-
.../IgniteMarshallerSelfTestSuite.java | 14 +-
...essagingConfigVariationFullApiTestSuite.java | 2 +-
...ServiceConfigVariationsFullApiTestSuite.java | 2 +-
.../webapp/META-INF/ignite-webapp-config.xml | 2 +-
.../test/config/hadoop-fs-open-test/grid-0.xml | 2 +-
.../test/config/hadoop-fs-open-test/grid-1.xml | 2 +-
.../test/config/hadoop-fs-open-test/grid-2.xml | 2 +-
.../test/config/igfs-cli-config-dual-async.xml | 2 +-
.../test/config/igfs-cli-config-dual-sync.xml | 2 +-
.../src/test/config/igfs-cli-config-primary.xml | 2 +-
.../src/test/config/igfs-cli-config-proxy.xml | 2 +-
.../IgniteHadoopFileSystemAbstractSelfTest.java | 2 +-
.../cache/IgniteCacheNoClassQuerySelfTest.java | 2 +-
.../h2/sql/AbstractH2CompareQueryTest.java | 4 +-
.../FetchingQueryCursorStressTest.java | 2 +-
.../Config/marshaller-invalid.xml | 2 +-
.../GridSpringBeanSerializationSelfTest.java | 2 +-
.../webapp2/META-INF/ignite-webapp-config.xml | 2 +-
.../ignite-int-max-values-offheap-config.xml | 2 +-
.../ignite-int-max-values-onheap-config.xml | 2 +-
.../ignite-int-max-values-swap-config.xml | 2 +-
modules/yardstick/config/ignite-jdbc-config.xml | 2 +-
109 files changed, 8483 insertions(+), 8633 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/examples/config/filesystem/example-igfs.xml
----------------------------------------------------------------------
diff --git a/examples/config/filesystem/example-igfs.xml b/examples/config/filesystem/example-igfs.xml
index 2236821..9e45450 100644
--- a/examples/config/filesystem/example-igfs.xml
+++ b/examples/config/filesystem/example-igfs.xml
@@ -51,10 +51,7 @@
-->
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="marshaller">
- <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller">
- <!-- Set to false to allow non-serializable objects in examples, default is true. -->
- <property name="requireSerializable" value="false"/>
- </bean>
+ <bean class="org.apache.ignite.internal.binary.BinaryMarshaller" />
</property>
<property name="fileSystemConfiguration">
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java b/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
index 3c835be..439e042 100644
--- a/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
+++ b/examples/src/main/java/org/apache/ignite/examples/misc/client/memcache/MemcacheRestExampleNodeStartup.java
@@ -23,7 +23,6 @@ import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.ConnectorConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -64,12 +63,6 @@ public class MemcacheRestExampleNodeStartup {
cfg.setConnectorConfiguration(new ConnectorConfiguration());
- OptimizedMarshaller marsh = new OptimizedMarshaller();
-
- marsh.setRequireSerializable(false);
-
- cfg.setMarshaller(marsh);
-
CacheConfiguration cacheCfg = new CacheConfiguration();
cacheCfg.setAtomicityMode(TRANSACTIONAL);
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
----------------------------------------------------------------------
diff --git a/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java b/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
index 7985fb2..428d8e0 100644
--- a/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
+++ b/modules/aop/src/test/java/org/apache/ignite/marshaller/optimized/OptimizedMarshallerAopTest.java
@@ -21,6 +21,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ignite.compute.gridify.Gridify;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.Event;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.lang.IgnitePredicate;
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/clients/src/test/config/jdbc-config.xml
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/config/jdbc-config.xml b/modules/clients/src/test/config/jdbc-config.xml
index 27d2617..b05fe64 100644
--- a/modules/clients/src/test/config/jdbc-config.xml
+++ b/modules/clients/src/test/config/jdbc-config.xml
@@ -31,12 +31,6 @@
<property name="localHost" value="127.0.0.1"/>
- <property name="marshaller">
- <bean class="org.apache.ignite.marshaller.optimized.OptimizedMarshaller">
- <property name="requireSerializable" value="false"/>
- </bean>
- </property>
-
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="ipFinder">
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 3c73bd5..446b9a5 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -23,8 +23,8 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.net.ssl.HostnameVerifier;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.jetbrains.annotations.Nullable;
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/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 6705393..74b4dcd 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
@@ -98,6 +98,7 @@ import org.apache.ignite.internal.managers.failover.GridFailoverManager;
import org.apache.ignite.internal.managers.indexing.GridIndexingManager;
import org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerManager;
import org.apache.ignite.internal.managers.swapspace.GridSwapSpaceManager;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.processors.GridProcessor;
import org.apache.ignite.internal.processors.affinity.GridAffinityProcessor;
import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
@@ -167,7 +168,6 @@ import org.apache.ignite.lifecycle.LifecycleAware;
import org.apache.ignite.lifecycle.LifecycleBean;
import org.apache.ignite.lifecycle.LifecycleEventType;
import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.mxbean.ClusterLocalNodeMetricsMXBean;
import org.apache.ignite.mxbean.IgniteMXBean;
import org.apache.ignite.mxbean.StripedExecutorMXBean;
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
index 92e4874..adbbc04 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryClassDescriptor.java
@@ -40,6 +40,7 @@ import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryReflectiveSerializer;
import org.apache.ignite.binary.BinarySerializer;
import org.apache.ignite.binary.Binarylizable;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
import org.apache.ignite.internal.processors.query.QueryUtils;
import org.apache.ignite.internal.util.GridUnsafe;
@@ -48,7 +49,6 @@ import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.marshaller.MarshallerExclusions;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.jetbrains.annotations.Nullable;
import static org.apache.ignite.internal.processors.query.QueryUtils.isGeometryClass;
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
index d918aa3..9227b82 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryContext.java
@@ -17,6 +17,33 @@
package org.apache.ignite.internal.binary;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentMap;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
@@ -24,10 +51,10 @@ import org.apache.ignite.binary.BinaryArrayIdentityResolver;
import org.apache.ignite.binary.BinaryBasicIdMapper;
import org.apache.ignite.binary.BinaryBasicNameMapper;
import org.apache.ignite.binary.BinaryIdMapper;
+import org.apache.ignite.binary.BinaryIdentityResolver;
import org.apache.ignite.binary.BinaryInvalidTypeException;
import org.apache.ignite.binary.BinaryNameMapper;
import org.apache.ignite.binary.BinaryObjectException;
-import org.apache.ignite.binary.BinaryIdentityResolver;
import org.apache.ignite.binary.BinaryReflectiveSerializer;
import org.apache.ignite.binary.BinarySerializer;
import org.apache.ignite.binary.BinaryType;
@@ -38,6 +65,7 @@ import org.apache.ignite.cache.affinity.AffinityKeyMapped;
import org.apache.ignite.configuration.BinaryConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.igfs.IgfsPath;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.processors.cache.binary.BinaryMetadataKey;
import org.apache.ignite.internal.processors.closure.GridClosureProcessor;
import org.apache.ignite.internal.processors.datastructures.CollocatedQueueItemKey;
@@ -89,38 +117,9 @@ import org.apache.ignite.lang.IgniteBiTuple;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.marshaller.MarshallerContext;
import org.apache.ignite.marshaller.MarshallerUtils;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.math.BigDecimal;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentMap;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
import static org.apache.ignite.internal.MarshallerPlatformIds.JAVA_ID;
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
index 6a4b5e8..257b34c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientOptimizedMarshaller.java
@@ -24,9 +24,9 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.internal.MarshallerContextImpl;
import org.apache.ignite.internal.client.marshaller.GridClientMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.plugin.PluginProvider;
import org.jetbrains.annotations.Nullable;
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
index b709634..1545444 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/marshaller/optimized/GridClientZipOptimizedMarshaller.java
@@ -26,12 +26,11 @@ import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
-
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.client.marshaller.GridClientMarshaller;
+import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.processors.rest.client.message.GridClientMessage;
import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.plugin.PluginProvider;
import org.jetbrains.annotations.Nullable;
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java
new file mode 100644
index 0000000..e34e8cc
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedClassDescriptor.java
@@ -0,0 +1,1141 @@
+/*
+ * 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.marshaller.optimized;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.SerializableTransient;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
+import org.apache.ignite.marshaller.MarshallerContext;
+import org.apache.ignite.marshaller.MarshallerExclusions;
+import org.apache.ignite.marshaller.MarshallerUtils;
+
+import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isPrivate;
+import static java.lang.reflect.Modifier.isStatic;
+import static java.lang.reflect.Modifier.isTransient;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.ARRAY_LIST;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BOOLEAN;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BOOLEAN_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BYTE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.BYTE_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.CHAR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.CHAR_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.CLS;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.DATE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.DOUBLE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.DOUBLE_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.ENUM;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.EXTERNALIZABLE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.FLOAT;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.FLOAT_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HASH_MAP;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HASH_SET;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.HASH_SET_MAP_OFF;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.INT_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_MAP;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_HASH_SET;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LINKED_LIST;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LONG;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.LONG_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.OBJ_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.PROPS;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.PROXY;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.SERIALIZABLE;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.SHORT;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.SHORT_ARR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.STR;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.UUID;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.classDescriptor;
+import static org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.computeSerialVersionUid;
+
+/**
+ * Class descriptor.
+ */
+class OptimizedClassDescriptor {
+ /** Class. */
+ private final Class<?> cls;
+
+ /** Context. */
+ private final MarshallerContext ctx;
+
+ /** */
+ private ConcurrentMap<Class, OptimizedClassDescriptor> clsMap;
+
+ /** ID mapper. */
+ private final OptimizedMarshallerIdMapper mapper;
+
+ /** Class name. */
+ private final String name;
+
+ /** Type ID. */
+ private final int typeId;
+
+ /** Short ID. */
+ private final short checksum;
+
+ /** Class type. */
+ private int type;
+
+ /** Primitive flag. */
+ private boolean isPrimitive;
+
+ /** Enum flag. */
+ private boolean isEnum;
+
+ /** Serializable flag. */
+ private boolean isSerial;
+
+ /** Excluded flag. */
+ private boolean excluded;
+
+ /** {@code True} if descriptor is for {@link Class}. */
+ private boolean isCls;
+
+ /** Enumeration values. */
+ private Object[] enumVals;
+
+ /** Constructor. */
+ private Constructor<?> constructor;
+
+ /** Fields. */
+ private Fields fields;
+
+ /** {@code writeObject} methods. */
+ private List<Method> writeObjMtds;
+
+ /** {@code writeReplace} method. */
+ private Method writeReplaceMtd;
+
+ /** {@code readObject} methods. */
+ private List<Method> readObjMtds;
+
+ /** {@code readResolve} method. */
+ private Method readResolveMtd;
+
+ /** Defaults field offset. */
+ private long dfltsFieldOff;
+
+ /** Load factor field offset. */
+ private long loadFactorFieldOff;
+
+ /** Access order field offset. */
+ private long accessOrderFieldOff;
+
+ /** Proxy interfaces. */
+ private Class<?>[] proxyIntfs;
+
+ /** Method returns serializable transient fields. */
+ private Method serTransMtd;
+
+ /**
+ * Creates descriptor for class.
+ *
+ * @param typeId Type ID.
+ * @param clsMap Class descriptors by class map.
+ * @param cls Class.
+ * @param ctx Context.
+ * @param mapper ID mapper.
+ * @throws IOException In case of error.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ OptimizedClassDescriptor(Class<?> cls,
+ int typeId,
+ ConcurrentMap<Class, OptimizedClassDescriptor> clsMap,
+ MarshallerContext ctx,
+ OptimizedMarshallerIdMapper mapper)
+ throws IOException {
+ this.cls = cls;
+ this.typeId = typeId;
+ this.clsMap = clsMap;
+ this.ctx = ctx;
+ this.mapper = mapper;
+
+ name = cls.getName();
+
+ excluded = MarshallerExclusions.isExcluded(cls);
+
+ if (!excluded) {
+ Class<?> parent;
+
+ if (cls == byte.class || cls == Byte.class) {
+ type = BYTE;
+
+ isPrimitive = true;
+ }
+ else if (cls == short.class || cls == Short.class) {
+ type = SHORT;
+
+ isPrimitive = true;
+ }
+ else if (cls == int.class || cls == Integer.class) {
+ type = INT;
+
+ isPrimitive = true;
+ }
+ else if (cls == long.class || cls == Long.class) {
+ type = LONG;
+
+ isPrimitive = true;
+ }
+ else if (cls == float.class || cls == Float.class) {
+ type = FLOAT;
+
+ isPrimitive = true;
+ }
+ else if (cls == double.class || cls == Double.class) {
+ type = DOUBLE;
+
+ isPrimitive = true;
+ }
+ else if (cls == char.class || cls == Character.class) {
+ type = CHAR;
+
+ isPrimitive = true;
+ }
+ else if (cls == boolean.class || cls == Boolean.class) {
+ type = BOOLEAN;
+
+ isPrimitive = true;
+ }
+ else if (cls == byte[].class)
+ type = BYTE_ARR;
+ else if (cls == short[].class)
+ type = SHORT_ARR;
+ else if (cls == int[].class)
+ type = INT_ARR;
+ else if (cls == long[].class)
+ type = LONG_ARR;
+ else if (cls == float[].class)
+ type = FLOAT_ARR;
+ else if (cls == double[].class)
+ type = DOUBLE_ARR;
+ else if (cls == char[].class)
+ type = CHAR_ARR;
+ else if (cls == boolean[].class)
+ type = BOOLEAN_ARR;
+ else if (cls.isArray())
+ type = OBJ_ARR;
+ else if (cls == String.class)
+ type = STR;
+ else if (cls.isEnum()) {
+ type = ENUM;
+
+ isEnum = true;
+ enumVals = cls.getEnumConstants();
+ }
+ // Support for enum constants, based on anonymous children classes.
+ else if ((parent = cls.getSuperclass()) != null && parent.isEnum()) {
+ type = ENUM;
+
+ isEnum = true;
+ enumVals = parent.getEnumConstants();
+ }
+ else if (cls == UUID.class)
+ type = UUID;
+ else if (cls == Properties.class) {
+ type = PROPS;
+
+ try {
+ dfltsFieldOff = GridUnsafe.objectFieldOffset(Properties.class.getDeclaredField("defaults"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == ArrayList.class)
+ type = ARRAY_LIST;
+ else if (cls == HashMap.class) {
+ type = HASH_MAP;
+
+ try {
+ loadFactorFieldOff = GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == HashSet.class) {
+ type = HASH_SET;
+
+ try {
+ loadFactorFieldOff = GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == LinkedList.class)
+ type = LINKED_LIST;
+ else if (cls == LinkedHashMap.class) {
+ type = LINKED_HASH_MAP;
+
+ try {
+ loadFactorFieldOff =
+ GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ accessOrderFieldOff =
+ GridUnsafe.objectFieldOffset(LinkedHashMap.class.getDeclaredField("accessOrder"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == LinkedHashSet.class) {
+ type = LINKED_HASH_SET;
+
+ try {
+ loadFactorFieldOff = GridUnsafe.objectFieldOffset(HashMap.class.getDeclaredField("loadFactor"));
+ }
+ catch (NoSuchFieldException e) {
+ throw new IOException(e);
+ }
+ }
+ else if (cls == Date.class)
+ type = DATE;
+ else if (cls == Class.class) {
+ type = CLS;
+
+ isCls = true;
+ }
+ else if (Proxy.class.isAssignableFrom(cls)) {
+ type = PROXY;
+
+ proxyIntfs = cls.getInterfaces();
+ }
+ else {
+ Class<?> c = cls;
+
+ while ((writeReplaceMtd == null || readResolveMtd == null) && c != null && !c.equals(Object.class)) {
+ if (writeReplaceMtd == null) {
+ try {
+ writeReplaceMtd = c.getDeclaredMethod("writeReplace");
+
+ if (!isStatic(writeReplaceMtd.getModifiers()) &&
+ !(isPrivate(writeReplaceMtd.getModifiers()) && c != cls) &&
+ writeReplaceMtd.getReturnType().equals(Object.class))
+ writeReplaceMtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ writeReplaceMtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ // No-op.
+ }
+ }
+
+ if (readResolveMtd == null) {
+ try {
+ readResolveMtd = c.getDeclaredMethod("readResolve");
+
+ if (!isStatic(readResolveMtd.getModifiers()) &&
+ !(isPrivate(readResolveMtd.getModifiers()) && c != cls) &&
+ readResolveMtd.getReturnType().equals(Object.class))
+ readResolveMtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ readResolveMtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ // No-op.
+ }
+ }
+
+ c = c.getSuperclass();
+ }
+
+ if (Externalizable.class.isAssignableFrom(cls)) {
+ type = EXTERNALIZABLE;
+
+ try {
+ constructor = !Modifier.isStatic(cls.getModifiers()) && cls.getDeclaringClass() != null ?
+ cls.getDeclaredConstructor(cls.getDeclaringClass()) :
+ cls.getDeclaredConstructor();
+
+ constructor.setAccessible(true);
+ }
+ catch (NoSuchMethodException e) {
+ throw new IOException("Externalizable class doesn't have default constructor: " + cls, e);
+ }
+ }
+ else {
+ type = SERIALIZABLE;
+
+ isSerial = Serializable.class.isAssignableFrom(cls);
+
+ writeObjMtds = new ArrayList<>();
+ readObjMtds = new ArrayList<>();
+ List<ClassFields> fields = new ArrayList<>();
+
+ for (c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
+ Method mtd;
+
+ try {
+ mtd = c.getDeclaredMethod("writeObject", ObjectOutputStream.class);
+
+ int mod = mtd.getModifiers();
+
+ if (!isStatic(mod) && isPrivate(mod) && mtd.getReturnType() == Void.TYPE)
+ mtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ mtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ mtd = null;
+ }
+
+ writeObjMtds.add(mtd);
+
+ try {
+ mtd = c.getDeclaredMethod("readObject", ObjectInputStream.class);
+
+ int mod = mtd.getModifiers();
+
+ if (!isStatic(mod) && isPrivate(mod) && mtd.getReturnType() == Void.TYPE)
+ mtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ mtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ mtd = null;
+ }
+
+ readObjMtds.add(mtd);
+
+ final SerializableTransient serTransAn = c.getAnnotation(SerializableTransient.class);
+
+ // Custom serialization policy for transient fields.
+ if (serTransAn != null) {
+ try {
+ serTransMtd = c.getDeclaredMethod(serTransAn.methodName(), cls, IgniteProductVersion.class);
+
+ int mod = serTransMtd.getModifiers();
+
+ if (isStatic(mod) && isPrivate(mod)
+ && serTransMtd.getReturnType() == String[].class)
+ serTransMtd.setAccessible(true);
+ else
+ // Set method back to null if it has incorrect signature.
+ serTransMtd = null;
+ }
+ catch (NoSuchMethodException ignored) {
+ serTransMtd = null;
+ }
+ }
+
+ Field[] clsFields0 = c.getDeclaredFields();
+
+ Map<String, Field> fieldNames = new HashMap<>();
+
+ for (Field f : clsFields0)
+ fieldNames.put(f.getName(), f);
+
+ List<FieldInfo> clsFields = new ArrayList<>(clsFields0.length);
+
+ boolean hasSerialPersistentFields = false;
+
+ try {
+ Field serFieldsDesc = c.getDeclaredField("serialPersistentFields");
+
+ int mod = serFieldsDesc.getModifiers();
+
+ if (serFieldsDesc.getType() == ObjectStreamField[].class &&
+ isPrivate(mod) && isStatic(mod) && isFinal(mod)) {
+ hasSerialPersistentFields = true;
+
+ serFieldsDesc.setAccessible(true);
+
+ ObjectStreamField[] serFields = (ObjectStreamField[]) serFieldsDesc.get(null);
+
+ for (int i = 0; i < serFields.length; i++) {
+ ObjectStreamField serField = serFields[i];
+
+ FieldInfo fieldInfo;
+
+ if (!fieldNames.containsKey(serField.getName())) {
+ fieldInfo = new FieldInfo(null,
+ serField.getName(),
+ -1,
+ fieldType(serField.getType()));
+ }
+ else {
+ Field f = fieldNames.get(serField.getName());
+
+ fieldInfo = new FieldInfo(f,
+ serField.getName(),
+ GridUnsafe.objectFieldOffset(f),
+ fieldType(serField.getType()));
+ }
+
+ clsFields.add(fieldInfo);
+ }
+ }
+ }
+ catch (NoSuchFieldException ignored) {
+ // No-op.
+ }
+ catch (IllegalAccessException e) {
+ throw new IOException("Failed to get value of 'serialPersistentFields' field in class: " +
+ cls.getName(), e);
+ }
+
+ if (!hasSerialPersistentFields) {
+ for (int i = 0; i < clsFields0.length; i++) {
+ Field f = clsFields0[i];
+
+ int mod = f.getModifiers();
+
+ if (!isStatic(mod) && !isTransient(mod)) {
+ FieldInfo fieldInfo = new FieldInfo(f, f.getName(),
+ GridUnsafe.objectFieldOffset(f), fieldType(f.getType()));
+
+ clsFields.add(fieldInfo);
+ }
+ }
+ }
+
+ Collections.sort(clsFields, new Comparator<FieldInfo>() {
+ @Override public int compare(FieldInfo t1, FieldInfo t2) {
+ return t1.name().compareTo(t2.name());
+ }
+ });
+
+ fields.add(new ClassFields(clsFields));
+ }
+
+ Collections.reverse(writeObjMtds);
+ Collections.reverse(readObjMtds);
+ Collections.reverse(fields);
+
+ this.fields = new Fields(fields);
+ }
+ }
+ }
+
+ checksum = computeSerialVersionUid(cls, fields != null ? fields.ownFields() : null);
+ }
+
+ /**
+ * @return Excluded flag.
+ */
+ boolean excluded() {
+ return excluded;
+ }
+
+ /**
+ * @return Class.
+ */
+ Class<?> describedClass() {
+ return cls;
+ }
+
+ /**
+ * @return Primitive flag.
+ */
+ boolean isPrimitive() {
+ return isPrimitive;
+ }
+
+ /**
+ * @return Enum flag.
+ */
+ boolean isEnum() {
+ return isEnum;
+ }
+
+ /**
+ * @return {@code True} if descriptor is for {@link Class}.
+ */
+ boolean isClass() {
+ return isCls;
+ }
+
+ /**
+ * @return {@code True} if descriptor is for {@link Proxy}.
+ */
+ boolean isProxy() {
+ return type == PROXY;
+ }
+
+ /**
+ * Replaces object.
+ *
+ * @param obj Object.
+ * @return Replaced object or {@code null} if there is no {@code writeReplace} method.
+ * @throws IOException In case of error.
+ */
+ Object replace(Object obj) throws IOException {
+ if (writeReplaceMtd != null) {
+ try {
+ return writeReplaceMtd.invoke(obj);
+ }
+ catch (IllegalAccessException | InvocationTargetException e) {
+ throw new IOException(e);
+ }
+ }
+
+ return obj;
+ }
+
+ /**
+ * Writes object to stream.
+ *
+ * @param out Output stream.
+ * @param obj Object.
+ * @throws IOException In case of error.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ void write(OptimizedObjectOutputStream out, Object obj) throws IOException {
+ out.write(type);
+
+ switch (type) {
+ case BYTE:
+ out.writeByte((Byte)obj);
+
+ break;
+
+ case SHORT:
+ out.writeShort((Short)obj);
+
+ break;
+
+ case INT:
+ out.writeInt((Integer)obj);
+
+ break;
+
+ case LONG:
+ out.writeLong((Long)obj);
+
+ break;
+
+ case FLOAT:
+ out.writeFloat((Float)obj);
+
+ break;
+
+ case DOUBLE:
+ out.writeDouble((Double)obj);
+
+ break;
+
+ case CHAR:
+ out.writeChar((Character)obj);
+
+ break;
+
+ case BOOLEAN:
+ out.writeBoolean((Boolean)obj);
+
+ break;
+
+ case BYTE_ARR:
+ out.writeByteArray((byte[])obj);
+
+ break;
+
+ case SHORT_ARR:
+ out.writeShortArray((short[])obj);
+
+ break;
+
+ case INT_ARR:
+ out.writeIntArray((int[])obj);
+
+ break;
+
+ case LONG_ARR:
+ out.writeLongArray((long[])obj);
+
+ break;
+
+ case FLOAT_ARR:
+ out.writeFloatArray((float[])obj);
+
+ break;
+
+ case DOUBLE_ARR:
+ out.writeDoubleArray((double[])obj);
+
+ break;
+
+ case CHAR_ARR:
+ out.writeCharArray((char[])obj);
+
+ break;
+
+ case BOOLEAN_ARR:
+ out.writeBooleanArray((boolean[])obj);
+
+ break;
+
+ case OBJ_ARR:
+ OptimizedClassDescriptor compDesc = classDescriptor(clsMap,
+ obj.getClass().getComponentType(),
+ ctx,
+ mapper);
+
+ compDesc.writeTypeData(out);
+
+ out.writeArray((Object[])obj);
+
+ break;
+
+ case STR:
+ out.writeString((String)obj);
+
+ break;
+
+ case UUID:
+ out.writeUuid((UUID)obj);
+
+ break;
+
+ case PROPS:
+ out.writeProperties((Properties)obj, dfltsFieldOff);
+
+ break;
+
+ case ARRAY_LIST:
+ out.writeArrayList((ArrayList<?>)obj);
+
+ break;
+
+ case HASH_MAP:
+ out.writeHashMap((HashMap<?, ?>)obj, loadFactorFieldOff, false);
+
+ break;
+
+ case HASH_SET:
+ out.writeHashSet((HashSet<?>)obj, HASH_SET_MAP_OFF, loadFactorFieldOff);
+
+ break;
+
+ case LINKED_LIST:
+ out.writeLinkedList((LinkedList<?>)obj);
+
+ break;
+
+ case LINKED_HASH_MAP:
+ out.writeLinkedHashMap((LinkedHashMap<?, ?>)obj, loadFactorFieldOff, accessOrderFieldOff, false);
+
+ break;
+
+ case LINKED_HASH_SET:
+ out.writeLinkedHashSet((LinkedHashSet<?>)obj, HASH_SET_MAP_OFF, loadFactorFieldOff);
+
+ break;
+
+ case DATE:
+ out.writeDate((Date)obj);
+
+ break;
+
+ case CLS:
+ OptimizedClassDescriptor clsDesc = classDescriptor(clsMap, (Class<?>)obj, ctx, mapper);
+
+ clsDesc.writeTypeData(out);
+
+ break;
+
+ case PROXY:
+ out.writeInt(proxyIntfs.length);
+
+ for (Class<?> intf : proxyIntfs) {
+ OptimizedClassDescriptor intfDesc = classDescriptor(clsMap, intf, ctx, mapper);
+
+ intfDesc.writeTypeData(out);
+ }
+
+ InvocationHandler ih = Proxy.getInvocationHandler(obj);
+
+ assert ih != null;
+
+ out.writeObject(ih);
+
+ break;
+
+ case ENUM:
+ writeTypeData(out);
+
+ out.writeInt(((Enum)obj).ordinal());
+
+ break;
+
+ case EXTERNALIZABLE:
+ writeTypeData(out);
+
+ out.writeShort(checksum);
+ out.writeExternalizable(obj);
+
+ break;
+
+ case SERIALIZABLE:
+ if (out.requireSerializable() && !isSerial)
+ throw new NotSerializableException("Must implement java.io.Serializable or " +
+ "set OptimizedMarshaller.setRequireSerializable() to false " +
+ "(note that performance may degrade if object is not Serializable): " + name);
+
+ writeTypeData(out);
+
+ out.writeShort(checksum);
+ out.writeSerializable(obj, writeObjMtds, serializableFields(obj.getClass(), obj, null));
+
+ break;
+
+ default:
+ throw new IllegalStateException("Invalid class type: " + type);
+ }
+ }
+
+ /**
+ * Gets list of serializable fields. If {@link #serTransMtd} method
+ * returns list of transient fields, they will be added to other fields.
+ * Transient fields that are not included in that list will be normally
+ * ignored.
+ *
+ * @param cls Class.
+ * @param obj Object.
+ * @param ver Job sender version.
+ * @return Serializable fields.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private Fields serializableFields(Class<?> cls, Object obj, IgniteProductVersion ver) {
+ if (serTransMtd == null)
+ return fields;
+
+ try {
+ final String[] transFields = (String[])serTransMtd.invoke(cls, obj, ver);
+
+ if (transFields == null || transFields.length == 0)
+ return fields;
+
+ List<FieldInfo> clsFields = new ArrayList<>();
+
+ clsFields.addAll(fields.fields.get(0).fields);
+
+ for (int i = 0; i < transFields.length; i++) {
+ final String fieldName = transFields[i];
+
+ final Field f = cls.getDeclaredField(fieldName);
+
+ FieldInfo fieldInfo = new FieldInfo(f, f.getName(),
+ GridUnsafe.objectFieldOffset(f), fieldType(f.getType()));
+
+ clsFields.add(fieldInfo);
+ }
+
+ Collections.sort(clsFields, new Comparator<FieldInfo>() {
+ @Override public int compare(FieldInfo t1, FieldInfo t2) {
+ return t1.name().compareTo(t2.name());
+ }
+ });
+
+ List<ClassFields> fields = new ArrayList<>();
+
+ fields.add(new ClassFields(clsFields));
+
+ return new Fields(fields);
+ }
+ catch (Exception ignored) {
+ return fields;
+ }
+ }
+
+ /**
+ * @param out Output stream.
+ * @throws IOException In case of error.
+ */
+ void writeTypeData(OptimizedObjectOutputStream out) throws IOException {
+ out.writeInt(typeId);
+
+ if (typeId == 0)
+ out.writeUTF(name);
+ }
+
+ /**
+ * Reads object from stream.
+ *
+ * @param in Input stream.
+ * @return Object.
+ * @throws ClassNotFoundException If class not found.
+ * @throws IOException In case of error.
+ */
+ Object read(OptimizedObjectInputStream in) throws ClassNotFoundException, IOException {
+ switch (type) {
+ case ENUM:
+ return enumVals[in.readInt()];
+
+ case EXTERNALIZABLE:
+ verifyChecksum(in.readShort());
+
+ return in.readExternalizable(constructor, readResolveMtd);
+
+ case SERIALIZABLE:
+ verifyChecksum(in.readShort());
+
+ // If no serialize method, then unmarshal as usual.
+ if (serTransMtd != null)
+ return in.readSerializable(cls, readObjMtds, readResolveMtd,
+ serializableFields(cls, null, MarshallerUtils.jobSenderVersion()));
+ else
+ return in.readSerializable(cls, readObjMtds, readResolveMtd, fields);
+
+ default:
+ assert false : "Unexpected type: " + type;
+
+ return null;
+ }
+ }
+
+ /**
+ * @param checksum Checksum.
+ * @throws ClassNotFoundException If checksum is wrong.
+ * @throws IOException In case of error.
+ */
+ private void verifyChecksum(short checksum) throws ClassNotFoundException, IOException {
+ if (checksum != this.checksum)
+ throw new ClassNotFoundException("Optimized stream class checksum mismatch " +
+ "(is same version of marshalled class present on all nodes?) " +
+ "[expected=" + this.checksum + ", actual=" + checksum + ", cls=" + cls + ']');
+ }
+
+ /**
+ * @param cls Class.
+ * @return Type.
+ */
+ @SuppressWarnings("IfMayBeConditional")
+ private OptimizedFieldType fieldType(Class<?> cls) {
+ OptimizedFieldType type;
+
+ if (cls == byte.class)
+ type = OptimizedFieldType.BYTE;
+ else if (cls == short.class)
+ type = OptimizedFieldType.SHORT;
+ else if (cls == int.class)
+ type = OptimizedFieldType.INT;
+ else if (cls == long.class)
+ type = OptimizedFieldType.LONG;
+ else if (cls == float.class)
+ type = OptimizedFieldType.FLOAT;
+ else if (cls == double.class)
+ type = OptimizedFieldType.DOUBLE;
+ else if (cls == char.class)
+ type = OptimizedFieldType.CHAR;
+ else if (cls == boolean.class)
+ type = OptimizedFieldType.BOOLEAN;
+ else
+ type = OptimizedFieldType.OTHER;
+
+ return type;
+ }
+
+ /**
+ * Information about one field.
+ */
+ @SuppressWarnings("PackageVisibleInnerClass")
+ static class FieldInfo {
+ /** Field. */
+ private final Field field;
+
+ /** Field offset. */
+ private final long fieldOffs;
+
+ /** Field type. */
+ private final OptimizedFieldType fieldType;
+
+ /** Field name. */
+ private final String fieldName;
+
+ /**
+ * @param field Field.
+ * @param name Field name.
+ * @param offset Field offset.
+ * @param type Grid optimized field type.
+ */
+ FieldInfo(Field field, String name, long offset, OptimizedFieldType type) {
+ this.field = field;
+ fieldOffs = offset;
+ fieldType = type;
+ fieldName = name;
+ }
+
+ /**
+ * @return Returns field.
+ */
+ Field field() {
+ return field;
+ }
+
+ /**
+ * @return Offset.
+ */
+ long offset() {
+ return fieldOffs;
+ }
+
+ /**
+ * @return Type.
+ */
+ OptimizedFieldType type() {
+ return fieldType;
+ }
+
+ /**
+ * @return Name.
+ */
+ String name() {
+ return fieldName;
+ }
+ }
+
+ /**
+ * Information about one class.
+ */
+ static class ClassFields {
+ /** Fields. */
+ private final List<FieldInfo> fields;
+
+ private final Map<String, Integer> nameToIndex;
+
+ /**
+ * @param fields Field infos.
+ */
+ ClassFields(List<FieldInfo> fields) {
+ this.fields = fields;
+
+ nameToIndex = U.newHashMap(fields.size());
+
+ for (int i = 0; i < fields.size(); ++i)
+ nameToIndex.put(fields.get(i).name(), i);
+ }
+
+ /**
+ * @return Class fields.
+ */
+ List<FieldInfo> fields() {
+ return fields;
+ }
+
+ /**
+ * @return Fields count.
+ */
+ int size() {
+ return fields.size();
+ }
+
+ /**
+ * @param i Field's index.
+ * @return FieldInfo.
+ */
+ FieldInfo get(int i) {
+ return fields.get(i);
+ }
+
+ /**
+ * @param name Field's name.
+ * @return Field's index.
+ */
+ int getIndex(String name) {
+ assert nameToIndex.containsKey(name);
+
+ return nameToIndex.get(name);
+ }
+ }
+
+ /**
+ * Encapsulates data about class fields.
+ */
+ @SuppressWarnings("PackageVisibleInnerClass")
+ static class Fields {
+ /** Fields. */
+ private final List<ClassFields> fields;
+
+ /** Own fields (excluding inherited). */
+ private final List<Field> ownFields;
+
+ /**
+ * Creates new instance.
+ *
+ * @param fields Fields.
+ */
+ Fields(List<ClassFields> fields) {
+ this.fields = fields;
+
+ if (fields.isEmpty())
+ ownFields = null;
+ else {
+ ownFields = new ArrayList<>(fields.size());
+
+ for (FieldInfo f : fields.get(fields.size() - 1).fields()) {
+ if (f.field() != null)
+ ownFields.add(f.field);
+ }
+ }
+ }
+
+ /**
+ * Returns class's own fields (excluding inherited).
+ *
+ * @return List of fields or {@code null} if fields list is empty.
+ */
+ List<Field> ownFields() {
+ return ownFields;
+ }
+
+ /**
+ * Returns field types and their offsets.
+ *
+ * @param i hierarchy level where 0 corresponds to top level.
+ * @return list of pairs where first value is field type and second value is its offset.
+ */
+ ClassFields fields(int i) {
+ return fields.get(i);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java
new file mode 100644
index 0000000..39cad13
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedFieldType.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.marshaller.optimized;
+
+/**
+ * Field type used to calculate {@code Unsafe} offsets into objects.
+ */
+enum OptimizedFieldType {
+ /** */
+ BYTE,
+
+ /** */
+ SHORT,
+
+ /** */
+ INT,
+
+ /** */
+ LONG,
+
+ /** */
+ FLOAT,
+
+ /** */
+ DOUBLE,
+
+ /** */
+ CHAR,
+
+ /** */
+ BOOLEAN,
+
+ /** */
+ OTHER
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java
new file mode 100644
index 0000000..f69c6dc
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshaller.java
@@ -0,0 +1,313 @@
+/*
+ * 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.marshaller.optimized;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller;
+import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentHashMap8;
+import sun.misc.Unsafe;
+
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID;
+
+/**
+ * Optimized implementation of {@link org.apache.ignite.marshaller.Marshaller}.
+ * Unlike {@link org.apache.ignite.marshaller.jdk.JdkMarshaller},
+ * which is based on standard {@link ObjectOutputStream}, this marshaller does not
+ * enforce that all serialized objects implement {@link Serializable} interface. It is also
+ * about 20 times faster as it removes lots of serialization overhead that exists in
+ * default JDK implementation.
+ * <p>
+ * {@code OptimizedMarshaller} is tested only on Java HotSpot VM on other VMs
+ * it could yield unexpected results. It is the default marshaller on Java HotSpot VMs
+ * and will be used if no other marshaller was explicitly configured.
+ * <p>
+ * <h1 class="header">Configuration</h1>
+ * <h2 class="header">Mandatory</h2>
+ * This marshaller has no mandatory configuration parameters.
+ * <h2 class="header">Java Example</h2>
+ * <pre name="code" class="java">
+ * OptimizedMarshaller marshaller = new OptimizedMarshaller();
+ *
+ * // Enforce Serializable interface.
+ * marshaller.setRequireSerializable(true);
+ *
+ * IgniteConfiguration cfg = new IgniteConfiguration();
+ *
+ * // Override marshaller.
+ * cfg.setMarshaller(marshaller);
+ *
+ * // Starts grid.
+ * G.start(cfg);
+ * </pre>
+ * <h2 class="header">Spring Example</h2>
+ * GridOptimizedMarshaller can be configured from Spring XML configuration file:
+ * <pre name="code" class="xml">
+ * <bean id="grid.custom.cfg" class="org.apache.ignite.configuration.IgniteConfiguration" singleton="true">
+ * ...
+ * <property name="marshaller">
+ * <bean class="OptimizedMarshaller">
+ * <property name="requireSerializable">true</property>
+ * </bean>
+ * </property>
+ * ...
+ * </bean>
+ * </pre>
+ * <p>
+ * <img src="http://ignite.apache.org/images/spring-small.png">
+ * <br>
+ * For information about Spring framework visit <a href="http://www.springframework.org/">www.springframework.org</a>
+ */
+public class OptimizedMarshaller extends AbstractNodeNameAwareMarshaller {
+ /** Use default {@code serialVersionUID} for {@link Serializable} classes. */
+ public static final boolean USE_DFLT_SUID =
+ IgniteSystemProperties.getBoolean(IGNITE_OPTIMIZED_MARSHALLER_USE_DEFAULT_SUID, false);
+
+ /** Default class loader. */
+ private final ClassLoader dfltClsLdr = getClass().getClassLoader();
+
+ /** Whether or not to require an object to be serializable in order to be marshalled. */
+ private boolean requireSer = true;
+
+ /** ID mapper. */
+ private OptimizedMarshallerIdMapper mapper;
+
+ /** Class descriptors by class. */
+ private final ConcurrentMap<Class, OptimizedClassDescriptor> clsMap = new ConcurrentHashMap8<>();
+
+ /**
+ * Creates new marshaller will all defaults.
+ *
+ * @throws IgniteException If this marshaller is not supported on the current JVM.
+ */
+ public OptimizedMarshaller() {
+ if (!available())
+ throw new IgniteException("Using OptimizedMarshaller on unsupported JVM version (some of " +
+ "JVM-private APIs required for the marshaller to work are missing).");
+ }
+
+ /**
+ * Creates new marshaller providing whether it should
+ * require {@link Serializable} interface or not.
+ *
+ * @param requireSer Whether to require {@link Serializable}.
+ */
+ public OptimizedMarshaller(boolean requireSer) {
+ this.requireSer = requireSer;
+ }
+
+ /**
+ * Sets whether marshaller should require {@link Serializable} interface or not.
+ *
+ * @param requireSer Whether to require {@link Serializable}.
+ * @return {@code this} for chaining.
+ */
+ public OptimizedMarshaller setRequireSerializable(boolean requireSer) {
+ this.requireSer = requireSer;
+
+ return this;
+ }
+
+ /**
+ * Sets ID mapper.
+ *
+ * @param mapper ID mapper.
+ * @return {@code this} for chaining.
+ */
+ public OptimizedMarshaller setIdMapper(OptimizedMarshallerIdMapper mapper) {
+ this.mapper = mapper;
+
+ return this;
+ }
+
+ /**
+ * 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.
+ * <p>
+ * Since each stream has an internal buffer, creating a stream for each thread can lead to
+ * high memory consumption if many large messages are marshalled or unmarshalled concurrently.
+ * Consider using pool in this case. This will limit number of streams that can be created and,
+ * therefore, decrease memory consumption.
+ * <p>
+ * NOTE: Using streams pool can decrease performance since streams will be shared between
+ * different threads which will lead to more frequent context switching.
+ *
+ * @param poolSize Streams pool size. If {@code 0}, pool is not used.
+ * @return {@code this} for chaining.
+ */
+ public OptimizedMarshaller setPoolSize(int poolSize) {
+ OptimizedObjectStreamRegistry.poolSize(poolSize);
+
+ return this;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void marshal0(@Nullable Object obj, OutputStream out) throws IgniteCheckedException {
+ assert out != null;
+
+ OptimizedObjectOutputStream objOut = null;
+
+ try {
+ objOut = OptimizedObjectStreamRegistry.out();
+
+ objOut.context(clsMap, ctx, mapper, requireSer);
+
+ objOut.out().outputStream(out);
+
+ objOut.writeObject(obj);
+ }
+ catch (IOException e) {
+ throw new IgniteCheckedException("Failed to serialize object: " + obj, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeOut(objOut);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected byte[] marshal0(@Nullable Object obj) throws IgniteCheckedException {
+ OptimizedObjectOutputStream objOut = null;
+
+ try {
+ objOut = OptimizedObjectStreamRegistry.out();
+
+ objOut.context(clsMap, ctx, mapper, requireSer);
+
+ objOut.writeObject(obj);
+
+ return objOut.out().array();
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to serialize object: " + obj, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeOut(objOut);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override protected <T> T unmarshal0(InputStream in, @Nullable ClassLoader clsLdr) throws IgniteCheckedException {
+ assert in != null;
+
+ OptimizedObjectInputStream objIn = null;
+
+ try {
+ objIn = OptimizedObjectStreamRegistry.in();
+
+ objIn.context(clsMap, ctx, mapper, clsLdr != null ? clsLdr : dfltClsLdr);
+
+ objIn.in().inputStream(in);
+
+ return (T)objIn.readObject();
+ }
+ catch (ClassNotFoundException e) {
+ throw new IgniteCheckedException("Failed to find class with given class loader for unmarshalling " +
+ "(make sure same versions of all classes are available on all nodes or enable peer-class-loading) " +
+ "[clsLdr=" + clsLdr + ", cls=" + e.getMessage() + "]", e);
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to deserialize object with given class loader: " + clsLdr, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeIn(objIn);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override protected <T> T unmarshal0(byte[] arr, @Nullable ClassLoader clsLdr) throws IgniteCheckedException {
+ assert arr != null;
+
+ OptimizedObjectInputStream objIn = null;
+
+ try {
+ objIn = OptimizedObjectStreamRegistry.in();
+
+ objIn.context(clsMap, ctx, mapper, clsLdr != null ? clsLdr : dfltClsLdr);
+
+ objIn.in().bytes(arr, arr.length);
+
+ return (T)objIn.readObject();
+ }
+ catch (ClassNotFoundException e) {
+ throw new IgniteCheckedException("Failed to find class with given class loader for unmarshalling " +
+ "(make sure same version of all classes are available on all nodes or enable peer-class-loading)" +
+ " [clsLdr=" + clsLdr + ", cls=" + e.getMessage() + "]", e);
+ }
+ catch (Exception e) {
+ throw new IgniteCheckedException("Failed to deserialize object with given class loader: " + clsLdr, e);
+ }
+ finally {
+ OptimizedObjectStreamRegistry.closeIn(objIn);
+ }
+ }
+
+ /**
+ * Checks whether {@code GridOptimizedMarshaller} is able to work on the current JVM.
+ * <p>
+ * As long as {@code GridOptimizedMarshaller} uses JVM-private API, which is not guaranteed
+ * to be available on all JVM, this method should be called to ensure marshaller could work properly.
+ * <p>
+ * Result of this method is automatically checked in constructor.
+ *
+ * @return {@code true} if {@code GridOptimizedMarshaller} can work on the current JVM or
+ * {@code false} if it can't.
+ */
+ @SuppressWarnings({"TypeParameterExtendsFinalClass", "ErrorNotRethrown"})
+ public static boolean available() {
+ try {
+ Class<? extends Unsafe> unsafeCls = Unsafe.class;
+
+ unsafeCls.getMethod("allocateInstance", Class.class);
+ unsafeCls.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
+
+ return true;
+ }
+ catch (Exception ignored) {
+ return false;
+ }
+ catch (NoClassDefFoundError ignored) {
+ return false;
+ }
+ }
+
+ /**
+ * Undeployment callback invoked when class loader is being undeployed.
+ *
+ * @param ldr Class loader being undeployed.
+ */
+ @Override public void onUndeploy(ClassLoader ldr) {
+ for (Class<?> cls : clsMap.keySet()) {
+ if (ldr.equals(cls.getClassLoader()))
+ clsMap.remove(cls);
+ }
+
+ U.clearClassCache(ldr);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/faa8681a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java b/modules/core/src/main/java/org/apache/ignite/internal/marshaller/optimized/OptimizedMarshallerIdMapper.java
new file mode 100644
index 0000000..381e5d0
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/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.internal.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);
+}
\ No newline at end of file