You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/01/18 09:24:10 UTC

[24/29] ignite git commit: IGNITE-2365 - Notify policy if swap or offheap is enabled and rebalanced entry was not preloaded. IGNITE-2099 - Fixing custom collections. This closes #396

IGNITE-2365 - Notify policy if swap or offheap is enabled and rebalanced entry was not preloaded.
IGNITE-2099 - Fixing custom collections.
This closes #396


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

Branch: refs/heads/ignite-2236
Commit: 6524c79629f587fb28bc43ddbef973aa2e83f66b
Parents: 2af1d9b
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Wed Jan 13 16:47:32 2016 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Fri Jan 15 10:27:48 2016 +0300

----------------------------------------------------------------------
 .../ignite/internal/binary/BinaryUtils.java     |  78 ++++++++
 .../processors/cache/CacheObjectContext.java    |  91 +++++----
 .../binary/CacheObjectBinaryProcessorImpl.java  |  33 ++--
 .../dht/preloader/GridDhtPartitionDemander.java |  11 +-
 .../binary/BinaryMarshallerSelfTest.java        |  44 ++++-
 .../cache/GridCacheDeploymentSelfTest.java      |   3 +-
 ...IgniteCacheGetCustomCollectionsSelfTest.java | 128 +++++++++++++
 ...gniteCacheLoadRebalanceEvictionSelfTest.java | 188 +++++++++++++++++++
 .../platform/PlatformComputeEchoTask.java       |   6 +-
 .../testsuites/IgniteCacheTestSuite4.java       |   5 +
 10 files changed, 515 insertions(+), 72 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
index 62a9d26..a82b65f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryUtils.java
@@ -590,6 +590,43 @@ public class BinaryUtils {
     }
 
     /**
+     * @param map Map to check.
+     * @return {@code True} if this map type is supported.
+     */
+    public static boolean knownMap(Object map) {
+        Class<?> cls = map == null ? null : map.getClass();
+
+        return cls == HashMap.class ||
+            cls == LinkedHashMap.class ||
+            cls == TreeMap.class ||
+            cls == ConcurrentHashMap8.class ||
+            cls == ConcurrentHashMap.class;
+    }
+
+    /**
+     * Attempts to create a new map of the same known type. Will return null if map type is not supported.
+     *
+     * @param map Map.
+     * @return New map of the same type or null.
+     */
+    public static <K, V> Map<K, V> newKnownMap(Object map) {
+        Class<?> cls = map == null ? null : map.getClass();
+
+        if (cls == HashMap.class)
+            return U.newHashMap(((Map)map).size());
+        else if (cls == LinkedHashMap.class)
+            return U.newLinkedHashMap(((Map)map).size());
+        else if (cls == TreeMap.class)
+            return new TreeMap<>(((TreeMap<Object, Object>)map).comparator());
+        else if (cls == ConcurrentHashMap8.class)
+            return new ConcurrentHashMap8<>(U.capacity(((Map)map).size()));
+        else if (cls == ConcurrentHashMap.class)
+            return new ConcurrentHashMap<>(U.capacity(((Map)map).size()));
+
+        return null;
+    }
+
+    /**
      * Attempts to create a new map of the same type as {@code map} has. Otherwise returns new {@code HashMap} instance.
      *
      * @param map Original map.
@@ -609,6 +646,47 @@ public class BinaryUtils {
     }
 
     /**
+     * @param col Collection to check.
+     * @return True if this is a collection of a known type.
+     */
+    public static boolean knownCollection(Object col) {
+        Class<?> cls = col == null ? null : col.getClass();
+
+        return cls == HashSet.class ||
+            cls == LinkedHashSet.class ||
+            cls == TreeSet.class ||
+            cls == ConcurrentSkipListSet.class ||
+            cls == ArrayList.class ||
+            cls == LinkedList.class;
+    }
+
+    /**
+     * Attempts to create a new collection of the same known type. Will return null if collection type is
+     * unknown.
+     *
+     * @param col Collection.
+     * @return New empty collection.
+     */
+    public static <V> Collection<V> newKnownCollection(Object col) {
+        Class<?> cls = col == null ? null : col.getClass();
+
+        if (cls == HashSet.class)
+            return U.newHashSet(((Collection)col).size());
+        else if (cls == LinkedHashSet.class)
+            return U.newLinkedHashSet(((Collection)col).size());
+        else if (cls == TreeSet.class)
+            return new TreeSet<>(((TreeSet<Object>)col).comparator());
+        else if (cls == ConcurrentSkipListSet.class)
+            return new ConcurrentSkipListSet<>(((ConcurrentSkipListSet<Object>)col).comparator());
+        else if (cls == ArrayList.class)
+            return new ArrayList<>(((Collection)col).size());
+        else if (cls == LinkedList.class)
+            return new LinkedList<>();
+
+        return null;
+    }
+
+    /**
      * Attempts to create a new set of the same type as {@code set} has. Otherwise returns new {@code HashSet} instance.
      *
      * @param set Original set.

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
index 7401434..d22bc75 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheObjectContext.java
@@ -19,8 +19,11 @@ package org.apache.ignite.internal.processors.cache;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
 import java.util.Map;
-import java.util.Set;
 import org.apache.ignite.cache.affinity.AffinityKeyMapper;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.binary.BinaryUtils;
@@ -161,13 +164,25 @@ import org.apache.ignite.internal.util.typedef.F;
      * @return Unwrapped collection.
      */
     public Collection<Object> unwrapBinariesIfNeeded(Collection<Object> col, boolean keepBinary, boolean cpy) {
-        if (col instanceof ArrayList)
-            return unwrapBinaries((ArrayList<Object>)col, keepBinary, cpy);
+        Collection<Object> col0 = BinaryUtils.newKnownCollection(col);
 
-        if (col instanceof Set)
-            return unwrapBinaries((Set<Object>)col, keepBinary, cpy);
+        if (col0 == null)
+            col0 = new ArrayList<>(col.size());
 
-        Collection<Object> col0 = new ArrayList<>(col.size());
+        for (Object obj : col)
+            col0.add(unwrapBinary(obj, keepBinary, cpy));
+
+        return col0;
+    }
+
+    /**
+     * @param col Collection to unwrap.
+     * @param keepBinary Keep binary flag.
+     * @param cpy Copy flag.
+     * @return Unwrapped collection.
+     */
+    private Collection<Object> unwrapKnownCollection(Collection<Object> col, boolean keepBinary, boolean cpy) {
+        Collection<Object> col0 = BinaryUtils.newKnownCollection(col);
 
         for (Object obj : col)
             col0.add(unwrapBinary(obj, keepBinary, cpy));
@@ -212,44 +227,6 @@ import org.apache.ignite.internal.util.typedef.F;
     }
 
     /**
-     * Unwraps array list.
-     *
-     * @param col List to unwrap.
-     * @return Unwrapped list.
-     */
-    private Collection<Object> unwrapBinaries(ArrayList<Object> col, boolean keepBinary, boolean cpy) {
-        int size = col.size();
-
-        col = new ArrayList<>(col);
-
-        for (int i = 0; i < size; i++) {
-            Object o = col.get(i);
-
-            Object unwrapped = unwrapBinary(o, keepBinary, cpy);
-
-            if (o != unwrapped)
-                col.set(i, unwrapped);
-        }
-
-        return col;
-    }
-
-    /**
-     * Unwraps set with binary.
-     *
-     * @param set Set to unwrap.
-     * @return Unwrapped set.
-     */
-    private Set<Object> unwrapBinaries(Set<Object> set, boolean keepBinary, boolean cpy) {
-        Set<Object> set0 = BinaryUtils.newSet(set);
-
-        for (Object obj : set)
-            set0.add(unwrapBinary(obj, keepBinary, cpy));
-
-        return set0;
-    }
-
-    /**
      * @param o Object to unwrap.
      * @return Unwrapped object.
      */
@@ -267,9 +244,9 @@ import org.apache.ignite.internal.util.typedef.F;
 
             return (key != uKey || val != uVal) ? F.t(uKey, uVal) : o;
         }
-        else if (o instanceof Collection)
-            return unwrapBinariesIfNeeded((Collection<Object>)o, keepBinary, cpy);
-        else if (o instanceof Map)
+        else if (BinaryUtils.knownCollection(o))
+            return unwrapKnownCollection((Collection<Object>)o, keepBinary, cpy);
+        else if (BinaryUtils.knownMap(o))
             return unwrapBinariesIfNeeded((Map<Object, Object>)o, keepBinary, cpy);
         else if (o instanceof Object[])
             return unwrapBinariesInArrayIfNeeded((Object[])o, keepBinary, cpy);
@@ -282,4 +259,24 @@ import org.apache.ignite.internal.util.typedef.F;
 
         return o;
     }
+
+    /**
+     * @param o Object to test.
+     * @return True if collection should be recursively unwrapped.
+     */
+    private boolean knownCollection(Object o) {
+        Class<?> cls = o == null ? null : o.getClass();
+
+        return cls == ArrayList.class || cls == LinkedList.class || cls == HashSet.class;
+    }
+
+    /**
+     * @param o Object to test.
+     * @return True if map should be recursively unwrapped.
+     */
+    private boolean knownMap(Object o) {
+        Class<?> cls = o == null ? null : o.getClass();
+
+        return cls == HashMap.class || cls == LinkedHashMap.class;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
index bcc2ab7..c9d6dad 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/CacheObjectBinaryProcessorImpl.java
@@ -402,31 +402,30 @@ public class CacheObjectBinaryProcessorImpl extends IgniteCacheObjectProcessorIm
             return new IgniteBiTuple<>(marshalToBinary(tup.get1()), marshalToBinary(tup.get2()));
         }
 
-        if (obj instanceof Collection) {
-            Collection<Object> col = (Collection<Object>)obj;
+        {
+            Collection<Object> pCol = BinaryUtils.newKnownCollection(obj);
 
-            Collection<Object> pCol;
+            if (pCol != null) {
+                Collection<?> col = (Collection<?>)obj;
 
-            if (col instanceof Set)
-                pCol = (Collection<Object>)BinaryUtils.newSet((Set<?>)col);
-            else
-                pCol = new ArrayList<>(col.size());
+                for (Object item : col)
+                    pCol.add(marshalToBinary(item));
 
-            for (Object item : col)
-                pCol.add(marshalToBinary(item));
-
-            return pCol;
+                return pCol;
+            }
         }
 
-        if (obj instanceof Map) {
-            Map<?, ?> map = (Map<?, ?>)obj;
+        {
+            Map<Object, Object> pMap = BinaryUtils.newKnownMap(obj);
 
-            Map<Object, Object> pMap = BinaryUtils.newMap((Map<Object, Object>)obj);
+            if (pMap != null) {
+                Map<?, ?> map = (Map<?, ?>)obj;
 
-            for (Map.Entry<?, ?> e : map.entrySet())
-                pMap.put(marshalToBinary(e.getKey()), marshalToBinary(e.getValue()));
+                for (Map.Entry<?, ?> e : map.entrySet())
+                    pMap.put(marshalToBinary(e.getKey()), marshalToBinary(e.getValue()));
 
-            return pMap;
+                return pMap;
+            }
         }
 
         if (obj instanceof Map.Entry) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
index 998f7a2..9553656 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
@@ -696,9 +696,14 @@ public class GridDhtPartitionDemander {
                                 (IgniteUuid)null, null, EVT_CACHE_REBALANCE_OBJECT_LOADED, entry.value(), true, null,
                                 false, null, null, null, true);
                     }
-                    else if (log.isDebugEnabled())
-                        log.debug("Rebalancing entry is already in cache (will ignore) [key=" + cached.key() +
-                            ", part=" + p + ']');
+                    else {
+                        if (cctx.isSwapOrOffheapEnabled())
+                            cctx.evicts().touch(cached, topVer); // Start tracking.
+
+                        if (log.isDebugEnabled())
+                            log.debug("Rebalancing entry is already in cache (will ignore) [key=" + cached.key() +
+                                ", part=" + p + ']');
+                    }
                 }
                 else if (log.isDebugEnabled())
                     log.debug("Rebalance predicate evaluated to false for entry (will ignore): " + entry);

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
index 20b2258..c347b9f 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryMarshallerSelfTest.java
@@ -113,7 +113,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
      * @throws Exception If failed.
      */
     public void testByte() throws Exception {
-        assertEquals((byte) 100, marshalUnmarshal((byte)100).byteValue());
+        assertEquals((byte)100, marshalUnmarshal((byte)100).byteValue());
     }
 
     /**
@@ -401,7 +401,7 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         CustomCollections cc = new CustomCollections();
 
         cc.list.add(1);
-        cc.customList.add(2);
+        cc.customList.add(new Value(1));
 
         CustomCollections copiedCc = marshalUnmarshal(cc);
 
@@ -415,6 +415,28 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Test serialization of custom collections.
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("unchecked")
+    public void testCustomCollections2() throws Exception {
+        CustomArrayList arrList = new CustomArrayList();
+
+        arrList.add(1);
+
+        Object cp = marshalUnmarshal(arrList);
+
+        assert cp.getClass().equals(CustomArrayList.class);
+
+        CustomArrayList customCp = (CustomArrayList)cp;
+
+        assertEquals(customCp.size(), arrList.size());
+
+        assertEquals(customCp.get(0), arrList.get(0));
+    }
+
+    /**
      * Test custom collections with factories.
      *
      * @throws Exception If failed.
@@ -3958,6 +3980,24 @@ public class BinaryMarshallerSelfTest extends GridCommonAbstractTest {
         private Value(int val) {
             this.val = val;
         }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (!(o instanceof Value))
+                return false;
+
+            Value value = (Value)o;
+
+            return val == value.val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val;
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
index c18554e..613e98c 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentSelfTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.cache;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
@@ -306,7 +307,7 @@ public class GridCacheDeploymentSelfTest extends GridCommonAbstractTest {
 
             assert cache != null;
 
-            cache.put(key, Arrays.asList(val1Cls.newInstance()));
+            cache.put(key, new ArrayList<>(Arrays.asList(val1Cls.newInstance())));
 
             info(">>>>>>> First put completed.");
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGetCustomCollectionsSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGetCustomCollectionsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGetCustomCollectionsSelfTest.java
new file mode 100644
index 0000000..aa6fbd5
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheGetCustomCollectionsSelfTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.processors.cache;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public class IgniteCacheGetCustomCollectionsSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setMarshaller(null);
+
+        final CacheConfiguration<String, MyMap> mapCacheConfig = new CacheConfiguration<>();
+
+        mapCacheConfig.setCacheMode(CacheMode.PARTITIONED);
+        mapCacheConfig.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
+        mapCacheConfig.setBackups(1);
+        mapCacheConfig.setName("cache");
+
+        cfg.setCacheConfiguration(mapCacheConfig);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testPutGet() throws Exception {
+        startGrids(3);
+
+        try {
+            IgniteEx ignite = grid(0);
+
+            IgniteCache<String, MyMap> cache = ignite.cache("cache");
+
+            Set<String> keys = new HashSet<>();
+
+            for (int i = 0; i < 100; i++) {
+                String key = "a" + i;;
+
+                MyMap map = new MyMap();
+
+                map.put("a", new Value());
+
+                cache.put(key, map);
+
+                map = cache.get(key);
+
+                keys.add(key);
+
+                Object a = map.get("a");
+
+                assertNotNull(a);
+                assertEquals(Value.class, a.getClass());
+            }
+
+            Map<String, MyMap> vals = cache.getAll(keys);
+
+            for (String key : keys) {
+                MyMap map = vals.get(key);
+
+                Object a = map.get("a");
+
+                assertNotNull(a);
+                assertEquals(Value.class, a.getClass());
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    private static class MyMap extends HashMap implements Serializable {
+
+    }
+
+    /**
+     *
+     */
+    private static class Value implements Serializable {
+        private int val;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheLoadRebalanceEvictionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheLoadRebalanceEvictionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheLoadRebalanceEvictionSelfTest.java
new file mode 100644
index 0000000..0b1e029
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheLoadRebalanceEvictionSelfTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.processors.cache;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import javax.cache.Cache;
+import javax.cache.configuration.FactoryBuilder;
+import javax.cache.integration.CacheLoaderException;
+import javax.cache.integration.CacheWriterException;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CacheAtomicityMode;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy;
+import org.apache.ignite.cache.store.CacheStoreAdapter;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.typedef.PA;
+import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class IgniteCacheLoadRebalanceEvictionSelfTest extends GridCommonAbstractTest {
+    /** */
+    public static final int LRU_MAX_SIZE = 10;
+
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final int ENTRIES_CNT = 10000;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+
+        LruEvictionPolicy evictionPolicy = new LruEvictionPolicy<>();
+        evictionPolicy.setMaxSize(LRU_MAX_SIZE);
+
+        CacheConfiguration<String, byte[]> cacheCfg = new CacheConfiguration<>();
+        cacheCfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
+        cacheCfg.setEvictSynchronized(false);
+        cacheCfg.setCacheMode(CacheMode.PARTITIONED);
+        cacheCfg.setBackups(1);
+        cacheCfg.setReadFromBackup(true);
+        cacheCfg.setEvictionPolicy(evictionPolicy);
+        cacheCfg.setOffHeapMaxMemory(1024 * 1024 * 1024L);
+        cacheCfg.setStatisticsEnabled(true);
+
+        cacheCfg.setWriteThrough(false);
+        cacheCfg.setReadThrough(false);
+
+        cacheCfg.setCacheStoreFactory(new FactoryBuilder.SingletonFactory(new Storage()));
+
+        cfg.setCacheConfiguration(cacheCfg);
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testStartRebalancing() throws Exception {
+        List<IgniteInternalFuture<Object>> futs = new ArrayList<>();
+
+        int gridCnt = 4;
+
+        for (int i = 0; i < gridCnt; i++) {
+            final IgniteEx ig = startGrid(i);
+
+            futs.add(GridTestUtils.runAsync(new Callable<Object>() {
+                @Override public Object call() throws Exception {
+                    ig.cache(null).localLoadCache(null);
+
+                    return null;
+                }
+            }));
+        }
+
+        try {
+            for (IgniteInternalFuture<Object> fut : futs)
+                fut.get();
+
+            for (int i = 0; i < gridCnt; i++) {
+                IgniteEx grid = grid(i);
+
+                final IgniteCache<Object, Object> cache = grid.cache(null);
+
+                GridTestUtils.waitForCondition(new PA() {
+                    @Override public boolean apply() {
+                        return cache.localSize(CachePeekMode.ONHEAP) <= 10;
+                    }
+                }, getTestTimeout());
+            }
+        }
+        finally {
+            stopAllGrids();
+        }
+    }
+
+    /**
+     *
+     */
+    private static class Storage extends CacheStoreAdapter<Integer, byte[]> implements Serializable {
+        /** */
+        private static final byte[] data = new byte[1024];
+
+        /** {@inheritDoc} */
+        @Override public void write(Cache.Entry<? extends Integer, ? extends byte[]> e) throws CacheWriterException {
+            throw new UnsupportedOperationException("Unsupported");
+        }
+
+        /** {@inheritDoc} */
+        @Override public void writeAll(Collection<Cache.Entry<? extends Integer, ? extends byte[]>> entries)
+            throws CacheWriterException {
+            throw new UnsupportedOperationException("Unsupported");
+        }
+
+        /** {@inheritDoc} */
+        @Override public void delete(Object key) throws CacheWriterException {
+            throw new UnsupportedOperationException("Unsupported");
+        }
+
+        /** {@inheritDoc} */
+        @Override public void deleteAll(Collection<?> keys) throws CacheWriterException {
+            throw new UnsupportedOperationException("Unsupported");
+        }
+
+        /** {@inheritDoc} */
+        @Override public byte[] load(Integer key) throws CacheLoaderException {
+            return data;
+        }
+
+        /** {@inheritDoc} */
+        @Override public Map<Integer, byte[]> loadAll(Iterable<? extends Integer> keys) throws CacheLoaderException {
+            Map<Integer, byte[]> res = new HashMap<>();
+
+            for (Integer key : keys)
+                res.put(key, data);
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public void loadCache(IgniteBiInClosure<Integer, byte[]> clo,
+            @Nullable Object... args) throws CacheLoaderException {
+
+            for (int i = 0; i < ENTRIES_CNT; i++)
+                clo.apply(i, data);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
index 03ab998..e945ada 100644
--- a/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
+++ b/modules/core/src/test/java/org/apache/ignite/platform/PlatformComputeEchoTask.java
@@ -17,6 +17,8 @@
 
 package org.apache.ignite.platform;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteException;
@@ -160,10 +162,10 @@ public class PlatformComputeEchoTask extends ComputeTaskAdapter<Integer, Object>
                     return new int[] { 1 };
 
                 case TYPE_COLLECTION:
-                    return Collections.singletonList(1);
+                    return new ArrayList<>(Collections.singletonList(1));
 
                 case TYPE_MAP:
-                    return Collections.singletonMap(1, 1);
+                    return new HashMap<>(Collections.singletonMap(1, 1));
 
                 case TYPE_BINARY:
                     return new PlatformComputeBinarizable(1);

http://git-wip-us.apache.org/repos/asf/ignite/blob/6524c796/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
index fcc8d37..1b8eeda 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite4.java
@@ -19,6 +19,7 @@ package org.apache.ignite.testsuites;
 
 import junit.framework.TestSuite;
 import org.apache.ignite.cache.store.jdbc.CacheJdbcStoreSessionListenerSelfTest;
+import org.apache.ignite.internal.processors.cache.IgniteCacheGetCustomCollectionsSelfTest;
 import org.apache.ignite.internal.processors.GridCacheTxLoadFromStoreOnLockSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheClientStoreSelfTest;
 import org.apache.ignite.internal.processors.cache.CacheOffheapMapEntrySelfTest;
@@ -57,6 +58,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheConfigurationDefau
 import org.apache.ignite.internal.processors.cache.IgniteCacheConfigurationTemplateTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheDynamicStopSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheInvokeReadThroughTest;
+import org.apache.ignite.internal.processors.cache.IgniteCacheLoadRebalanceEvictionSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheTxCopyOnReadDisabledTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheTxLocalPeekModesTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheTxLocalStoreValueTest;
@@ -286,6 +288,9 @@ public class IgniteCacheTestSuite4 extends TestSuite {
 
         suite.addTestSuite(IgniteCacheSingleGetMessageTest.class);
 
+        suite.addTestSuite(IgniteCacheGetCustomCollectionsSelfTest.class);
+        suite.addTestSuite(IgniteCacheLoadRebalanceEvictionSelfTest.class);
+
         return suite;
     }
 }
\ No newline at end of file