You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/03 07:21:39 UTC

[01/50] [abbrv] ignite git commit: Minor fix: missing toString() method.

Repository: ignite
Updated Branches:
  refs/heads/ignite-gg-8.0.3.ea6-clients-test [created] eaf62e080


Minor fix: missing toString() method.

(cherry picked from commit 571586c)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 63e6a2189814fb0b3c6b808f02fe2de81c19a5b0
Parents: 10f6cbb
Author: Vasiliy Sisko <vs...@gridgain.com>
Authored: Wed Feb 15 11:08:23 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Feb 15 11:13:33 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/visor/cache/VisorCacheTypeMetadata.java    | 6 ++++++
 1 file changed, 6 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/63e6a218/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
index f17e588..c87ad05 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/cache/VisorCacheTypeMetadata.java
@@ -32,6 +32,7 @@ import org.apache.ignite.cache.store.jdbc.JdbcType;
 import org.apache.ignite.cache.store.jdbc.JdbcTypeField;
 import org.apache.ignite.internal.LessNamingBean;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiTuple;
 
@@ -372,4 +373,9 @@ public class VisorCacheTypeMetadata implements Serializable, LessNamingBean {
     public Map<String, LinkedHashMap<String, IgniteBiTuple<String, Boolean>>> grps() {
         return grps;
     }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(VisorCacheTypeMetadata.class, this);
+    }
 }


[36/50] [abbrv] ignite git commit: Merge remote-tracking branch 'origin/ignite-gg-8.0.3.ea3' into ignite-gg-12061

Posted by sb...@apache.org.
Merge remote-tracking branch 'origin/ignite-gg-8.0.3.ea3' into ignite-gg-12061


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 565602fb1a0ee920662ed38d9ee7722d155f07d3
Parents: ef4238f 719fb5a
Author: EdShangGG <es...@gridgain.com>
Authored: Wed Mar 29 14:21:12 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Wed Mar 29 14:21:12 2017 +0300

----------------------------------------------------------------------
 .../cache/database/freelist/PagesList.java      | 221 +++++++----
 .../resources/META-INF/classnames.properties    |  27 +-
 .../ignite/cache/LargeEntryUpdateTest.java      | 177 +++++++++
 .../database/IgniteDbAbstractTest.java          | 391 +++++++++++++++++++
 .../IgniteDbMemoryLeakAbstractTest.java         | 265 +++++++++++++
 .../IgniteDbMemoryLeakLargeObjectsTest.java     |  56 +++
 .../IgniteDbMemoryLeakLargePagesTest.java       |  33 ++
 .../IgniteDbMemoryLeakNonTransactionalTest.java |  31 ++
 .../database/IgniteDbMemoryLeakTest.java        |  46 +++
 .../IgniteDbMemoryLeakWithExpirationTest.java   |  44 +++
 .../database/IgniteDbPutGetAbstractTest.java    | 357 +----------------
 .../testsuites/IgniteDbMemoryLeakTestSuite.java |  49 +++
 .../database/IgniteDbMemoryLeakIndexedTest.java |  33 ++
 .../IgniteDbMemoryLeakSqlQueryTest.java         |  76 ++++
 ...IgniteDbMemoryLeakWithIndexingTestSuite.java |  40 ++
 15 files changed, 1407 insertions(+), 439 deletions(-)
----------------------------------------------------------------------



[50/50] [abbrv] ignite git commit: clients start test

Posted by sb...@apache.org.
clients start test


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: eaf62e0808db08077b48327e4a723c41c289ae3a
Parents: 58b6e05
Author: sboikov <sb...@gridgain.com>
Authored: Wed May 3 10:20:49 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Wed May 3 10:20:49 2017 +0300

----------------------------------------------------------------------
 .../CacheClientsConcurrentStartTest.java        | 248 +++++++++++++++++++
 1 file changed, 248 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/eaf62e08/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheClientsConcurrentStartTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheClientsConcurrentStartTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheClientsConcurrentStartTest.java
new file mode 100644
index 0000000..44425f1
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/CacheClientsConcurrentStartTest.java
@@ -0,0 +1,248 @@
+/*
+ * 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.distributed;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteAtomicSequence;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.CacheAtomicityMode;
+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.IgniteInternalFuture;
+import org.apache.ignite.internal.TestRecordingCommunicationSpi;
+import org.apache.ignite.internal.managers.communication.GridIoMessage;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.marshaller.optimized.OptimizedMarshaller;
+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.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage;
+import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCustomEventMessage;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.*;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.*;
+
+/**
+ *
+ */
+public class CacheClientsConcurrentStartTest extends GridCommonAbstractTest {
+    /** */
+    private static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+    /** */
+    private static final int SRV_CNT = 4;
+
+    /** */
+    private static final int CLIENTS_CNT = 16;
+
+    /** */
+    private static final int CACHES = 30;
+
+    /** Stopped. */
+    private volatile boolean stopped;
+
+    /** Iteration. */
+    private static final int ITERATIONS = 2;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        TcpDiscoverySpi testSpi = new TcpDiscoverySpi() {
+            @Override protected void writeToSocket(Socket sock, OutputStream out, TcpDiscoveryAbstractMessage msg, long timeout) throws IOException, IgniteCheckedException {
+                if (msg instanceof TcpDiscoveryCustomEventMessage && msg.verified()) {
+                    try {
+                        System.out.println(Thread.currentThread().getName() + " delay custom message");
+
+                        U.sleep(ThreadLocalRandom.current().nextLong(500) + 100);
+                    }
+                    catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+
+                super.writeToSocket(sock, out, msg, timeout);
+            }
+        };
+
+        ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(ipFinder);
+
+        cfg.setMarshaller(null);
+
+        cfg.setCommunicationSpi(new TestRecordingCommunicationSpi());
+
+        if (getTestGridIndex(gridName) >= SRV_CNT)
+            cfg.setClientMode(true);
+        else {
+            CacheConfiguration ccfgs[] = new CacheConfiguration[CACHES / 2];
+
+            for (int i = 0; i < ccfgs.length; i++)
+                ccfgs[i] = cacheConfiguration("cache-" + i);
+
+            cfg.setCacheConfiguration(ccfgs);
+        }
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long getTestTimeout() {
+        return 10 * 60 * 1000L;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testStartNodes() throws Exception {
+        for (int i = 0; i < ITERATIONS; i++) {
+            try {
+                log.info("Iteration: " + (i + 1) + '/' + ITERATIONS);
+
+                doTest();
+            }
+            finally {
+                stopAllGrids(true);
+            }
+        }
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    private void doTest() throws Exception {
+        final AtomicBoolean failed = new AtomicBoolean();
+
+        startGrids(SRV_CNT);
+
+        for (int i = 0; i < SRV_CNT; i++) {
+            ((TestRecordingCommunicationSpi)ignite(i).configuration().getCommunicationSpi()).blockMessages(new IgnitePredicate<GridIoMessage>() {
+                @Override public boolean apply(GridIoMessage msg) {
+                    if (msg.message() instanceof GridDhtPartitionsFullMessage) {
+                        try {
+                            U.sleep(ThreadLocalRandom.current().nextLong(500) + 100);
+                        }
+                        catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+
+                    return false;
+                }
+            });
+        }
+
+        List<IgniteInternalFuture<?>> futs = new ArrayList<>();
+
+        for (int i = 0; i < CLIENTS_CNT; i++) {
+            final int idx = i;
+
+            IgniteInternalFuture<?> fut = multithreadedAsync(new Runnable() {
+                @Override public void run() {
+                    Random rnd = new Random();
+
+                    try {
+                        Ignite ignite = startGrid(SRV_CNT + idx);
+
+                        assertTrue(ignite.configuration().isClientMode());
+
+                        for (int i = 0; i < CACHES / 2; i++) {
+                            String cacheName = "cache-" + rnd.nextInt(CACHES);
+
+                            IgniteCache<Object, Object> cache = getCache(ignite, cacheName);
+
+                            cache.put(ignite.cluster().localNode().id(), UUID.randomUUID());
+
+                            IgniteAtomicSequence seq = ignite.atomicSequence("seq-" + rnd.nextInt(20), 0, true);
+
+                            seq.getAndIncrement();
+                        }
+
+                        while (!stopped) {
+                            IgniteCache<Object, Object> cache = getCache(ignite, "cache-" + rnd.nextInt(CACHES));
+
+                            int val = Math.abs(rnd.nextInt(100));
+
+                            if (val >= 0 && val < 40)
+                                cache.containsKey(ignite.cluster().localNode().id());
+                            else if (val >= 40 && val < 80)
+                                cache.get(ignite.cluster().localNode().id());
+                            else
+                                cache.put(ignite.cluster().localNode().id(), UUID.randomUUID());
+
+                            Thread.sleep(10);
+                        }
+                    }
+                    catch (Exception e) {
+                        log.error("Unexpected error: " + e, e);
+
+                        failed.set(true);
+                    }
+                }
+            }, 1, "client-thread");
+
+            futs.add(fut);
+        }
+
+        Thread.sleep(10_000);
+
+        stopped = true;
+
+        for (IgniteInternalFuture<?> fut : futs)
+            fut.get();
+
+        assertFalse(failed.get());
+    }
+
+    /**
+     * @param grid Grid.
+     * @return Cache.
+     */
+    private IgniteCache getCache(Ignite grid, String cacheName) {
+        return grid.getOrCreateCache(cacheConfiguration(cacheName));
+    }
+
+    private CacheConfiguration cacheConfiguration(String cacheName) {
+        CacheConfiguration ccfg = defaultCacheConfiguration();
+
+        ccfg.setName(cacheName);
+        ccfg.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg.setCacheMode(CacheMode.PARTITIONED);
+        ccfg.setBackups(2);
+        ccfg.setNearConfiguration(null);
+        ccfg.setAtomicityMode(TRANSACTIONAL);
+
+        return ccfg;
+    }
+}
\ No newline at end of file


[25/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -introducing SnapshotOperationFuture -adding to API gettingOngoingOperation

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-introducing SnapshotOperationFuture
-adding to API gettingOngoingOperation


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: d37d4df928ae2c9a1ba8cb5a236e4c3a7ab1b361
Parents: b51a2f8
Author: Eduard Shangareev <es...@gridgain.com>
Authored: Mon Mar 13 11:33:55 2017 +0300
Committer: Eduard Shangareev <es...@gridgain.com>
Committed: Mon Mar 13 11:33:55 2017 +0300

----------------------------------------------------------------------
 ...ishSnapshotOperationAckDiscoveryMessage.java | 74 ++++++++++++++++++++
 .../pagemem/snapshot/SnapshotOperation.java     | 10 +++
 .../StartSnapshotOperationDiscoveryMessage.java | 35 +++++++--
 .../IgniteCacheDatabaseSharedManager.java       | 10 +--
 .../GridDhtPartitionsExchangeFuture.java        |  7 +-
 5 files changed, 123 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d37d4df9/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
new file mode 100644
index 0000000..e19ddc4
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
@@ -0,0 +1,74 @@
+/*
+ * 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.pagemem.snapshot;
+
+import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class FinishSnapshotOperationAckDiscoveryMessage implements DiscoveryCustomMessage {
+    /** Id. */
+    private final IgniteUuid id = IgniteUuid.randomUuid();
+
+    /** Op id. */
+    private final IgniteUuid opId;
+
+    /** Success. */
+    private final boolean success;
+
+    /**
+     * @param opId Op id.
+     * @param success Success.
+     */
+    public FinishSnapshotOperationAckDiscoveryMessage(IgniteUuid opId, boolean success) {
+        this.opId = opId;
+        this.success = success;
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteUuid id() {
+        return id;
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public DiscoveryCustomMessage ackMessage() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isMutable() {
+        return false;
+    }
+
+    /**
+     * @return Op id.
+     */
+    public IgniteUuid operationId() {
+        return opId;
+    }
+
+    /**
+     * @return Success.
+     */
+    public boolean success() {
+        return success;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/d37d4df9/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
index f3b5eee..36577a6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -154,4 +154,14 @@ public class SnapshotOperation implements Serializable {
         result = 31 * result + (extraParam != null ? extraParam.hashCode() : 0);
         return result;
     }
+
+    @Override public String toString() {
+        return "SnapshotOperation{" +
+                "type=" + type +
+                ", snapshotId=" + snapshotId +
+                ", cacheNames=" + cacheNames +
+                ", msg='" + msg + '\'' +
+                ", extraParam=" + extraParam +
+                '}';
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d37d4df9/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
index 2373a9b..700f404 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
@@ -21,6 +21,8 @@ package org.apache.ignite.internal.pagemem.snapshot;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
+
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.lang.IgniteUuid;
@@ -33,8 +35,11 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
     /** */
     private static final long serialVersionUID = 0L;
 
+    /** Id. */
+    private IgniteUuid id = IgniteUuid.randomUuid();
+
     /** Custom message ID. */
-    private IgniteUuid id;
+    private IgniteUuid operationId;
 
     /** Snapshot operation. */
     private SnapshotOperation snapshotOperation;
@@ -42,6 +47,9 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
     /** */
     private UUID initiatorId;
 
+    /** Validated by coordinator. */
+    private boolean validatedByCoordinator = false;
+
     /** Error. */
     private Exception err;
 
@@ -56,11 +64,11 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
      * @param initiatorId initiator node id
      */
     public StartSnapshotOperationDiscoveryMessage(
-        IgniteUuid id,
+        IgniteUuid operationId,
         SnapshotOperation snapshotOperation,
         UUID initiatorId
     ) {
-        this.id = id;
+        this.operationId = operationId;
         this.snapshotOperation = snapshotOperation;
         this.initiatorId = initiatorId;
     }
@@ -98,7 +106,7 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
     /**
      * @return Initiator node id.
      */
-    public UUID initiatorId() {
+    public UUID initiatorNodeId() {
         return initiatorId;
     }
 
@@ -107,6 +115,11 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
         return id;
     }
 
+    /** {@inheritDoc} */
+    public IgniteUuid operationId() {
+        return operationId;
+    }
+
     /**
      * @param cacheId Cache id.
      */
@@ -129,6 +142,16 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
         return lastSnapshotIdForCache.get(cacheId);
     }
 
+    /** @return Validated by coordinator. */
+    public boolean validatedByCoordinator() {
+        return validatedByCoordinator;
+    }
+
+    /** Validated by coordinator. */
+    public void validatedByCoordinator(boolean validatedByCoordinator) {
+        this.validatedByCoordinator = validatedByCoordinator;
+    }
+
     /**
      * @param cacheId Cache id.
      * @param id Id.
@@ -140,11 +163,11 @@ public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMe
     /** {@inheritDoc} */
     @Nullable @Override public DiscoveryCustomMessage ackMessage() {
         return new StartSnapshotOperationAckDiscoveryMessage(
-            id,
+            operationId,
             snapshotOperation,
             lastFullSnapshotIdForCache,
             lastSnapshotIdForCache,
-            err,
+            err != null ? err : (validatedByCoordinator? null : new IgniteException("Coordinator didn't validate operation!")),
             initiatorId);
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d37d4df9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index 95ed3ae..3380e16 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@ -19,9 +19,9 @@ package org.apache.ignite.internal.processors.cache.database;
 
 import java.io.File;
 import java.util.Collection;
+import java.util.UUID;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.MemoryConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -29,7 +29,7 @@ import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.file.MappedFileMemoryProvider;
 import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
 import org.apache.ignite.internal.pagemem.PageMemory;
-import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
+import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperation;
 import org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedManagerAdapter;
@@ -208,11 +208,13 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
     }
 
     /**
-     * @param snapshotMsg Snapshot message.
+     * @param initiatorNodeId Snapshot message.
+     * @param snapshotOperation
      * @return Snapshot creation init future or {@code null} if snapshot is not available.
      * @throws IgniteCheckedException If failed.
      */
-    @Nullable public IgniteInternalFuture startLocalSnapshotOperation(StartSnapshotOperationAckDiscoveryMessage snapshotMsg)
+    @Nullable public IgniteInternalFuture startLocalSnapshotOperation(UUID initiatorNodeId,
+        SnapshotOperation snapshotOperation)
         throws IgniteCheckedException {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d37d4df9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 4c179e6..925848b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -889,11 +889,12 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
-     * @param snapshotOperationMsg Snapshot operation message.
+     * @param snapOpMsg Snapshot operation message.
      */
-    private void startLocalSnasphotOperation(StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg
+    private void startLocalSnasphotOperation(StartSnapshotOperationAckDiscoveryMessage snapOpMsg
     ) throws IgniteCheckedException {
-        IgniteInternalFuture fut = cctx.database().startLocalSnapshotOperation(snapshotOperationMsg);
+        IgniteInternalFuture fut = cctx.database()
+            .startLocalSnapshotOperation(snapOpMsg.initiatorNodeId(), snapOpMsg.snapshotOperation());
 
         if (fut != null)
             fut.get();


[07/50] [abbrv] ignite git commit: ignite-4710 More information in IgniteTxOptimisticCheckedException message.

Posted by sb...@apache.org.
ignite-4710 More information in IgniteTxOptimisticCheckedException message.

(cherry picked from commit 7f74458)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 5ad1933b018583ee7749677aaa39dc5718ae1e36
Parents: 1f70cd6
Author: sboikov <sb...@gridgain.com>
Authored: Thu Feb 16 18:34:02 2017 +0300
Committer: Evgeny Stanilovskiy <es...@gridgain.com>
Committed: Fri Feb 17 10:21:43 2017 +0300

----------------------------------------------------------------------
 .../distributed/dht/GridDhtTxPrepareFuture.java | 35 ++++++++++++++++++--
 1 file changed, 32 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5ad1933b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index d11e3da..a17b782 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -1142,11 +1142,40 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
      * @return Optimistic version check error.
      */
     private IgniteTxOptimisticCheckedException versionCheckError(IgniteTxEntry entry) {
+        StringBuilder msg = new StringBuilder("Failed to prepare transaction, read/write conflict [");
+
         GridCacheContext cctx = entry.context();
 
-        return new IgniteTxOptimisticCheckedException("Failed to prepare transaction, " +
-            "read/write conflict [key=" + entry.key().value(cctx.cacheObjectContext(), false) +
-            ", cache=" + cctx.name() + ']');
+        try {
+            Object key = cctx.unwrapBinaryIfNeeded(entry.key(), entry.keepBinary(), false);
+
+            assert key != null : entry.key();
+
+            msg.append("key=").append(key.toString()).append(", keyCls=").append(key.getClass().getName());
+        }
+        catch (Exception e) {
+            msg.append("key=<failed to get key: ").append(e.toString()).append(">");
+        }
+
+        try {
+            GridCacheEntryEx entryEx = entry.cached();
+
+            CacheObject cacheVal = entryEx != null ? entryEx.rawGet() : null;
+
+            Object val = cacheVal != null ? cctx.unwrapBinaryIfNeeded(cacheVal, entry.keepBinary(), false) : null;
+
+            if (val != null)
+                msg.append(", val=").append(val.toString()).append(", valCls=").append(val.getClass().getName());
+            else
+                msg.append(", val=null");
+        }
+        catch (Exception e) {
+            msg.append(", val=<failed to get value: ").append(e.toString()).append(">");
+        }
+
+        msg.append(", cache=").append(cctx.name()).append(", thread=").append(Thread.currentThread()).append("]");
+
+        return new IgniteTxOptimisticCheckedException(msg.toString());
     }
 
     /**


[09/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -fix tests with node filters

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-fix tests with node filters


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 0384b66252d331f8a0406eecbaeec5ba6f12ed2c
Parents: 4f85917
Author: EdShangGG <es...@gridgain.com>
Authored: Fri Feb 17 20:10:50 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Fri Feb 17 20:10:50 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/pagemem/snapshot/SnapshotOperation.java   | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0384b662/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
index 221d0ce..3e13f95 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -98,7 +98,6 @@ public class SnapshotOperation implements Serializable {
         return extraParam;
     }
 
-    /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)
             return true;
@@ -111,19 +110,15 @@ public class SnapshotOperation implements Serializable {
             return false;
         if (type != operation.type)
             return false;
-        if (cacheNames != null ? !cacheNames.equals(operation.cacheNames) : operation.cacheNames != null)
-            return false;
         if (msg != null ? !msg.equals(operation.msg) : operation.msg != null)
             return false;
         return extraParam != null ? extraParam.equals(operation.extraParam) : operation.extraParam == null;
 
     }
 
-    /** {@inheritDoc} */
     @Override public int hashCode() {
-        int result = type != null ? type.hashCode() : 0;
+        int result = type.hashCode();
         result = 31 * result + (int)(snapshotId ^ (snapshotId >>> 32));
-        result = 31 * result + (cacheNames != null ? cacheNames.hashCode() : 0);
         result = 31 * result + (msg != null ? msg.hashCode() : 0);
         result = 31 * result + (extraParam != null ? extraParam.hashCode() : 0);
         return result;


[27/50] [abbrv] ignite git commit: RESTORE snapshot test with modifications using DirectoryStream API

Posted by sb...@apache.org.
RESTORE snapshot test with modifications using DirectoryStream API


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 476e8f1e19dbaae426b1121a48d0d23043e1babb
Parents: 22b6a9a
Author: Alexandr Kuramshin <ak...@gridgain.com>
Authored: Thu Mar 16 00:34:14 2017 +0700
Committer: Alexandr Kuramshin <ak...@gridgain.com>
Committed: Thu Mar 16 00:34:14 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/util/lang/GridFunc.java     | 22 ++++++++++++++++++++
 1 file changed, 22 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/476e8f1e/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
old mode 100644
new mode 100755
index 5eb27d3..4ddf615
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
@@ -17,6 +17,10 @@
 
 package org.apache.ignite.internal.util.lang;
 
+import java.io.IOException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -41,6 +45,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import javax.cache.Cache;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.compute.ComputeJobResult;
 import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
@@ -2313,6 +2318,23 @@ public class GridFunc {
     }
 
     /**
+     * Tests if the given path is a directory and is not {@code null} or empty.
+     *
+     * @param dir Path to test.
+     * @return Whether or not the given path is a directory and is not {@code null} or empty.
+     */
+    public static boolean isEmptyDirectory(Path dir) {
+        if (dir == null || !Files.isDirectory(dir))
+            return false;
+        try (DirectoryStream<Path> files = Files.newDirectoryStream(dir)) {
+            return !files.iterator().hasNext();
+        }
+        catch (IOException e) {
+            throw new IgniteException(e);
+        }
+    }
+
+    /**
      * Converts collection of numbers to primitive {@code int[]} array.
      *
      * @param col Collection of numbers.


[06/50] [abbrv] ignite git commit: Merge branch 'GG-11860' into ignite-gg-8.0.3.ea2

Posted by sb...@apache.org.
Merge branch 'GG-11860' into ignite-gg-8.0.3.ea2

# Conflicts:
#	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 1f70cd62065fea359b3b9cb98562a650fa5a8c68
Parents: a19f94b e14cab1
Author: EdShangGG <es...@gridgain.com>
Authored: Thu Feb 16 21:07:24 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Thu Feb 16 21:07:24 2017 +0300

----------------------------------------------------------------------
 .../snapshot/SnapshotFinishedMessage.java       |  32 ++++-
 .../pagemem/snapshot/SnapshotOperation.java     |  31 +++++
 .../StartFullSnapshotAckDiscoveryMessage.java   | 132 -------------------
 .../StartFullSnapshotDiscoveryMessage.java      |   4 +-
 ...artSnapshotOperationAckDiscoveryMessage.java | 129 ++++++++++++++++++
 .../GridCachePartitionExchangeManager.java      |  10 +-
 .../processors/cache/GridCacheProcessor.java    |   6 +-
 .../IgniteCacheDatabaseSharedManager.java       |  12 +-
 .../GridDhtPartitionsExchangeFuture.java        |  12 +-
 .../resources/META-INF/classnames.properties    |   2 +-
 10 files changed, 203 insertions(+), 167 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1f70cd62/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index 0b15480,a5fdeef..95ed3ae
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@@ -19,10 -19,7 +19,9 @@@ package org.apache.ignite.internal.proc
  
  import java.io.File;
  import java.util.Collection;
- import java.util.UUID;
  import org.apache.ignite.IgniteCheckedException;
 +import org.apache.ignite.IgniteLogger;
 +import org.apache.ignite.cluster.ClusterNode;
  import org.apache.ignite.configuration.MemoryConfiguration;
  import org.apache.ignite.internal.GridKernalContext;
  import org.apache.ignite.internal.IgniteInternalFuture;


[24/50] [abbrv] ignite git commit: Merge branch 'ignite-gg-8.0.3.ea2' of https://github.com/gridgain/apache-ignite into ignite-gg-8.0.3.ea2

Posted by sb...@apache.org.
Merge branch 'ignite-gg-8.0.3.ea2' of https://github.com/gridgain/apache-ignite into ignite-gg-8.0.3.ea2


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 977653fdef4ef1c7acc1cc0406341890fc4b8574
Parents: 2be1307 4234667
Author: Aleksei Scherbakov <al...@gmail.com>
Authored: Fri Mar 10 16:24:40 2017 +0300
Committer: Aleksei Scherbakov <al...@gmail.com>
Committed: Fri Mar 10 16:24:40 2017 +0300

----------------------------------------------------------------------
 .../internal/managers/discovery/DiscoCache.java | 310 +++++++++
 .../discovery/GridDiscoveryManager.java         | 680 +++++--------------
 .../eventstorage/DiscoveryEventListener.java    |  33 +
 .../eventstorage/GridEventStorageManager.java   | 162 ++++-
 .../pagemem/snapshot/SnapshotOperation.java     |   3 +-
 .../StartFullSnapshotDiscoveryMessage.java      | 164 -----
 ...artSnapshotOperationAckDiscoveryMessage.java |  12 +
 .../StartSnapshotOperationDiscoveryMessage.java | 167 +++++
 .../pagemem/wal/IgniteWriteAheadLogManager.java |  27 +-
 .../internal/pagemem/wal/record/WALRecord.java  |   5 +-
 .../MetaPageUpdatePartitionDataRecord.java      |  17 +-
 .../record/delta/PartitionDestroyRecord.java    |  73 ++
 .../record/delta/PartitionMetaStateRecord.java  |   2 +-
 .../affinity/GridAffinityAssignmentCache.java   |   7 +-
 .../cache/CacheAffinitySharedManager.java       |  35 +-
 .../cache/GridCacheAffinityManager.java         |   3 +-
 .../GridCachePartitionExchangeManager.java      | 100 ++-
 .../cache/IgniteCacheOffheapManager.java        |   3 +-
 .../cache/IgniteCacheOffheapManagerImpl.java    |  57 +-
 .../IgniteCacheDatabaseSharedManager.java       |  44 +-
 .../dht/GridClientPartitionTopology.java        |  53 +-
 .../dht/GridDhtAssignmentFetchFuture.java       |   7 +-
 .../distributed/dht/GridDhtCacheEntry.java      |   2 +-
 .../distributed/dht/GridDhtLocalPartition.java  |  60 +-
 .../distributed/dht/GridDhtLockFuture.java      |  29 +-
 .../dht/GridDhtPartitionTopology.java           |  22 +-
 .../dht/GridDhtPartitionTopologyImpl.java       | 255 ++++---
 .../distributed/dht/GridDhtTxLocalAdapter.java  |   2 +-
 .../GridDhtPartitionDemandMessage.java          |  73 +-
 .../dht/preloader/GridDhtPartitionDemander.java |  81 +--
 .../dht/preloader/GridDhtPartitionSupplier.java |  10 +-
 .../GridDhtPartitionSupplyMessageV2.java        |   1 -
 .../GridDhtPartitionsExchangeFuture.java        | 302 +++++++-
 .../preloader/GridDhtPartitionsFullMessage.java | 120 +++-
 .../GridDhtPartitionsSingleMessage.java         |  77 ++-
 .../dht/preloader/GridDhtPreloader.java         | 106 ++-
 .../IgniteDhtPartitionCountersMap.java          |  64 ++
 .../IgniteDhtPartitionHistorySuppliersMap.java  | 107 +++
 .../IgniteDhtPartitionsToReloadMap.java         |  88 +++
 .../service/GridServiceProcessor.java           |  21 +-
 .../internal/visor/query/VisorQueryArg.java     |  16 +-
 .../internal/visor/query/VisorQueryJob.java     |   1 +
 .../resources/META-INF/classnames.properties    |   2 +-
 .../GridDiscoveryManagerAliveCacheSelfTest.java |  14 -
 .../commands/cache/VisorCacheScanCommand.scala  |   2 +-
 45 files changed, 2292 insertions(+), 1127 deletions(-)
----------------------------------------------------------------------



[45/50] [abbrv] ignite git commit: IGNITE-4920 Fixed.

Posted by sb...@apache.org.
IGNITE-4920 Fixed.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 9ad0883c66120940740bc1944bd1e17814f9d540
Parents: ead06b0
Author: Aleksei Scherbakov <al...@gmail.com>
Authored: Mon Apr 10 19:58:09 2017 +0300
Committer: Aleksei Scherbakov <al...@gmail.com>
Committed: Mon Apr 10 19:58:09 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/spi/deployment/local/LocalDeploymentSpi.java   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9ad0883c/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
index 87fa452..66f0326 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
@@ -68,10 +68,10 @@ import org.jsr166.ConcurrentLinkedHashMap;
 @IgniteSpiConsistencyChecked(optional = false)
 @IgnoreIfPeerClassLoadingDisabled
 public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSpi, LocalDeploymentSpiMBean {
-    /** */
+    /** Enables additional check for resource name on resources removal. */
     public static final String IGNITE_DEPLOYMENT_ADDITIONAL_CHECK = "ignite.deployment.additional.check";
 
-    /** */
+    /** Value for additional check on resources removal. */
     private static final boolean ENABLE_IGNITE_DEPLOYMENT_ADDITIONAL_CHECK =
         IgniteSystemProperties.getBoolean(IGNITE_DEPLOYMENT_ADDITIONAL_CHECK);
 


[13/50] [abbrv] ignite git commit: IGNITE-4538: Improved messages for BinaryMarshaller field read errors. This closes #1470.

Posted by sb...@apache.org.
IGNITE-4538: Improved messages for BinaryMarshaller field read errors. This closes #1470.

(cherry picked from commit f52ba0f)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 5424b706163c2539c7e54a4cdf7e007766e17088
Parents: d13520e
Author: Alexandr Kuramshin <ak...@gridgain.com>
Authored: Thu Feb 16 16:09:22 2017 +0700
Committer: Alexandr Kuramshin <ak...@gridgain.com>
Committed: Wed Mar 1 17:57:06 2017 +0700

----------------------------------------------------------------------
 .../org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5424b706/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
index 3496dbf..1a348e0 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteBinaryObjectsTestSuite.java
@@ -33,6 +33,7 @@ import org.apache.ignite.internal.binary.BinaryMarshallerSelfTest;
 import org.apache.ignite.internal.binary.BinaryObjectBuilderAdditionalSelfTest;
 import org.apache.ignite.internal.binary.BinaryObjectBuilderDefaultMappersSelfTest;
 import org.apache.ignite.internal.binary.BinaryObjectBuilderSimpleNameLowerCaseMappersSelfTest;
+import org.apache.ignite.internal.binary.BinaryObjectExceptionSelfTest;
 import org.apache.ignite.internal.binary.BinaryObjectToStringSelfTest;
 import org.apache.ignite.internal.binary.BinarySerialiedFieldComparatorSelfTest;
 import org.apache.ignite.internal.binary.BinarySimpleNameTestPropertySelfTest;
@@ -93,6 +94,7 @@ public class IgniteBinaryObjectsTestSuite extends TestSuite {
 
         suite.addTestSuite(BinaryTreeSelfTest.class);
         suite.addTestSuite(BinaryMarshallerSelfTest.class);
+        suite.addTestSuite(BinaryObjectExceptionSelfTest.class);
 
         suite.addTestSuite(BinarySerialiedFieldComparatorSelfTest.class);
         suite.addTestSuite(BinaryArrayIdentityResolverSelfTest.class);


[40/50] [abbrv] ignite git commit: Merge remote-tracking branch 'origin/ignite-gg-8.0.3.ea4' into GG-11860-2

Posted by sb...@apache.org.
Merge remote-tracking branch 'origin/ignite-gg-8.0.3.ea4' into GG-11860-2

# Conflicts:
#	modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
#	modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 8893337a67269ee4b7cf37737bcf21f0938dc020
Parents: 1229d2f 3a7e801
Author: EdShangGG <es...@gridgain.com>
Authored: Mon Apr 3 15:03:12 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Mon Apr 3 15:03:12 2017 +0300

----------------------------------------------------------------------
 .../configuration/IgniteConfiguration.java      |   2 +-
 .../internal/managers/discovery/DiscoCache.java | 310 +++++++++
 .../discovery/GridDiscoveryManager.java         | 680 +++++--------------
 .../eventstorage/DiscoveryEventListener.java    |  33 +
 .../eventstorage/GridEventStorageManager.java   | 162 ++++-
 .../pagemem/snapshot/SnapshotOperation.java     |  12 +-
 .../pagemem/wal/IgniteWriteAheadLogManager.java |  27 +-
 .../internal/pagemem/wal/record/WALRecord.java  |   5 +-
 .../delta/MetaPageUpdateLastAllocatedIndex.java |   2 +-
 .../MetaPageUpdatePartitionDataRecord.java      |  17 +-
 .../record/delta/PartitionDestroyRecord.java    |  73 ++
 .../record/delta/PartitionMetaStateRecord.java  |   2 +-
 .../affinity/GridAffinityAssignmentCache.java   |   7 +-
 .../cache/CacheAffinitySharedManager.java       |  35 +-
 .../cache/GridCacheAffinityManager.java         |   3 +-
 .../GridCachePartitionExchangeManager.java      | 100 ++-
 .../cache/IgniteCacheOffheapManager.java        |   3 +-
 .../cache/IgniteCacheOffheapManagerImpl.java    |  57 +-
 .../IgniteCacheDatabaseSharedManager.java       |  40 +-
 .../cache/database/freelist/PagesList.java      | 221 ++++--
 .../cache/database/tree/io/PageMetaIO.java      |  34 +-
 .../dht/GridClientPartitionTopology.java        |  53 +-
 .../dht/GridDhtAssignmentFetchFuture.java       |   7 +-
 .../distributed/dht/GridDhtCacheEntry.java      |   2 +-
 .../distributed/dht/GridDhtLocalPartition.java  |  60 +-
 .../distributed/dht/GridDhtLockFuture.java      |  29 +-
 .../dht/GridDhtPartitionTopology.java           |  22 +-
 .../dht/GridDhtPartitionTopologyImpl.java       | 255 ++++---
 .../distributed/dht/GridDhtTxLocalAdapter.java  |   2 +-
 .../GridDhtPartitionDemandMessage.java          |  73 +-
 .../dht/preloader/GridDhtPartitionDemander.java |  81 +--
 .../dht/preloader/GridDhtPartitionSupplier.java |  10 +-
 .../GridDhtPartitionSupplyMessageV2.java        |   1 -
 .../GridDhtPartitionsExchangeFuture.java        | 183 ++++-
 .../preloader/GridDhtPartitionsFullMessage.java | 120 +++-
 .../GridDhtPartitionsSingleMessage.java         |  77 ++-
 .../dht/preloader/GridDhtPreloader.java         | 106 ++-
 .../IgniteDhtPartitionCountersMap.java          |  64 ++
 .../IgniteDhtPartitionHistorySuppliersMap.java  | 107 +++
 .../IgniteDhtPartitionsToReloadMap.java         |  88 +++
 .../cache/transactions/IgniteTxStateImpl.java   |   4 +-
 .../service/GridServiceProcessor.java           |  21 +-
 .../ignite/internal/util/IgniteUtils.java       |  26 +
 .../ignite/internal/util/lang/GridFunc.java     |  39 ++
 .../resources/META-INF/classnames.properties    |  27 +-
 modules/core/src/test/config/log4j-test.xml     |   8 +-
 .../ignite/cache/LargeEntryUpdateTest.java      | 177 +++++
 .../GridDiscoveryManagerAliveCacheSelfTest.java |  14 -
 .../database/IgniteDbAbstractTest.java          | 391 +++++++++++
 .../IgniteDbMemoryLeakAbstractTest.java         | 265 ++++++++
 .../IgniteDbMemoryLeakLargeObjectsTest.java     |  56 ++
 .../IgniteDbMemoryLeakLargePagesTest.java       |  33 +
 .../IgniteDbMemoryLeakNonTransactionalTest.java |  31 +
 .../database/IgniteDbMemoryLeakTest.java        |  46 ++
 .../IgniteDbMemoryLeakWithExpirationTest.java   |  44 ++
 .../database/IgniteDbPutGetAbstractTest.java    | 357 +---------
 .../junits/common/GridCommonAbstractTest.java   |   4 +-
 .../testsuites/IgniteDbMemoryLeakTestSuite.java |  49 ++
 .../database/IgniteDbMemoryLeakIndexedTest.java |  33 +
 .../IgniteDbMemoryLeakSqlQueryTest.java         |  76 +++
 ...IgniteDbMemoryLeakWithIndexingTestSuite.java |  40 ++
 61 files changed, 3489 insertions(+), 1417 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8893337a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index 3380e16,743cd77..6220c43
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@@ -19,7 -19,8 +19,9 @@@ package org.apache.ignite.internal.proc
  
  import java.io.File;
  import java.util.Collection;
 +import java.util.UUID;
+ import java.util.Collections;
+ import java.util.Map;
  import org.apache.ignite.IgniteCheckedException;
  import org.apache.ignite.IgniteLogger;
  import org.apache.ignite.configuration.MemoryConfiguration;

http://git-wip-us.apache.org/repos/asf/ignite/blob/8893337a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------


[08/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -refactoring moveSnapshot operation

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-refactoring moveSnapshot operation


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 4f859170d7eebaec47470fb3ff4286936e4dac9a
Parents: 5ad1933
Author: EdShangGG <es...@gridgain.com>
Authored: Fri Feb 17 18:39:32 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Fri Feb 17 18:39:32 2017 +0300

----------------------------------------------------------------------
 .../communication/GridIoMessageFactory.java     |   4 +-
 .../snapshot/SnapshotFinishedMessage.java       | 158 ----------------
 .../SnapshotOperationFinishedMessage.java       | 181 +++++++++++++++++++
 .../resources/META-INF/classnames.properties    |   2 +-
 4 files changed, 184 insertions(+), 161 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4f859170/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index 979e8db..1574909 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -33,7 +33,7 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentRequest;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentResponse;
 import org.apache.ignite.internal.managers.eventstorage.GridEventStorageMessage;
-import org.apache.ignite.internal.pagemem.snapshot.SnapshotFinishedMessage;
+import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationFinishedMessage;
 import org.apache.ignite.internal.pagemem.snapshot.SnapshotProgressMessage;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridChangeGlobalStateMessageResponse;
@@ -186,7 +186,7 @@ public class GridIoMessageFactory implements MessageFactory {
                 break;
 
             case -45:
-                msg = new SnapshotFinishedMessage();
+                msg = new SnapshotOperationFinishedMessage();
 
                 break;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/4f859170/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
deleted file mode 100644
index 8ccef42..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.pagemem.snapshot;
-
-import java.nio.ByteBuffer;
-import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageReader;
-import org.apache.ignite.plugin.extensions.communication.MessageWriter;
-
-/**
- * Message indicating that snapshot has been finished on a single node.
- */
-public class SnapshotFinishedMessage implements Message {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** */
-    private long snapshotId;
-
-    /** Operation type. */
-    private int operationType;
-
-    /** */
-    private boolean success;
-
-    /** */
-    public SnapshotFinishedMessage() {
-    }
-
-    /**
-     * @param snapshotId Snapshot ID.
-     */
-    public SnapshotFinishedMessage(long snapshotId, SnapshotOperationType type, boolean success) {
-        this.snapshotId = snapshotId;
-        this.operationType = type.ordinal();
-        this.success = success;
-    }
-
-    /**
-     * @return Snapshot ID.
-     */
-    public long snapshotId() {
-        return snapshotId;
-    }
-
-    /** */
-    public SnapshotOperationType operationType() {
-        return SnapshotOperationType.values()[operationType];
-    }
-
-    /** */
-    public boolean success() {
-        return success;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
-        writer.setBuffer(buf);
-
-        if (!writer.isHeaderWritten()) {
-            if (!writer.writeHeader(directType(), fieldsCount()))
-                return false;
-
-            writer.onHeaderWritten();
-        }
-
-        switch (writer.state()) {
-            case 0:
-                if (!writer.writeLong("snapshotId", snapshotId))
-                    return false;
-
-                writer.incrementState();
-
-            case 1:
-                if (!writer.writeInt("operationType", operationType))
-                    return false;
-
-                writer.incrementState();
-
-            case 2:
-                if (!writer.writeBoolean("success", success))
-                    return false;
-
-                writer.incrementState();
-
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
-        reader.setBuffer(buf);
-
-        if (!reader.beforeMessageRead())
-            return false;
-
-        switch (reader.state()) {
-            case 0:
-                snapshotId = reader.readLong("snapshotId");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-            case 1:
-                operationType = reader.readInt("operationType");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-            case 2:
-                success = reader.readBoolean("success");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-        }
-
-        return reader.afterMessageRead(SnapshotFinishedMessage.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte directType() {
-        return -45;
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte fieldsCount() {
-        return 3;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void onAckReceived() {
-        // No-op
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4f859170/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java
new file mode 100644
index 0000000..8986e5c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java
@@ -0,0 +1,181 @@
+/*
+ * 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.pagemem.snapshot;
+
+import java.nio.ByteBuffer;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+
+/**
+ * Message indicating that snapshot has been finished on a single node.
+ */
+public class SnapshotOperationFinishedMessage implements Message {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private long snapshotId;
+
+    /** Operation type. */
+    private int operationType;
+
+    /** */
+    private boolean success;
+
+    /** Error message. */
+    private String errorMsg;
+
+    /** */
+    public SnapshotOperationFinishedMessage() {
+    }
+
+    /**
+     * @param snapshotId Snapshot ID.
+     * @param errorMsg
+     */
+    public SnapshotOperationFinishedMessage(long snapshotId, SnapshotOperationType type, boolean success, String errorMsg) {
+        this.snapshotId = snapshotId;
+        this.operationType = type.ordinal();
+        this.success = success;
+        this.errorMsg = errorMsg;
+    }
+
+    /**
+     * @return Snapshot ID.
+     */
+    public long snapshotId() {
+        return snapshotId;
+    }
+
+    /** */
+    public SnapshotOperationType operationType() {
+        return SnapshotOperationType.values()[operationType];
+    }
+
+    /** */
+    public boolean success() {
+        return success;
+    }
+
+    /** */
+    public String errorMessage() {
+        return errorMsg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
+        writer.setBuffer(buf);
+
+        if (!writer.isHeaderWritten()) {
+            if (!writer.writeHeader(directType(), fieldsCount()))
+                return false;
+
+            writer.onHeaderWritten();
+        }
+
+        switch (writer.state()) {
+            case 0:
+                if (!writer.writeLong("snapshotId", snapshotId))
+                    return false;
+
+                writer.incrementState();
+
+            case 1:
+                if (!writer.writeInt("operationType", operationType))
+                    return false;
+
+                writer.incrementState();
+
+            case 2:
+                if (!writer.writeBoolean("success", success))
+                    return false;
+
+                writer.incrementState();
+
+            case 3:
+                if (!writer.writeString("errorMsg", errorMsg))
+                    return false;
+
+                writer.incrementState();
+
+        }
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
+        reader.setBuffer(buf);
+
+        if (!reader.beforeMessageRead())
+            return false;
+
+        switch (reader.state()) {
+            case 0:
+                snapshotId = reader.readLong("snapshotId");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 1:
+                operationType = reader.readInt("operationType");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 2:
+                success = reader.readBoolean("success");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 3:
+                errorMsg = reader.readString("errorMsg");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+        }
+
+        return reader.afterMessageRead(SnapshotOperationFinishedMessage.class);
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte directType() {
+        return -45;
+    }
+
+    /** {@inheritDoc} */
+    @Override public byte fieldsCount() {
+        return 4;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void onAckReceived() {
+        // No-op
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4f859170/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index a0838b1..13a3bce 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -326,7 +326,7 @@ org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerAdapter
 org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerManager$1
 org.apache.ignite.internal.mem.OutOfMemoryException
 org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl$Segment
-org.apache.ignite.internal.pagemem.snapshot.SnapshotFinishedMessage
+org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationFinishedMessage
 org.apache.ignite.internal.pagemem.snapshot.SnapshotProgressMessage
 org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage
 org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotDiscoveryMessage


[14/50] [abbrv] ignite git commit: IGNITE-4538: Improved messages for BinaryMarshaller field read errors. This closes #1470.

Posted by sb...@apache.org.
IGNITE-4538: Improved messages for BinaryMarshaller field read errors. This closes #1470.

(cherry picked from commit f52ba0f)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 1118c72837096f29ff58065137f82763831c2c85
Parents: 5424b70
Author: Alexandr Kuramshin <ak...@gridgain.com>
Authored: Thu Feb 16 16:09:22 2017 +0700
Committer: Alexandr Kuramshin <ak...@gridgain.com>
Committed: Wed Mar 1 17:58:25 2017 +0700

----------------------------------------------------------------------
 .../internal/binary/BinaryClassDescriptor.java  |  81 +++---
 .../internal/binary/BinaryFieldAccessor.java    |  56 ++--
 .../internal/binary/BinaryReaderExImpl.java     | 284 ++++++++++++++++---
 .../ignite/internal/binary/BinaryUtils.java     |  11 +-
 .../binary/BinaryObjectExceptionSelfTest.java   | 209 ++++++++++++++
 5 files changed, 542 insertions(+), 99 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1118c728/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 3a72a31..5616c69 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
@@ -44,6 +44,7 @@ import org.apache.ignite.internal.processors.query.GridQueryProcessor;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+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;
@@ -806,58 +807,66 @@ public class BinaryClassDescriptor {
      * @throws BinaryObjectException If failed.
      */
     Object read(BinaryReaderExImpl reader) throws BinaryObjectException {
-        assert reader != null;
-        assert mode != BinaryWriteMode.OPTIMIZED : "OptimizedMarshaller should not be used here: " + cls.getName();
+        try {
+            assert reader != null;
+            assert mode != BinaryWriteMode.OPTIMIZED : "OptimizedMarshaller should not be used here: " + cls.getName();
 
-        Object res;
+            Object res;
 
-        switch (mode) {
-            case BINARY:
-                res = newInstance();
+            switch (mode) {
+                case BINARY:
+                    res = newInstance();
 
-                reader.setHandle(res);
+                    reader.setHandle(res);
 
-                if (serializer != null)
-                    serializer.readBinary(res, reader);
-                else
-                    ((Binarylizable)res).readBinary(reader);
+                    if (serializer != null)
+                        serializer.readBinary(res, reader);
+                    else
+                        ((Binarylizable)res).readBinary(reader);
 
-                break;
+                    break;
 
-            case OBJECT:
-                res = newInstance();
+                case OBJECT:
+                    res = newInstance();
 
-                reader.setHandle(res);
+                    reader.setHandle(res);
 
-                for (BinaryFieldAccessor info : fields)
-                    info.read(res, reader);
+                    for (BinaryFieldAccessor info : fields)
+                        info.read(res, reader);
 
-                break;
+                    break;
 
-            default:
-                assert false : "Invalid mode: " + mode;
+                default:
+                    assert false : "Invalid mode: " + mode;
 
-                return null;
-        }
+                    return null;
+            }
 
-        if (readResolveMtd != null) {
-            try {
-                res = readResolveMtd.invoke(res);
+            if (readResolveMtd != null) {
+                try {
+                    res = readResolveMtd.invoke(res);
 
-                reader.setHandle(res);
-            }
-            catch (IllegalAccessException e) {
-                throw new RuntimeException(e);
-            }
-            catch (InvocationTargetException e) {
-                if (e.getTargetException() instanceof BinaryObjectException)
-                    throw (BinaryObjectException)e.getTargetException();
+                    reader.setHandle(res);
+                }
+                catch (IllegalAccessException e) {
+                    throw new RuntimeException(e);
+                }
+                catch (InvocationTargetException e) {
+                    if (e.getTargetException() instanceof BinaryObjectException)
+                        throw (BinaryObjectException)e.getTargetException();
 
-                throw new BinaryObjectException("Failed to execute readResolve() method on " + res, e);
+                    throw new BinaryObjectException("Failed to execute readResolve() method on " + res, e);
+                }
             }
-        }
 
-        return res;
+            return res;
+        }
+        catch (Exception e) {
+            if (S.INCLUDE_SENSITIVE && !F.isEmpty(typeName))
+                throw new BinaryObjectException("Failed to deserialize object [typeName=" + typeName + ']', e);
+            else
+                throw new BinaryObjectException("Failed to deserialize object [typeId=" + typeId + ']', e);
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1118c728/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
index af33b63..db683db 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryFieldAccessor.java
@@ -26,6 +26,8 @@ import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.binary.BinaryObjectException;
 import org.apache.ignite.internal.util.GridUnsafe;
+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;
 
 /**
@@ -35,6 +37,9 @@ public abstract class BinaryFieldAccessor {
     /** Field ID. */
     protected final int id;
 
+    /** Field name */
+    protected final String name;
+
     /** Mode. */
     protected final BinaryWriteMode mode;
 
@@ -116,10 +121,12 @@ public abstract class BinaryFieldAccessor {
      * @param id Field ID.
      * @param mode Mode;
      */
-    protected BinaryFieldAccessor(int id, BinaryWriteMode mode) {
+    protected BinaryFieldAccessor(Field field, int id, BinaryWriteMode mode) {
+        assert field != null;
         assert id != 0;
         assert mode != null;
 
+        this.name = field.getName();
         this.id = id;
         this.mode = mode;
     }
@@ -149,7 +156,26 @@ public abstract class BinaryFieldAccessor {
      * @param reader Reader.
      * @throws BinaryObjectException If failed.
      */
-    public abstract void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException;
+    public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        try {
+            read0(obj, reader);
+        }
+        catch (Exception ex) {
+            if (S.INCLUDE_SENSITIVE && !F.isEmpty(name))
+                throw new BinaryObjectException("Failed to read field [name=" + name + ']', ex);
+            else
+                throw new BinaryObjectException("Failed to read field [id=" + id + ']', ex);
+        }
+    }
+
+    /**
+     * Read field.
+     *
+     * @param obj Object.
+     * @param reader Reader.
+     * @throws BinaryObjectException If failed.
+     */
+    protected abstract void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException;
 
     /**
      * Base primitive field accessor.
@@ -166,9 +192,7 @@ public abstract class BinaryFieldAccessor {
          * @param mode Mode.
          */
         protected AbstractPrimitiveAccessor(Field field, int id, BinaryWriteMode mode) {
-            super(id, mode);
-
-            assert field != null;
+            super(field, id, mode);
 
             offset = GridUnsafe.objectFieldOffset(field);
         }
@@ -197,7 +221,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             byte val = reader.readByte(id);
 
             GridUnsafe.putByteField(obj, offset, val);
@@ -227,7 +251,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             boolean val = reader.readBoolean(id);
 
             GridUnsafe.putBooleanField(obj, offset, val);
@@ -257,7 +281,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             short val = reader.readShort(id);
 
             GridUnsafe.putShortField(obj, offset, val);
@@ -287,7 +311,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             char val = reader.readChar(id);
 
             GridUnsafe.putCharField(obj, offset, val);
@@ -317,7 +341,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             int val = reader.readInt(id);
 
             GridUnsafe.putIntField(obj, offset, val);
@@ -347,7 +371,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             long val = reader.readLong(id);
 
             GridUnsafe.putLongField(obj, offset, val);
@@ -377,7 +401,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             float val = reader.readFloat(id);
 
             GridUnsafe.putFloatField(obj, offset, val);
@@ -407,7 +431,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             double val = reader.readDouble(id);
 
             GridUnsafe.putDoubleField(obj, offset, val);
@@ -432,9 +456,7 @@ public abstract class BinaryFieldAccessor {
          * @param mode Mode.
          */
         DefaultFinalClassAccessor(Field field, int id, BinaryWriteMode mode, boolean dynamic) {
-            super(id, mode);
-
-            assert field != null;
+            super(field, id, mode);
 
             this.field = field;
             this.dynamic = dynamic;
@@ -635,7 +657,7 @@ public abstract class BinaryFieldAccessor {
         }
 
         /** {@inheritDoc} */
-        @Override public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
+        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
             Object val = dynamic ? reader.readField(id) : readFixedType(reader);
 
             try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/1118c728/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
index 775f237..a0aac3f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/BinaryReaderExImpl.java
@@ -35,6 +35,7 @@ import org.apache.ignite.binary.BinaryRawReader;
 import org.apache.ignite.binary.BinaryReader;
 import org.apache.ignite.internal.binary.streams.BinaryInputStream;
 import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -329,7 +330,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
      * @throws BinaryObjectException In case of error.
      */
     @Nullable Object unmarshalField(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? BinaryUtils.unmarshal(in, ctx, ldr, this) : null;
+        try {
+            return findFieldByName(fieldName) ? BinaryUtils.unmarshal(in, ctx, ldr, this) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -421,9 +427,29 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
         return (T)obj;
     }
+
+    /**
+     * Wraps an exception by adding the fieldName
+     *
+     * @param fieldName the name of the field, causes failure
+     * @param e the cause of the deserialization failure
+     * @return wrapping exception
+     */
+    private BinaryObjectException wrapFieldException(String fieldName, Exception e) {
+        if (S.INCLUDE_SENSITIVE)
+            return new BinaryObjectException("Failed to read field: " + fieldName, e);
+        else
+            return new BinaryObjectException("Failed to read field.", e);
+    }
+
     /** {@inheritDoc} */
     @Override public byte readByte(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(BYTE) == Flag.NORMAL ? in.readByte() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(BYTE) == Flag.NORMAL ? in.readByte() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -451,7 +477,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public byte[] readByteArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readByteArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readByteArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -479,7 +510,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public boolean readBoolean(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(BOOLEAN) == Flag.NORMAL && in.readBoolean();
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(BOOLEAN) == Flag.NORMAL && in.readBoolean();
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -507,7 +543,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public boolean[] readBooleanArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readBooleanArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readBooleanArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -535,7 +576,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public short readShort(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(SHORT) == Flag.NORMAL ? in.readShort() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(SHORT) == Flag.NORMAL ? in.readShort() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -563,7 +609,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public short[] readShortArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readShortArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readShortArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -591,7 +642,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public char readChar(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(CHAR) == Flag.NORMAL ? in.readChar() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(CHAR) == Flag.NORMAL ? in.readChar() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -619,7 +675,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public char[] readCharArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readCharArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readCharArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -647,7 +708,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public int readInt(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(INT) == Flag.NORMAL ? in.readInt() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(INT) == Flag.NORMAL ? in.readInt() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -675,7 +741,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public int[] readIntArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readIntArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readIntArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -703,7 +774,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public long readLong(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(LONG) == Flag.NORMAL ? in.readLong() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(LONG) == Flag.NORMAL ? in.readLong() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -731,7 +807,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public long[] readLongArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readLongArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readLongArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -759,7 +840,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public float readFloat(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(FLOAT) == Flag.NORMAL ? in.readFloat() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(FLOAT) == Flag.NORMAL ? in.readFloat() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -787,7 +873,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public float[] readFloatArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readFloatArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readFloatArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -815,7 +906,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override public double readDouble(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) && checkFlagNoHandles(DOUBLE) == Flag.NORMAL ? in.readDouble() : 0;
+        try {
+            return findFieldByName(fieldName) && checkFlagNoHandles(DOUBLE) == Flag.NORMAL ? in.readDouble() : 0;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -843,7 +939,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public double[] readDoubleArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDoubleArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDoubleArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -871,7 +972,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public BigDecimal readDecimal(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDecimal() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDecimal() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -890,7 +996,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public BigDecimal[] readDecimalArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDecimalArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDecimalArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -918,7 +1029,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public String readString(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readString() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readString() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -937,7 +1053,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public String[] readStringArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readStringArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readStringArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -965,7 +1086,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public UUID readUuid(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readUuid() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readUuid() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -984,7 +1110,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public UUID[] readUuidArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readUuidArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readUuidArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1012,7 +1143,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Date readDate(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDate() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDate() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1031,7 +1167,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Date[] readDateArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readDateArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readDateArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1059,7 +1200,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Timestamp readTimestamp(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readTimestamp() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readTimestamp() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1078,7 +1224,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Override @Nullable public Timestamp[] readTimestampArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readTimestampArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readTimestampArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1107,7 +1258,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Nullable @Override public <T> T readObject(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (T)BinaryUtils.doReadObject(in, ctx, ldr, this) : null;
+        try {
+            return findFieldByName(fieldName) ? (T)BinaryUtils.doReadObject(in, ctx, ldr, this) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1131,7 +1287,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public Object[] readObjectArray(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? this.readObjectArray() : null;
+        try {
+            return findFieldByName(fieldName) ? this.readObjectArray() : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1159,7 +1320,12 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public <T extends Enum<?>> T readEnum(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (T)readEnum0(null) : null;
+        try {
+            return findFieldByName(fieldName) ? (T)readEnum0(null) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1201,7 +1367,13 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
     /** {@inheritDoc} */
     @Nullable @Override public <T extends Enum<?>> T[] readEnumArray(String fieldName)
         throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (T[])readEnumArray0(null) : null;
+
+        try {
+            return findFieldByName(fieldName) ? (T[])readEnumArray0(null) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1247,13 +1419,24 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public <T> Collection<T> readCollection(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (Collection<T>)readCollection0(null) : null;
+        try {
+            return findFieldByName(fieldName) ? (Collection<T>)readCollection0(null) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /** {@inheritDoc} */
     @Nullable @Override public <T> Collection<T> readCollection(String fieldName, BinaryCollectionFactory<T> factory)
         throws BinaryObjectException {
-        return findFieldByName(fieldName) ? readCollection0(factory) : null;
+
+        try {
+            return findFieldByName(fieldName) ? readCollection0(factory) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1316,13 +1499,24 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
     /** {@inheritDoc} */
     @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName) throws BinaryObjectException {
-        return findFieldByName(fieldName) ? (Map<K, V>)readMap0(null) : null;
+        try {
+            return findFieldByName(fieldName) ? (Map<K, V>)readMap0(null) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /** {@inheritDoc} */
     @Nullable @Override public <K, V> Map<K, V> readMap(String fieldName, BinaryMapFactory<K, V> factory)
         throws BinaryObjectException {
-        return findFieldByName(fieldName) ? readMap0(factory) : null;
+
+        try {
+            return findFieldByName(fieldName) ? readMap0(factory) : null;
+        }
+        catch (Exception ex) {
+            throw wrapFieldException(fieldName, ex);
+        }
     }
 
     /**
@@ -1400,8 +1594,8 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
         int pos = BinaryUtils.positionForHandle(in);
 
-        throw new BinaryObjectException("Unexpected flag value [pos=" + pos + ", expected=" + expFlag +
-            ", actual=" + flag + ']');
+        throw new BinaryObjectException("Unexpected field type [pos=" + pos + ", expected=" + fieldFlagName(expFlag) +
+            ", actual=" + fieldFlagName(flag) + ']');
     }
 
     /**
@@ -1421,8 +1615,20 @@ public class BinaryReaderExImpl implements BinaryReader, BinaryRawReaderEx, Bina
 
         int pos = BinaryUtils.positionForHandle(in);
 
-        throw new BinaryObjectException("Unexpected flag value [pos=" + pos + ", expected=" + expFlag +
-            ", actual=" + flag + ']');
+        throw new BinaryObjectException("Unexpected field type [pos=" + pos + ", expected=" + fieldFlagName(expFlag) +
+            ", actual=" + fieldFlagName(flag) + ']');
+    }
+
+    /**
+     * Gets a flag name
+     *
+     * @param flag a flag value
+     * @return string representation of the flag (type name, handle, else number)
+     */
+    private String fieldFlagName(byte flag) {
+        String typeName = BinaryUtils.fieldTypeName(flag);
+
+        return typeName == null ? String.valueOf(flag) : typeName;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/1118c728/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 1153d15..1d06417 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
@@ -347,16 +347,13 @@ public class BinaryUtils {
 
     /**
      * @param typeId Field type ID.
-     * @return Field type name.
+     * @return Field type name or {@code null} if unknown.
      */
     public static String fieldTypeName(int typeId) {
-        assert typeId >= 0 && typeId < FIELD_TYPE_NAMES.length : typeId;
-
-        String typeName = FIELD_TYPE_NAMES[typeId];
-
-        assert typeName != null : typeId;
+        if(typeId < 0 || typeId >= FIELD_TYPE_NAMES.length)
+            return null;
 
-        return typeName;
+        return FIELD_TYPE_NAMES[typeId];
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/1118c728/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
new file mode 100644
index 0000000..e4be824
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectExceptionSelfTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.binary;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.UUID;
+import javax.cache.Cache;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.binary.BinaryBasicNameMapper;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.configuration.BinaryConfiguration;
+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;
+
+/**
+ * BinaryObjectExceptionSelfTest
+ */
+public class BinaryObjectExceptionSelfTest extends GridCommonAbstractTest {
+    /** */
+    private static final String TEST_KEY = "test_key";
+
+    /** */
+    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(new BinaryMarshaller());
+        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(IP_FINDER));
+
+        cfg.setCacheConfiguration(new CacheConfiguration().setCopyOnRead(true));
+
+        BinaryConfiguration bcfg = new BinaryConfiguration();
+
+        bcfg.setNameMapper(new BinaryBasicNameMapper(false));
+
+        cfg.setBinaryConfiguration(bcfg);
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        startGrids(2);
+
+        awaitPartitionMapExchange();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+    }
+
+    /**
+     * Test unexpected field type.
+     *
+     * @throws Exception If failed.
+     */
+    @SuppressWarnings("WhileLoopReplaceableByForEach")
+    public void testUnexpectedFieldType() throws Exception {
+        IgniteEx grid = grid(0);
+
+        IgniteCache<String, Value> cache = grid.cache(null);
+
+        cache.put(TEST_KEY, new Value());
+
+        BinaryObjectImpl b = (BinaryObjectImpl)cache.withKeepBinary().get(TEST_KEY);
+
+        b.deserialize(); // deserialize working
+
+        byte[] a = b.array();
+
+        int unexpectedCnt = 0;
+
+        Field[] fields = Value.class.getDeclaredFields();
+
+        StringBuilder sb = new StringBuilder(4 << 10);
+
+        for (int i = b.dataStartOffset(), j = b.footerStartOffset(); i < j; ++i) {
+            byte old = a[i];
+
+            a[i] = -1;
+
+            try {
+                Iterator<Cache.Entry<String, Value>> it = cache.iterator();
+
+                while (it.hasNext())
+                    it.next();
+            }
+            catch (Exception ex) {
+                Throwable root = ex;
+
+                sb.setLength(0);
+
+                sb.append(root.getMessage());
+
+                while (root.getCause() != null) {
+                    root = root.getCause();
+
+                    sb.append(". ").append(root.getMessage());
+                }
+                if (root instanceof BinaryObjectException && root.getMessage().startsWith("Unexpected field type")) {
+                    log().info(sb.toString());
+
+                    Field f = fields[unexpectedCnt];
+
+                    Throwable t = ex;
+
+                    assertTrue(t.getMessage(), t.getMessage().contains(
+                        "object [typeName=org.apache.ignite.internal.binary.BinaryObjectExceptionSelfTest$Value"));
+
+                    t = t.getCause();
+
+                    assertTrue(t.getMessage(), t.getMessage().contains("field [name=" + f.getName()));
+
+                    ++unexpectedCnt;
+                }
+                else
+                    log().info("Ignored exception: " + sb);
+            }
+
+            a[i] = old;
+        }
+
+        assertEquals("Fields count must match \"Unexpected field type\" exception count", fields.length, unexpectedCnt);
+    }
+
+    /** */
+    private enum EnumValues {
+        /** */
+        val1,
+
+        /** */
+        val2,
+
+        /** */
+        val3;
+    }
+
+    /** */
+    @SuppressWarnings("unused")
+    private static class Value {
+        /** */
+        public byte byteVal = 1;
+
+        /** */
+        public boolean booleanVal = true;
+
+        /** */
+        public short shortVal = 2;
+
+        /** */
+        public char charVal = 'Q';
+
+        /** */
+        public int intVal = 3;
+
+        /** */
+        public long longVal = 4;
+
+        /** */
+        public float floatVal = 5;
+
+        /** */
+        public double doubleVal = 6;
+
+        /** */
+        public BigDecimal bigDecimal = new BigDecimal(7);
+
+        /** */
+        public String string = "QWERTY";
+
+        /** */
+        public UUID uuid = UUID.randomUUID();
+
+        /** */
+        public Date date = new Date();
+
+        /** */
+        public Timestamp timestamp = new Timestamp(date.getTime() + 1000L);
+
+        /** */
+        public EnumValues enumVal = EnumValues.val2;
+    }
+}


[21/50] [abbrv] ignite git commit: ignite-4779 Missed discovery data snapshot during exchange processing (do not use discovery manager cache to handle exchange)

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index e63379a..a96cc43 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -33,6 +33,7 @@ import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionExchangeId;
@@ -45,7 +46,6 @@ import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
 
@@ -107,6 +107,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     /** */
     private final Object similarAffKey;
 
+    /** */
+    private volatile DiscoCache discoCache;
+
     /**
      * @param cctx Context.
      * @param cacheId Cache ID.
@@ -125,6 +128,8 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
         topVer = exchFut.topologyVersion();
 
+        discoCache = exchFut.discoCache();
+
         log = cctx.logger(getClass());
 
         lock.writeLock().lock();
@@ -193,6 +198,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
             this.stopping = stopping;
 
             topVer = exchId.topologyVersion();
+            discoCache = exchFut.discoCache();
 
             updateSeq.setIfGreater(updSeq);
 
@@ -273,7 +279,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
             removeNode(exchId.nodeId());
 
         // In case if node joins, get topology at the time of joining node.
-        ClusterNode oldest = cctx.discovery().oldestAliveCacheServerNode(topVer);
+        ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
         assert oldest != null;
 
@@ -432,7 +438,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
             if (!F.isEmpty(nodeIds)) {
                 for (UUID nodeId : nodeIds) {
-                    ClusterNode n = cctx.discovery().node(nodeId);
+                    ClusterNode n = discoCache.node(nodeId);
 
                     if (n != null && (topVer.topologyVersion() < 0 || n.order() <= topVer.topologyVersion())) {
                         if (nodes == null)
@@ -458,7 +464,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
      * @return List of nodes for the partition.
      */
     private List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer, GridDhtPartitionState state, GridDhtPartitionState... states) {
-        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.allNodes(cctx, topVer)) : null;
+        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(discoCache.allNodesWithCaches()) : null;
 
         lock.readLock().lock();
 
@@ -481,7 +487,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
                     continue;
 
                 if (hasState(p, id, state, states)) {
-                    ClusterNode n = cctx.discovery().node(id);
+                    ClusterNode n = discoCache.node(id);
 
                     if (n != null && (topVer.topologyVersion() < 0 || n.order() <= topVer.topologyVersion()))
                         nodes.add(n);
@@ -792,7 +798,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         assert nodeId.equals(cctx.localNodeId());
 
         // In case if node joins, get topology at the time of joining node.
-        ClusterNode oldest = cctx.discovery().oldestAliveCacheServerNode(topVer);
+        ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
         // If this node became the oldest node.
         if (oldest.id().equals(cctx.localNodeId())) {
@@ -842,7 +848,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         assert nodeId != null;
         assert lock.writeLock().isHeldByCurrentThread();
 
-        ClusterNode oldest = cctx.discovery().oldestAliveCacheServerNode(topVer);
+        ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
         ClusterNode loc = cctx.localNode();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAssignmentFetchFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAssignmentFetchFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAssignmentFetchFuture.java
index ab8e863..7dcfcf2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAssignmentFetchFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtAssignmentFetchFuture.java
@@ -29,6 +29,7 @@ import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.GridNodeOrderComparator;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -72,16 +73,18 @@ public class GridDhtAssignmentFetchFuture extends GridFutureAdapter<GridDhtAffin
      * @param ctx Context.
      * @param cacheName Cache name.
      * @param topVer Topology version.
+     * @param discoCache Discovery cache.
      */
     public GridDhtAssignmentFetchFuture(
         GridCacheSharedContext ctx,
         String cacheName,
-        AffinityTopologyVersion topVer
+        AffinityTopologyVersion topVer,
+        DiscoCache discoCache
     ) {
         this.ctx = ctx;
         this.key = new T2<>(CU.cacheId(cacheName), topVer);
 
-        Collection<ClusterNode> availableNodes = ctx.discovery().cacheAffinityNodes(cacheName, topVer);
+        Collection<ClusterNode> availableNodes = discoCache.cacheAffinityNodes(cacheName);
 
         LinkedList<ClusterNode> tmp = new LinkedList<>();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index 553aa2a..36c1ae5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@ -37,6 +37,7 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.EventType;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.ClusterState;
@@ -98,6 +99,9 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     /** */
     private volatile AffinityTopologyVersion topVer = AffinityTopologyVersion.NONE;
 
+    /** Discovery cache. */
+    private volatile DiscoCache discoCache;
+
     /** */
     private volatile boolean stopping;
 
@@ -162,6 +166,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
             rebalancedTopVer = AffinityTopologyVersion.NONE;
 
             topVer = AffinityTopologyVersion.NONE;
+
+            discoCache = cctx.discovery().discoCache();
         }
         finally {
             lock.writeLock().unlock();
@@ -219,6 +225,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
             rebalancedTopVer = AffinityTopologyVersion.NONE;
 
             topVer = exchId.topologyVersion();
+
+            discoCache = exchFut.discoCache();
         }
         finally {
             lock.writeLock().unlock();
@@ -281,7 +289,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     private void initPartitions0(GridDhtPartitionsExchangeFuture exchFut, long updateSeq) {
         ClusterNode loc = cctx.localNode();
 
-        ClusterNode oldest = currentCoordinator();
+        ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
         GridDhtPartitionExchangeId exchId = exchFut.exchangeId();
 
@@ -430,7 +438,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                     if (exchId.isLeft())
                         removeNode(exchId.nodeId());
 
-                    ClusterNode oldest = currentCoordinator();
+                    ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
                     if (log.isDebugEnabled())
                         log.debug("Partition map beforeExchange [exchId=" + exchId + ", fullMap=" + fullMapString() + ']');
@@ -875,7 +883,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         AffinityTopologyVersion topVer,
         GridDhtPartitionState state,
         GridDhtPartitionState... states) {
-        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(CU.affinityNodes(cctx, topVer)) : null;
+        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(discoCache.cacheAffinityNodes(cctx.cacheId())) : null;
 
         lock.readLock().lock();
 
@@ -1599,7 +1607,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 List<ClusterNode> affNodes = aff.get(p);
 
                 if (!affNodes.contains(cctx.localNode())) {
-                    Collection<UUID> nodeIds = F.nodeIds(nodes(p, topVer, OWNING));
+                    List<ClusterNode> nodes = nodes(p, topVer, OWNING);
+                    Collection<UUID> nodeIds = F.nodeIds(nodes);
 
                     // If all affinity nodes are owners, then evict partition from local node.
                     if (nodeIds.containsAll(F.nodeIds(affNodes))) {
@@ -1619,15 +1628,13 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                         int affCnt = affNodes.size();
 
                         if (ownerCnt > affCnt) {
-                            List<ClusterNode> sorted = new ArrayList<>(cctx.discovery().nodes(nodeIds));
-
                             // Sort by node orders in ascending order.
-                            Collections.sort(sorted, CU.nodeComparator(true));
+                            Collections.sort(nodes, CU.nodeComparator(true));
 
-                            int diff = sorted.size() - affCnt;
+                            int diff = nodes.size() - affCnt;
 
                             for (int i = 0; i < diff; i++) {
-                                ClusterNode n = sorted.get(i);
+                                ClusterNode n = nodes.get(i);
 
                                 if (locId.equals(n.id())) {
                                     part.reload(false);
@@ -1655,17 +1662,6 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     }
 
     /**
-     * @return Current coordinator node.
-     */
-    @Nullable private ClusterNode currentCoordinator() {
-        ClusterNode oldest = cctx.discovery().oldestAliveCacheServerNode(topVer);
-
-        assert oldest != null || cctx.kernalContext().clientNode();
-
-        return oldest;
-    }
-
-    /**
      * Updates value for single partition.
      *
      * @param p Partition.
@@ -1675,7 +1671,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
      */
     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
     private long updateLocal(int p, GridDhtPartitionState state, long updateSeq) {
-        ClusterNode oldest = currentCoordinator();
+        ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
         assert oldest != null || cctx.kernalContext().clientNode();
 
@@ -1742,7 +1738,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     private void removeNode(UUID nodeId) {
         assert nodeId != null;
 
-        ClusterNode oldest = CU.oldest(cctx.discovery().serverNodes(topVer));
+        ClusterNode oldest = discoCache.oldestAliveServerNode();
 
         assert oldest != null;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 6cba4f4..b3f3d4f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -51,6 +51,7 @@ import org.apache.ignite.internal.managers.discovery.GridDiscoveryTopologySnapsh
 import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperation;
 import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationType;
 import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache;
 import org.apache.ignite.internal.processors.cache.CacheAffinityChangeMessage;
@@ -121,6 +122,10 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     /** Dummy reassign flag. */
     private final boolean reassign;
 
+    /** */
+    @GridToStringExclude
+    private volatile DiscoCache discoCache;
+
     /** Discovery event. */
     private volatile DiscoveryEvent discoEvt;
 
@@ -161,9 +166,6 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     /** */
     private boolean init;
 
-    /** Topology snapshot. */
-    private AtomicReference<GridDiscoveryTopologySnapshot> topSnapshot = new AtomicReference<>();
-
     /** Last committed cache version before next topology version use. */
     private AtomicReference<GridCacheVersion> lastVer = new AtomicReference<>();
 
@@ -386,6 +388,13 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
+     * @return Discovery cache.
+     */
+    public DiscoCache discoCache() {
+        return discoCache;
+    }
+
+    /**
      * @param cacheId Cache ID to check.
      * @param topVer Topology version.
      * @return {@code True} if cache was added during this exchange.
@@ -428,11 +437,13 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      *
      * @param exchId Exchange ID.
      * @param discoEvt Discovery event.
+     * @param discoCache Discovery data cache.
      */
-    public void onEvent(GridDhtPartitionExchangeId exchId, DiscoveryEvent discoEvt) {
+    public void onEvent(GridDhtPartitionExchangeId exchId, DiscoveryEvent discoEvt, DiscoCache discoCache) {
         assert exchId.equals(this.exchId);
 
         this.discoEvt = discoEvt;
+        this.discoCache = discoCache;
 
         evtLatch.countDown();
     }
@@ -512,7 +523,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         try {
             AffinityTopologyVersion topVer = topologyVersion();
 
-            srvNodes = new ArrayList<>(cctx.discovery().serverNodes(topVer));
+            discoCache.updateAlives(cctx.discovery());
+
+            srvNodes = new ArrayList<>(discoCache.serverNodes());
 
             remaining.addAll(F.nodeIds(F.view(srvNodes, F.remoteNodes(cctx.localNodeId()))));
 
@@ -1017,7 +1030,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         List<String> cachesWithoutNodes = null;
 
         for (String name : cctx.cache().cacheNames()) {
-            if (cctx.discovery().cacheAffinityNodes(name, topologyVersion()).isEmpty()) {
+            if (discoCache.cacheAffinityNodes(name).isEmpty()) {
                 if (cachesWithoutNodes == null)
                     cachesWithoutNodes = new ArrayList<>();
 
@@ -1446,7 +1459,6 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      * Cleans up resources to avoid excessive memory usage.
      */
     public void cleanUp() {
-        topSnapshot.set(null);
         singleMsgs.clear();
         fullMsgs.clear();
         msgs.clear();
@@ -1732,7 +1744,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
             assert partHistSuppliers.isEmpty();
 
-            if (!crd.equals(cctx.discovery().serverNodes(topologyVersion()).get(0))) {
+            if (!crd.equals(discoCache.serverNodes().get(0))) {
                 for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
                     if (!cacheCtx.isLocal())
                         cacheCtx.topology().beforeExchange(this, !centralizedAff);
@@ -2090,6 +2102,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
                         ClusterNode crd0;
 
+                        discoCache.updateAlives(node);
+
                         synchronized (mux) {
                             if (!srvNodes.remove(node))
                                 return;

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
index f1be372..94cf6e0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/service/GridServiceProcessor.java
@@ -48,7 +48,6 @@ import org.apache.ignite.compute.ComputeJobContext;
 import org.apache.ignite.configuration.DeploymentMode;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.events.DiscoveryEvent;
-import org.apache.ignite.events.Event;
 import org.apache.ignite.events.EventType;
 import org.apache.ignite.internal.GridClosureCallMode;
 import org.apache.ignite.internal.GridKernalContext;
@@ -58,8 +57,9 @@ import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
-import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
+import org.apache.ignite.internal.managers.eventstorage.DiscoveryEventListener;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.CacheAffinityChangeMessage;
@@ -168,7 +168,7 @@ public class GridServiceProcessor extends GridProcessorAdapter implements Ignite
     private IgniteInternalCache<Object, Object> cache;
 
     /** Topology listener. */
-    private GridLocalEventListener topLsnr = new TopologyListener();
+    private DiscoveryEventListener topLsnr = new TopologyListener();
 
     static {
         Set<IgniteProductVersion> versions = new TreeSet<>(new Comparator<IgniteProductVersion>() {
@@ -250,7 +250,7 @@ public class GridServiceProcessor extends GridProcessorAdapter implements Ignite
         cache = ctx.cache().utilityCache();
 
         if (!ctx.clientNode())
-            ctx.event().addLocalEventListener(topLsnr, EVTS);
+            ctx.event().addDiscoveryEventListener(topLsnr, EVTS);
 
         try {
             if (ctx.deploy().enabled())
@@ -312,7 +312,7 @@ public class GridServiceProcessor extends GridProcessorAdapter implements Ignite
                 return;
 
             if (!ctx.clientNode())
-                ctx.event().removeLocalEventListener(topLsnr);
+                ctx.event().removeDiscoveryEventListener(topLsnr);
 
             Collection<ServiceContextImpl> ctxs = new ArrayList<>();
 
@@ -1588,9 +1588,9 @@ public class GridServiceProcessor extends GridProcessorAdapter implements Ignite
     /**
      * Topology listener.
      */
-    private class TopologyListener implements GridLocalEventListener {
+    private class TopologyListener implements DiscoveryEventListener {
         /** {@inheritDoc} */
-        @Override public void onEvent(Event evt) {
+        @Override public void onEvent(DiscoveryEvent evt, final DiscoCache discoCache) {
             if (!busyLock.enterBusy())
                 return;
 
@@ -1612,11 +1612,14 @@ public class GridServiceProcessor extends GridProcessorAdapter implements Ignite
                     }
                 }
                 else
-                    topVer = new AffinityTopologyVersion(((DiscoveryEvent)evt).topologyVersion(), 0);
+                    topVer = new AffinityTopologyVersion((evt).topologyVersion(), 0);
 
                 depExe.execute(new BusyRunnable() {
                     @Override public void run0() {
-                        ClusterNode oldest = ctx.discovery().oldestAliveCacheServerNode(topVer);
+                        // In case the cache instance isn't tracked by DiscoveryManager anymore.
+                        discoCache.updateAlives(ctx.discovery());
+
+                        ClusterNode oldest = discoCache.oldestAliveServerNodeWithCache();
 
                         if (oldest != null && oldest.isLocal()) {
                             final Collection<GridServiceDeployment> retries = new ConcurrentLinkedQueue<>();

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAliveCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAliveCacheSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAliveCacheSelfTest.java
index 31b4bc7..69573d6 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAliveCacheSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManagerAliveCacheSelfTest.java
@@ -222,20 +222,6 @@ public class GridDiscoveryManagerAliveCacheSelfTest extends GridCommonAbstractTe
             long startVer = discoMgr.localNode().order();
 
             for (long v = currVer; v > currVer - GridDiscoveryManager.DISCOVERY_HISTORY_SIZE && v >= startVer; v--) {
-                F.forAll(discoMgr.aliveCacheNodes(null, new AffinityTopologyVersion(v)),
-                    new IgnitePredicate<ClusterNode>() {
-                        @Override public boolean apply(ClusterNode e) {
-                            return currTop.contains(e);
-                        }
-                    });
-
-                F.forAll(discoMgr.aliveRemoteCacheNodes(null, new AffinityTopologyVersion(v)),
-                    new IgnitePredicate<ClusterNode>() {
-                        @Override public boolean apply(ClusterNode e) {
-                            return currTop.contains(e) || g.cluster().localNode().equals(e);
-                        }
-                    });
-
                 GridCacheSharedContext<?, ?> ctx = k.context().cache().context();
 
                 ClusterNode oldest =


[16/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -refactoring RESTORE

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-refactoring RESTORE


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: a62cc454466f921e2edd26bb0a6e0646bdb3a7f1
Parents: ef35f4f
Author: EdShangGG <es...@gridgain.com>
Authored: Thu Mar 2 16:33:58 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Thu Mar 2 16:34:27 2017 +0300

----------------------------------------------------------------------
 .../pagemem/snapshot/SnapshotOperation.java     |   3 +-
 .../GridDhtPartitionsExchangeFuture.java        | 119 +++++++++++++++++--
 2 files changed, 109 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a62cc454/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
index 3f84b97..f3b5eee 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -105,7 +105,8 @@ public class SnapshotOperation implements Serializable {
      * @param op Op.
      */
     public static Collection<File> getOptionalPathsParameter(SnapshotOperation op) {
-        assert op.type() == SnapshotOperationType.CHECK || op.extraParameter() instanceof Collection;
+        assert (op.type() == SnapshotOperationType.CHECK || op.type() == SnapshotOperationType.RESTORE)
+            && (op.extraParameter() == null || op.extraParameter() instanceof Collection);
 
         return (Collection<File>)op.extraParameter();
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/a62cc454/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 987ba54..4c179e6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -48,6 +48,8 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
 import org.apache.ignite.internal.managers.discovery.GridDiscoveryTopologySnapshot;
+import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperation;
+import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationType;
 import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache;
@@ -59,6 +61,7 @@ import org.apache.ignite.internal.processors.cache.DynamicCacheChangeRequest;
 import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
+import org.apache.ignite.internal.processors.cache.GridCacheProcessor;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridClientPartitionTopology;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
@@ -81,6 +84,7 @@ import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteInClosure;
 import org.apache.ignite.lang.IgniteRunnable;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
@@ -510,10 +514,36 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
                     exchange = onCacheChangeRequest(crdNode);
                 }
-                else if (msg instanceof StartSnapshotOperationAckDiscoveryMessage)
+                else if (msg instanceof StartSnapshotOperationAckDiscoveryMessage) {
                     exchange = CU.clientNode(discoEvt.eventNode()) ?
                         onClientNodeEvent(crdNode) :
                         onServerNodeEvent(crdNode);
+
+                    StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg = (StartSnapshotOperationAckDiscoveryMessage)msg;
+
+                    if (!cctx.localNode().isDaemon()) {
+                        SnapshotOperation op = snapshotOperationMsg.snapshotOperation();
+
+                        if (op.type() == SnapshotOperationType.RESTORE) {
+                            if (reqs != null)
+                                reqs = new ArrayList<>(reqs);
+                            else
+                                reqs = new ArrayList<>();
+
+                            List<DynamicCacheChangeRequest> destroyRequests = getStopCacheRequests(
+                                cctx.cache(), op.cacheNames(), cctx.localNodeId());
+
+                            reqs.addAll(destroyRequests);
+
+                            if (!reqs.isEmpty()) { //Emulate destroy cache request
+                                if (op.type() == SnapshotOperationType.RESTORE)
+                                    cctx.cache().onCustomEvent(new DynamicCacheChangeBatch(reqs), topVer);
+
+                                onCacheChangeRequest(crdNode);
+                            }
+                        }
+                    }
+                }
                 else {
                     assert affChangeMsg != null : this;
 
@@ -578,6 +608,36 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
+     * @param cache Cache.
+     * @param cacheNames Cache names.
+     * @param locNodeId Local node id.
+     */
+    @NotNull public static List<DynamicCacheChangeRequest> getStopCacheRequests(GridCacheProcessor cache,
+        Set<String> cacheNames, UUID locNodeId) {
+        List<DynamicCacheChangeRequest> destroyRequests = new ArrayList<>();
+
+        for (String cacheName : cacheNames) {
+            DynamicCacheDescriptor desc = cache.cacheDescriptor(CU.cacheId(cacheName));
+
+            if (desc == null)
+                continue;
+
+            DynamicCacheChangeRequest t = new DynamicCacheChangeRequest(UUID.randomUUID(), cacheName, locNodeId);
+
+            t.stop(true);
+            t.destroy(true);
+
+            t.deploymentId(desc.deploymentId());
+
+            t.restart(true);
+
+            destroyRequests.add(t);
+        }
+
+        return destroyRequests;
+    }
+
+    /**
      * @throws IgniteCheckedException If failed.
      */
     private void initTopologies() throws IgniteCheckedException {
@@ -806,19 +866,15 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
         cctx.database().beforeExchange(this);
 
-        // If a backup request, synchronously wait for backup start.
-        if (discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT) {
-            DiscoveryCustomMessage customMsg = ((DiscoveryCustomEvent)discoEvt).customMessage();
-
-            if (customMsg instanceof StartSnapshotOperationAckDiscoveryMessage) {
-                StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg = (StartSnapshotOperationAckDiscoveryMessage)customMsg;
+        StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg = getSnapshotOperationMessage();
 
-                if (!cctx.localNode().isClient() && !cctx.localNode().isDaemon()) {
-                    IgniteInternalFuture fut = cctx.database().startLocalSnapshotOperation(snapshotOperationMsg);
+        // If it's a snapshot operation request, synchronously wait for backup start.
+        if (snapshotOperationMsg != null) {
+            if (!cctx.localNode().isClient() && !cctx.localNode().isDaemon()) {
+                SnapshotOperation op = snapshotOperationMsg.snapshotOperation();
 
-                    if (fut != null)
-                        fut.get();
-                }
+                if (op.type() != SnapshotOperationType.RESTORE)
+                    startLocalSnasphotOperation(snapshotOperationMsg);
             }
         }
 
@@ -833,6 +889,17 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
+     * @param snapshotOperationMsg Snapshot operation message.
+     */
+    private void startLocalSnasphotOperation(StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg
+    ) throws IgniteCheckedException {
+        IgniteInternalFuture fut = cctx.database().startLocalSnapshotOperation(snapshotOperationMsg);
+
+        if (fut != null)
+            fut.get();
+    }
+
+    /**
      * @throws IgniteCheckedException If failed.
      */
     private void waitPartitionRelease() throws IgniteCheckedException {
@@ -1168,6 +1235,20 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                 cctx.cache().completeStartFuture(req);
         }
 
+        StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg = getSnapshotOperationMessage();
+
+        if (snapshotOperationMsg != null && !cctx.localNode().isClient() && !cctx.localNode().isDaemon()) {
+            SnapshotOperation op = snapshotOperationMsg.snapshotOperation();
+
+            if (op.type() == SnapshotOperationType.RESTORE)
+                try {
+                    startLocalSnasphotOperation(snapshotOperationMsg);
+                }
+                catch (IgniteCheckedException e) {
+                    log.error("Error while starting snapshot operation", e);
+                }
+        }
+
         if (exchangeOnChangeGlobalState && err == null)
             cctx.kernalContext().state().onExchangeDone();
 
@@ -1196,6 +1277,20 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         return dummy;
     }
 
+    /**
+     *
+     */
+    private StartSnapshotOperationAckDiscoveryMessage getSnapshotOperationMessage() {
+        // If it's a snapshot operation request, synchronously wait for backup start.
+        if (discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT) {
+            DiscoveryCustomMessage customMsg = ((DiscoveryCustomEvent)discoEvt).customMessage();
+
+            if (customMsg instanceof StartSnapshotOperationAckDiscoveryMessage)
+                return  (StartSnapshotOperationAckDiscoveryMessage)customMsg;
+        }
+        return null;
+    }
+
     /** {@inheritDoc} */
     @Nullable @Override public Throwable validateCache(
         GridCacheContext cctx,


[17/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -fixing race with operation finish message

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-fixing race with operation finish message


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: b51a2f8006a13a24e7115c44bcb7124ee20be255
Parents: a62cc45
Author: EdShangGG <es...@gridgain.com>
Authored: Thu Mar 2 22:20:08 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Thu Mar 2 22:20:08 2017 +0300

----------------------------------------------------------------------
 .../StartFullSnapshotDiscoveryMessage.java      | 164 ------------------
 ...artSnapshotOperationAckDiscoveryMessage.java |  12 ++
 .../StartSnapshotOperationDiscoveryMessage.java | 167 +++++++++++++++++++
 .../resources/META-INF/classnames.properties    |   2 +-
 4 files changed, 180 insertions(+), 165 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b51a2f80/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
deleted file mode 100644
index 3a67e49..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.pagemem.snapshot;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
-import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.lang.IgniteUuid;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Message indicating that a snapshot has been started.
- */
-public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** Custom message ID. */
-    private IgniteUuid id = IgniteUuid.randomUuid();
-
-    /** Snapshot operation. */
-    private SnapshotOperation snapshotOperation;
-
-    /** */
-    private UUID initiatorId;
-
-    /** Error. */
-    private Exception err;
-
-    /** Last full snapshot id for cache. */
-    private Map<Integer, Long> lastFullSnapshotIdForCache = new HashMap<>();
-
-    /** Last snapshot id for cache. */
-    private Map<Integer, Long> lastSnapshotIdForCache = new HashMap<>();
-
-    /**
-     * @param snapshotOperation Snapshot operation
-     * @param initiatorId initiator node id
-     */
-    public StartFullSnapshotDiscoveryMessage(
-        SnapshotOperation snapshotOperation,
-        UUID initiatorId
-    ) {
-        this.snapshotOperation = snapshotOperation;
-        this.initiatorId = initiatorId;
-    }
-
-    /**
-     *
-     */
-    public SnapshotOperation snapshotOperation() {
-        return snapshotOperation;
-    }
-
-    /**
-     * Sets error.
-     *
-     * @param err Error.
-     */
-    public void error(Exception err) {
-        this.err = err;
-    }
-
-    /**
-     * @return {@code True} if message contains error.
-     */
-    public boolean hasError() {
-        return err != null;
-    }
-
-    /**
-     * @return Error.
-     */
-    public Exception error() {
-        return err;
-    }
-
-    /**
-     * @return Initiator node id.
-     */
-    public UUID initiatorId() {
-        return initiatorId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public IgniteUuid id() {
-        return id;
-    }
-
-    /**
-     * @param cacheId Cache id.
-     */
-    public Long lastFullSnapshotId(int cacheId) {
-        return lastFullSnapshotIdForCache.get(cacheId);
-    }
-
-    /**
-     * @param cacheId Cache id.
-     * @param id Id.
-     */
-    public void lastFullSnapshotId(int cacheId, long id) {
-        lastFullSnapshotIdForCache.put(cacheId, id);
-    }
-
-    /**
-     * @param cacheId Cache id.
-     */
-    public Long lastSnapshotId(int cacheId) {
-        return lastSnapshotIdForCache.get(cacheId);
-    }
-
-    /**
-     * @param cacheId Cache id.
-     * @param id Id.
-     */
-    public void lastSnapshotId(int cacheId, long id) {
-        lastSnapshotIdForCache.put(cacheId, id);
-    }
-
-    /** {@inheritDoc} */
-    @Nullable @Override public DiscoveryCustomMessage ackMessage() {
-        return new StartSnapshotOperationAckDiscoveryMessage(
-            snapshotOperation,
-            lastFullSnapshotIdForCache,
-            lastSnapshotIdForCache,
-            err,
-            initiatorId);
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isMutable() {
-        return true;
-    }
-
-    /**
-     * @param snapshotOperation new snapshot operation
-     */
-    public void snapshotOperation(SnapshotOperation snapshotOperation) {
-        this.snapshotOperation = snapshotOperation;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return S.toString(StartFullSnapshotDiscoveryMessage.class, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/b51a2f80/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
index e84b2e8..72defd4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
@@ -38,6 +38,9 @@ public class StartSnapshotOperationAckDiscoveryMessage implements DiscoveryCusto
     /** Custom message ID. */
     private IgniteUuid id = IgniteUuid.randomUuid();
 
+    /** Operation id. */
+    private IgniteUuid opId;
+
     /** */
     private Exception err;
 
@@ -55,12 +58,14 @@ public class StartSnapshotOperationAckDiscoveryMessage implements DiscoveryCusto
      * @param err Error.
      */
     public StartSnapshotOperationAckDiscoveryMessage(
+        IgniteUuid id,
         SnapshotOperation snapshotOperation,
         Map<Integer, Long> lastFullSnapshotIdForCache,
         Map<Integer, Long> lastSnapshotIdForCache,
         Exception err,
         UUID initiatorNodeId
     ) {
+        this.opId = id;
         this.snapshotOperation = snapshotOperation;
         this.lastFullSnapshotIdForCache = lastFullSnapshotIdForCache;
         this.lastSnapshotIdForCache = lastSnapshotIdForCache;
@@ -74,6 +79,13 @@ public class StartSnapshotOperationAckDiscoveryMessage implements DiscoveryCusto
     }
 
     /**
+     *
+     */
+    public IgniteUuid operationId() {
+        return opId;
+    }
+
+    /**
      * @return Initiator node id.
      */
     public UUID initiatorNodeId() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/b51a2f80/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
new file mode 100644
index 0000000..2373a9b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationDiscoveryMessage.java
@@ -0,0 +1,167 @@
+/*
+ * 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.pagemem.snapshot;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Message indicating that a snapshot has been started.
+ */
+public class StartSnapshotOperationDiscoveryMessage implements DiscoveryCustomMessage {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Custom message ID. */
+    private IgniteUuid id;
+
+    /** Snapshot operation. */
+    private SnapshotOperation snapshotOperation;
+
+    /** */
+    private UUID initiatorId;
+
+    /** Error. */
+    private Exception err;
+
+    /** Last full snapshot id for cache. */
+    private Map<Integer, Long> lastFullSnapshotIdForCache = new HashMap<>();
+
+    /** Last snapshot id for cache. */
+    private Map<Integer, Long> lastSnapshotIdForCache = new HashMap<>();
+
+    /**
+     * @param snapshotOperation Snapshot operation
+     * @param initiatorId initiator node id
+     */
+    public StartSnapshotOperationDiscoveryMessage(
+        IgniteUuid id,
+        SnapshotOperation snapshotOperation,
+        UUID initiatorId
+    ) {
+        this.id = id;
+        this.snapshotOperation = snapshotOperation;
+        this.initiatorId = initiatorId;
+    }
+
+    /**
+     *
+     */
+    public SnapshotOperation snapshotOperation() {
+        return snapshotOperation;
+    }
+
+    /**
+     * Sets error.
+     *
+     * @param err Error.
+     */
+    public void error(Exception err) {
+        this.err = err;
+    }
+
+    /**
+     * @return {@code True} if message contains error.
+     */
+    public boolean hasError() {
+        return err != null;
+    }
+
+    /**
+     * @return Error.
+     */
+    public Exception error() {
+        return err;
+    }
+
+    /**
+     * @return Initiator node id.
+     */
+    public UUID initiatorId() {
+        return initiatorId;
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteUuid id() {
+        return id;
+    }
+
+    /**
+     * @param cacheId Cache id.
+     */
+    public Long lastFullSnapshotId(int cacheId) {
+        return lastFullSnapshotIdForCache.get(cacheId);
+    }
+
+    /**
+     * @param cacheId Cache id.
+     * @param id Id.
+     */
+    public void lastFullSnapshotId(int cacheId, long id) {
+        lastFullSnapshotIdForCache.put(cacheId, id);
+    }
+
+    /**
+     * @param cacheId Cache id.
+     */
+    public Long lastSnapshotId(int cacheId) {
+        return lastSnapshotIdForCache.get(cacheId);
+    }
+
+    /**
+     * @param cacheId Cache id.
+     * @param id Id.
+     */
+    public void lastSnapshotId(int cacheId, long id) {
+        lastSnapshotIdForCache.put(cacheId, id);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public DiscoveryCustomMessage ackMessage() {
+        return new StartSnapshotOperationAckDiscoveryMessage(
+            id,
+            snapshotOperation,
+            lastFullSnapshotIdForCache,
+            lastSnapshotIdForCache,
+            err,
+            initiatorId);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isMutable() {
+        return true;
+    }
+
+    /**
+     * @param snapshotOperation new snapshot operation
+     */
+    public void snapshotOperation(SnapshotOperation snapshotOperation) {
+        this.snapshotOperation = snapshotOperation;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(StartSnapshotOperationDiscoveryMessage.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/b51a2f80/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index 13a3bce..1750276 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -329,7 +329,7 @@ org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl$Segment
 org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationFinishedMessage
 org.apache.ignite.internal.pagemem.snapshot.SnapshotProgressMessage
 org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage
-org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotDiscoveryMessage
+org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationDiscoveryMessage
 org.apache.ignite.internal.pagemem.wal.StorageException
 org.apache.ignite.internal.pagemem.wal.WALIterator
 org.apache.ignite.internal.pagemem.wal.record.StoreOperationRecord$StoreOperationType


[44/50] [abbrv] ignite git commit: IGNITE-4920 Fixed.

Posted by sb...@apache.org.
IGNITE-4920 Fixed.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: ead06b06f4b164998bfc5853dfa28cac4b618d8d
Parents: f2c9d6c
Author: Aleksei Scherbakov <al...@gmail.com>
Authored: Mon Apr 10 19:46:18 2017 +0300
Committer: Aleksei Scherbakov <al...@gmail.com>
Committed: Mon Apr 10 19:46:18 2017 +0300

----------------------------------------------------------------------
 .../deployment/local/LocalDeploymentSpi.java    |  12 +-
 .../p2p/GridP2PLocalDeploymentSelfTest.java     | 109 +++++++++++++++++++
 2 files changed, 120 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ead06b06/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
index 68ef178..87fa452 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.ConcurrentMap;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.compute.ComputeTask;
 import org.apache.ignite.compute.ComputeTaskName;
 import org.apache.ignite.internal.util.GridAnnotationsCache;
@@ -68,6 +69,13 @@ import org.jsr166.ConcurrentLinkedHashMap;
 @IgnoreIfPeerClassLoadingDisabled
 public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSpi, LocalDeploymentSpiMBean {
     /** */
+    public static final String IGNITE_DEPLOYMENT_ADDITIONAL_CHECK = "ignite.deployment.additional.check";
+
+    /** */
+    private static final boolean ENABLE_IGNITE_DEPLOYMENT_ADDITIONAL_CHECK =
+        IgniteSystemProperties.getBoolean(IGNITE_DEPLOYMENT_ADDITIONAL_CHECK);
+
+    /** */
     @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"})
     @LoggerResource
     private IgniteLogger log;
@@ -333,7 +341,9 @@ public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSp
                     // Check classes with class loader only when classes points to classes to avoid redundant check.
                     // Resources map contains two entries for class with task name(alias).
                     if (entry.getKey().equals(entry.getValue()) && isResourceExist(ldr, entry.getKey()) &&
-                        !U.hasParent(clsLdrToIgnore, ldr) && ldrRsrcs.remove(ldr, clsLdrRsrcs)) {
+                        !U.hasParent(clsLdrToIgnore, ldr) &&
+                        (!ENABLE_IGNITE_DEPLOYMENT_ADDITIONAL_CHECK || clsLdrRsrcs.containsKey(entry.getKey())) &&
+                        ldrRsrcs.remove(ldr, clsLdrRsrcs)) {
                         // Add class loaders in collection to notify listener outside synchronization block.
                         rmvClsLdrs.add(ldr);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ead06b06/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PLocalDeploymentSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PLocalDeploymentSelfTest.java b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PLocalDeploymentSelfTest.java
index 05f102c..8884ea8 100644
--- a/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PLocalDeploymentSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/p2p/GridP2PLocalDeploymentSelfTest.java
@@ -24,6 +24,9 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.cluster.ClusterNode;
@@ -33,11 +36,17 @@ import org.apache.ignite.compute.ComputeJobResult;
 import org.apache.ignite.compute.ComputeTaskAdapter;
 import org.apache.ignite.configuration.DeploymentMode;
 import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.lang.GridPeerDeployAware;
+import org.apache.ignite.lang.IgniteCallable;
 import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.testframework.config.GridTestProperties;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.testframework.junits.common.GridCommonTest;
 
+import static org.apache.ignite.IgniteSystemProperties.IGNITE_CACHE_REMOVED_ENTRIES_TTL;
+import static org.apache.ignite.spi.deployment.local.LocalDeploymentSpi.IGNITE_DEPLOYMENT_ADDITIONAL_CHECK;
+
 /**
  * Test to make sure that if job executes on the same node, it reuses the same class loader as task.
  */
@@ -205,6 +214,106 @@ public class GridP2PLocalDeploymentSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Tests concurrent deployment using delegating classloader for the task.
+     */
+    public void testConcurrentDeploymentWithDelegatingClassloader() throws Exception {
+        depMode = DeploymentMode.SHARED;
+
+        // Force rmvQueue removal task to run very often.
+        System.setProperty(IGNITE_CACHE_REMOVED_ENTRIES_TTL, "1");
+        System.setProperty(IGNITE_DEPLOYMENT_ADDITIONAL_CHECK, "true");
+
+        try {
+            final Ignite ignite = startGrid();
+
+            final ClassLoader delegate = ignite.getClass().getClassLoader();
+
+            final ClassLoader root = new DelegateClassLoader(null, delegate);
+
+            final AtomicBoolean stop = new AtomicBoolean();
+
+            IgniteInternalFuture<?> fut = multithreadedAsync(new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    while (!stop.get()) {
+                        final Class<?> clazz = root.loadClass("org.apache.ignite.p2p.GridP2PLocalDeploymentSelfTest$TestClosure");
+
+                        ignite.compute().
+                            call((IgniteCallable) clazz.getDeclaredConstructor(ClassLoader.class).newInstance(root));
+                    }
+
+                    return null;
+                }
+            }, 1);
+
+            ignite.scheduler().runLocal(new Runnable() {
+                @Override public void run() {
+                    stop.set(true);
+                }
+            }, 10, TimeUnit.SECONDS);
+
+            fut.get();
+        } finally {
+            stopAllGrids();
+
+            System.clearProperty(IGNITE_CACHE_REMOVED_ENTRIES_TTL);
+            System.clearProperty(IGNITE_DEPLOYMENT_ADDITIONAL_CHECK);
+        }
+    }
+
+    /** */
+    private static class TestClosure implements IgniteCallable, GridPeerDeployAware {
+        /** */
+        transient ClassLoader clsLdr;
+
+        /**
+         * @param cls Class.
+         */
+        public TestClosure(ClassLoader cls) {
+            this.clsLdr = cls;
+        }
+
+        /** {@inheritDoc} */
+        public Object call() throws Exception {
+            return null;
+        }
+
+        /** {@inheritDoc} */
+        public Class<?> deployClass() {
+            return this.getClass();
+        }
+
+        /** {@inheritDoc} */
+        public ClassLoader classLoader() {
+            return clsLdr;
+        }
+    }
+
+    /** */
+    private static class DelegateClassLoader extends ClassLoader {
+        /** Delegate class loader. */
+        private ClassLoader delegateClsLdr;
+
+        /**
+         * @param parent Parent.
+         * @param delegateClsLdr Delegate class loader.
+         */
+        public DelegateClassLoader(ClassLoader parent, ClassLoader delegateClsLdr) {
+            super(parent); // Parent doesn't matter.
+            this.delegateClsLdr = delegateClsLdr;
+        }
+
+        /** {@inheritDoc} */
+        @Override public URL getResource(String name) {
+            return delegateClsLdr.getResource(name);
+        }
+
+        /** {@inheritDoc} */
+        @Override public Class<?> loadClass(String name) throws ClassNotFoundException {
+            return delegateClsLdr.loadClass(name);
+        }
+    }
+
+    /**
      * Simple resource.
      */
     public static class UserResource {


[12/50] [abbrv] ignite git commit: ignite-4484 Call commit for read-only transactions (reverted changes introduced in ignite-3601).

Posted by sb...@apache.org.
ignite-4484 Call commit for read-only transactions (reverted changes introduced in ignite-3601).

(cherry picked from commit d77fe815395dcd2871d7)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: d13520e9a05bd9e9b987529472d6317951b72f96
Parents: 9e6b8cc
Author: sboikov <sb...@gridgain.com>
Authored: Wed Feb 22 11:47:38 2017 +0300
Committer: Evgeny Stanilovskiy <es...@gridgain.com>
Committed: Mon Feb 27 09:44:47 2017 +0300

----------------------------------------------------------------------
 .../cache/distributed/near/GridNearTxLocal.java |   2 +-
 .../cache/CacheGetEntryAbstractTest.java        |  16 +-
 .../CacheSerializableTransactionsTest.java      | 173 +++++++++++++++++--
 .../processors/cache/CacheTxFastFinishTest.java |   2 +-
 4 files changed, 170 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d13520e9/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index ba48e7a..66a3a95 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -958,7 +958,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
      * @return {@code True} if 'fast finish' path can be used for transaction completion.
      */
     private boolean fastFinish() {
-        return writeMap().isEmpty() && (optimistic() || readMap().isEmpty());
+        return writeMap().isEmpty() && ((optimistic() && !serializable()) || readMap().isEmpty());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/d13520e9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGetEntryAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGetEntryAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGetEntryAbstractTest.java
index 8a2a86e..320d06b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGetEntryAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheGetEntryAbstractTest.java
@@ -267,25 +267,27 @@ public abstract class CacheGetEntryAbstractTest extends GridCacheAbstractSelfTes
      */
     private void testConcurrentOptimisticTxGet(final IgniteCache<Integer, TestValue> cache,
         final TransactionIsolation txIsolation) throws Exception {
+        final int key1 = 42;
+        final int key2 = 43;
+
+        cache.put(key1, new TestValue(key1));
+
         GridTestUtils.runMultiThreaded(new Runnable() {
             @Override public void run() {
-                final int key = 42;
-
                 IgniteTransactions txs = grid(0).transactions();
 
-                cache.put(key, new TestValue(key));
+                cache.put(key2, new TestValue(key2));
 
                 long stopTime = System.currentTimeMillis() + 3000;
 
                 while (System.currentTimeMillis() < stopTime) {
                     try (Transaction tx = txs.txStart(OPTIMISTIC, txIsolation)) {
-                        cache.get(key);
+                        cache.get(key1);
 
                         tx.commit();
                     }
-                    catch (TransactionOptimisticException e) {
-                        assertTrue("Should not throw optimistic exception in only read TX. Tx isolation: "
-                            + txIsolation, false);
+                    catch (Exception ignored) {
+                        fail("Unexpected exception: " + ignored);
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d13520e9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
index ce2e75d..f78db62 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheSerializableTransactionsTest.java
@@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentSkipListSet;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.CyclicBarrier;
 import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import javax.cache.Cache;
@@ -748,6 +749,11 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
                         updateKey(cache, key, 1);
 
                         tx.commit();
+
+                        fail();
+                    }
+                    catch (TransactionOptimisticException e) {
+                        log.info("Expected exception: " + e);
                     }
 
                     checkValue(key, 1, cache.getName());
@@ -2914,7 +2920,8 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
                                         sum += account.value();
                                     }
 
-                                    cache.put(putKey, new Account(sum));
+                                    if (ThreadLocalRandom.current().nextBoolean())
+                                        cache.put(putKey, new Account(sum));
 
                                     tx.commit();
                                 }
@@ -3204,14 +3211,21 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
             cache0.put(key2, -1);
             cache0.put(key3, -1);
 
-            try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
-                cache.get(key1);
-                cache.get(key2);
-                cache.get(key3);
+            try {
+                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                    cache.get(key1);
+                    cache.get(key2);
+                    cache.get(key3);
 
-                updateKey(near ? cache : cache0, key2, -2);
+                    updateKey(near ? cache : cache0, key2, -2);
 
-                tx.commit();
+                    tx.commit();
+                }
+
+                fail();
+            }
+            catch (TransactionOptimisticException e) {
+                log.info("Expected exception: " + e);
             }
 
             checkValue(key1, -1, cacheName);
@@ -3462,16 +3476,23 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
                 checkValue(key1, newVal, CACHE1);
                 checkValue(key2, newVal, CACHE2);
 
-                try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
-                    Object val1 = cache1.get(key1);
-                    Object val2 = cache2.get(key2);
+                try {
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        Object val1 = cache1.get(key1);
+                        Object val2 = cache2.get(key2);
 
-                    assertEquals(newVal, val1);
-                    assertEquals(newVal, val2);
+                        assertEquals(newVal, val1);
+                        assertEquals(newVal, val2);
 
-                    updateKey(cache2, key2, newVal);
+                        updateKey(cache2, key2, newVal);
 
-                    tx.commit();
+                        tx.commit();
+                    }
+
+                    fail();
+                }
+                catch (TransactionOptimisticException e) {
+                    log.info("Expected exception: " + e);
                 }
 
                 try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
@@ -4480,6 +4501,130 @@ public class CacheSerializableTransactionsTest extends GridCommonAbstractTest {
     }
 
     /**
+     * Multithreaded transactional reads.
+     *
+     * @throws Exception If failed.
+     */
+    public void testMultipleOptimisticRead() throws Exception {
+        final Ignite ignite = ignite(0);
+        final Integer key = 1;
+        final Integer val = 1;
+        final int THREADS_CNT = 50;
+
+        final String cacheName =
+            ignite.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false)).getName();
+
+        try {
+            final IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+            try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+                cache.put(key, val);
+
+                tx.commit();
+            }
+
+            assertTrue(cache.get(key).equals(val));
+
+            for (int i = 0; i < 10; i++) {
+                GridTestUtils.runMultiThreadedAsync(new Callable<Void>() {
+                    @Override public Void call() throws Exception {
+                        IgniteTransactions txs = cache.unwrap(Ignite.class).transactions();
+
+                        try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                            assertTrue(cache.get(key).equals(val));
+
+                            tx.commit();
+
+                        }
+                        return null;
+                    }
+                }, THREADS_CNT, "multiple-reads-thread").get();
+            }
+        }
+        finally {
+                destroyCache(cacheName);
+        }
+    }
+
+    /**
+     * Transactional read in parallel with changing the same data.
+     *
+     * @throws Exception If failed.
+     */
+    public void testTxReadInParallerTxWrite() throws Exception {
+        final Ignite ignite = ignite(0);
+        final Integer key = 1;
+        final Integer val = 1;
+
+        final CountDownLatch readLatch = new CountDownLatch(1);
+        final CountDownLatch writeLatch = new CountDownLatch(1);
+
+        final Exception[] err = {null};
+
+        final String cacheName =
+            ignite.createCache(cacheConfiguration(PARTITIONED, FULL_SYNC, 1, false, false)).getName();
+
+        final IgniteCache<Integer, Integer> cache = ignite.cache(cacheName);
+
+        try (Transaction tx = ignite.transactions().txStart(OPTIMISTIC, SERIALIZABLE)) {
+            cache.put(key, val);
+
+            tx.commit();
+        }
+
+        try {
+            IgniteInternalFuture<?> fut = GridTestUtils.runAsync(new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    IgniteTransactions txs = cache.unwrap(Ignite.class).transactions();
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        assertTrue(cache.get(key).equals(val));
+
+                        readLatch.countDown();
+
+                        writeLatch.await(10, TimeUnit.SECONDS);
+
+                        try {
+                            tx.commit();
+                        }
+                        catch (TransactionOptimisticException e) {
+                            log.info("Expected exception: " + e);
+
+                            err[0] = e;
+                        }
+                    }
+                    return null;
+                }
+            }, "read-thread");
+
+            GridTestUtils.runAsync(new Callable<Void>() {
+                @Override public Void call() throws Exception {
+                    IgniteTransactions txs = cache.unwrap(Ignite.class).transactions();
+
+                    readLatch.await(10, TimeUnit.SECONDS);
+
+                    try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
+                        cache.put(key, val);
+
+                        tx.commit();
+                    }
+
+                    writeLatch.countDown();
+
+                    return null;
+                }
+            }, "write-thread").get();
+
+            fut.get();
+
+            assertNotNull("Expected exception was not thrown", err[0]);
+        }
+        finally {
+            destroyCache(cacheName);
+        }
+    }
+
+    /**
      * @throws Exception If failed.
      */
     public void testConcurrentUpdateNoDeadlock() throws Exception {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d13520e9/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTxFastFinishTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTxFastFinishTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTxFastFinishTest.java
index f9c6683..35b1405 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTxFastFinishTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/CacheTxFastFinishTest.java
@@ -173,7 +173,7 @@ public class CacheTxFastFinishTest extends GridCommonAbstractTest {
                 try (Transaction tx = txs.txStart(OPTIMISTIC, SERIALIZABLE)) {
                     cache.get(i);
 
-                    checkFastTxFinish(tx, commit);
+                    checkNormalTxFinish(tx, commit);
                 }
 
                 try (Transaction tx = txs.txStart(PESSIMISTIC, REPEATABLE_READ)) {


[46/50] [abbrv] ignite git commit: IGNITE-4920 Uppercase system prop.

Posted by sb...@apache.org.
IGNITE-4920 Uppercase system prop.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: a3ad6e04c163718306044573be7b30fe636ad193
Parents: 9ad0883
Author: Aleksei Scherbakov <al...@gmail.com>
Authored: Wed Apr 12 16:07:33 2017 +0300
Committer: Aleksei Scherbakov <al...@gmail.com>
Committed: Wed Apr 12 16:07:33 2017 +0300

----------------------------------------------------------------------
 .../org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a3ad6e04/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
index 66f0326..741335b 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/deployment/local/LocalDeploymentSpi.java
@@ -69,7 +69,7 @@ import org.jsr166.ConcurrentLinkedHashMap;
 @IgnoreIfPeerClassLoadingDisabled
 public class LocalDeploymentSpi extends IgniteSpiAdapter implements DeploymentSpi, LocalDeploymentSpiMBean {
     /** Enables additional check for resource name on resources removal. */
-    public static final String IGNITE_DEPLOYMENT_ADDITIONAL_CHECK = "ignite.deployment.additional.check";
+    public static final String IGNITE_DEPLOYMENT_ADDITIONAL_CHECK = "IGNITE.DEPLOYMENT.ADDITIONAL.CHECK";
 
     /** Value for additional check on resources removal. */
     private static final boolean ENABLE_IGNITE_DEPLOYMENT_ADDITIONAL_CHECK =


[42/50] [abbrv] ignite git commit: Merge remote-tracking branch 'origin/ignite-gg-8.0.3.ea4' into GG-11860-2

Posted by sb...@apache.org.
Merge remote-tracking branch 'origin/ignite-gg-8.0.3.ea4' into GG-11860-2


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: c540206e8350a5625c854a38791b0d094a996d55
Parents: 8893337 0f5cadf
Author: EdShangGG <es...@gridgain.com>
Authored: Thu Apr 6 15:43:26 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Thu Apr 6 15:43:26 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/processors/cache/GridCacheAdapter.java  | 9 +++++++--
 .../ignite/internal/processors/cache/GridCacheGateway.java  | 4 ++--
 .../dht/atomic/GridNearAtomicUpdateResponse.java            | 2 +-
 3 files changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------



[29/50] [abbrv] ignite git commit: implement U.ensureDirectory() for Path

Posted by sb...@apache.org.
implement U.ensureDirectory() for Path


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 2d3d5eb229728ef984ead430b00720e423c50102
Parents: 0693a9a
Author: Alexandr Kuramshin <ak...@gridgain.com>
Authored: Sun Mar 19 19:13:21 2017 +0700
Committer: Alexandr Kuramshin <ak...@gridgain.com>
Committed: Sun Mar 19 19:13:21 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/util/IgniteUtils.java       | 26 ++++++++++++++++++++
 1 file changed, 26 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2d3d5eb2/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
old mode 100644
new mode 100755
index 4892917..e8cb32b
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -9167,6 +9167,32 @@ public abstract class IgniteUtils {
     }
 
     /**
+     * Checks if the given directory exists and attempts to create one if not.
+     *
+     * @param dir Directory to check.
+     * @param msg Directory name for the messages.
+     * @param log Optional logger to log a message that the directory has been resolved.
+     * @throws IgniteCheckedException If directory does not exist and failed to create it, or if a file with
+     *      the same name already exists.
+     */
+    public static void ensureDirectory(Path dir, String msg, IgniteLogger log) throws IgniteCheckedException {
+        if (!Files.exists(dir)) {
+            try {
+                Files.createDirectories(dir);
+            }
+            catch (IOException e) {
+                throw new IgniteCheckedException("Failed to create " + msg + ": " + dir.toAbsolutePath(), e);
+            }
+        }
+        else if (!Files.isDirectory(dir))
+            throw new IgniteCheckedException("Failed to initialize " + msg +
+                " (a file with the same name already exists): " + dir.toAbsolutePath());
+
+        if (log != null && log.isInfoEnabled())
+            log.info("Resolved " + msg + ": " + dir.toAbsolutePath());
+    }
+
+    /**
      * Creates {@code IgniteCheckedException} with the collection of suppressed exceptions.
      *
      * @param msg Message.


[11/50] [abbrv] ignite git commit: Fixed NPE in IgniteProcessProxy.kill() (cherry picked from commit 11bc058)

Posted by sb...@apache.org.
Fixed NPE in IgniteProcessProxy.kill()
(cherry picked from commit 11bc058)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 9e6b8ccea36ba2665cbe4e91c59a35a26590f9ae
Parents: 4c97f43
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Fri Feb 17 18:45:17 2017 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Wed Feb 22 22:00:22 2017 +0700

----------------------------------------------------------------------
 .../testframework/junits/multijvm/IgniteProcessProxy.java       | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9e6b8cce/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
index 2ef9c59..4f204c4 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/multijvm/IgniteProcessProxy.java
@@ -241,9 +241,12 @@ public class IgniteProcessProxy implements IgniteEx {
      * @param gridName Grid name.
      */
     public static void kill(String gridName) {
+        A.notNull(gridName, "gridName");
+
         IgniteProcessProxy proxy = gridProxies.get(gridName);
 
-        A.notNull(gridName, "gridName");
+        if (proxy == null)
+            return;
 
         try {
             proxy.getProcess().kill();


[39/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -fixing tests

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-fixing tests


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 1229d2f1eaa8cf0fbdbc9b2409e089af4ce00fd9
Parents: d37d4df
Author: EdShangGG <es...@gridgain.com>
Authored: Mon Apr 3 13:59:05 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Mon Apr 3 13:59:05 2017 +0300

----------------------------------------------------------------------
 .../snapshot/FinishSnapshotOperationAckDiscoveryMessage.java      | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1229d2f1/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
index e19ddc4..1e5ed42 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/FinishSnapshotOperationAckDiscoveryMessage.java
@@ -25,6 +25,9 @@ import org.jetbrains.annotations.Nullable;
  *
  */
 public class FinishSnapshotOperationAckDiscoveryMessage implements DiscoveryCustomMessage {
+    /** */
+    private static final long serialVersionUID = 0L;
+
     /** Id. */
     private final IgniteUuid id = IgniteUuid.randomUuid();
 


[03/50] [abbrv] ignite git commit: Merge inline indexes

Posted by sb...@apache.org.
Merge inline indexes


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 56fadcd27fe321b79417a917404cf744e1549a10
Parents: 63e6a21 8f836cb
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Feb 16 14:55:27 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Feb 16 14:55:27 2017 +0300

----------------------------------------------------------------------
 .../benchmarks/jmh/tree/BPlusTreeBenchmark.java |  13 +-
 .../apache/ignite/IgniteSystemProperties.java   |   7 +
 .../org/apache/ignite/cache/QueryIndex.java     |  21 ++
 .../configuration/CacheConfiguration.java       |  35 ++-
 .../apache/ignite/internal/IgniteKernal.java    |   9 +-
 .../apache/ignite/internal/pagemem/Page.java    |   2 +-
 .../ignite/internal/pagemem/PageIdUtils.java    |   2 +-
 .../ignite/internal/pagemem/PageMemory.java     |   9 +-
 .../pagemem/impl/PageMemoryNoStoreImpl.java     |  28 +-
 .../internal/pagemem/wal/record/WALRecord.java  |   5 +-
 .../pagemem/wal/record/delta/InsertRecord.java  |  25 +-
 .../delta/MetaPageInitRootInlineRecord.java     |  62 ++++
 .../record/delta/MetaPageInitRootRecord.java    |   3 +-
 .../wal/record/delta/NewRootInitRecord.java     |  26 +-
 .../pagemem/wal/record/delta/ReplaceRecord.java |  23 +-
 .../cache/IgniteCacheOffheapManagerImpl.java    |  54 +---
 .../IgniteCacheDatabaseSharedManager.java       |   9 +
 .../cache/database/MetadataStorage.java         |  57 +---
 .../cache/database/freelist/FreeList.java       |   6 +
 .../cache/database/freelist/FreeListImpl.java   | 289 +++++++++++--------
 .../cache/database/freelist/PagesList.java      | 267 +++++++++++------
 .../cache/database/tree/BPlusTree.java          | 197 ++++++++++---
 .../cache/database/tree/io/BPlusIO.java         |  34 +--
 .../cache/database/tree/io/BPlusInnerIO.java    |  44 +--
 .../cache/database/tree/io/BPlusLeafIO.java     |   9 +-
 .../cache/database/tree/io/BPlusMetaIO.java     |  45 ++-
 .../cache/database/tree/io/DataPageIO.java      |  48 ++-
 .../cache/database/tree/io/DataPagePayload.java |   2 +-
 .../cache/database/tree/io/PageIO.java          |  60 ++++
 .../dht/GridDhtPartitionTopologyImpl.java       |   2 +-
 .../cluster/IgniteChangeGlobalStateSupport.java |   2 +
 .../query/GridQueryIndexDescriptor.java         |   7 +
 .../processors/query/GridQueryProcessor.java    |  39 ++-
 .../apache/ignite/internal/util/GridUnsafe.java |  45 ++-
 .../GridCacheRebalancingSyncSelfTest.java       |  12 +-
 .../processors/database/BPlusTreeSelfTest.java  |  13 +-
 .../odbc/OdbcProcessorValidationSelfTest.java   |   4 +-
 .../unsafe/GridUnsafeMemorySelfTest.java        |  35 +++
 .../junits/common/GridCommonAbstractTest.java   |  59 ++--
 .../ignite/testsuites/IgniteCacheTestSuite.java |  10 -
 .../testsuites/IgniteCacheTestSuite5.java       |  19 +-
 .../processors/query/h2/IgniteH2Indexing.java   |  19 +-
 .../processors/query/h2/database/H2Tree.java    |  57 +++-
 .../query/h2/database/H2TreeIndex.java          | 236 ++++++++++++++-
 .../query/h2/database/InlineIndexHelper.java    | 279 ++++++++++++++++++
 .../query/h2/database/io/H2ExtrasInnerIO.java   | 135 +++++++++
 .../query/h2/database/io/H2ExtrasLeafIO.java    | 132 +++++++++
 .../query/h2/database/io/H2InnerIO.java         |  10 -
 .../query/h2/database/io/H2LeafIO.java          |  10 -
 .../processors/query/h2/opt/GridH2Row.java      |   2 +-
 .../processors/query/h2/opt/GridH2Table.java    |   3 +-
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 +
 .../query/h2/database/H2TreeIndexTest.java      |  59 ++++
 .../h2/database/InlineIndexHelperTest.java      |  46 +++
 54 files changed, 2063 insertions(+), 568 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index 43ba08a,5df99b6..05eaf0a
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@@ -785,38 -776,31 +787,38 @@@ public class IgniteCacheOffheapManagerI
          IgniteInClosure2X<GridCacheEntryEx, GridCacheVersion> c,
          int amount
      ) throws IgniteCheckedException {
-         if (pendingEntries != null) {
+         if (hasPendingEntries && pendingEntries != null) {
 -            GridCacheVersion obsoleteVer = null;
 +            cctx.shared().database().checkpointReadLock();
  
 -            long now = U.currentTimeMillis();
 +            try {
 +                GridCacheVersion obsoleteVer = null;
  
 -            GridCursor<PendingRow> cur = pendingEntries.find(START_PENDING_ROW, new PendingRow(now, 0));
 +                long now = U.currentTimeMillis();
  
 -            int cleared = 0;
 +                GridCursor<PendingRow> cur = pendingEntries.find(START_PENDING_ROW, new PendingRow(now, 0));
  
 -            while (cur.next()) {
 -                PendingRow row = cur.get();
 +                int cleared = 0;
  
 -                if (amount != -1 && cleared > amount)
 -                    return true;
 +                while (cur.next()) {
 +                    PendingRow row = cur.get();
  
 -                assert row.key != null && row.link != 0 && row.expireTime != 0 : row;
 +                    if (amount != -1 && cleared > amount)
 +                        return true;
  
 -                if (pendingEntries.remove(row) != null) {
 -                    if (obsoleteVer == null)
 -                        obsoleteVer = cctx.versions().next();
 +                    assert row.key != null && row.link != 0 && row.expireTime != 0 : row;
  
 -                    c.apply(cctx.cache().entryEx(row.key), obsoleteVer);
 -                }
 +                    if (pendingEntries.remove(row) != null) {
 +                        if (obsoleteVer == null)
 +                            obsoleteVer = cctx.versions().next();
  
 -                cleared++;
 +                        c.apply(cctx.cache().entryEx(row.key), obsoleteVer);
 +                    }
 +
 +                    cleared++;
 +                }
 +            }
 +            finally {
 +                cctx.shared().database().checkpointReadUnlock();
              }
          }
  

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/main/java/org/apache/ignite/internal/processors/query/GridQueryProcessor.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/56fadcd2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
----------------------------------------------------------------------


[20/50] [abbrv] ignite git commit: IGNITE-3477 - Remove waitForRent() in exchange future

Posted by sb...@apache.org.
IGNITE-3477 - Remove waitForRent() in exchange future


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 7e956ed07c70c6d4de0ccb60a222529ecef3ea9b
Parents: e4b05d5
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Mar 9 15:09:42 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Mar 9 15:09:42 2017 +0300

----------------------------------------------------------------------
 .../pagemem/wal/IgniteWriteAheadLogManager.java |  27 ++-
 .../GridCachePartitionExchangeManager.java      |  27 ++-
 .../cache/IgniteCacheOffheapManager.java        |   3 +-
 .../cache/IgniteCacheOffheapManagerImpl.java    |  57 +++--
 .../IgniteCacheDatabaseSharedManager.java       |  44 +++-
 .../dht/GridClientPartitionTopology.java        |  33 ++-
 .../distributed/dht/GridDhtCacheEntry.java      |   2 +-
 .../distributed/dht/GridDhtLocalPartition.java  |  60 +++---
 .../distributed/dht/GridDhtLockFuture.java      |  29 ++-
 .../dht/GridDhtPartitionTopology.java           |  22 +-
 .../dht/GridDhtPartitionTopologyImpl.java       | 215 +++++++++----------
 .../distributed/dht/GridDhtTxLocalAdapter.java  |   2 +-
 .../GridDhtPartitionDemandMessage.java          |  73 +++++--
 .../dht/preloader/GridDhtPartitionSupplier.java |  10 +-
 .../GridDhtPartitionSupplyMessageV2.java        |   1 -
 .../GridDhtPartitionsExchangeFuture.java        | 153 +++++++++++--
 .../preloader/GridDhtPartitionsFullMessage.java | 120 +++++++++--
 .../GridDhtPartitionsSingleMessage.java         |  77 ++++++-
 .../dht/preloader/GridDhtPreloader.java         | 106 ++++++---
 .../IgniteDhtPartitionCountersMap.java          |  64 ++++++
 .../IgniteDhtPartitionHistorySuppliersMap.java  | 107 +++++++++
 .../IgniteDhtPartitionsToReloadMap.java         |  88 ++++++++
 22 files changed, 1043 insertions(+), 277 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
index fb7a39b..ac785b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/IgniteWriteAheadLogManager.java
@@ -59,8 +59,9 @@ public interface IgniteWriteAheadLogManager extends GridCacheSharedManager, Igni
      * the underlying storage.
      *
      * @param ptr Optional pointer to sync. If {@code null}, will sync up to the latest record.
-     * @throws IgniteCheckedException If
-     * @throws StorageException
+     * @throws IgniteCheckedException If failed to fsync.
+     * @throws StorageException If IO exception occurred during the write. If an exception is thrown from this
+     *      method, the WAL will be invalidated and the node will be stopped.
      */
     public void fsync(WALPointer ptr) throws IgniteCheckedException, StorageException;
 
@@ -75,6 +76,22 @@ public interface IgniteWriteAheadLogManager extends GridCacheSharedManager, Igni
     public WALIterator replay(WALPointer start) throws IgniteCheckedException, StorageException;
 
     /**
+     * Invoke this method to reserve WAL history since provided pointer and prevent it's deletion.
+     *
+     * @param start WAL pointer.
+     * @throws IgniteException If failed to reserve.
+     */
+    public boolean reserve(WALPointer start) throws IgniteCheckedException;
+
+    /**
+     * Invoke this method to release WAL history since provided pointer that was previously reserved.
+     *
+     * @param start WAL pointer.
+     * @throws IgniteException If failed to release.
+     */
+    public void release(WALPointer start) throws IgniteCheckedException;
+
+    /**
      * Gives a hint to WAL manager to clear entries logged before the given pointer. Some entries before the
      * the given pointer will be kept because there is a configurable WAL history size. Those entries may be used
      * for partial partition rebalancing.
@@ -83,4 +100,10 @@ public interface IgniteWriteAheadLogManager extends GridCacheSharedManager, Igni
      * @return Number of deleted WAL segments.
      */
     public int truncate(WALPointer ptr);
+
+    /**
+     * @param ptr Pointer.
+     * @return True if given pointer is located in reserved segment.
+     */
+    public boolean reserved(WALPointer ptr);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 232dc83..695872f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -73,6 +73,8 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.Gri
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsSingleMessage;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsSingleRequest;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloaderAssignments;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.IgniteDhtPartitionHistorySuppliersMap;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.IgniteDhtPartitionsToReloadMap;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -822,7 +824,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
      * @return {@code True} if message was sent, {@code false} if node left grid.
      */
     private boolean sendAllPartitions(Collection<ClusterNode> nodes) {
-        GridDhtPartitionsFullMessage m = createPartitionsFullMessage(nodes, null, null, true);
+        GridDhtPartitionsFullMessage m = createPartitionsFullMessage(nodes, null, null, null, null, true);
 
         if (log.isDebugEnabled())
             log.debug("Sending all partitions [nodeIds=" + U.nodeIds(nodes) + ", msg=" + m + ']');
@@ -854,12 +856,17 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
      * @return Message.
      */
     public GridDhtPartitionsFullMessage createPartitionsFullMessage(Collection<ClusterNode> nodes,
-        final @Nullable GridDhtPartitionExchangeId exchId,
+        @Nullable final GridDhtPartitionExchangeId exchId,
         @Nullable GridCacheVersion lastVer,
+        @Nullable IgniteDhtPartitionHistorySuppliersMap partHistSuppliers,
+        @Nullable IgniteDhtPartitionsToReloadMap partsToReload,
         final boolean compress) {
         final GridDhtPartitionsFullMessage m = new GridDhtPartitionsFullMessage(exchId,
             lastVer,
-            exchId != null ? exchId.topologyVersion() : AffinityTopologyVersion.NONE);
+            exchId != null ? exchId.topologyVersion() : AffinityTopologyVersion.NONE,
+            partHistSuppliers,
+            partsToReload
+            );
 
         m.compress(compress);
 
@@ -1239,11 +1246,23 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                         top = cacheCtx.topology();
 
                     if (top != null)
-                        updated |= top.update(null, entry.getValue(), null) != null;
+                        updated |= top.update(null, entry.getValue(), null, msg.partsToReload(cctx.localNodeId(), cacheId)) != null;
                 }
 
                 if (!cctx.kernalContext().clientNode() && updated)
                     refreshPartitions();
+
+                boolean hasMovingParts = false;
+
+                for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
+                    if (!cacheCtx.isLocal() && cacheCtx.started() && cacheCtx.topology().hasMovingPartitions()) {
+                        hasMovingParts = true;
+                        break;
+                    }
+                }
+
+                if (!hasMovingParts)
+                    cctx.database().releaseHistoryForPreloading();
             }
             else
                 exchangeFuture(msg.exchangeId(), null, null, null).onReceive(node, msg);

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
index 4b85abe..d1ab787 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManager.java
@@ -82,10 +82,9 @@ public interface IgniteCacheOffheapManager extends GridCacheManager {
     public Iterable<CacheDataStore> cacheDataStores();
 
     /**
-     * @param p Partition ID.
      * @param store Data store.
      */
-    public void destroyCacheDataStore(int p, CacheDataStore store) throws IgniteCheckedException;
+    public void destroyCacheDataStore(CacheDataStore store) throws IgniteCheckedException;
 
     /**
      * TODO: GG-10884, used on only from initialValue.

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index 05eaf0a..5d1f7b9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -59,6 +59,7 @@ import org.apache.ignite.internal.util.GridAtomicLong;
 import org.apache.ignite.internal.util.GridCloseableIteratorAdapter;
 import org.apache.ignite.internal.util.GridEmptyCloseableIterator;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
+import org.apache.ignite.internal.util.GridStripedLock;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.lang.GridCloseableIterator;
 import org.apache.ignite.internal.util.lang.GridCursor;
@@ -92,9 +93,6 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
     protected final ConcurrentMap<Integer, CacheDataStore> partDataStores = new ConcurrentHashMap<>();
 
     /** */
-    protected final CacheDataStore rmvdStore = new CacheDataStoreImpl(-1, null, null, null);
-
-    /** */
     protected PendingEntriesTree pendingEntries;
 
     /** */
@@ -112,6 +110,9 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
     /** */
     private int updateValSizeThreshold;
 
+    /** */
+    private GridStripedLock partStoreLock = new GridStripedLock(Runtime.getRuntime().availableProcessors());
+
     /** {@inheritDoc} */
     @Override public GridAtomicLong globalRemoveId() {
         return globalRmvId;
@@ -172,7 +173,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
         super.stop0(cancel, destroy);
 
         if (destroy && cctx.affinityNode())
-            destroyCacheDataStructures(destroy);
+            destroyCacheDataStructures();
     }
 
     /** {@inheritDoc} */
@@ -185,7 +186,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
     /**
      *
      */
-    protected void destroyCacheDataStructures(boolean destroy) {
+    protected void destroyCacheDataStructures() {
         assert cctx.affinityNode();
 
         try {
@@ -196,7 +197,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
                 pendingEntries.destroy();
 
             for (CacheDataStore store : partDataStores.values())
-                store.destroy();
+                destroyCacheDataStore(store);
         }
         catch (IgniteCheckedException e) {
             throw new IgniteException(e.getMessage(), e);
@@ -238,7 +239,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
         if (cctx.isLocal())
             return locCacheDataStore;
         else {
-            GridDhtLocalPartition part = cctx.topology().localPartition(p, AffinityTopologyVersion.NONE, false);
+            GridDhtLocalPartition part = cctx.topology().localPartition(p, AffinityTopologyVersion.NONE, false, true);
 
             return part != null ? part.dataStore() : null;
         }
@@ -278,7 +279,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
 
     /** {@inheritDoc} */
     @Override public long entriesCount(int part) {
-        if (cctx.isLocal()){
+        if (cctx.isLocal()) {
             assert part == 0;
 
             return locCacheDataStore.size();
@@ -709,15 +710,20 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
 
     /** {@inheritDoc} */
     @Override public final CacheDataStore createCacheDataStore(int p) throws IgniteCheckedException {
-        CacheDataStore dataStore = null;
-        CacheDataStore oldStore = null;
+        CacheDataStore dataStore;
+
+        partStoreLock.lock(p);
+
+        try {
+            assert !partDataStores.containsKey(p);
 
-        do {
             dataStore = createCacheDataStore0(p);
 
-            oldStore = partDataStores.putIfAbsent(p, dataStore);
+            partDataStores.put(p, dataStore);
+        }
+        finally {
+            partStoreLock.unlock(p);
         }
-        while (oldStore != null);
 
         return dataStore;
     }
@@ -763,15 +769,32 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
     }
 
     /** {@inheritDoc} */
-    @Override public void destroyCacheDataStore(int p, CacheDataStore store) throws IgniteCheckedException {
+    @Override public final void destroyCacheDataStore(CacheDataStore store) throws IgniteCheckedException {
+        int p = store.partId();
+
+        partStoreLock.lock(p);
+
         try {
-            partDataStores.remove(p, store);
+            boolean removed = partDataStores.remove(p, store);
+
+            assert removed;
 
-            store.destroy();
+            destroyCacheDataStore0(store);
         }
         catch (IgniteCheckedException e) {
             throw new IgniteException(e);
         }
+        finally {
+            partStoreLock.unlock(p);
+        }
+    }
+
+    /**
+     * @param store Cache data store.
+     * @throws IgniteCheckedException If failed.
+     */
+    protected void destroyCacheDataStore0(CacheDataStore store) throws IgniteCheckedException {
+        store.destroy();
     }
 
     /**
@@ -1155,7 +1178,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
             KeyCacheObject key,
             CacheObject oldVal,
             CacheObject newVal
-            ) throws IgniteCheckedException {
+        ) {
             // In case we deal with IGFS cache, count updated data
             if (cctx.cache().isIgfsDataCache() &&
                 !cctx.isNear() &&

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index 95ed3ae..743cd77 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@ -19,9 +19,10 @@ package org.apache.ignite.internal.processors.cache.database;
 
 import java.io.File;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.MemoryConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -95,7 +96,7 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
     /**
      * @throws IgniteCheckedException If failed.
      */
-    public void initDataBase() throws IgniteCheckedException{
+    public void initDataBase() throws IgniteCheckedException {
         // No-op.
     }
 
@@ -152,7 +153,7 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
     /**
      *
      */
-    public void unLock(){
+    public void unLock() {
 
     }
 
@@ -212,7 +213,8 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
      * @return Snapshot creation init future or {@code null} if snapshot is not available.
      * @throws IgniteCheckedException If failed.
      */
-    @Nullable public IgniteInternalFuture startLocalSnapshotOperation(StartSnapshotOperationAckDiscoveryMessage snapshotMsg)
+    @Nullable public IgniteInternalFuture startLocalSnapshotOperation(
+        StartSnapshotOperationAckDiscoveryMessage snapshotMsg)
         throws IgniteCheckedException {
         return null;
     }
@@ -225,6 +227,40 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
     }
 
     /**
+     * Reserve update history for exchange.
+     *
+     * @return Reserved update counters per cache and partition.
+     */
+    public Map<Integer, Map<Integer, Long>> reserveHistoryForExchange() {
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Release reserved update history.
+     */
+    public void releaseHistoryForExchange() {
+        // No-op
+    }
+
+    /**
+     * Reserve update history for preloading.
+     * @param cacheId Cache ID.
+     * @param partId Partition Id.
+     * @param cntr Update counter.
+     * @return True if successfully reserved.
+     */
+    public boolean reserveHistoryForPreloading(int cacheId, int partId, long cntr) {
+        return false;
+    }
+
+    /**
+     * Release reserved update history.
+     */
+    public void releaseHistoryForPreloading() {
+        // No-op
+    }
+
+    /**
      * @param dbCfg Database configuration.
      * @return Page memory instance.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index ca71f51..e63379a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -51,6 +52,7 @@ import org.jetbrains.annotations.Nullable;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.EVICTED;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.MOVING;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
+import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.RENTING;
 
 /**
  * Partition topology for node which does not have any local partitions.
@@ -353,6 +355,12 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
+    @Nullable @Override public GridDhtLocalPartition localPartition(int p, AffinityTopologyVersion topVer,
+        boolean create, boolean showRenting) throws GridDhtInvalidPartitionException {
+        return localPartition(p, topVer, create);
+    }
+
+    /** {@inheritDoc} */
     @Override public GridDhtLocalPartition localPartition(Object key, boolean create) {
         return localPartition(1, AffinityTopologyVersion.NONE, create);
     }
@@ -550,9 +558,11 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
     /** {@inheritDoc} */
     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
-    @Nullable @Override public GridDhtPartitionMap2 update(@Nullable GridDhtPartitionExchangeId exchId,
-        GridDhtPartitionFullMap partMap,
-        Map<Integer, T2<Long, Long>> cntrMap) {
+    @Nullable @Override public GridDhtPartitionMap2 update(@Nullable GridDhtPartitionsExchangeFuture exchFut,
+        GridDhtPartitionFullMap partMap, Map<Integer, T2<Long, Long>> cntrMap, Set<Integer> partsToReload) {
+
+        GridDhtPartitionExchangeId exchId = exchFut != null ? exchFut.exchangeId() : null;
+
         if (log.isDebugEnabled())
             log.debug("Updating full partition map [exchId=" + exchId + ", parts=" + fullMapString() + ']');
 
@@ -910,7 +920,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
-    @Override public void setOwners(int p, Set<UUID> owners, boolean updateSeq) {
+    @Override public Set<UUID> setOwners(int p, Set<UUID> owners, boolean haveHistory, boolean updateSeq) {
+        Set<UUID> result = haveHistory ? Collections.<UUID>emptySet() : new HashSet<UUID>();
+
         lock.writeLock().lock();
 
         try {
@@ -918,8 +930,15 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
                 if (!e.getValue().containsKey(p))
                     continue;
 
-                if (e.getValue().get(p) == OWNING && !owners.contains(e.getKey()))
-                    e.getValue().put(p, MOVING);
+                if (e.getValue().get(p) == OWNING && !owners.contains(e.getKey())) {
+                    if (haveHistory)
+                        e.getValue().put(p, MOVING);
+                    else {
+                        e.getValue().put(p, RENTING);
+
+                        result.add(e.getKey());
+                    }
+                }
                 else if (owners.contains(e.getKey()))
                     e.getValue().put(p, OWNING);
             }
@@ -932,6 +951,8 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
         finally {
             lock.writeLock().unlock();
         }
+
+        return result;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
index 5b5cc3b..f1f4376 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java
@@ -91,7 +91,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
         // Record this entry with partition.
         int p = cctx.affinity().partition(key);
 
-        locPart = ctx.topology().localPartition(p, topVer, true);
+        locPart = ctx.topology().localPartition(p, topVer, true, true);
 
         assert locPart != null : p;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
index 4418f53..aeb40f8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
@@ -138,13 +138,16 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      * reservation is released. */
     private volatile boolean shouldBeRenting;
 
+    /** Set if partition must be re-created and preloaded after eviction. */
+    private boolean reload;
+
     /**
      * @param cctx Context.
      * @param id Partition ID.
      * @param entryFactory Entry factory.
      */
-    @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor")
-    GridDhtLocalPartition(GridCacheContext cctx, int id, GridCacheMapEntryFactory entryFactory) {
+    @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor") GridDhtLocalPartition(GridCacheContext cctx,
+        int id, GridCacheMapEntryFactory entryFactory) {
         assert cctx != null;
 
         this.id = id;
@@ -373,12 +376,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
         map.removeEntry(entry);
 
         // Attempt to evict.
-        try {
-            tryEvict();
-        }
-        catch (NodeStoppingException ignore) {
-            // No-op.
-        }
+        tryEvictAsync(false);
     }
 
     /**
@@ -514,12 +512,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
                 if ((reservations & 0xFFFF) == 0 && shouldBeRenting)
                     rent(true);
 
-                try {
-                    tryEvict();
-                }
-                catch (NodeStoppingException ignore) {
-                    // No-op.
-                }
+                tryEvictAsync(false);
 
                 break;
             }
@@ -530,7 +523,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      * @param stateToRestore State to restore.
      */
     public void restoreState(GridDhtPartitionState stateToRestore) {
-        state.set(((long)stateToRestore.ordinal())  <<  32);
+        state.set(((long)stateToRestore.ordinal()) << 32);
     }
 
     /**
@@ -632,10 +625,24 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
     }
 
     /**
+     * @return {@code True} if partition should be re-created after it is cleared.
+     */
+    public boolean reload() {
+        return reload;
+    }
+
+    /**
+     * @param value {@code reload} flag value.
+     */
+    public void reload(boolean value) {
+        reload = value;
+    }
+
+    /**
      * @param updateSeq Update sequence.
      * @return Future to signal that this node is no longer an owner or backup.
      */
-    IgniteInternalFuture<?> rent(boolean updateSeq) {
+    public IgniteInternalFuture<?> rent(boolean updateSeq) {
         long reservations = state.get();
 
         int ord = (int)(reservations >> 32);
@@ -663,8 +670,6 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      * @param updateSeq Update sequence.
      */
     void tryEvictAsync(boolean updateSeq) {
-        assert cctx.kernalContext().state().active();
-
         long reservations = state.get();
 
         int ord = (int)(reservations >> 32);
@@ -713,7 +718,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      *
      */
     private void clearEvicting() {
-       boolean free;
+        boolean free;
 
         while (true) {
             int cnt = evictGuard.get();
@@ -804,9 +809,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      */
     private void destroyCacheDataStore() {
         try {
-            CacheDataStore store = dataStore();
-
-            cctx.offheap().destroyCacheDataStore(id, store);
+            cctx.offheap().destroyCacheDataStore(dataStore());
         }
         catch (IgniteCheckedException e) {
             log.error("Unable to destroy cache data store on partition eviction [id=" + id + "]", e);
@@ -817,12 +820,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
      *
      */
     void onUnlock() {
-        try {
-            tryEvict();
-        }
-        catch (NodeStoppingException ignore) {
-            // No-op.
-        }
+        tryEvictAsync(false);
     }
 
     /**
@@ -949,7 +947,11 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
                     try {
                         CacheDataRow row = it0.next();
 
-                        GridDhtCacheEntry cached = (GridDhtCacheEntry)cctx.cache().entryEx(row.key());
+                        GridDhtCacheEntry cached = (GridDhtCacheEntry) getEntry(row.key());
+
+                        if (cached == null || cached.obsolete())
+                            cached = (GridDhtCacheEntry) putEntryIfObsoleteOrAbsent(
+                                cctx.affinity().affinityTopologyVersion(), row.key(), null, true, false);
 
                         if (cached.clearInternal(clearVer, extras)) {
                             if (rec) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
index b57ca57..7b5dee3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockFuture.java
@@ -1262,17 +1262,24 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
                     try {
                         GridCacheEntryEx entry = cache0.entryEx(info.key(), topVer);
 
-                        if (entry.initialValue(info.value(),
-                            info.version(),
-                            info.ttl(),
-                            info.expireTime(),
-                            true, topVer,
-                            replicate ? DR_PRELOAD : DR_NONE,
-                            false)) {
-                            if (rec && !entry.isInternal())
-                                cctx.events().addEvent(entry.partition(), entry.key(), cctx.localNodeId(),
-                                    (IgniteUuid)null, null, EVT_CACHE_REBALANCE_OBJECT_LOADED, info.value(), true, null,
-                                    false, null, null, null, false);
+                        cctx.shared().database().checkpointReadLock();
+
+                        try {
+                            if (entry.initialValue(info.value(),
+                                info.version(),
+                                info.ttl(),
+                                info.expireTime(),
+                                true, topVer,
+                                replicate ? DR_PRELOAD : DR_NONE,
+                                false)) {
+                                if (rec && !entry.isInternal())
+                                    cctx.events().addEvent(entry.partition(), entry.key(), cctx.localNodeId(),
+                                        (IgniteUuid)null, null, EVT_CACHE_REBALANCE_OBJECT_LOADED, info.value(), true, null,
+                                        false, null, null, null, false);
+                            }
+                        }
+                        finally {
+                            cctx.shared().database().checkpointReadUnlock();
                         }
                     }
                     catch (IgniteCheckedException e) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
index ac3e2c8..37c3af9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
@@ -128,6 +128,18 @@ public interface GridDhtPartitionTopology {
         throws GridDhtInvalidPartitionException;
 
     /**
+     * @param topVer Topology version at the time of creation.
+     * @param p Partition ID.
+     * @param create If {@code true}, then partition will be created if it's not there.
+     * @return Local partition.
+     * @throws GridDhtInvalidPartitionException If partition is evicted or absent and
+     *      does not belong to this node.
+     */
+    @Nullable public GridDhtLocalPartition localPartition(int p, AffinityTopologyVersion topVer, boolean create,
+        boolean showRenting)
+        throws GridDhtInvalidPartitionException;
+
+    /**
      * @param parts Partitions to release (should be reserved before).
      */
     public void releasePartitions(int... parts);
@@ -213,14 +225,15 @@ public interface GridDhtPartitionTopology {
     public void onRemoved(GridDhtCacheEntry e);
 
     /**
-     * @param exchId Exchange ID.
+     * @param exchFut Exchange future.
      * @param partMap Update partition map.
      * @param cntrMap Partition update counters.
      * @return Local partition map if there were evictions or {@code null} otherwise.
      */
-    public GridDhtPartitionMap2 update(@Nullable GridDhtPartitionExchangeId exchId,
+    public GridDhtPartitionMap2 update(@Nullable GridDhtPartitionsExchangeFuture exchFut,
         GridDhtPartitionFullMap partMap,
-        @Nullable Map<Integer, T2<Long, Long>> cntrMap);
+        @Nullable Map<Integer, T2<Long, Long>> cntrMap,
+        Set<Integer> partsToReload);
 
     /**
      * @param exchId Exchange ID.
@@ -301,6 +314,7 @@ public interface GridDhtPartitionTopology {
      * @param p Partition ID.
      * @param updateSeq If should increment sequence when updated.
      * @param owners Set of new owners.
+     * @return Set of node IDs that should reload partitions.
      */
-    public void setOwners(int p, Set<UUID> owners, boolean updateSeq);
+    public Set<UUID> setOwners(int p, Set<UUID> owners, boolean haveHistory, boolean updateSeq);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index 66e5be3..553aa2a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@ -32,12 +32,10 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.cache.PartitionLossPolicy;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.EventType;
-import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -59,7 +57,6 @@ import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
 
-import static org.apache.ignite.IgniteSystemProperties.IGNITE_THREAD_DUMP_ON_EXCHANGE_TIMEOUT;
 import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.EVICTED;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.LOST;
@@ -70,8 +67,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 /**
  * Partition topology.
  */
-@GridToStringExclude
-class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
+@GridToStringExclude class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
     /** If true, then check consistency. */
     private static final boolean CONSISTENCY_CHECK = false;
 
@@ -189,93 +185,6 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
         return map == null ? "null" : FULL_MAP_DEBUG ? map.toFullString() : map.toString();
     }
 
-    /**
-     * Waits for renting partitions.
-     *
-     * @return {@code True} if mapping was changed.
-     * @throws IgniteCheckedException If failed.
-     */
-    private boolean waitForRent() throws IgniteCheckedException {
-        final long longOpDumpTimeout =
-            IgniteSystemProperties.getLong(IgniteSystemProperties.IGNITE_LONG_OPERATIONS_DUMP_TIMEOUT, 60_000);
-
-        int dumpCnt = 0;
-
-        GridDhtLocalPartition part;
-
-        for (int i = 0; i < locParts.length(); i++) {
-            part = locParts.get(i);
-
-            if (part == null)
-                continue;
-
-            GridDhtPartitionState state = part.state();
-
-            if (state == RENTING || state == EVICTED) {
-                if (log.isDebugEnabled())
-                    log.debug("Waiting for renting partition: " + part);
-
-                part.tryEvictAsync(false);
-
-                // Wait for partition to empty out.
-                if (longOpDumpTimeout > 0) {
-                    while (true) {
-                        try {
-                            part.rent(true).get(longOpDumpTimeout);
-
-                            break;
-                        }
-                        catch (IgniteFutureTimeoutCheckedException e) {
-                            if (dumpCnt++ < GridDhtPartitionsExchangeFuture.DUMP_PENDING_OBJECTS_THRESHOLD) {
-                                U.warn(log, "Failed to wait for partition eviction [" +
-                                    "topVer=" + topVer +
-                                    ", cache=" + cctx.name() +
-                                    ", part=" + part.id() +
-                                    ", partState=" + part.state() +
-                                    ", size=" + part.size() +
-                                    ", reservations=" + part.reservations() +
-                                    ", grpReservations=" + part.groupReserved() +
-                                    ", node=" + cctx.localNodeId() + "]");
-
-                                if (IgniteSystemProperties.getBoolean(IGNITE_THREAD_DUMP_ON_EXCHANGE_TIMEOUT, false))
-                                    U.dumpThreads(log);
-                            }
-                        }
-                    }
-                }
-                else
-                    part.rent(true).get();
-
-                if (log.isDebugEnabled())
-                    log.debug("Finished waiting for renting partition: " + part);
-            }
-        }
-
-        // Remove evicted partition.
-        lock.writeLock().lock();
-
-        try {
-            boolean changed = false;
-
-            for (int i = 0; i < locParts.length(); i++) {
-                part = locParts.get(i);
-
-                if (part == null)
-                    continue;
-
-                if (part.state() == EVICTED) {
-                    locParts.set(i, null);
-                    changed = true;
-                }
-            }
-
-            return changed;
-        }
-        finally {
-            lock.writeLock().unlock();
-        }
-    }
-
     /** {@inheritDoc} */
     @SuppressWarnings({"LockAcquiredButNotSafelyReleased"})
     @Override public void readLock() {
@@ -422,7 +331,7 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
             // If preloader is disabled, then we simply clear out
             // the partitions this node is not responsible for.
             for (int p = 0; p < num; p++) {
-                GridDhtLocalPartition locPart = localPartition(p, topVer, false, false);
+                GridDhtLocalPartition locPart = localPartition0(p, topVer, false, true, false);
 
                 boolean belongs = localNode(p, aff);
 
@@ -498,9 +407,6 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
             && !cctx.kernalContext().clientNode()
         );
 
-        // Wait for rent outside of checkpoint lock.
-        waitForRent();
-
         ClusterNode loc = cctx.localNode();
 
         cctx.shared().database().checkpointReadLock();
@@ -580,16 +486,13 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
         finally {
             cctx.shared().database().checkpointReadUnlock();
         }
-
-        // Wait for evictions.
-        waitForRent();
     }
 
     /** {@inheritDoc} */
     @Override public boolean afterExchange(GridDhtPartitionsExchangeFuture exchFut) throws IgniteCheckedException {
         treatAllPartAsLoc = false;
 
-        boolean changed = waitForRent();
+        boolean changed = false;
 
         int num = cctx.affinity().partitions();
 
@@ -616,7 +519,7 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
             long updateSeq = this.updateSeq.incrementAndGet();
 
             for (int p = 0; p < num; p++) {
-                GridDhtLocalPartition locPart = localPartition(p, topVer, false, false);
+                GridDhtLocalPartition locPart = localPartition0(p, topVer, false, false, false);
 
                 if (cctx.affinity().partitionLocalNode(p, topVer)) {
                     // This partition will be created during next topology event,
@@ -697,7 +600,13 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
     @Nullable @Override public GridDhtLocalPartition localPartition(int p, AffinityTopologyVersion topVer,
         boolean create)
         throws GridDhtInvalidPartitionException {
-        return localPartition(p, topVer, create, true);
+        return localPartition0(p, topVer, create, false, true);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public GridDhtLocalPartition localPartition(int p, AffinityTopologyVersion topVer,
+        boolean create, boolean showRenting) throws GridDhtInvalidPartitionException {
+        return localPartition0(p, topVer, create, showRenting, true);
     }
 
     /**
@@ -734,9 +643,10 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
      * @return Local partition.
      */
     @SuppressWarnings("TooBroadScope")
-    private GridDhtLocalPartition localPartition(int p,
+    private GridDhtLocalPartition localPartition0(int p,
         AffinityTopologyVersion topVer,
         boolean create,
+        boolean showRenting,
         boolean updateSeq) {
         GridDhtLocalPartition loc;
 
@@ -744,7 +654,7 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
 
         GridDhtPartitionState state = loc != null ? loc.state() : null;
 
-        if (loc != null && state != EVICTED && (state != RENTING || !cctx.allowFastEviction()))
+        if (loc != null && state != EVICTED && (state != RENTING || showRenting))
             return loc;
 
         if (!create)
@@ -769,8 +679,9 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
                         "(often may be caused by inconsistent 'key.hashCode()' implementation) " +
                         "[part=" + p + ", topVer=" + topVer + ", this.topVer=" + this.topVer + ']');
             }
-            else if (loc != null && state == RENTING && cctx.allowFastEviction())
-                throw new GridDhtInvalidPartitionException(p, "Adding entry to partition that is concurrently evicted.");
+            else if (loc != null && state == RENTING && !showRenting)
+                throw new GridDhtInvalidPartitionException(p, "Adding entry to partition that is concurrently evicted " +
+                    "[part=" + p + ", shouldBeMoving=" + loc.reload() + "]");
 
             if (loc == null) {
                 if (!treatAllPartAsLoc && !belongs)
@@ -1062,10 +973,13 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
     /** {@inheritDoc} */
     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
     @Nullable @Override public GridDhtPartitionMap2 update(
-        @Nullable GridDhtPartitionExchangeId exchId,
+        @Nullable GridDhtPartitionsExchangeFuture exchFut,
         GridDhtPartitionFullMap partMap,
-        @Nullable Map<Integer, T2<Long, Long>> cntrMap
+        @Nullable Map<Integer, T2<Long, Long>> cntrMap,
+        Set<Integer> partsToReload
     ) {
+        GridDhtPartitionExchangeId exchId = exchFut != null ? exchFut.exchangeId() : null;
+
         if (log.isDebugEnabled())
             log.debug("Updating full partition map [exchId=" + exchId + ", parts=" + fullMapString() + ']');
 
@@ -1117,8 +1031,6 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
                 return null;
             }
 
-            long updateSeq = this.updateSeq.incrementAndGet();
-
             if (exchId != null)
                 lastExchangeId = exchId;
 
@@ -1186,11 +1098,32 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
                     int p = e.getKey();
                     GridDhtPartitionState state = e.getValue();
 
-                   if (state == MOVING) {
+                    if (state == OWNING) {
                         GridDhtLocalPartition locPart = locParts.get(p);
 
                         assert locPart != null;
 
+                        if (cntrMap != null) {
+                            T2<Long, Long> cntr = cntrMap.get(p);
+
+                            if (cntr != null && cntr.get2() > locPart.updateCounter())
+                                locPart.updateCounter(cntr.get2());
+                        }
+
+                        if (locPart.state() == MOVING) {
+                            boolean success = locPart.own();
+
+                            assert success : locPart;
+
+                            changed |= success;
+                        }
+                    }
+                    else if (state == MOVING) {
+                        GridDhtLocalPartition locPart = locParts.get(p);
+
+                        if (locPart == null || locPart.state() == EVICTED)
+                            locPart = createPartition(p);
+
                         if (locPart.state() == OWNING) {
                             locPart.moving();
 
@@ -1204,9 +1137,30 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
                                 locPart.updateCounter(cntr.get2());
                         }
                     }
+                    else if (state == RENTING && partsToReload.contains(p)) {
+                        GridDhtLocalPartition locPart = locParts.get(p);
+
+                        if (locPart == null || locPart.state() == EVICTED) {
+                            createPartition(p);
+
+                            changed = true;
+                        }
+                        else if (locPart.state() == OWNING || locPart.state() == MOVING) {
+                            locPart.reload(true);
+
+                            locPart.rent(false);
+
+                            changed = true;
+                        }
+                        else {
+                            locPart.reload(true);
+                        }
+                    }
                 }
             }
 
+            long updateSeq = this.updateSeq.incrementAndGet();
+
             if (!affVer.equals(AffinityTopologyVersion.NONE) && affVer.compareTo(topVer) >= 0) {
                 List<List<ClusterNode>> aff = cctx.affinity().assignments(topVer);
 
@@ -1536,24 +1490,42 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
-    @Override public void setOwners(int p, Set<UUID> owners, boolean updateSeq) {
+    @Override public Set<UUID> setOwners(int p, Set<UUID> owners, boolean haveHistory, boolean updateSeq) {
+        Set<UUID> result = haveHistory ? Collections.<UUID>emptySet() : new HashSet<UUID>();
+
         lock.writeLock().lock();
 
         try {
-
             GridDhtLocalPartition locPart = locParts.get(p);
 
             if (locPart != null) {
-                if (locPart.state() == OWNING && !owners.contains(cctx.localNodeId()))
-                    locPart.moving();
+                if (locPart.state() == OWNING && !owners.contains(cctx.localNodeId())) {
+                    if (haveHistory)
+                        locPart.moving();
+                    else {
+                        locPart.rent(false);
+
+                        locPart.reload(true);
+
+                        result.add(cctx.localNodeId());
+                    }
+
+                }
             }
 
             for (Map.Entry<UUID, GridDhtPartitionMap2> e : node2part.entrySet()) {
                 if (!e.getValue().containsKey(p))
                     continue;
 
-                if (e.getValue().get(p) == OWNING && !owners.contains(e.getKey()))
-                    e.getValue().put(p, MOVING);
+                if (e.getValue().get(p) == OWNING && !owners.contains(e.getKey())) {
+                    if (haveHistory)
+                        e.getValue().put(p, MOVING);
+                    else {
+                        e.getValue().put(p, RENTING);
+
+                        result.add(e.getKey());
+                    }
+                }
             }
 
             if (updateSeq)
@@ -1562,6 +1534,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
         finally {
             lock.writeLock().unlock();
         }
+
+        return result;
     }
 
     /**
@@ -1629,6 +1603,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
 
                     // If all affinity nodes are owners, then evict partition from local node.
                     if (nodeIds.containsAll(F.nodeIds(affNodes))) {
+                        part.reload(false);
+
                         part.rent(false);
 
                         updateSeq = updateLocal(part.id(), part.state(), updateSeq);
@@ -1654,6 +1630,8 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
                                 ClusterNode n = sorted.get(i);
 
                                 if (locId.equals(n.id())) {
+                                    part.reload(false);
+
                                     part.rent(false);
 
                                     updateSeq = updateLocal(part.id(), part.state(), updateSeq);
@@ -1833,6 +1811,9 @@ class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
 
             long seq = updateSeq ? this.updateSeq.incrementAndGet() : this.updateSeq.get();
 
+            if (part.reload())
+                part = createPartition(part.id());
+
             updateLocal(part.id(), part.state(), seq);
 
             consistencyCheck();

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
index debf8b6..5169f27 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
@@ -147,7 +147,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
             storeEnabled,
             onePhaseCommit,
             txSize,
-            subjId, 
+            subjId,
             taskNameHash
         );
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
index c9dcaaf..377c274 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandMessage.java
@@ -50,7 +50,11 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
     @GridDirectCollection(int.class)
     private Collection<Integer> parts;
 
-    /** Partition. */
+    /** Partitions that must be restored from history. */
+    @GridDirectCollection(int.class)
+    private Collection<Integer> historicalParts;
+
+    /** Partition counters. */
     @GridDirectMap(keyType = int.class, valueType = long.class)
     private Map<Integer, Long> partsCntrs;
 
@@ -85,7 +89,8 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
      * @param cp Message to copy from.
      * @param parts Partitions.
      */
-    GridDhtPartitionDemandMessage(GridDhtPartitionDemandMessage cp, Collection<Integer> parts, Map<Integer, Long> partsCntrs) {
+    GridDhtPartitionDemandMessage(GridDhtPartitionDemandMessage cp, Collection<Integer> parts,
+        Map<Integer, Long> partsCntrs) {
         cacheId = cp.cacheId;
         updateSeq = cp.updateSeq;
         topic = cp.topic;
@@ -96,6 +101,9 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
         // Create a copy of passed in collection since it can be modified when this message is being sent.
         this.parts = new HashSet<>(parts);
         this.partsCntrs = partsCntrs;
+
+        if (cp.historicalParts != null)
+            historicalParts = new HashSet<>(cp.historicalParts);
     }
 
     /**
@@ -108,13 +116,19 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
     /**
      * @param p Partition.
      */
-    void addPartition(int p) {
+    void addPartition(int p, boolean historical) {
         if (parts == null)
             parts = new HashSet<>();
 
         parts.add(p);
-    }
 
+        if (historical) {
+            if (historicalParts == null)
+                historicalParts = new HashSet<>();
+
+            historicalParts.add(p);
+        }
+    }
 
     /**
      * @return Partition.
@@ -124,6 +138,17 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
     }
 
     /**
+     * @param p Partition to check.
+     * @return {@code True} if historical.
+     */
+    boolean isHistorical(int p) {
+        if (historicalParts == null)
+            return false;
+
+        return historicalParts.contains(p);
+    }
+
+    /**
      * @param updateSeq Update sequence.
      */
     void updateSequence(long updateSeq) {
@@ -232,42 +257,48 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
 
         switch (writer.state()) {
             case 3:
-                if (!writer.writeCollection("parts", parts, MessageCollectionItemType.INT))
+                if (!writer.writeCollection("historicalParts", historicalParts, MessageCollectionItemType.INT))
                     return false;
 
                 writer.incrementState();
 
             case 4:
-                if (!writer.writeMap("partsCntrs", partsCntrs, MessageCollectionItemType.INT, MessageCollectionItemType.LONG))
+                if (!writer.writeCollection("parts", parts, MessageCollectionItemType.INT))
                     return false;
 
                 writer.incrementState();
 
             case 5:
-                if (!writer.writeLong("timeout", timeout))
+                if (!writer.writeMap("partsCntrs", partsCntrs, MessageCollectionItemType.INT, MessageCollectionItemType.LONG))
                     return false;
 
                 writer.incrementState();
 
             case 6:
-                if (!writer.writeMessage("topVer", topVer))
+                if (!writer.writeLong("timeout", timeout))
                     return false;
 
                 writer.incrementState();
 
             case 7:
-                if (!writer.writeByteArray("topicBytes", topicBytes))
+                if (!writer.writeMessage("topVer", topVer))
                     return false;
 
                 writer.incrementState();
 
             case 8:
-                if (!writer.writeLong("updateSeq", updateSeq))
+                if (!writer.writeByteArray("topicBytes", topicBytes))
                     return false;
 
                 writer.incrementState();
 
             case 9:
+                if (!writer.writeLong("updateSeq", updateSeq))
+                    return false;
+
+                writer.incrementState();
+
+            case 10:
                 if (!writer.writeInt("workerId", workerId))
                     return false;
 
@@ -290,7 +321,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
 
         switch (reader.state()) {
             case 3:
-                parts = reader.readCollection("parts", MessageCollectionItemType.INT);
+                historicalParts = reader.readCollection("historicalParts", MessageCollectionItemType.INT);
 
                 if (!reader.isLastRead())
                     return false;
@@ -298,7 +329,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
                 reader.incrementState();
 
             case 4:
-                partsCntrs = reader.readMap("partsCntrs", MessageCollectionItemType.INT, MessageCollectionItemType.LONG, false);
+                parts = reader.readCollection("parts", MessageCollectionItemType.INT);
 
                 if (!reader.isLastRead())
                     return false;
@@ -306,7 +337,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
                 reader.incrementState();
 
             case 5:
-                timeout = reader.readLong("timeout");
+                partsCntrs = reader.readMap("partsCntrs", MessageCollectionItemType.INT, MessageCollectionItemType.LONG, false);
 
                 if (!reader.isLastRead())
                     return false;
@@ -314,7 +345,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
                 reader.incrementState();
 
             case 6:
-                topVer = reader.readMessage("topVer");
+                timeout = reader.readLong("timeout");
 
                 if (!reader.isLastRead())
                     return false;
@@ -322,7 +353,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
                 reader.incrementState();
 
             case 7:
-                topicBytes = reader.readByteArray("topicBytes");
+                topVer = reader.readMessage("topVer");
 
                 if (!reader.isLastRead())
                     return false;
@@ -330,7 +361,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
                 reader.incrementState();
 
             case 8:
-                updateSeq = reader.readLong("updateSeq");
+                topicBytes = reader.readByteArray("topicBytes");
 
                 if (!reader.isLastRead())
                     return false;
@@ -338,6 +369,14 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
                 reader.incrementState();
 
             case 9:
+                updateSeq = reader.readLong("updateSeq");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 10:
                 workerId = reader.readInt("workerId");
 
                 if (!reader.isLastRead())
@@ -357,7 +396,7 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
 
     /** {@inheritDoc} */
     @Override public byte fieldsCount() {
-        return 10;
+        return 11;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
index b80ad04..c04a7b5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
@@ -278,10 +278,16 @@ class GridDhtPartitionSupplier {
                         IgniteRebalanceIterator iter;
 
                         if (sctx == null || sctx.entryIt == null) {
-                            iter = cctx.offheap().rebalanceIterator(part, d.topologyVersion(), d.partitionCounter(part));
+                            iter = cctx.offheap().rebalanceIterator(part, d.topologyVersion(),
+                                d.isHistorical(part) ? d.partitionCounter(part) : null);
+
+                            if (!iter.historical()) {
+                                assert !cctx.shared().database().persistenceEnabled() || !d.isHistorical(part);
 
-                            if (!iter.historical())
                                 s.clean(part);
+                            }
+                            else
+                                assert cctx.shared().database().persistenceEnabled() && d.isHistorical(part);
                         }
                         else
                             iter = (IgniteRebalanceIterator)sctx.entryIt;

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessageV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessageV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessageV2.java
index f4c624d..5cfd6e5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessageV2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessageV2.java
@@ -235,7 +235,6 @@ public class GridDhtPartitionSupplyMessageV2 extends GridCacheMessage implements
     void addEntry0(int p, GridCacheEntryInfo info, GridCacheContext ctx) throws IgniteCheckedException {
         assert info != null;
         assert (info.key() != null || info.keyBytes() != null);
-        assert info.value() != null;
 
         // Need to call this method to initialize info properly.
         marshalInfo(info, ctx);

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 4c179e6..6cba4f4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -218,11 +218,20 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     private boolean exchangeOnChangeGlobalState;
 
     /** */
-    private final ConcurrentMap<UUID, GridDhtPartitionsAbstractMessage> msgs = new ConcurrentHashMap8<>();
+    private ConcurrentMap<UUID, GridDhtPartitionsSingleMessage> msgs = new ConcurrentHashMap8<>();
+
+    /** */
+    private volatile IgniteDhtPartitionHistorySuppliersMap partHistSuppliers = new IgniteDhtPartitionHistorySuppliersMap();
 
     /** Forced Rebalance future. */
     private GridFutureAdapter<Boolean> forcedRebFut;
 
+    /** */
+    private volatile Map<Integer, Map<Integer, Long>> partHistReserved;
+
+    /** */
+    private volatile IgniteDhtPartitionsToReloadMap partsToReload = new IgniteDhtPartitionsToReloadMap();
+
     /**
      * Dummy future created to trigger reassignments if partition
      * topology changed while preloading.
@@ -368,6 +377,15 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     }
 
     /**
+     * @param cacheId Cache ID.
+     * @param partId Partition ID.
+     * @return ID of history supplier node or null if it doesn't exist.
+     */
+    @Nullable public UUID partitionHistorySupplier(int cacheId, int partId) {
+        return partHistSuppliers.getSupplier(cacheId, partId);
+    }
+
+    /**
      * @param cacheId Cache ID to check.
      * @param topVer Topology version.
      * @return {@code True} if cache was added during this exchange.
@@ -509,7 +527,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
             if (discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT) {
                 DiscoveryCustomMessage msg = ((DiscoveryCustomEvent)discoEvt).customMessage();
 
-                if (msg instanceof DynamicCacheChangeBatch){
+                if (msg instanceof DynamicCacheChangeBatch) {
                     assert !F.isEmpty(reqs);
 
                     exchange = onCacheChangeRequest(crdNode);
@@ -678,7 +696,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                     exchId.topologyVersion().equals(cacheCtx.startTopologyVersion());
 
                 if (updateTop && clientTop != null)
-                    cacheCtx.topology().update(exchId, clientTop.partitionMap(true), clientTop.updateCounters(false));
+                    cacheCtx.topology().update(this, clientTop.partitionMap(true), clientTop.updateCounters(false), Collections.<Integer>emptySet());
             }
 
             top.updateTopologyVersion(exchId, this, updSeq, stopping(cacheCtx.cacheId()));
@@ -798,9 +816,10 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                     if (updateTop) {
                         for (GridClientPartitionTopology top : cctx.exchange().clientTopologies()) {
                             if (top.cacheId() == cacheCtx.cacheId()) {
-                                cacheCtx.topology().update(exchId,
+                                cacheCtx.topology().update(this,
                                     top.partitionMap(true),
-                                    top.updateCounters(false));
+                                    top.updateCounters(false),
+                                    Collections.<Integer>emptySet());
 
                                 break;
                             }
@@ -845,11 +864,15 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
             cacheCtx.preloader().onTopologyChanged(this);
         }
 
+        cctx.database().releaseHistoryForPreloading();
+
+        // To correctly rebalance when persistence is enabled, it is necessary to reserve history within exchange.
+        partHistReserved = cctx.database().reserveHistoryForExchange();
+
         waitPartitionRelease();
 
         boolean topChanged = discoEvt.type() != EVT_DISCOVERY_CUSTOM_EVT || affChangeMsg != null;
 
-        //todo check
         for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
             if (cacheCtx.isLocal() || stopping(cacheCtx.cacheId()))
                 continue;
@@ -1107,6 +1130,11 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         GridDhtPartitionsSingleMessage m = cctx.exchange().createPartitionsSingleMessage(
             node, exchangeId(), clientOnlyExchange, true);
 
+        Map<Integer, Map<Integer, Long>> partHistReserved0 = partHistReserved;
+
+        if (partHistReserved0 != null)
+            m.partitionHistoryCounters(partHistReserved0);
+
         if (exchangeOnChangeGlobalState && changeGlobalStateE != null)
             m.setException(changeGlobalStateE);
 
@@ -1133,6 +1161,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
             nodes,
             exchangeId(),
             last != null ? last : cctx.versions().last(),
+            partHistSuppliers,
+            partsToReload,
             compress);
 
         if (exchangeOnChangeGlobalState && !F.isEmpty(changeGlobalStateExceptions))
@@ -1252,6 +1282,22 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         if (exchangeOnChangeGlobalState && err == null)
             cctx.kernalContext().state().onExchangeDone();
 
+        Map<T2<Integer, Integer>, Long> localReserved = partHistSuppliers.getReservations(cctx.localNodeId());
+
+        if (localReserved != null) {
+            for (Map.Entry<T2<Integer, Integer>, Long> e : localReserved.entrySet()) {
+                boolean success = cctx.database().reserveHistoryForPreloading(
+                    e.getKey().get1(), e.getKey().get2(), e.getValue());
+
+                if (!success) {
+                    // TODO: how to handle?
+                    err = new IgniteCheckedException("Could not reserve history");
+                }
+            }
+        }
+
+        cctx.database().releaseHistoryForExchange();
+
         if (super.onDone(res, err) && realExchange) {
             if (log.isDebugEnabled())
                 log.debug("Completed partition exchange [localNode=" + cctx.localNodeId() + ", exchange= " + this +
@@ -1523,8 +1569,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      */
     private void assignPartitionStates(GridDhtPartitionTopology top) {
         Map<Integer, CounterWithNodes> maxCntrs = new HashMap<>();
+        Map<Integer, Long> minCntrs = new HashMap<>();
 
-        for (Map.Entry<UUID, GridDhtPartitionsAbstractMessage> e : msgs.entrySet()) {
+        for (Map.Entry<UUID, GridDhtPartitionsSingleMessage> e : msgs.entrySet()) {
             assert e.getValue().partitionUpdateCounters(top.cacheId()) != null;
 
             for (Map.Entry<Integer, T2<Long, Long>> e0 : e.getValue().partitionUpdateCounters(top.cacheId()).entrySet()) {
@@ -1534,12 +1581,20 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
                 GridDhtPartitionState state = top.partitionState(uuid, p);
 
-                if (state != GridDhtPartitionState.OWNING)
+                if (state != GridDhtPartitionState.OWNING && state != GridDhtPartitionState.MOVING)
                     continue;
 
-                Long cntr = e0.getValue().get1();
+                Long cntr = state == GridDhtPartitionState.MOVING ? e0.getValue().get1() : e0.getValue().get2();
 
                 if (cntr == null)
+                    cntr = 0L;
+
+                Long minCntr = minCntrs.get(p);
+
+                if (minCntr == null || minCntr > cntr)
+                    minCntrs.put(p, cntr);
+
+                if (state != GridDhtPartitionState.OWNING)
                     continue;
 
                 CounterWithNodes maxCntr = maxCntrs.get(p);
@@ -1555,29 +1610,86 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         for (GridDhtLocalPartition part : top.currentLocalPartitions()) {
             GridDhtPartitionState state = top.partitionState(cctx.localNodeId(), part.id());
 
+            if (state != GridDhtPartitionState.OWNING && state != GridDhtPartitionState.MOVING)
+                continue;
+
+            long cntr = state == GridDhtPartitionState.MOVING ? part.initialUpdateCounter() : part.updateCounter();
+
+            Long minCntr = minCntrs.get(part.id());
+
+            if (minCntr == null || minCntr > cntr)
+                minCntrs.put(part.id(), cntr);
+
             if (state != GridDhtPartitionState.OWNING)
                 continue;
 
             CounterWithNodes maxCntr = maxCntrs.get(part.id());
 
-            if (maxCntr == null || part.initialUpdateCounter() > maxCntr.cnt)
-                maxCntrs.put(part.id(), new CounterWithNodes(part.updateCounter(), cctx.localNodeId()));
-            else if (part.initialUpdateCounter() == maxCntr.cnt)
+            if (maxCntr == null || cntr > maxCntr.cnt)
+                maxCntrs.put(part.id(), new CounterWithNodes(cntr, cctx.localNodeId()));
+            else if (cntr == maxCntr.cnt)
                 maxCntr.nodes.add(cctx.localNodeId());
         }
 
         int entryLeft = maxCntrs.size();
 
+        Map<Integer, Map<Integer, Long>> partHistReserved0 = partHistReserved;
+
+        Map<Integer, Long> localReserved = partHistReserved0 != null ? partHistReserved0.get(top.cacheId()) : null;
+
+        Set<Integer> haveHistory = new HashSet<>();
+
+        for (Map.Entry<Integer, Long> e : minCntrs.entrySet()) {
+            int p = e.getKey();
+            long minCntr = e.getValue();
+
+            CounterWithNodes maxCntrObj = maxCntrs.get(p);
+
+            long maxCntr = maxCntrObj != null ? maxCntrObj.cnt : 0;
+
+            // If minimal counter is zero, do clean preloading.
+            if (minCntr == 0 || minCntr == maxCntr)
+                continue;
+
+            if (localReserved != null) {
+                Long localCntr = localReserved.get(p);
+
+                if (localCntr != null && localCntr <= minCntr &&
+                    maxCntrObj.nodes.contains(cctx.localNodeId())) {
+                    partHistSuppliers.put(cctx.localNodeId(), top.cacheId(), p, minCntr);
+
+                    haveHistory.add(p);
+
+                    continue;
+                }
+            }
+
+            for (Map.Entry<UUID, GridDhtPartitionsSingleMessage> e0 : msgs.entrySet()) {
+                Long histCntr = e0.getValue().partitionHistoryCounters(top.cacheId()).get(p);
+
+                if (histCntr != null && histCntr <= minCntr && maxCntrObj.nodes.contains(e0.getKey())) {
+                    partHistSuppliers.put(e0.getKey(), top.cacheId(), p, minCntr);
+
+                    haveHistory.add(p);
+
+                    break;
+                }
+            }
+        }
+
         for (Map.Entry<Integer, CounterWithNodes> e : maxCntrs.entrySet()) {
             int p = e.getKey();
             long maxCntr = e.getValue().cnt;
 
-            entryLeft --;
+            entryLeft--;
 
             if (entryLeft != 0 && maxCntr == 0)
                 continue;
 
-            top.setOwners(p, e.getValue().nodes, entryLeft == 0);
+            Set<UUID> nodesToReload = top.setOwners(p, e.getValue().nodes, haveHistory.contains(p), entryLeft == 0);
+
+            for (UUID nodeId : nodesToReload)
+                partsToReload.put(nodeId, top.cacheId(), p);
         }
     }
 
@@ -1618,6 +1730,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         try {
             assert crd.isLocal();
 
+            assert partHistSuppliers.isEmpty();
+
             if (!crd.equals(cctx.discovery().serverNodes(topologyVersion()).get(0))) {
                 for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
                     if (!cacheCtx.isLocal())
@@ -1818,6 +1932,10 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     private void updatePartitionFullMap(GridDhtPartitionsFullMessage msg) {
         cctx.versions().onExchange(msg.lastVersion().order());
 
+        assert partHistSuppliers.isEmpty();
+
+        partHistSuppliers.putAll(msg.partitionHistorySuppliers());
+
         for (Map.Entry<Integer, GridDhtPartitionFullMap> entry : msg.partitions().entrySet()) {
             Integer cacheId = entry.getKey();
 
@@ -1826,12 +1944,13 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
             GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
 
             if (cacheCtx != null)
-                cacheCtx.topology().update(exchId, entry.getValue(), cntrMap);
+                cacheCtx.topology().update(this, entry.getValue(), cntrMap,
+                    msg.partsToReload(cctx.localNodeId(), cacheId));
             else {
                 ClusterNode oldest = cctx.discovery().oldestAliveCacheServerNode(AffinityTopologyVersion.NONE);
 
                 if (oldest != null && oldest.isLocal())
-                    cctx.exchange().clientTopology(cacheId, this).update(exchId, entry.getValue(), cntrMap);
+                    cctx.exchange().clientTopology(cacheId, this).update(this, entry.getValue(), cntrMap, Collections.<Integer>emptySet());
             }
         }
     }
@@ -2014,7 +2133,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                         }
 
                         if (crd0.isLocal()) {
-                            if (exchangeOnChangeGlobalState && changeGlobalStateE !=null)
+                            if (exchangeOnChangeGlobalState && changeGlobalStateE != null)
                                 changeGlobalStateExceptions.put(crd0.id(), changeGlobalStateE);
 
                             if (allReceived) {


[28/50] [abbrv] ignite git commit: create F.isNotEmptyDirectory() as an opposite to F.isEmptyDirectory() (fixing call to !F.isEmptyDirectory()) revert some FileSnapshot.getStream() changes

Posted by sb...@apache.org.
create F.isNotEmptyDirectory() as an opposite to F.isEmptyDirectory() (fixing call to !F.isEmptyDirectory())
revert some FileSnapshot.getStream() changes


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 0693a9a7eb0f4c7b3fd7109885f1e1150f4da126
Parents: 476e8f1
Author: Alexandr Kuramshin <ak...@gridgain.com>
Authored: Sun Mar 19 00:08:50 2017 +0700
Committer: Alexandr Kuramshin <ak...@gridgain.com>
Committed: Sun Mar 19 00:08:50 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/util/lang/GridFunc.java     | 21 ++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0693a9a7/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
index 4ddf615..fff76cb 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridFunc.java
@@ -2318,10 +2318,10 @@ public class GridFunc {
     }
 
     /**
-     * Tests if the given path is a directory and is not {@code null} or empty.
+     * Tests if the given path is not {@code null} and is an empty directory.
      *
      * @param dir Path to test.
-     * @return Whether or not the given path is a directory and is not {@code null} or empty.
+     * @return Whether or not the given path is not {@code null} and is an empty directory.
      */
     public static boolean isEmptyDirectory(Path dir) {
         if (dir == null || !Files.isDirectory(dir))
@@ -2335,6 +2335,23 @@ public class GridFunc {
     }
 
     /**
+     * Tests if the given path is not {@code null} and is a not empty directory.
+     *
+     * @param dir Path to test.
+     * @return Whether or not the given path is not {@code null} and is a not empty directory.
+     */
+    public static boolean isNotEmptyDirectory(Path dir) {
+        if (dir == null || !Files.isDirectory(dir))
+            return false;
+        try (DirectoryStream<Path> files = Files.newDirectoryStream(dir)) {
+            return files.iterator().hasNext();
+        }
+        catch (IOException e) {
+            throw new IgniteException(e);
+        }
+    }
+
+    /**
      * Converts collection of numbers to primitive {@code int[]} array.
      *
      * @param col Collection of numbers.


[49/50] [abbrv] ignite git commit: Optimizations from ignite-5068.

Posted by sb...@apache.org.
Optimizations from ignite-5068.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 58b6e05e82978c68ba9e2e53a3b9b866e2c474ca
Parents: 52556f4
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Fri Apr 28 19:57:32 2017 +0300
Committer: Ilya Lantukh <il...@gridgain.com>
Committed: Fri Apr 28 19:57:32 2017 +0300

----------------------------------------------------------------------
 .../dht/GridClientPartitionTopology.java        |   5 +
 .../dht/GridDhtPartitionTopology.java           |   6 +
 .../dht/GridDhtPartitionTopologyImpl.java       | 473 +++++++++++--------
 .../GridDhtPartitionsExchangeFuture.java        |   9 +
 4 files changed, 302 insertions(+), 191 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/58b6e05e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index 5c5a3c4..e71c18f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -778,6 +778,11 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
+    @Override public void onExchangeDone(AffinityAssignment assignment) {
+        // no-op
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean detectLostPartitions(DiscoveryEvent discoEvt) {
         assert false : "detectLostPartitions should never be called on client topology";
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/58b6e05e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
index 2bef267..5df8714 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
@@ -326,4 +326,10 @@ public interface GridDhtPartitionTopology {
      * @return Set of node IDs that should reload partitions.
      */
     public Set<UUID> setOwners(int p, Set<UUID> owners, boolean haveHistory, boolean updateSeq);
+
+    /**
+     * Callback on exchange done.
+     * @param assignment New affinity assignment.
+     */
+    public void onExchangeDone(AffinityAssignment assignment);
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/58b6e05e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index fb09b38..d1283c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@ -79,6 +79,9 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     private static final boolean FULL_MAP_DEBUG = false;
 
     /** */
+    private static final boolean FAST_DIFF_REBUILD = true;
+
+    /** */
     private static final Long ZERO = 0L;
 
     /** Context. */
@@ -93,8 +96,11 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     /** Node to partition map. */
     private GridDhtPartitionFullMap node2part;
 
-    /** Partition to node map. */
-    private final Map<Integer, Set<UUID>> part2node;
+    /** */
+    private final Map<Integer, Set<UUID>> diffFromAffinity = new HashMap<>();
+
+    /** */
+    private volatile AffinityTopologyVersion diffFromAffinityVer = AffinityTopologyVersion.NONE;
 
     /** */
     private GridDhtPartitionExchangeId lastExchangeId;
@@ -142,8 +148,6 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         log = cctx.logger(getClass());
 
         locParts = new AtomicReferenceArray<>(cctx.config().getAffinity().partitions());
-
-        part2node = new HashMap<>(cctx.config().getAffinity().partitions(), 1.0f);
     }
 
     /** {@inheritDoc} */
@@ -160,7 +164,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         try {
             node2part = null;
 
-            part2node.clear();
+            diffFromAffinity.clear();
 
             lastExchangeId = null;
 
@@ -168,6 +172,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             topReadyFut = null;
 
+            diffFromAffinityVer = AffinityTopologyVersion.NONE;
+
             rebalancedTopVer = AffinityTopologyVersion.NONE;
 
             topVer = AffinityTopologyVersion.NONE;
@@ -863,18 +869,42 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             List<ClusterNode> nodes = null;
 
-            Collection<UUID> nodeIds = part2node.get(p);
+            if (!topVer.equals(diffFromAffinityVer)) {
+                log.error("??? node2part [topVer=" + topVer + ", diffVer=" + diffFromAffinityVer + "]");
+
+                nodes = new ArrayList<>();
+
+                nodes.addAll(affNodes);
 
-            if (!F.isEmpty(nodeIds)) {
-                for (UUID nodeId : nodeIds) {
-                    HashSet<UUID> affIds = affAssignment.getIds(p);
+                for (Map.Entry<UUID, GridDhtPartitionMap2> entry : node2part.entrySet()) {
+                    GridDhtPartitionState state = entry.getValue().get(p);
 
-                    if (!affIds.contains(nodeId) && hasState(p, nodeId, OWNING, MOVING)) {
+                    ClusterNode n = cctx.discovery().node(entry.getKey());
+
+                    if (n != null && state != null && (state == MOVING || state == OWNING) && !nodes.contains(n)
+                        && (topVer.topologyVersion() < 0 || n.order() <= topVer.topologyVersion())) {
+                        nodes.add(n);
+                    }
+
+                }
+
+                return nodes;
+            }
+
+            Collection<UUID> diffIds = diffFromAffinity.get(p);
+
+            if (!F.isEmpty(diffIds)) {
+                HashSet<UUID> affIds = affAssignment.getIds(p);
+
+                for (UUID nodeId : diffIds) {
+                    assert !affIds.contains(nodeId);
+
+                    if (hasState(p, nodeId, OWNING, MOVING)) {
                         ClusterNode n = cctx.discovery().node(nodeId);
 
                         if (n != null && (topVer.topologyVersion() < 0 || n.order() <= topVer.topologyVersion())) {
                             if (nodes == null) {
-                                nodes = new ArrayList<>(affNodes.size() + 2);
+                                nodes = new ArrayList<>(affNodes.size() + diffIds.size());
 
                                 nodes.addAll(affNodes);
                             }
@@ -903,7 +933,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         AffinityTopologyVersion topVer,
         GridDhtPartitionState state,
         GridDhtPartitionState... states) {
-        Collection<UUID> allIds = topVer.topologyVersion() > 0 ? F.nodeIds(discoCache.cacheAffinityNodes(cctx.cacheId())) : null;
+        Collection<UUID> allIds = F.nodeIds(discoCache.cacheAffinityNodes(cctx.cacheId()));
 
         lock.readLock().lock();
 
@@ -913,20 +943,10 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 ", node2part=" + node2part +
                 ", cache=" + cctx.name() + ']';
 
-            Collection<UUID> nodeIds = part2node.get(p);
-
             // Node IDs can be null if both, primary and backup, nodes disappear.
-            int size = nodeIds == null ? 0 : nodeIds.size();
-
-            if (size == 0)
-                return Collections.emptyList();
-
-            List<ClusterNode> nodes = new ArrayList<>(size);
-
-            for (UUID id : nodeIds) {
-                if (topVer.topologyVersion() > 0 && !F.contains(allIds, id))
-                    continue;
+            List<ClusterNode> nodes = new ArrayList<>();
 
+            for (UUID id : allIds) {
                 if (hasState(p, id, state, states)) {
                     ClusterNode n = cctx.discovery().node(id);
 
@@ -1098,30 +1118,39 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             node2part = partMap;
 
-            part2node.clear();
+            AffinityTopologyVersion affVer = cctx.affinity().affinityTopologyVersion();
+
+            if (diffFromAffinityVer.compareTo(affVer) <= 0) {
+                AffinityAssignment affAssignment = cctx.affinity().assignment(affVer);
 
-            for (Map.Entry<UUID, GridDhtPartitionMap2> e : partMap.entrySet()) {
-                for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
-                    if (e0.getValue() != MOVING && e0.getValue() != OWNING)
-                        continue;
+                for (Map.Entry<UUID, GridDhtPartitionMap2> e : partMap.entrySet()) {
+                    for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
+                        int p = e0.getKey();
 
-                    int p = e0.getKey();
+                        Set<UUID> diffIds = diffFromAffinity.get(p);
 
-                    Set<UUID> ids = part2node.get(p);
+                        if ((e0.getValue() == MOVING || e0.getValue() == OWNING || e0.getValue() == RENTING) &&
+                            !affAssignment.getIds(p).contains(e.getKey())) {
 
-                    if (ids == null)
-                        // Initialize HashSet to size 3 in anticipation that there won't be
-                        // more than 3 nodes per partitions.
-                        part2node.put(p, ids = U.newHashSet(3));
+                            if (diffIds == null)
+                                diffFromAffinity.put(p, diffIds = U.newHashSet(3));
 
-                    ids.add(e.getKey());
+                            diffIds.add(e.getKey());
+                        }
+                        else {
+                            if (diffIds != null && diffIds.remove(e.getKey())) {
+                                if (diffIds.isEmpty())
+                                    diffFromAffinity.remove(p);
+                            }
+                        }
+                    }
                 }
+
+                diffFromAffinityVer = affVer;
             }
 
             boolean changed = false;
 
-            AffinityTopologyVersion affVer = cctx.affinity().affinityTopologyVersion();
-
             GridDhtPartitionMap2 nodeMap = partMap.get(cctx.localNodeId());
 
             if (nodeMap != null && cctx.shared().database().persistenceEnabled()) {
@@ -1296,37 +1325,52 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             node2part.put(parts.nodeId(), parts);
 
-            // Add new mappings.
-            for (Map.Entry<Integer,GridDhtPartitionState> e : parts.entrySet()) {
-                int p = e.getKey();
+            AffinityTopologyVersion affVer = cctx.affinity().affinityTopologyVersion();
 
-                Set<UUID> ids = part2node.get(p);
+            if (affVer.compareTo(diffFromAffinityVer) >= 0) {
+                AffinityAssignment affAssignment = cctx.affinity().assignment(affVer);
 
-                if (e.getValue() == MOVING || e.getValue() == OWNING) {
-                    if (ids == null)
-                        // Initialize HashSet to size 3 in anticipation that there won't be
-                        // more than 3 nodes per partition.
-                        part2node.put(p, ids = U.newHashSet(3));
+                // Add new mappings.
+                for (Map.Entry<Integer, GridDhtPartitionState> e : parts.entrySet()) {
+                    int p = e.getKey();
 
-                    changed |= ids.add(parts.nodeId());
-                }
-                else {
-                    if (ids != null)
-                        changed |= ids.remove(parts.nodeId());
+                    Set<UUID> diffIds = diffFromAffinity.get(p);
+
+                    if ((e.getValue() == MOVING || e.getValue() == OWNING || e.getValue() == RENTING)
+                        && !affAssignment.getIds(p).contains(parts.nodeId())) {
+                        if (diffIds == null)
+                            diffFromAffinity.put(p, diffIds = U.newHashSet(3));
+
+                        if (diffIds.add(parts.nodeId()))
+                            changed = true;
+                    }
+                    else {
+                        if (diffIds != null && diffIds.remove(parts.nodeId())) {
+                            changed = true;
+
+                            if (diffIds.isEmpty())
+                                diffFromAffinity.remove(p);
+                        }
+
+                    }
                 }
-            }
 
-            // Remove obsolete mappings.
-            if (cur != null) {
-                for (Integer p : F.view(cur.keySet(), F0.notIn(parts.keySet()))) {
-                    Set<UUID> ids = part2node.get(p);
+                // Remove obsolete mappings.
+                if (cur != null) {
+                    for (Integer p : F.view(cur.keySet(), F0.notIn(parts.keySet()))) {
+                        Set<UUID> ids = diffFromAffinity.get(p);
 
-                    if (ids != null)
-                        changed |= ids.remove(parts.nodeId());
+                        if (ids != null && ids.remove(parts.nodeId())) {
+                            changed = true;
+
+                            if (ids.isEmpty())
+                                diffFromAffinity.remove(p);
+                        }
+                    }
                 }
-            }
 
-            AffinityTopologyVersion affVer = cctx.affinity().affinityTopologyVersion();
+                diffFromAffinityVer = affVer;
+            }
 
             if (!affVer.equals(AffinityTopologyVersion.NONE) && affVer.compareTo(topVer) >= 0) {
                 List<List<ClusterNode>> aff = cctx.affinity().assignments(topVer);
@@ -1352,44 +1396,96 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     }
 
     /** {@inheritDoc} */
-    @Override public boolean detectLostPartitions(DiscoveryEvent discoEvt) {
+    @Override public void onExchangeDone(AffinityAssignment assignment) {
         lock.writeLock().lock();
 
         try {
-            int parts = cctx.affinity().partitions();
+            if (assignment.topologyVersion().compareTo(diffFromAffinityVer) >= 0)
+                rebuildDiff(assignment);
+        }
+        finally {
+            lock.writeLock().unlock();
+        }
+    }
+
+    /**
+     * @param affAssignment New affinity assignment.
+     */
+    private void rebuildDiff(AffinityAssignment affAssignment) {
+        assert lock.isWriteLockedByCurrentThread();
 
-            Collection<Integer> lost = null;
+        if (node2part == null)
+            return;
 
-            for (int p = 0; p < parts; p++) {
-                boolean foundOwner = false;
+        if (FAST_DIFF_REBUILD) {
+            Collection<UUID> affNodes = F.nodeIds(cctx.discovery().cacheAffinityNodes(cctx.name(), affAssignment.topologyVersion()));
 
-                Set<UUID> nodeIds = part2node.get(p);
+            for (Map.Entry<Integer, Set<UUID>> e : diffFromAffinity.entrySet()) {
+                int p = e.getKey();
+
+                Iterator<UUID> iter = e.getValue().iterator();
+
+                while (iter.hasNext()) {
+                    UUID nodeId = iter.next();
 
-                if (nodeIds != null) {
-                    for (UUID nodeId : nodeIds) {
-                        GridDhtPartitionMap2 partMap = node2part.get(nodeId);
+                    if (!affNodes.contains(nodeId) || affAssignment.getIds(p).contains(nodeId))
+                        iter.remove();
+                }
+            }
+        }
+        else {
+            for (Map.Entry<UUID, GridDhtPartitionMap2> e : node2part.entrySet()) {
+                UUID nodeId = e.getKey();
 
-                        GridDhtPartitionState state = partMap.get(p);
+                for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
+                    int p0 = e0.getKey();
 
-                        if (state == OWNING) {
-                            foundOwner = true;
+                    GridDhtPartitionState state = e0.getValue();
 
-                            break;
-                        }
+                    Set<UUID> ids = diffFromAffinity.get(p0);
+
+                    if ((state == MOVING || state == OWNING) && !affAssignment.getIds(p0).contains(nodeId)) {
+                        if (ids == null)
+                            diffFromAffinity.put(p0, ids = U.newHashSet(3));
+
+                        ids.add(nodeId);
+                    }
+                    else {
+                        if (ids != null)
+                            ids.remove(nodeId);
                     }
                 }
+            }
+        }
+
+        diffFromAffinityVer = affAssignment.topologyVersion();
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean detectLostPartitions(DiscoveryEvent discoEvt) {
+        lock.writeLock().lock();
+
+        try {
+            if (node2part == null)
+                return false;
+
+            int parts = cctx.affinity().partitions();
 
-                if (!foundOwner) {
-                    if (lost == null)
-                        lost = new HashSet<>(parts - p, 1.0f);
+            Set<Integer> lost = new HashSet<>(parts);
 
-                    lost.add(p);
+            for (int p = 0; p < parts; p++)
+                lost.add(p);
+
+            for (GridDhtPartitionMap2 partMap : node2part.values()) {
+                for (Map.Entry<Integer, GridDhtPartitionState> e : partMap.entrySet()) {
+                    if (e.getValue() == OWNING)
+                        lost.remove(e.getKey());
                 }
             }
 
             boolean changed = false;
 
-            if (lost != null) {
+            if (!lost.isEmpty()) {
                 PartitionLossPolicy plc = cctx.config().getPartitionLossPolicy();
 
                 assert plc != null;
@@ -1410,16 +1506,17 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                     }
                     // Update map for remote node.
                     else if (plc != PartitionLossPolicy.IGNORE) {
-                        Set<UUID> nodeIds = part2node.get(part);
-
-                        if (nodeIds != null) {
-                            for (UUID nodeId : nodeIds) {
-                                GridDhtPartitionMap2 nodeMap = node2part.get(nodeId);
-
-                                if (nodeMap.get(part) != EVICTED)
-                                    nodeMap.put(part, LOST);
-                            }
-                        }
+                        // TODO
+//                        Set<UUID> nodeIds = part2node.get(part);
+//
+//                        if (nodeIds != null) {
+//                            for (UUID nodeId : nodeIds) {
+//                                GridDhtPartitionMap nodeMap = node2part.get(nodeId);
+//
+//                                if (nodeMap.get(part) != EVICTED)
+//                                    nodeMap.put(part, LOST);
+//                            }
+//                        }
                     }
 
                     if (cctx.events().isRecordable(EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST))
@@ -1440,86 +1537,83 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
     /** {@inheritDoc} */
     @Override public void resetLostPartitions() {
-        lock.writeLock().lock();
-
-        try {
-            int parts = cctx.affinity().partitions();
-            long updSeq = updateSeq.incrementAndGet();
-
-            for (int part = 0; part < parts; part++) {
-                Set<UUID> nodeIds = part2node.get(part);
-
-                if (nodeIds != null) {
-                    boolean lost = false;
-
-                    for (UUID node : nodeIds) {
-                        GridDhtPartitionMap2 map = node2part.get(node);
-
-                        if (map.get(part) == LOST) {
-                            lost = true;
-
-                            break;
-                        }
-                    }
-
-                    if (lost) {
-                        GridDhtLocalPartition locPart = localPartition(part, topVer, false);
-
-                        if (locPart != null) {
-                            boolean marked = locPart.own();
-
-                            if (marked)
-                                updateLocal(locPart.id(), locPart.state(), updSeq);
-                        }
-
-                        for (UUID nodeId : nodeIds) {
-                            GridDhtPartitionMap2 nodeMap = node2part.get(nodeId);
-
-                            if (nodeMap.get(part) == LOST)
-                                nodeMap.put(part, OWNING);
-                        }
-                    }
-                }
-            }
-
-            checkEvictions(updSeq, cctx.affinity().assignments(topVer));
-
-            cctx.needsRecovery(false);
-        }
-        finally {
-            lock.writeLock().unlock();
-        }
+        // TODO
+
+//        lock.writeLock().lock();
+//
+//        try {
+//            int parts = cctx.affinity().partitions();
+//            long updSeq = updateSeq.incrementAndGet();
+//
+//            for (int part = 0; part < parts; part++) {
+//                Set<UUID> nodeIds = part2node.get(part);
+//
+//                if (nodeIds != null) {
+//                    boolean lost = false;
+//
+//                    for (UUID node : nodeIds) {
+//                        GridDhtPartitionMap2 map = node2part.get(node);
+//
+//                        if (map.get(part) == LOST) {
+//                            lost = true;
+//
+//                            break;
+//                        }
+//                    }
+//
+//                    if (lost) {
+//                        GridDhtLocalPartition locPart = localPartition(part, topVer, false);
+//
+//                        if (locPart != null) {
+//                            boolean marked = locPart.own();
+//
+//                            if (marked)
+//                                updateLocal(locPart.id(), locPart.state(), updSeq);
+//                        }
+//
+//                        for (UUID nodeId : nodeIds) {
+//                            GridDhtPartitionMap2 nodeMap = node2part.get(nodeId);
+//
+//                            if (nodeMap.get(part) == LOST)
+//                                nodeMap.put(part, OWNING);
+//                        }
+//                    }
+//                }
+//            }
+//
+//            checkEvictions(updSeq, cctx.affinity().assignments(topVer));
+//
+//            cctx.needsRecovery(false);
+//        }
+//        finally {
+//            lock.writeLock().unlock();
+//        }
     }
 
     /** {@inheritDoc} */
     @Override public Collection<Integer> lostPartitions() {
+        if (cctx.config().getPartitionLossPolicy() == PartitionLossPolicy.IGNORE)
+            return Collections.emptySet();
+
         lock.readLock().lock();
 
         try {
-            Collection<Integer> res = null;
+            Set<Integer> res = null;
 
             int parts = cctx.affinity().partitions();
 
-            for (int part = 0; part < parts; part++) {
-                Set<UUID> nodeIds = part2node.get(part);
-
-                if (nodeIds != null) {
-                    for (UUID node : nodeIds) {
-                        GridDhtPartitionMap2 map = node2part.get(node);
-
-                        if (map.get(part) == LOST) {
-                            if (res == null)
-                                res = new ArrayList<>(parts - part);
+            for (GridDhtPartitionMap2 partMap : node2part.values()) {
+                for (Map.Entry<Integer, GridDhtPartitionState> e : partMap.entrySet()) {
+                    if (e.getValue() == LOST) {
+                        if (res == null)
+                            res = new HashSet<>(parts);
 
-                            res.add(part);
-
-                            break;
-                        }
+                        res.add(e.getKey());
                     }
                 }
             }
 
-            return res == null ? Collections.<Integer>emptyList() : res;
+            return res == null ? Collections.<Integer>emptySet() : res;
         }
         finally {
             lock.readLock().unlock();
@@ -1750,12 +1844,18 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             map.put(p, state);
 
-            Set<UUID> ids = part2node.get(p);
+            if (state == MOVING || state == OWNING) {
+                    AffinityAssignment assignment = cctx.affinity().assignment(diffFromAffinityVer);
 
-            if (ids == null)
-                part2node.put(p, ids = U.newHashSet(3));
+                    if (!assignment.getIds(p).contains(cctx.localNodeId())) {
+                        Set<UUID> diffIds = diffFromAffinity.get(p);
 
-            ids.add(locNodeId);
+                        if (diffIds == null)
+                            diffFromAffinity.put(p, diffIds = U.newHashSet(3));
+
+                        diffIds.add(cctx.localNodeId());
+                    }
+                }
         }
 
         return updateSeq;
@@ -1787,14 +1887,10 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             if (parts != null) {
                 for (Integer p : parts.keySet()) {
-                    Set<UUID> nodeIds = part2node.get(p);
+                    Set<UUID> diffIds = diffFromAffinity.get(p);
 
-                    if (nodeIds != null) {
-                        nodeIds.remove(nodeId);
-
-                        if (nodeIds.isEmpty())
-                            part2node.remove(p);
-                    }
+                    if (diffIds != null)
+                        diffIds.remove(nodeId);
                 }
             }
 
@@ -1986,7 +2082,25 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 if (affNodes.isEmpty())
                     continue;
 
-                List<ClusterNode> owners = owners(i);
+                Set<ClusterNode> owners = U.newHashSet(affNodes.size());
+
+                for (ClusterNode node : affNodes) {
+                    if (hasState(i, node.id(), OWNING))
+                        owners.add(node);
+                }
+
+                Set<UUID> diff = diffFromAffinity.get(i);
+
+                if (diff != null) {
+                    for (UUID nodeId : diff) {
+                        if (hasState(i, nodeId, OWNING)) {
+                            ClusterNode node = cctx.discovery().node(nodeId);
+
+                            if (node != null)
+                                owners.add(node);
+                        }
+                    }
+                }
 
                 if (affNodes.size() != owners.size() || !owners.containsAll(affNodes))
                     return;
@@ -2035,30 +2149,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
      * Checks consistency after all operations.
      */
     private void consistencyCheck() {
-        if (CONSISTENCY_CHECK) {
-            if (node2part == null)
-                return;
-
-            for (Map.Entry<UUID, GridDhtPartitionMap2> e : node2part.entrySet()) {
-                for (Integer p : e.getValue().keySet()) {
-                    Set<UUID> nodeIds = part2node.get(p);
-
-                    assert nodeIds != null : "Failed consistency check [part=" + p + ", nodeId=" + e.getKey() + ']';
-                    assert nodeIds.contains(e.getKey()) : "Failed consistency check [part=" + p + ", nodeId=" +
-                        e.getKey() + ", nodeIds=" + nodeIds + ']';
-                }
-            }
-
-            for (Map.Entry<Integer, Set<UUID>> e : part2node.entrySet()) {
-                for (UUID nodeId : e.getValue()) {
-                    GridDhtPartitionMap2 map = node2part.get(nodeId);
-
-                    assert map != null : "Failed consistency check [part=" + e.getKey() + ", nodeId=" + nodeId + ']';
-                    assert map.containsKey(e.getKey()) : "Failed consistency check [part=" + e.getKey() +
-                        ", nodeId=" + nodeId + ']';
-                }
-            }
-        }
+        // no-op
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/58b6e05e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 078e67b5..28c3956 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -1342,6 +1342,15 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
         cctx.database().releaseHistoryForExchange();
 
+        if (err == null && realExchange) {
+            for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
+                if (cacheCtx.isLocal())
+                    continue;
+
+                cacheCtx.topology().onExchangeDone(cacheCtx.affinity().assignment(topologyVersion()));
+            }
+        }
+
         if (super.onDone(res, err) && realExchange) {
             exchLog.info("exchange finished [topVer=" + topologyVersion() +
                 ", time1=" + duration() +


[23/50] [abbrv] ignite git commit: Reverted default late aff value.

Posted by sb...@apache.org.
Reverted default late aff value.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 2be130769e9c913ee7c84d660b813cca76a113eb
Parents: 1118c72
Author: Aleksei Scherbakov <al...@gmail.com>
Authored: Fri Mar 10 16:23:50 2017 +0300
Committer: Aleksei Scherbakov <al...@gmail.com>
Committed: Fri Mar 10 16:23:50 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/configuration/IgniteConfiguration.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2be13076/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
index cda74ae..235f753 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/IgniteConfiguration.java
@@ -216,7 +216,7 @@ public class IgniteConfiguration {
     public static final boolean DFLT_CACHE_SANITY_CHECK_ENABLED = true;
 
     /** Default value for late affinity assignment flag. */
-    public static final boolean DFLT_LATE_AFF_ASSIGNMENT = false;
+    public static final boolean DFLT_LATE_AFF_ASSIGNMENT = true;
 
     /** Default value for active on start flag. */
     public static final boolean DFLT_ACTIVE_ON_START = true;


[19/50] [abbrv] ignite git commit: IGNITE-3477 - Remove waitForRent() in exchange future

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
index 9ef9c8d..cd731cf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsFullMessage.java
@@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 import java.util.UUID;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.GridDirectMap;
@@ -62,11 +63,27 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
     /** Partitions update counters. */
     @GridToStringInclude
     @GridDirectTransient
-    private Map<Integer, Map<Integer, T2<Long, Long>>> partCntrs;
+    private IgniteDhtPartitionCountersMap partCntrs;
 
     /** Serialized partitions counters. */
     private byte[] partCntrsBytes;
 
+    /** Partitions history suppliers. */
+    @GridToStringInclude
+    @GridDirectTransient
+    private IgniteDhtPartitionHistorySuppliersMap partHistSuppliers;
+
+    /** Serialized partitions history suppliers. */
+    private byte[] partHistSuppliersBytes;
+
+    /** Partitions that must be cleared and re-loaded. */
+    @GridToStringInclude
+    @GridDirectTransient
+    private IgniteDhtPartitionsToReloadMap partsToReload;
+
+    /** Serialized partitions that must be cleared and re-loaded. */
+    private byte[] partsToReloadBytes;
+
     /** Topology version. */
     private AffinityTopologyVersion topVer;
 
@@ -96,12 +113,16 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
      */
     public GridDhtPartitionsFullMessage(@Nullable GridDhtPartitionExchangeId id,
         @Nullable GridCacheVersion lastVer,
-        @NotNull AffinityTopologyVersion topVer) {
+        @NotNull AffinityTopologyVersion topVer,
+        @Nullable IgniteDhtPartitionHistorySuppliersMap partHistSuppliers,
+        @Nullable IgniteDhtPartitionsToReloadMap partsToReload) {
         super(id, lastVer);
 
         assert id == null || topVer.equals(id.topologyVersion());
 
         this.topVer = topVer;
+        this.partHistSuppliers = partHistSuppliers;
+        this.partsToReload = partsToReload;
     }
 
     /**
@@ -159,10 +180,9 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
      */
     public void addPartitionUpdateCounters(int cacheId, Map<Integer, T2<Long, Long>> cntrMap) {
         if (partCntrs == null)
-            partCntrs = new HashMap<>();
+            partCntrs = new IgniteDhtPartitionCountersMap();
 
-        if (!partCntrs.containsKey(cacheId))
-            partCntrs.put(cacheId, cntrMap);
+        partCntrs.putIfAbsent(cacheId, cntrMap);
     }
 
     /**
@@ -171,9 +191,7 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
      */
     @Override public Map<Integer, T2<Long, Long>> partitionUpdateCounters(int cacheId) {
         if (partCntrs != null) {
-            Map<Integer, T2<Long, Long>> res = partCntrs.get(cacheId);
-
-            return res != null ? res : Collections.<Integer, T2<Long, Long>>emptyMap();
+            return partCntrs.get(cacheId);
         }
 
         return Collections.emptyMap();
@@ -182,6 +200,23 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
     /**
      *
      */
+    public IgniteDhtPartitionHistorySuppliersMap partitionHistorySuppliers() {
+        if (partHistSuppliers == null)
+            return IgniteDhtPartitionHistorySuppliersMap.empty();
+
+        return partHistSuppliers;
+    }
+
+    public Set<Integer> partsToReload(UUID nodeId, int cacheId) {
+        if (partsToReload == null)
+            return Collections.emptySet();
+
+        return partsToReload.get(nodeId, cacheId);
+    }
+
+    /**
+     *
+     */
     public Map<UUID, Exception> getExceptionsMap() {
         return exs;
     }
@@ -199,11 +234,15 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
 
         boolean marshal = (parts != null && partsBytes == null) ||
             (partCntrs != null && partCntrsBytes == null) ||
+            (partHistSuppliers != null && partHistSuppliersBytes == null) ||
+            (partsToReload != null && partsToReloadBytes == null) ||
             (exs != null && exsBytes == null);
 
         if (marshal) {
             byte[] partsBytes0 = null;
             byte[] partCntrsBytes0 = null;
+            byte[] partHistSuppliersBytes0 = null;
+            byte[] partsToReloadBytes0 = null;
             byte[] exsBytes0 = null;
 
             if (parts != null && partsBytes == null)
@@ -212,6 +251,12 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
             if (partCntrs != null && partCntrsBytes == null)
                 partCntrsBytes0 = U.marshal(ctx, partCntrs);
 
+            if (partHistSuppliers != null && partHistSuppliersBytes == null)
+                partHistSuppliersBytes0 = U.marshal(ctx, partHistSuppliers);
+
+            if (partsToReload != null && partsToReloadBytes == null)
+                partsToReloadBytes0 = U.marshal(ctx, partsToReload);
+
             if (exs != null && exsBytes == null)
                 exsBytes0 = U.marshal(ctx, exs);
 
@@ -221,10 +266,14 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
                 try {
                     byte[] partsBytesZip = U.zip(partsBytes0);
                     byte[] partCntrsBytesZip = U.zip(partCntrsBytes0);
+                    byte[] partHistSuppliersBytesZip = U.zip(partHistSuppliersBytes0);
+                    byte[] partsToReloadBytesZip = U.zip(partsToReloadBytes0);
                     byte[] exsBytesZip = U.zip(exsBytes0);
 
                     partsBytes0 = partsBytesZip;
                     partCntrsBytes0 = partCntrsBytesZip;
+                    partHistSuppliersBytes0 = partHistSuppliersBytesZip;
+                    partsToReloadBytes0 = partsToReloadBytesZip;
                     exsBytes0 = exsBytesZip;
 
                     compressed(true);
@@ -236,6 +285,8 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
 
             partsBytes = partsBytes0;
             partCntrsBytes = partCntrsBytes0;
+            partHistSuppliersBytes = partHistSuppliersBytes0;
+            partsToReloadBytes = partsToReloadBytes0;
             exsBytes = exsBytes0;
         }
     }
@@ -302,10 +353,24 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
                 partCntrs = U.unmarshal(ctx, partCntrsBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
         }
 
+        if (partHistSuppliersBytes != null && partHistSuppliers == null) {
+            if (compressed())
+                partHistSuppliers = U.unmarshalZip(ctx.marshaller(), partHistSuppliersBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
+            else
+                partHistSuppliers = U.unmarshal(ctx, partHistSuppliersBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
+        }
+
+        if (partsToReloadBytes != null && partsToReload == null) {
+            if (compressed())
+                partsToReload = U.unmarshalZip(ctx.marshaller(), partsToReloadBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
+            else
+                partsToReload = U.unmarshal(ctx, partsToReloadBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
+        }
+
         if (partCntrs == null)
-            partCntrs = new HashMap<>();
+            partCntrs = new IgniteDhtPartitionCountersMap();
 
-        if (exsBytes != null && exs == null){
+        if (exsBytes != null && exs == null) {
             if (compressed())
                 exs = U.unmarshalZip(ctx.marshaller(), exsBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
             else
@@ -350,12 +415,24 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
                 writer.incrementState();
 
             case 9:
-                if (!writer.writeByteArray("partsBytes", partsBytes))
+                if (!writer.writeByteArray("partHistSuppliersBytes", partHistSuppliersBytes))
                     return false;
 
                 writer.incrementState();
 
             case 10:
+                if (!writer.writeByteArray("partsBytes", partsBytes))
+                    return false;
+
+                writer.incrementState();
+
+            case 11:
+                if (!writer.writeByteArray("partsToReloadBytes", partsToReloadBytes))
+                    return false;
+
+                writer.incrementState();
+
+            case 12:
                 if (!writer.writeMessage("topVer", topVer))
                     return false;
 
@@ -402,7 +479,7 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
                 reader.incrementState();
 
             case 9:
-                partsBytes = reader.readByteArray("partsBytes");
+                partHistSuppliersBytes = reader.readByteArray("partHistSuppliersBytes");
 
                 if (!reader.isLastRead())
                     return false;
@@ -410,6 +487,22 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
                 reader.incrementState();
 
             case 10:
+                partsBytes = reader.readByteArray("partsBytes");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 11:
+                partsToReloadBytes = reader.readByteArray("partsToReloadBytes");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 12:
                 topVer = reader.readMessage("topVer");
 
                 if (!reader.isLastRead())
@@ -428,9 +521,10 @@ public class GridDhtPartitionsFullMessage extends GridDhtPartitionsAbstractMessa
     }
 
     //todo
+
     /** {@inheritDoc} */
     @Override public byte fieldsCount() {
-        return 11;
+        return 13;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
index 2f16c8c..8df7466 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsSingleMessage.java
@@ -65,6 +65,14 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
     /** Serialized partitions counters. */
     private byte[] partCntrsBytes;
 
+    /** Partitions history reservation counters. */
+    @GridToStringInclude
+    @GridDirectTransient
+    private Map<Integer, Map<Integer, Long>> partHistCntrs;
+
+    /** Serialized partitions history reservation counters. */
+    private byte[] partHistCntrsBytes;
+
     /** Exception. */
     @GridToStringInclude
     @GridDirectTransient
@@ -159,6 +167,43 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
     }
 
     /**
+     * @param cacheId Cache ID.
+     * @param cntrMap Partition history counters.
+     */
+    public void partitionHistoryCounters(int cacheId, Map<Integer, Long> cntrMap) {
+        if (cntrMap.isEmpty())
+            return;
+
+        if (partHistCntrs == null)
+            partHistCntrs = new HashMap<>();
+
+        partHistCntrs.put(cacheId, cntrMap);
+    }
+
+    /**
+     * @param cntrMap Partition history counters.
+     */
+    public void partitionHistoryCounters(Map<Integer, Map<Integer, Long>> cntrMap) {
+        for (Map.Entry<Integer, Map<Integer, Long>> e : cntrMap.entrySet()) {
+            partitionHistoryCounters(e.getKey(), e.getValue());
+        }
+    }
+
+    /**
+     * @param cacheId Cache ID.
+     * @return Partition history counters.
+     */
+    public Map<Integer, Long> partitionHistoryCounters(int cacheId) {
+        if (partHistCntrs != null) {
+            Map<Integer, Long> res = partHistCntrs.get(cacheId);
+
+            return res != null ? res : Collections.<Integer, Long>emptyMap();
+        }
+
+        return Collections.emptyMap();
+    }
+
+    /**
      * @return Local partitions.
      */
     public Map<Integer, GridDhtPartitionMap2> partitions() {
@@ -189,11 +234,13 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
 
         boolean marshal = (parts != null && partsBytes == null) ||
             (partCntrs != null && partCntrsBytes == null) ||
+            (partHistCntrs != null && partHistCntrsBytes == null) ||
             (ex != null && exBytes == null);
 
         if (marshal) {
             byte[] partsBytes0 = null;
             byte[] partCntrsBytes0 = null;
+            byte[] partHistCntrsBytes0 = null;
             byte[] exBytes0 = null;
 
             if (parts != null && partsBytes == null)
@@ -202,6 +249,9 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
             if (partCntrs != null && partCntrsBytes == null)
                 partCntrsBytes0 = U.marshal(ctx, partCntrs);
 
+            if (partHistCntrs != null && partHistCntrsBytes == null)
+                partHistCntrsBytes0 = U.marshal(ctx, partHistCntrs);
+
             if (ex != null && exBytes == null)
                 exBytes0 = U.marshal(ctx, ex);
 
@@ -211,10 +261,12 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
                 try {
                     byte[] partsBytesZip = U.zip(partsBytes0);
                     byte[] partCntrsBytesZip = U.zip(partCntrsBytes0);
+                    byte[] partHistCntrsBytesZip = U.zip(partHistCntrsBytes0);
                     byte[] exBytesZip = U.zip(exBytes0);
 
                     partsBytes0 = partsBytesZip;
                     partCntrsBytes0 = partCntrsBytesZip;
+                    partHistCntrsBytes0 = partHistCntrsBytesZip;
                     exBytes0 = exBytesZip;
 
                     compressed(true);
@@ -226,6 +278,7 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
 
             partsBytes = partsBytes0;
             partCntrsBytes = partCntrsBytes0;
+            partHistCntrsBytes = partHistCntrsBytes0;
             exBytes = exBytes0;
         }
     }
@@ -248,6 +301,13 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
                 partCntrs = U.unmarshal(ctx, partCntrsBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
         }
 
+        if (partHistCntrsBytes != null && partHistCntrs == null) {
+            if (compressed())
+                partHistCntrs = U.unmarshalZip(ctx.marshaller(), partHistCntrsBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
+            else
+                partHistCntrs = U.unmarshal(ctx, partHistCntrsBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
+        }
+
         if (exBytes != null && ex == null) {
             if (compressed())
                 ex = U.unmarshalZip(ctx.marshaller(), exBytes, U.resolveClassLoader(ldr, ctx.gridConfig()));
@@ -316,6 +376,12 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
                 writer.incrementState();
 
             case 10:
+                if (!writer.writeByteArray("partHistCntrsBytes", partHistCntrsBytes))
+                    return false;
+
+                writer.incrementState();
+
+            case 11:
                 if (!writer.writeByteArray("partsBytes", partsBytes))
                     return false;
 
@@ -370,6 +436,14 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
                 reader.incrementState();
 
             case 10:
+                partHistCntrsBytes = reader.readByteArray("partHistCntrsBytes");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 11:
                 partsBytes = reader.readByteArray("partsBytes");
 
                 if (!reader.isLastRead())
@@ -388,9 +462,10 @@ public class GridDhtPartitionsSingleMessage extends GridDhtPartitionsAbstractMes
     }
 
     //todo add ex
+
     /** {@inheritDoc} */
     @Override public byte fieldsCount() {
-        return 11;
+        return 12;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
index 8ada4b3..55f6bcb 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPreloader.java
@@ -75,6 +75,7 @@ import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.AFFINITY_POOL;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.MOVING;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.EVICTED;
+import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.RENTING;
 import static org.apache.ignite.internal.util.GridConcurrentFactory.newMap;
 
 /**
@@ -235,6 +236,7 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
 
         top = null;
     }
+
     /**
      * @return Node stop exception.
      */
@@ -270,8 +272,8 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
         assert exchFut.forcePreload() || exchFut.dummyReassign() ||
             exchFut.exchangeId().topologyVersion().equals(top.topologyVersion()) :
             "Topology version mismatch [exchId=" + exchFut.exchangeId() +
-            ", cache=" + cctx.name() +
-            ", topVer=" + top.topologyVersion() + ']';
+                ", cache=" + cctx.name() +
+                ", topVer=" + top.topologyVersion() + ']';
 
         GridDhtPreloaderAssignments assigns = new GridDhtPreloaderAssignments(exchFut, top.topologyVersion());
 
@@ -290,47 +292,95 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
 
             // If partition belongs to local node.
             if (cctx.affinity().partitionLocalNode(p, topVer)) {
-                GridDhtLocalPartition part = top.localPartition(p, topVer, true);
+                GridDhtLocalPartition part = top.localPartition(p, topVer, true, true);
 
                 assert part != null;
                 assert part.id() == p;
 
-                if (part.state() != MOVING) {
-                    if (log.isDebugEnabled())
-                        log.debug("Skipping partition assignment (state is not MOVING): " + part);
-
-                    continue; // For.
-                }
+                ClusterNode histSupplier = null;
 
-                Collection<ClusterNode> picked = pickedOwners(p, topVer);
+                if (cctx.shared().database().persistenceEnabled()) {
+                    UUID nodeId = exchFut.partitionHistorySupplier(cctx.cacheId(), p);
 
-                if (picked.isEmpty()) {
-                    top.own(part);
+                    if (nodeId != null)
+                        histSupplier = cctx.discovery().node(nodeId);
+                }
 
-                    if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_PART_DATA_LOST)) {
-                        DiscoveryEvent discoEvt = exchFut.discoveryEvent();
+                if (histSupplier != null) {
+                    if (part.state() != MOVING) {
+                        if (log.isDebugEnabled())
+                            log.debug("Skipping partition assignment (state is not MOVING): " + part);
 
-                        cctx.events().addPreloadEvent(p,
-                            EVT_CACHE_REBALANCE_PART_DATA_LOST, discoEvt.eventNode(),
-                            discoEvt.type(), discoEvt.timestamp());
+                        continue; // For.
                     }
 
-                    if (log.isDebugEnabled())
-                        log.debug("Owning partition as there are no other owners: " + part);
-                }
-                else {
-                    ClusterNode n = F.rand(picked);
+                    assert cctx.shared().database().persistenceEnabled();
+                    assert remoteOwners(p, topVer).contains(histSupplier) : remoteOwners(p, topVer);
 
-                    GridDhtPartitionDemandMessage msg = assigns.get(n);
+                    GridDhtPartitionDemandMessage msg = assigns.get(histSupplier);
 
                     if (msg == null) {
-                        assigns.put(n, msg = new GridDhtPartitionDemandMessage(
+                        assigns.put(histSupplier, msg = new GridDhtPartitionDemandMessage(
                             top.updateSequence(),
                             exchFut.exchangeId().topologyVersion(),
                             cctx.cacheId()));
                     }
 
-                    msg.addPartition(p);
+                    msg.addPartition(p, true);
+                }
+                else {
+                    if (cctx.shared().database().persistenceEnabled()) {
+                        if (part.state() == RENTING || part.state() == EVICTED) {
+                            try {
+                                part.rent(false).get();
+                            }
+                            catch (IgniteCheckedException e) {
+                                U.error(log, "Error while clearing outdated local partition", e);
+                            }
+
+                            part = top.localPartition(p, topVer, true);
+
+                            assert part != null;
+                        }
+                    }
+
+                    if (part.state() != MOVING) {
+                        if (log.isDebugEnabled())
+                            log.debug("Skipping partition assignment (state is not MOVING): " + part);
+
+                        continue; // For.
+                    }
+
+                    Collection<ClusterNode> picked = pickedOwners(p, topVer);
+
+                    if (picked.isEmpty()) {
+                        top.own(part);
+
+                        if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_PART_DATA_LOST)) {
+                            DiscoveryEvent discoEvt = exchFut.discoveryEvent();
+
+                            cctx.events().addPreloadEvent(p,
+                                EVT_CACHE_REBALANCE_PART_DATA_LOST, discoEvt.eventNode(),
+                                discoEvt.type(), discoEvt.timestamp());
+                        }
+
+                        if (log.isDebugEnabled())
+                            log.debug("Owning partition as there are no other owners: " + part);
+                    }
+                    else {
+                        ClusterNode n = F.rand(picked);
+
+                        GridDhtPartitionDemandMessage msg = assigns.get(n);
+
+                        if (msg == null) {
+                            assigns.put(n, msg = new GridDhtPartitionDemandMessage(
+                                top.updateSequence(),
+                                exchFut.exchangeId().topologyVersion(),
+                                cctx.cacheId()));
+                        }
+
+                        msg.addPartition(p, false);
+                    }
                 }
             }
         }
@@ -379,7 +429,7 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
     }
 
     /** {@inheritDoc} */
-    public void handleSupplyMessage(int idx, UUID id, final GridDhtPartitionSupplyMessageV2 s) {
+    @Override public void handleSupplyMessage(int idx, UUID id, final GridDhtPartitionSupplyMessageV2 s) {
         if (!enterBusy())
             return;
 
@@ -399,7 +449,7 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
     }
 
     /** {@inheritDoc} */
-    public void handleDemandMessage(int idx, UUID id, GridDhtPartitionDemandMessage d) {
+    @Override public void handleDemandMessage(int idx, UUID id, GridDhtPartitionDemandMessage d) {
         if (!enterBusy())
             return;
 
@@ -789,7 +839,7 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
                                 try {
                                     part.tryEvict();
 
-                                    if (part.state() != EVICTED)
+                                    if (part.state() == RENTING)
                                         partsToEvict.push(part);
                                 }
                                 catch (Throwable ex) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionCountersMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionCountersMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionCountersMap.java
new file mode 100644
index 0000000..9db80ae
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionCountersMap.java
@@ -0,0 +1,64 @@
+/*
+ * 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.distributed.dht.preloader;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.ignite.internal.util.typedef.T2;
+
+/**
+ * Partition counters map.
+ */
+public class IgniteDhtPartitionCountersMap implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private Map<Integer, Map<Integer, T2<Long, Long>>> map;
+
+    /**
+     * @param cacheId Cache ID.
+     * @param cntrMap Counters map.
+     */
+    public synchronized void putIfAbsent(int cacheId, Map<Integer, T2<Long, Long>> cntrMap) {
+        if (map == null)
+            map = new HashMap<>();
+
+        if (!map.containsKey(cacheId))
+            map.put(cacheId, cntrMap);
+    }
+
+    /**
+     * @param cacheId Cache ID.
+     * @return Counters map.
+     */
+    public synchronized Map<Integer, T2<Long, Long>> get(int cacheId) {
+        if (map == null)
+            map = new HashMap<>();
+
+        Map<Integer, T2<Long, Long>> cntrMap = map.get(cacheId);
+
+        if (cntrMap == null)
+            return Collections.emptyMap();
+
+        return cntrMap;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionHistorySuppliersMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionHistorySuppliersMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionHistorySuppliersMap.java
new file mode 100644
index 0000000..333eb97
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionHistorySuppliersMap.java
@@ -0,0 +1,107 @@
+/*
+ * 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.distributed.dht.preloader;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class IgniteDhtPartitionHistorySuppliersMap implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private static final IgniteDhtPartitionHistorySuppliersMap EMPTY = new IgniteDhtPartitionHistorySuppliersMap();
+
+    /** */
+    private Map<UUID, Map<T2<Integer, Integer>, Long>> map;
+
+    /**
+     * @return Empty map.
+     */
+    public static IgniteDhtPartitionHistorySuppliersMap empty() {
+        return EMPTY;
+    }
+
+    /**
+     * @param cacheId Cache ID.
+     * @param partId Partition ID.
+     * @return Supplier UUID.
+     */
+    @Nullable public synchronized UUID getSupplier(int cacheId, int partId) {
+        if (map == null)
+            return null;
+
+        for (Map.Entry<UUID, Map<T2<Integer, Integer>, Long>> e : map.entrySet()) {
+            if (e.getValue().containsKey(new T2<>(cacheId, partId)))
+                return e.getKey();
+        }
+
+        return null;
+    }
+
+    /**
+     * @param nodeId Node ID to check.
+     * @return Reservations for the given node.
+     */
+    @Nullable public synchronized Map<T2<Integer, Integer>, Long> getReservations(UUID nodeId) {
+        if (map == null)
+            return null;
+
+        return map.get(nodeId);
+    }
+
+    /**
+     * @param nodeId Node ID.
+     * @param cacheId Cache ID.
+     * @param partId Partition ID.
+     * @param cntr Partition counter.
+     */
+    public synchronized void put(UUID nodeId, int cacheId, int partId, long cntr) {
+        Map<T2<Integer, Integer>, Long> nodeMap = map.get(nodeId);
+
+        if (nodeMap == null) {
+            nodeMap = new HashMap<>();
+
+            map.put(nodeId, nodeMap);
+        }
+
+        nodeMap.put(new T2<>(cacheId, partId), cntr);
+    }
+
+    /**
+     * @return {@code True} if empty.
+     */
+    public synchronized boolean isEmpty() {
+        return map == null || map.isEmpty();
+    }
+
+    /**
+     * @param that Other map to put.
+     */
+    public synchronized void putAll(IgniteDhtPartitionHistorySuppliersMap that) {
+        map = that.map;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/7e956ed0/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionsToReloadMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionsToReloadMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionsToReloadMap.java
new file mode 100644
index 0000000..2a72e95
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/IgniteDhtPartitionsToReloadMap.java
@@ -0,0 +1,88 @@
+/*
+ * 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.distributed.dht.preloader;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * Partition reload map.
+ */
+public class IgniteDhtPartitionsToReloadMap implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private Map<UUID, Map<Integer, Set<Integer>>> map;
+
+    /**
+     * @param nodeId Node ID.
+     * @param cacheId Cache ID.
+     * @return Collection of partitions to reload.
+     */
+    public synchronized Set<Integer> get(UUID nodeId, int cacheId) {
+        if (map == null)
+            return Collections.emptySet();
+
+        Map<Integer, Set<Integer>> nodeMap = map.get(nodeId);
+
+        if (nodeMap == null)
+            return Collections.emptySet();
+
+        Set<Integer> parts = nodeMap.get(cacheId);
+
+        if (parts == null)
+            return Collections.emptySet();
+
+        return parts;
+    }
+
+    /**
+     * @param nodeId Node ID.
+     * @param cacheId Cache ID.
+     * @param partId Partition ID.
+     */
+    public synchronized void put(UUID nodeId, int cacheId, int partId) {
+        if (map == null)
+            map = new HashMap<>();
+
+        Map<Integer, Set<Integer>> nodeMap = map.get(nodeId);
+
+        if (nodeMap == null) {
+            nodeMap = new HashMap<>();
+
+            map.put(nodeId, nodeMap);
+        }
+
+        Set<Integer> parts = nodeMap.get(cacheId);
+
+        if (parts == null) {
+            parts = new HashSet<>();
+
+            nodeMap.put(cacheId, parts);
+        }
+
+        parts.add(partId);
+    }
+}


[04/50] [abbrv] ignite git commit: Merge branch 'ignite-gg-8.0.3.ea1' of https://github.com/gridgain/apache-ignite into ignite-gg-8.0.3.ea2

Posted by sb...@apache.org.
Merge branch 'ignite-gg-8.0.3.ea1' of https://github.com/gridgain/apache-ignite into ignite-gg-8.0.3.ea2


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: a19f94bdb8bf29d811bd795512719896fd9a0fc4
Parents: 9282116 56fadcd
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Feb 16 16:49:21 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Feb 16 16:49:21 2017 +0300

----------------------------------------------------------------------
 .../benchmarks/jmh/tree/BPlusTreeBenchmark.java |  13 +-
 .../apache/ignite/IgniteSystemProperties.java   |   7 +
 .../org/apache/ignite/cache/QueryIndex.java     |  21 ++
 .../configuration/CacheConfiguration.java       |  35 ++-
 .../apache/ignite/internal/IgniteKernal.java    |   9 +-
 .../apache/ignite/internal/pagemem/Page.java    |   2 +-
 .../ignite/internal/pagemem/PageIdUtils.java    |   2 +-
 .../ignite/internal/pagemem/PageMemory.java     |   9 +-
 .../pagemem/impl/PageMemoryNoStoreImpl.java     |  28 +-
 .../internal/pagemem/wal/record/WALRecord.java  |   5 +-
 .../pagemem/wal/record/delta/InsertRecord.java  |  25 +-
 .../delta/MetaPageInitRootInlineRecord.java     |  62 ++++
 .../record/delta/MetaPageInitRootRecord.java    |   3 +-
 .../wal/record/delta/NewRootInitRecord.java     |  26 +-
 .../pagemem/wal/record/delta/ReplaceRecord.java |  23 +-
 .../cache/IgniteCacheOffheapManagerImpl.java    |  54 +---
 .../IgniteCacheDatabaseSharedManager.java       |   9 +
 .../cache/database/MetadataStorage.java         |  57 +---
 .../cache/database/freelist/FreeList.java       |   6 +
 .../cache/database/freelist/FreeListImpl.java   | 289 +++++++++++--------
 .../cache/database/freelist/PagesList.java      | 267 +++++++++++------
 .../cache/database/tree/BPlusTree.java          | 197 ++++++++++---
 .../cache/database/tree/io/BPlusIO.java         |  34 +--
 .../cache/database/tree/io/BPlusInnerIO.java    |  44 +--
 .../cache/database/tree/io/BPlusLeafIO.java     |   9 +-
 .../cache/database/tree/io/BPlusMetaIO.java     |  45 ++-
 .../cache/database/tree/io/DataPageIO.java      |  48 ++-
 .../cache/database/tree/io/DataPagePayload.java |   2 +-
 .../cache/database/tree/io/PageIO.java          |  60 ++++
 .../dht/GridDhtPartitionTopologyImpl.java       |   2 +-
 .../cluster/IgniteChangeGlobalStateSupport.java |   2 +
 .../query/GridQueryIndexDescriptor.java         |   7 +
 .../processors/query/GridQueryProcessor.java    |  39 ++-
 .../apache/ignite/internal/util/GridUnsafe.java |  45 ++-
 .../GridCacheRebalancingSyncSelfTest.java       |  12 +-
 .../processors/database/BPlusTreeSelfTest.java  |  13 +-
 .../odbc/OdbcProcessorValidationSelfTest.java   |   4 +-
 .../unsafe/GridUnsafeMemorySelfTest.java        |  35 +++
 .../junits/common/GridCommonAbstractTest.java   |  59 ++--
 .../ignite/testsuites/IgniteCacheTestSuite.java |  10 -
 .../testsuites/IgniteCacheTestSuite5.java       |  19 +-
 .../processors/query/h2/IgniteH2Indexing.java   |  19 +-
 .../processors/query/h2/database/H2Tree.java    |  57 +++-
 .../query/h2/database/H2TreeIndex.java          | 236 ++++++++++++++-
 .../query/h2/database/InlineIndexHelper.java    | 279 ++++++++++++++++++
 .../query/h2/database/io/H2ExtrasInnerIO.java   | 135 +++++++++
 .../query/h2/database/io/H2ExtrasLeafIO.java    | 132 +++++++++
 .../query/h2/database/io/H2InnerIO.java         |  10 -
 .../query/h2/database/io/H2LeafIO.java          |  10 -
 .../processors/query/h2/opt/GridH2Row.java      |   2 +-
 .../processors/query/h2/opt/GridH2Table.java    |   3 +-
 .../h2/GridIndexingSpiAbstractSelfTest.java     |   5 +
 .../query/h2/database/H2TreeIndexTest.java      |  59 ++++
 .../h2/database/InlineIndexHelperTest.java      |  46 +++
 54 files changed, 2063 insertions(+), 568 deletions(-)
----------------------------------------------------------------------



[35/50] [abbrv] ignite git commit: GG-11894: Found one more place where CacheRestartingException is not thrown in case cache is restarting.

Posted by sb...@apache.org.
GG-11894: Found one more place where CacheRestartingException is not thrown in case cache is restarting.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 3a68d8550bfc34be48fd4298f537c4326de3feec
Parents: 719fb5a
Author: Ivan Rakov <iv...@gmail.com>
Authored: Tue Mar 28 17:19:56 2017 +0300
Committer: Ivan Rakov <iv...@gmail.com>
Committed: Tue Mar 28 17:19:56 2017 +0300

----------------------------------------------------------------------
 .../cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3a68d855/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
index b5b11db..4b62f6b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridNearAtomicUpdateResponse.java
@@ -370,7 +370,7 @@ public class GridNearAtomicUpdateResponse extends GridCacheMessage implements Gr
         }
 
         if (err == null)
-            err = new IgniteCheckedException("Failed to update keys on primary node.");
+            err = new IgniteCheckedException("Failed to update keys on primary node.", e);
 
         err.addSuppressed(e);
     }


[05/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -refactoring deleteSnapshot operation

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-refactoring deleteSnapshot operation


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: e14cab15f647acc20f45f97ec98c2c27a8c56b2e
Parents: 9282116
Author: EdShangGG <es...@gridgain.com>
Authored: Thu Feb 16 21:04:36 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Thu Feb 16 21:04:36 2017 +0300

----------------------------------------------------------------------
 .../snapshot/SnapshotFinishedMessage.java       |  32 ++++-
 .../pagemem/snapshot/SnapshotOperation.java     |  31 +++++
 .../StartFullSnapshotAckDiscoveryMessage.java   | 132 -------------------
 .../StartFullSnapshotDiscoveryMessage.java      |   4 +-
 ...artSnapshotOperationAckDiscoveryMessage.java | 129 ++++++++++++++++++
 .../GridCachePartitionExchangeManager.java      |  10 +-
 .../processors/cache/GridCacheProcessor.java    |   6 +-
 .../IgniteCacheDatabaseSharedManager.java       |  13 +-
 .../GridDhtPartitionsExchangeFuture.java        |  12 +-
 .../resources/META-INF/classnames.properties    |   2 +-
 10 files changed, 203 insertions(+), 168 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
index a62d339..8ccef42 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotFinishedMessage.java
@@ -33,20 +33,22 @@ public class SnapshotFinishedMessage implements Message {
     /** */
     private long snapshotId;
 
+    /** Operation type. */
+    private int operationType;
+
     /** */
     private boolean success;
 
-    /**
-     *
-     */
+    /** */
     public SnapshotFinishedMessage() {
     }
 
     /**
      * @param snapshotId Snapshot ID.
      */
-    public SnapshotFinishedMessage(long snapshotId, boolean success) {
+    public SnapshotFinishedMessage(long snapshotId, SnapshotOperationType type, boolean success) {
         this.snapshotId = snapshotId;
+        this.operationType = type.ordinal();
         this.success = success;
     }
 
@@ -57,6 +59,12 @@ public class SnapshotFinishedMessage implements Message {
         return snapshotId;
     }
 
+    /** */
+    public SnapshotOperationType operationType() {
+        return SnapshotOperationType.values()[operationType];
+    }
+
+    /** */
     public boolean success() {
         return success;
     }
@@ -80,6 +88,12 @@ public class SnapshotFinishedMessage implements Message {
                 writer.incrementState();
 
             case 1:
+                if (!writer.writeInt("operationType", operationType))
+                    return false;
+
+                writer.incrementState();
+
+            case 2:
                 if (!writer.writeBoolean("success", success))
                     return false;
 
@@ -107,6 +121,14 @@ public class SnapshotFinishedMessage implements Message {
                 reader.incrementState();
 
             case 1:
+                operationType = reader.readInt("operationType");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 2:
                 success = reader.readBoolean("success");
 
                 if (!reader.isLastRead())
@@ -126,7 +148,7 @@ public class SnapshotFinishedMessage implements Message {
 
     /** {@inheritDoc} */
     @Override public byte fieldsCount() {
-        return 2;
+        return 3;
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
index 8163049..221d0ce 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -97,4 +97,35 @@ public class SnapshotOperation implements Serializable {
     public Object extraParameter() {
         return extraParam;
     }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        SnapshotOperation operation = (SnapshotOperation)o;
+
+        if (snapshotId != operation.snapshotId)
+            return false;
+        if (type != operation.type)
+            return false;
+        if (cacheNames != null ? !cacheNames.equals(operation.cacheNames) : operation.cacheNames != null)
+            return false;
+        if (msg != null ? !msg.equals(operation.msg) : operation.msg != null)
+            return false;
+        return extraParam != null ? extraParam.equals(operation.extraParam) : operation.extraParam == null;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int result = type != null ? type.hashCode() : 0;
+        result = 31 * result + (int)(snapshotId ^ (snapshotId >>> 32));
+        result = 31 * result + (cacheNames != null ? cacheNames.hashCode() : 0);
+        result = 31 * result + (msg != null ? msg.hashCode() : 0);
+        result = 31 * result + (extraParam != null ? extraParam.hashCode() : 0);
+        return result;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
deleted file mode 100644
index 32a3dae..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.pagemem.snapshot;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.UUID;
-import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
-import org.apache.ignite.internal.util.typedef.internal.CU;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteUuid;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Message indicating that a snapshot has been started.
- */
-public class StartFullSnapshotAckDiscoveryMessage implements DiscoveryCustomMessage {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-
-    private SnapshotOperation snapshotOperation;
-
-    /** Custom message ID. */
-    private IgniteUuid id = IgniteUuid.randomUuid();
-
-    /** */
-    private Exception err;
-
-    /** */
-    private UUID initiatorNodeId;
-
-    /** Last full snapshot id for cache. */
-    private Map<Integer, Long> lastFullSnapshotIdForCache;
-
-    /** Last snapshot id for cache. */
-    private Map<Integer, Long> lastSnapshotIdForCache;
-
-    /**
-     * @param snapshotOperation Snapshot Operation.
-     * @param err Error.
-     */
-    public StartFullSnapshotAckDiscoveryMessage(
-        SnapshotOperation snapshotOperation,
-        Map<Integer, Long> lastFullSnapshotIdForCache,
-        Map<Integer, Long> lastSnapshotIdForCache,
-        Exception err,
-        UUID initiatorNodeId
-    ) {
-        this.snapshotOperation = snapshotOperation;
-        this.lastFullSnapshotIdForCache = lastFullSnapshotIdForCache;
-        this.lastSnapshotIdForCache = lastSnapshotIdForCache;
-        this.err = err;
-        this.initiatorNodeId = initiatorNodeId;
-    }
-
-    /** {@inheritDoc} */
-    @Override public IgniteUuid id() {
-        return id;
-    }
-
-    /**
-     * @return Initiator node id.
-     */
-    public UUID initiatorNodeId() {
-        return initiatorNodeId;
-    }
-
-    /**
-     * @return Error if start this process is not successfully.
-     */
-    public Exception error() {
-        return err;
-    }
-
-    /**
-     * @return {@code True} if message has error otherwise {@code false}.
-     */
-    public boolean hasError() {
-        return err != null;
-    }
-
-    public SnapshotOperation snapshotOperation() {
-        return snapshotOperation;
-    }
-
-    /**
-     * @param cacheId Cache id.
-     */
-    @Nullable public Long lastFullSnapshotId(int cacheId) {
-        return lastFullSnapshotIdForCache.get(cacheId);
-    }
-
-    /**
-     * @param cacheId Cache id.
-     */
-    @Nullable public Long lastSnapshotId(int cacheId) {
-        return lastSnapshotIdForCache.get(cacheId);
-    }
-
-    /** {@inheritDoc} */
-    @Nullable @Override public DiscoveryCustomMessage ackMessage() {
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean isMutable() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        return S.toString(StartFullSnapshotAckDiscoveryMessage.class, this);
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
index 2a977f4..3a67e49 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
@@ -18,13 +18,11 @@
 
 package org.apache.ignite.internal.pagemem.snapshot;
 
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
 import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteUuid;
 import org.jetbrains.annotations.Nullable;
 
@@ -139,7 +137,7 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
 
     /** {@inheritDoc} */
     @Nullable @Override public DiscoveryCustomMessage ackMessage() {
-        return new StartFullSnapshotAckDiscoveryMessage(
+        return new StartSnapshotOperationAckDiscoveryMessage(
             snapshotOperation,
             lastFullSnapshotIdForCache,
             lastSnapshotIdForCache,

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
new file mode 100644
index 0000000..e84b2e8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartSnapshotOperationAckDiscoveryMessage.java
@@ -0,0 +1,129 @@
+/*
+ * 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.pagemem.snapshot;
+
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Message indicating that a snapshot has been started.
+ */
+public class StartSnapshotOperationAckDiscoveryMessage implements DiscoveryCustomMessage {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+
+    private SnapshotOperation snapshotOperation;
+
+    /** Custom message ID. */
+    private IgniteUuid id = IgniteUuid.randomUuid();
+
+    /** */
+    private Exception err;
+
+    /** */
+    private UUID initiatorNodeId;
+
+    /** Last full snapshot id for cache. */
+    private Map<Integer, Long> lastFullSnapshotIdForCache;
+
+    /** Last snapshot id for cache. */
+    private Map<Integer, Long> lastSnapshotIdForCache;
+
+    /**
+     * @param snapshotOperation Snapshot Operation.
+     * @param err Error.
+     */
+    public StartSnapshotOperationAckDiscoveryMessage(
+        SnapshotOperation snapshotOperation,
+        Map<Integer, Long> lastFullSnapshotIdForCache,
+        Map<Integer, Long> lastSnapshotIdForCache,
+        Exception err,
+        UUID initiatorNodeId
+    ) {
+        this.snapshotOperation = snapshotOperation;
+        this.lastFullSnapshotIdForCache = lastFullSnapshotIdForCache;
+        this.lastSnapshotIdForCache = lastSnapshotIdForCache;
+        this.err = err;
+        this.initiatorNodeId = initiatorNodeId;
+    }
+
+    /** {@inheritDoc} */
+    @Override public IgniteUuid id() {
+        return id;
+    }
+
+    /**
+     * @return Initiator node id.
+     */
+    public UUID initiatorNodeId() {
+        return initiatorNodeId;
+    }
+
+    /**
+     * @return Error if start this process is not successfully.
+     */
+    public Exception error() {
+        return err;
+    }
+
+    /**
+     * @return {@code True} if message has error otherwise {@code false}.
+     */
+    public boolean hasError() {
+        return err != null;
+    }
+
+    public SnapshotOperation snapshotOperation() {
+        return snapshotOperation;
+    }
+
+    /**
+     * @param cacheId Cache id.
+     */
+    @Nullable public Long lastFullSnapshotId(int cacheId) {
+        return lastFullSnapshotIdForCache.get(cacheId);
+    }
+
+    /**
+     * @param cacheId Cache id.
+     */
+    @Nullable public Long lastSnapshotId(int cacheId) {
+        return lastSnapshotIdForCache.get(cacheId);
+    }
+
+    /** {@inheritDoc} */
+    @Nullable @Override public DiscoveryCustomMessage ackMessage() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean isMutable() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(StartSnapshotOperationAckDiscoveryMessage.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 46a20ab..232dc83 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -30,11 +30,9 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableMap;
-import java.util.Queue;
 import java.util.TreeMap;
 import java.util.UUID;
 import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.LinkedBlockingDeque;
@@ -58,7 +56,7 @@ import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
-import org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotAckDiscoveryMessage;
+import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridClientPartitionTopology;
@@ -70,7 +68,6 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.Gri
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap2;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessageV2;
-import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsAbstractMessage;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsSingleMessage;
@@ -100,7 +97,6 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
-import org.jsr166.ConcurrentLinkedDeque8;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.apache.ignite.IgniteSystemProperties.IGNITE_PRELOAD_RESEND_TIMEOUT;
@@ -280,8 +276,8 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                         else
                             exchangeFuture(msg.exchangeId(), null, null, null).onAffinityChangeMessage(customEvt.eventNode(), msg);
                     }
-                    else if (customEvt.customMessage() instanceof StartFullSnapshotAckDiscoveryMessage
-                        && !((StartFullSnapshotAckDiscoveryMessage)customEvt.customMessage()).hasError()) {
+                    else if (customEvt.customMessage() instanceof StartSnapshotOperationAckDiscoveryMessage
+                        && !((StartSnapshotOperationAckDiscoveryMessage)customEvt.customMessage()).hasError()) {
                         exchId = exchangeId(n.id(), affinityTopologyVersion(e), e.type());
 
                         exchFut = exchangeFuture(exchId, e, null, null);

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 74b6782..2bb1e42 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -72,7 +72,7 @@ import org.apache.ignite.internal.binary.BinaryContext;
 import org.apache.ignite.internal.binary.BinaryMarshaller;
 import org.apache.ignite.internal.binary.GridBinaryMarshaller;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
-import org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotAckDiscoveryMessage;
+import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
 import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager;
 import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
 import org.apache.ignite.internal.processors.GridProcessorAdapter;
@@ -2893,8 +2893,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         if (msg instanceof CacheAffinityChangeMessage)
             return sharedCtx.affinity().onCustomEvent(((CacheAffinityChangeMessage)msg));
 
-        if (msg instanceof StartFullSnapshotAckDiscoveryMessage &&
-            ((StartFullSnapshotAckDiscoveryMessage)msg).error() == null)
+        if (msg instanceof StartSnapshotOperationAckDiscoveryMessage &&
+            ((StartSnapshotOperationAckDiscoveryMessage)msg).error() == null)
             return true;
 
         if (msg instanceof DynamicCacheChangeBatch)

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
index 7a082cb..a5fdeef 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/IgniteCacheDatabaseSharedManager.java
@@ -19,9 +19,7 @@ package org.apache.ignite.internal.processors.cache.database;
 
 import java.io.File;
 import java.util.Collection;
-import java.util.UUID;
 import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.MemoryConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -29,7 +27,7 @@ import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.file.MappedFileMemoryProvider;
 import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
 import org.apache.ignite.internal.pagemem.PageMemory;
-import org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotAckDiscoveryMessage;
+import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
 import org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedManagerAdapter;
@@ -179,13 +177,6 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
     }
 
     /**
-     *
-     */
-    @Nullable public IgniteInternalFuture wakeupForSnapshot(long snapshotId) {
-        return null;
-    }
-
-    /**
      * @param discoEvt Before exchange for the given discovery event.
      */
     public void beforeExchange(GridDhtPartitionsExchangeFuture discoEvt) throws IgniteCheckedException {
@@ -211,7 +202,7 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap
      * @return Snapshot creation init future or {@code null} if snapshot is not available.
      * @throws IgniteCheckedException If failed.
      */
-    @Nullable public IgniteInternalFuture startLocalSnapshotCreation(StartFullSnapshotAckDiscoveryMessage snapshotMsg)
+    @Nullable public IgniteInternalFuture startLocalSnapshotOperation(StartSnapshotOperationAckDiscoveryMessage snapshotMsg)
         throws IgniteCheckedException {
         return null;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 2f9fc46..987ba54 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -48,7 +48,7 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
 import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
 import org.apache.ignite.internal.managers.discovery.GridDiscoveryTopologySnapshot;
-import org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotAckDiscoveryMessage;
+import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache;
 import org.apache.ignite.internal.processors.cache.CacheAffinityChangeMessage;
@@ -510,7 +510,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
                     exchange = onCacheChangeRequest(crdNode);
                 }
-                else if (msg instanceof StartFullSnapshotAckDiscoveryMessage)
+                else if (msg instanceof StartSnapshotOperationAckDiscoveryMessage)
                     exchange = CU.clientNode(discoEvt.eventNode()) ?
                         onClientNodeEvent(crdNode) :
                         onServerNodeEvent(crdNode);
@@ -808,13 +808,13 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
         // If a backup request, synchronously wait for backup start.
         if (discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT) {
-            DiscoveryCustomMessage customMessage = ((DiscoveryCustomEvent)discoEvt).customMessage();
+            DiscoveryCustomMessage customMsg = ((DiscoveryCustomEvent)discoEvt).customMessage();
 
-            if (customMessage instanceof StartFullSnapshotAckDiscoveryMessage) {
-                StartFullSnapshotAckDiscoveryMessage backupMsg = (StartFullSnapshotAckDiscoveryMessage)customMessage;
+            if (customMsg instanceof StartSnapshotOperationAckDiscoveryMessage) {
+                StartSnapshotOperationAckDiscoveryMessage snapshotOperationMsg = (StartSnapshotOperationAckDiscoveryMessage)customMsg;
 
                 if (!cctx.localNode().isClient() && !cctx.localNode().isDaemon()) {
-                    IgniteInternalFuture fut = cctx.database().startLocalSnapshotCreation(backupMsg);
+                    IgniteInternalFuture fut = cctx.database().startLocalSnapshotOperation(snapshotOperationMsg);
 
                     if (fut != null)
                         fut.get();

http://git-wip-us.apache.org/repos/asf/ignite/blob/e14cab15/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index 98d0da9..a0838b1 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -328,7 +328,7 @@ org.apache.ignite.internal.mem.OutOfMemoryException
 org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl$Segment
 org.apache.ignite.internal.pagemem.snapshot.SnapshotFinishedMessage
 org.apache.ignite.internal.pagemem.snapshot.SnapshotProgressMessage
-org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotAckDiscoveryMessage
+org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage
 org.apache.ignite.internal.pagemem.snapshot.StartFullSnapshotDiscoveryMessage
 org.apache.ignite.internal.pagemem.wal.StorageException
 org.apache.ignite.internal.pagemem.wal.WALIterator


[38/50] [abbrv] ignite git commit: GG-11894 - Fixed IgniteDbSnapshotSelfTest.testReuseCacheProxyAfterRestore

Posted by sb...@apache.org.
GG-11894 - Fixed IgniteDbSnapshotSelfTest.testReuseCacheProxyAfterRestore


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 9d71e3159ca4cc95e6943e637d7fa74cabf22d77
Parents: 3a68d85
Author: Ivan Rakov <iv...@gmail.com>
Authored: Fri Mar 31 17:21:02 2017 +0300
Committer: Ivan Rakov <iv...@gmail.com>
Committed: Fri Mar 31 17:21:02 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/processors/cache/GridCacheAdapter.java  | 9 +++++++--
 .../ignite/internal/processors/cache/GridCacheGateway.java  | 4 ++--
 2 files changed, 9 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9d71e315/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 1470a97..288eafc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -58,6 +58,7 @@ import org.apache.ignite.cache.CacheMetrics;
 import org.apache.ignite.cache.CachePeekMode;
 import org.apache.ignite.cache.affinity.Affinity;
 import org.apache.ignite.cluster.ClusterGroup;
+import org.apache.ignite.cluster.ClusterGroupEmptyException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.cluster.ClusterTopologyException;
 import org.apache.ignite.compute.ComputeJob;
@@ -3802,8 +3803,12 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
 
         ctx.kernalContext().task().setThreadContext(TC_SUBGRID, nodes);
 
-        return ctx.kernalContext().task().execute(
-            new SizeTask(ctx.name(), ctx.affinity().affinityTopologyVersion(), peekModes), null);
+        try {
+            return ctx.kernalContext().task().execute(
+                new SizeTask(ctx.name(), ctx.affinity().affinityTopologyVersion(), peekModes), null);
+        } catch (ClusterGroupEmptyException e) {
+            return new GridFinishedFuture<>(0);
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/9d71e315/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
index 1562d70..4314211 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheGateway.java
@@ -82,7 +82,7 @@ public class GridCacheGateway<K, V> {
 
             if (state == State.STOPPED) {
                 if (stopErr)
-                    throw new IllegalStateException("Cache has been stopped: " + ctx.name());
+                    throw new IllegalStateException(new CacheStoppedException(ctx.name()));
                 else
                     return false;
             }
@@ -157,7 +157,7 @@ public class GridCacheGateway<K, V> {
             GridCachePreloader preldr = cache != null ? cache.preloader() : null;
 
             if (preldr == null)
-                throw new IllegalStateException("Cache has been closed or destroyed: " + ctx.name());
+                throw new IllegalStateException(new CacheStoppedException(ctx.name()));
 
             preldr.startFuture().get();
         }


[22/50] [abbrv] ignite git commit: ignite-4779 Missed discovery data snapshot during exchange processing (do not use discovery manager cache to handle exchange)

Posted by sb...@apache.org.
ignite-4779 Missed discovery data snapshot during exchange processing (do not use discovery manager cache to handle exchange)

(cherry picked from commit a61a98ad3908770b77d0ffb071effbc92f4d5c5a)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 423466736904b55a6d4397aa6268fff5a9ee5ea9
Parents: 7e956ed
Author: Igor Seliverstov <gv...@gmail.com>
Authored: Thu Mar 9 21:01:41 2017 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Thu Mar 9 22:14:18 2017 +0300

----------------------------------------------------------------------
 .../internal/managers/discovery/DiscoCache.java | 310 +++++++++
 .../discovery/GridDiscoveryManager.java         | 680 +++++--------------
 .../eventstorage/DiscoveryEventListener.java    |  33 +
 .../eventstorage/GridEventStorageManager.java   | 162 ++++-
 .../affinity/GridAffinityAssignmentCache.java   |   7 +-
 .../cache/CacheAffinitySharedManager.java       |  35 +-
 .../cache/GridCacheAffinityManager.java         |   3 +-
 .../GridCachePartitionExchangeManager.java      |  73 +-
 .../dht/GridClientPartitionTopology.java        |  20 +-
 .../dht/GridDhtAssignmentFetchFuture.java       |   7 +-
 .../dht/GridDhtPartitionTopologyImpl.java       |  40 +-
 .../GridDhtPartitionsExchangeFuture.java        |  30 +-
 .../service/GridServiceProcessor.java           |  21 +-
 .../GridDiscoveryManagerAliveCacheSelfTest.java |  14 -
 14 files changed, 808 insertions(+), 627 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
new file mode 100644
index 0000000..5247ac1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/DiscoCache.java
@@ -0,0 +1,310 @@
+/*
+ * 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.managers.discovery;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class DiscoCache {
+    /** Local node. */
+    private final ClusterNode loc;
+
+    /** Remote nodes. */
+    private final List<ClusterNode> rmtNodes;
+
+    /** All nodes. */
+    private final List<ClusterNode> allNodes;
+
+    /** All server nodes. */
+    private final List<ClusterNode> srvNodes;
+
+    /** Daemon nodes. */
+    private final List<ClusterNode> daemonNodes;
+
+    /** All server nodes. */
+    private final List<ClusterNode> srvNodesWithCaches;
+
+    /** All nodes with at least one cache configured. */
+    @GridToStringInclude
+    private final List<ClusterNode> allNodesWithCaches;
+
+    /** All remote nodes with at least one cache configured. */
+    @GridToStringInclude
+    private final List<ClusterNode> rmtNodesWithCaches;
+
+    /** Cache nodes by cache name. */
+    @GridToStringInclude
+    private final Map<Integer, List<ClusterNode>> allCacheNodes;
+
+    /** Affinity cache nodes by cache name. */
+    @GridToStringInclude
+    private final Map<Integer, List<ClusterNode>> affCacheNodes;
+
+    /** Node map. */
+    private final Map<UUID, ClusterNode> nodeMap;
+
+    /** Caches where at least one node has near cache enabled. */
+    @GridToStringInclude
+    private final Set<Integer> nearEnabledCaches;
+
+    /** Alive nodes. */
+    private final Set<UUID> alives = new GridConcurrentHashSet<>();
+
+    /**
+     * @param loc Local node.
+     * @param rmtNodes Remote nodes.
+     * @param allNodes All nodes.
+     * @param srvNodes Server nodes.
+     * @param daemonNodes Daemon nodes.
+     * @param srvNodesWithCaches Server nodes with at least one cache configured.
+     * @param allNodesWithCaches All nodes with at least one cache configured.
+     * @param rmtNodesWithCaches Remote nodes with at least one cache configured.
+     * @param allCacheNodes Cache nodes by cache name.
+     * @param affCacheNodes Affinity cache nodes by cache name.
+     * @param nodeMap Node map.
+     * @param nearEnabledCaches Caches where at least one node has near cache enabled.
+     * @param alives Alive nodes.
+     */
+    DiscoCache(ClusterNode loc,
+        List<ClusterNode> rmtNodes,
+        List<ClusterNode> allNodes,
+        List<ClusterNode> srvNodes,
+        List<ClusterNode> daemonNodes,
+        List<ClusterNode> srvNodesWithCaches,
+        List<ClusterNode> allNodesWithCaches,
+        List<ClusterNode> rmtNodesWithCaches,
+        Map<Integer, List<ClusterNode>> allCacheNodes,
+        Map<Integer, List<ClusterNode>> affCacheNodes,
+        Map<UUID, ClusterNode> nodeMap,
+        Set<Integer> nearEnabledCaches,
+        Set<UUID> alives) {
+        this.loc = loc;
+        this.rmtNodes = rmtNodes;
+        this.allNodes = allNodes;
+        this.srvNodes = srvNodes;
+        this.daemonNodes = daemonNodes;
+        this.srvNodesWithCaches = srvNodesWithCaches;
+        this.allNodesWithCaches = allNodesWithCaches;
+        this.rmtNodesWithCaches = rmtNodesWithCaches;
+        this.allCacheNodes = allCacheNodes;
+        this.affCacheNodes = affCacheNodes;
+        this.nodeMap = nodeMap;
+        this.nearEnabledCaches = nearEnabledCaches;
+        this.alives.addAll(alives);
+    }
+
+    /** @return Local node. */
+    public ClusterNode localNode() {
+        return loc;
+    }
+
+    /** @return Remote nodes. */
+    public List<ClusterNode> remoteNodes() {
+        return rmtNodes;
+    }
+
+    /** @return All nodes. */
+    public List<ClusterNode> allNodes() {
+        return allNodes;
+    }
+
+    /** @return Server nodes. */
+    public List<ClusterNode> serverNodes() {
+        return srvNodes;
+    }
+
+    /** @return Daemon nodes. */
+    public List<ClusterNode> daemonNodes() {
+        return daemonNodes;
+    }
+
+    /** @return Server nodes with at least one cache configured. */
+    public List<ClusterNode> serverNodesWithCaches() {
+        return srvNodesWithCaches;
+    }
+
+    /**
+     * Gets all remote nodes that have at least one cache configured.
+     *
+     * @return Collection of nodes.
+     */
+    public List<ClusterNode> remoteNodesWithCaches() {
+        return rmtNodesWithCaches;
+    }
+
+    /**
+     * Gets collection of nodes with at least one cache configured.
+     *
+     * @return Collection of nodes.
+     */
+    public List<ClusterNode> allNodesWithCaches() {
+        return allNodesWithCaches;
+    }
+
+    /**
+     * Gets collection of server nodes with at least one cache configured.
+     *
+     * @return Collection of nodes.
+     */
+    public Collection<ClusterNode> aliveServerNodes() {
+        return F.view(serverNodes(), new P1<ClusterNode>() {
+            @Override public boolean apply(ClusterNode node) {
+                return alives.contains(node.id());
+            }
+        });
+    }
+
+    /**
+     * Gets collection of server nodes with at least one cache configured.
+     *
+     * @return Collection of nodes.
+     */
+    public Collection<ClusterNode> aliveServerNodesWithCaches() {
+        return F.view(serverNodesWithCaches(), new P1<ClusterNode>() {
+            @Override public boolean apply(ClusterNode node) {
+                return alives.contains(node.id());
+            }
+        });
+    }
+
+    /**
+     * @return Oldest alive server node.
+     */
+    public @Nullable ClusterNode oldestAliveServerNode(){
+        Iterator<ClusterNode> it = aliveServerNodes().iterator();
+        return it.hasNext() ? it.next() : null;
+    }
+
+    /**
+     * @return Oldest alive server node with at least one cache configured.
+     */
+    public @Nullable ClusterNode oldestAliveServerNodeWithCache(){
+        Iterator<ClusterNode> it = aliveServerNodesWithCaches().iterator();
+        return it.hasNext() ? it.next() : null;
+    }
+
+    /**
+     * Gets all nodes that have cache with given name.
+     *
+     * @param cacheName Cache name.
+     * @return Collection of nodes.
+     */
+    public List<ClusterNode> cacheNodes(@Nullable String cacheName) {
+        return cacheNodes(CU.cacheId(cacheName));
+    }
+
+    /**
+     * Gets all nodes that have cache with given ID.
+     *
+     * @param cacheId Cache ID.
+     * @return Collection of nodes.
+     */
+    public List<ClusterNode> cacheNodes(Integer cacheId) {
+        return emptyIfNull(allCacheNodes.get(cacheId));
+    }
+
+    /**
+     * Gets all nodes that have cache with given ID and should participate in affinity calculation. With
+     * partitioned cache nodes with near-only cache do not participate in affinity node calculation.
+     *
+     * @param cacheName Cache name.
+     * @return Collection of nodes.
+     */
+    public List<ClusterNode> cacheAffinityNodes(@Nullable String cacheName) {
+        return cacheAffinityNodes(CU.cacheId(cacheName));
+    }
+
+    /**
+     * Gets all nodes that have cache with given ID and should participate in affinity calculation. With
+     * partitioned cache nodes with near-only cache do not participate in affinity node calculation.
+     *
+     * @param cacheId Cache ID.
+     * @return Collection of nodes.
+     */
+    public List<ClusterNode> cacheAffinityNodes(int cacheId) {
+        return emptyIfNull(affCacheNodes.get(cacheId));
+    }
+
+    /**
+     * Checks if cache with given ID has at least one node with near cache enabled.
+     *
+     * @param cacheId Cache ID.
+     * @return {@code True} if cache with given name has at least one node with near cache enabled.
+     */
+    public boolean hasNearCache(int cacheId) {
+        return nearEnabledCaches.contains(cacheId);
+    }
+
+    /**
+     * @param id Node ID.
+     * @return Node.
+     */
+    public @Nullable ClusterNode node(UUID id) {
+        return nodeMap.get(id);
+    }
+
+    /**
+     * Removes left node from alives lists.
+     *
+     * @param rmvd Removed node.
+     */
+    public void updateAlives(ClusterNode rmvd) {
+        alives.remove(rmvd.id());
+    }
+
+    /**
+     * Removes left nodes from cached alives lists.
+     *
+     * @param discovery Discovery manager.
+     */
+    public void updateAlives(GridDiscoveryManager discovery) {
+        for (UUID alive : alives) {
+            if (!discovery.alive(alive))
+                alives.remove(alive);
+        }
+    }
+
+    /**
+     * @param nodes Cluster nodes.
+     * @return Empty collection if nodes list is {@code null}
+     */
+    private List<ClusterNode> emptyIfNull(List<ClusterNode> nodes) {
+        return nodes == null ? Collections.<ClusterNode>emptyList() : nodes;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(DiscoCache.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index 218aff0..960a064 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -35,14 +35,12 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.NavigableMap;
 import java.util.Set;
-import java.util.TreeMap;
+import java.util.TreeSet;
 import java.util.UUID;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -79,19 +77,17 @@ import org.apache.ignite.internal.processors.jobmetrics.GridJobMetrics;
 import org.apache.ignite.internal.processors.security.SecurityContext;
 import org.apache.ignite.internal.processors.service.GridServiceProcessor;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
-import org.apache.ignite.internal.util.F0;
 import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.lang.GridTuple5;
+import org.apache.ignite.internal.util.lang.GridTuple6;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
-import org.apache.ignite.internal.util.typedef.C1;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.P1;
+import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -100,7 +96,6 @@ import org.apache.ignite.internal.util.worker.GridWorker;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.lang.IgniteInClosure;
 import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.lang.IgniteProductVersion;
 import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.plugin.security.SecurityCredentials;
 import org.apache.ignite.plugin.segmentation.SegmentationPolicy;
@@ -114,6 +109,7 @@ import org.apache.ignite.spi.discovery.DiscoverySpiListener;
 import org.apache.ignite.spi.discovery.DiscoverySpiNodeAuthenticator;
 import org.apache.ignite.spi.discovery.DiscoverySpiOrderSupport;
 import org.apache.ignite.thread.IgniteThread;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
@@ -235,7 +231,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     private long segChkFreq;
 
     /** Local node join to topology event. */
-    private GridFutureAdapter<DiscoveryEvent> locJoinEvt = new GridFutureAdapter<>();
+    private GridFutureAdapter<T2<DiscoveryEvent, DiscoCache>> locJoin = new GridFutureAdapter<>();
 
     /** GC CPU load. */
     private volatile double gcCpuLoad;
@@ -560,20 +556,25 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     }
                 }
 
+                final DiscoCache discoCache;
+
                 // Put topology snapshot into discovery history.
                 // There is no race possible between history maintenance and concurrent discovery
                 // event notifications, since SPI notifies manager about all events from this listener.
                 if (verChanged) {
-                    DiscoCache cache = new DiscoCache(locNode, F.view(topSnapshot, F.remoteNodes(locNode.id())));
+                    discoCache = createDiscoCache(locNode, topSnapshot);
 
-                    discoCacheHist.put(nextTopVer, cache);
+                    discoCacheHist.put(nextTopVer, discoCache);
 
-                    boolean set = updateTopologyVersionIfGreater(nextTopVer, cache);
+                    boolean set = updateTopologyVersionIfGreater(nextTopVer, discoCache);
 
                     assert set || topVer == 0 : "Topology version has not been updated [this.topVer=" +
                         topSnap + ", topVer=" + topVer + ", node=" + node +
                         ", evt=" + U.gridEventName(type) + ']';
                 }
+                else
+                    // Current version.
+                    discoCache = discoCache();
 
                 // If this is a local join event, just save it and do not notify listeners.
                 if (type == EVT_NODE_JOINED && node.id().equals(locNode.id())) {
@@ -581,7 +582,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                         gridStartTime = getSpi().getGridStartTime();
 
                     updateTopologyVersionIfGreater(new AffinityTopologyVersion(locNode.order()),
-                        new DiscoCache(localNode(), F.view(topSnapshot, F.remoteNodes(locNode.id()))));
+                        discoCache);
 
                     startLatch.countDown();
 
@@ -591,14 +592,9 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     discoEvt.eventNode(node);
                     discoEvt.type(EVT_NODE_JOINED);
 
-                    discoEvt.topologySnapshot(topVer, new ArrayList<>(
-                        F.viewReadOnly(topSnapshot, new C1<ClusterNode, ClusterNode>() {
-                            @Override public ClusterNode apply(ClusterNode e) {
-                                return e;
-                            }
-                        }, FILTER_DAEMON)));
+                    discoEvt.topologySnapshot(topVer, new ArrayList<>(F.view(topSnapshot, FILTER_DAEMON)));
 
-                    locJoinEvt.onDone(discoEvt);
+                    locJoin.onDone(new T2<>(discoEvt, discoCache));
 
                     return;
                 }
@@ -613,7 +609,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
 
                     ((IgniteKernal)ctx.grid()).onDisconnected();
 
-                    locJoinEvt = new GridFutureAdapter<>();
+                    locJoin = new GridFutureAdapter<>();
 
                     registeredCaches.clear();
 
@@ -626,7 +622,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     topHist.clear();
 
                     topSnap.set(new Snapshot(AffinityTopologyVersion.ZERO,
-                        new DiscoCache(locNode, Collections.<ClusterNode>emptySet())));
+                        createDiscoCache(locNode, Collections.<ClusterNode>emptySet())));
                 }
                 else if (type == EVT_CLIENT_NODE_RECONNECTED) {
                     assert locNode.isClient() : locNode;
@@ -643,7 +639,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                             try {
                                 fut.get();
 
-                                discoWrk.addEvent(type, nextTopVer, node, topSnapshot, null);
+                                discoWrk.addEvent(type, nextTopVer, node, discoCache, topSnapshot, null);
                             }
                             catch (IgniteException ignore) {
                                 // No-op.
@@ -655,7 +651,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                 }
 
                 if (type == EVT_CLIENT_NODE_DISCONNECTED || type == EVT_NODE_SEGMENTED || !ctx.clientDisconnected())
-                    discoWrk.addEvent(type, nextTopVer, node, topSnapshot, customMsg);
+                    discoWrk.addEvent(type, nextTopVer, node, discoCache, topSnapshot, customMsg);
             }
         });
 
@@ -1372,8 +1368,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
             U.join(segChkThread, log);
         }
 
-        if (!locJoinEvt.isDone())
-            locJoinEvt.onDone(
+        if (!locJoin.isDone())
+            locJoin.onDone(
                 new IgniteCheckedException("Failed to wait for local node joined event (grid is stopping)."));
     }
 
@@ -1567,7 +1563,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      *
      * @return Discovery collection cache.
      */
-    private DiscoCache discoCache() {
+    public DiscoCache discoCache() {
         Snapshot cur = topSnap.get();
 
         assert cur != null;
@@ -1620,14 +1616,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     }
 
     /**
-     * @param topVer Topology version.
-     * @return All server nodes for given topology version.
-     */
-    public List<ClusterNode> serverNodes(AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(null, topVer).srvNodes;
-    }
-
-    /**
      * Gets node from history for given topology version.
      *
      * @param topVer Topology version.
@@ -1646,7 +1634,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return Collection of cache nodes.
      */
     public Collection<ClusterNode> cacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(cacheName, topVer).cacheNodes(cacheName, topVer.topologyVersion());
+        return resolveDiscoCache(cacheName, topVer).cacheNodes(cacheName);
     }
 
     /**
@@ -1656,7 +1644,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return Collection of cache nodes.
      */
     public Collection<ClusterNode> cacheNodes(AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(null, topVer).allNodesWithCaches(topVer.topologyVersion());
+        return resolveDiscoCache(null, topVer).allNodesWithCaches();
     }
 
     /**
@@ -1666,29 +1654,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return Collection of cache nodes.
      */
     public Collection<ClusterNode> remoteCacheNodes(AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(null, topVer).remoteCacheNodes(topVer.topologyVersion());
-    }
-
-    /**
-     * Gets cache nodes for cache with given name.
-     *
-     * @param cacheName Cache name.
-     * @param topVer Topology version.
-     * @return Collection of cache nodes.
-     */
-    Collection<ClusterNode> aliveCacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(cacheName, topVer).aliveCacheNodes(cacheName, topVer.topologyVersion());
-    }
-
-    /**
-     * Gets cache remote nodes for cache with given name.
-     *
-     * @param cacheName Cache name.
-     * @param topVer Topology version.
-     * @return Collection of cache nodes.
-     */
-    Collection<ClusterNode> aliveRemoteCacheNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(cacheName, topVer).aliveRemoteCacheNodes(cacheName, topVer.topologyVersion());
+        return resolveDiscoCache(null, topVer).remoteNodesWithCaches();
     }
 
     /**
@@ -1696,11 +1662,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return Oldest alive server nodes with at least one cache configured.
      */
     @Nullable public ClusterNode oldestAliveCacheServerNode(AffinityTopologyVersion topVer) {
-        DiscoCache cache = resolveDiscoCache(null, topVer);
-
-        Map.Entry<ClusterNode, Boolean> e = cache.aliveSrvNodesWithCaches.firstEntry();
-
-        return e != null ? e.getKey() : null;
+        return resolveDiscoCache(null, topVer).oldestAliveServerNodeWithCache();
     }
 
     /**
@@ -1711,7 +1673,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return Collection of cache affinity nodes.
      */
     public Collection<ClusterNode> cacheAffinityNodes(@Nullable String cacheName, AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(cacheName, topVer).cacheAffinityNodes(cacheName, topVer.topologyVersion());
+        return resolveDiscoCache(cacheName, topVer).cacheAffinityNodes(cacheName);
     }
 
     /**
@@ -1788,7 +1750,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
      * @return {@code True} if cache with given name has at least one node with near cache enabled.
      */
     public boolean hasNearCache(@Nullable String cacheName, AffinityTopologyVersion topVer) {
-        return resolveDiscoCache(cacheName, topVer).hasNearCache(cacheName);
+        return resolveDiscoCache(cacheName, topVer).hasNearCache(CU.cacheId(cacheName));
     }
 
     /**
@@ -1874,7 +1836,19 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     /** @return Event that represents a local node joined to topology. */
     public DiscoveryEvent localJoinEvent() {
         try {
-            return locJoinEvt.get();
+            return locJoin.get().get1();
+        }
+        catch (IgniteCheckedException e) {
+            throw new IgniteException(e);
+        }
+    }
+
+    /**
+     * @return Tuple that consists of a local join event and discovery cache at the join time.
+     */
+    public T2<DiscoveryEvent, DiscoCache> localJoin() {
+        try {
+            return locJoin.get();
         }
         catch (IgniteCheckedException e) {
             throw new IgniteException(e);
@@ -1948,6 +1922,114 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     }
 
     /**
+     * @param loc Local node.
+     * @param topSnapshot Topology snapshot.
+     * @return Newly created discovery cache.
+     */
+    @NotNull private DiscoCache createDiscoCache(ClusterNode loc, Collection<ClusterNode> topSnapshot) {
+        HashSet<UUID> alives = U.newHashSet(topSnapshot.size());
+        HashMap<UUID, ClusterNode> nodeMap = U.newHashMap(topSnapshot.size());
+
+        ArrayList<ClusterNode> daemonNodes = new ArrayList<>(topSnapshot.size());
+        ArrayList<ClusterNode> srvNodes = new ArrayList<>(topSnapshot.size());
+        ArrayList<ClusterNode> rmtNodes = new ArrayList<>(topSnapshot.size());
+        ArrayList<ClusterNode> allNodes = new ArrayList<>(topSnapshot.size());
+
+        for (ClusterNode node : topSnapshot) {
+            if (alive(node))
+                alives.add(node.id());
+
+            if (node.isDaemon())
+                daemonNodes.add(node);
+            else {
+                allNodes.add(node);
+
+                if (!node.isLocal())
+                    rmtNodes.add(node);
+
+                if (!CU.clientNode(node))
+                    srvNodes.add(node);
+            }
+
+            nodeMap.put(node.id(), node);
+        }
+
+        assert !rmtNodes.contains(loc) : "Remote nodes collection shouldn't contain local node" +
+            " [rmtNodes=" + rmtNodes + ", loc=" + loc + ']';
+
+        Map<Integer, List<ClusterNode>> allCacheNodes = U.newHashMap(allNodes.size());
+        Map<Integer, List<ClusterNode>> affCacheNodes = U.newHashMap(allNodes.size());
+
+        Set<ClusterNode> allNodesWithCaches = new TreeSet<>(GridNodeOrderComparator.INSTANCE);
+        Set<ClusterNode> rmtNodesWithCaches = new TreeSet<>(GridNodeOrderComparator.INSTANCE);
+        Set<ClusterNode> srvNodesWithCaches = new TreeSet<>(GridNodeOrderComparator.INSTANCE);
+
+        Set<Integer> nearEnabledCaches = new HashSet<>();
+
+        for (ClusterNode node : allNodes) {
+            assert node.order() != 0 : "Invalid node order [locNode=" + loc + ", node=" + node + ']';
+            assert !node.isDaemon();
+
+            for (Map.Entry<String, CachePredicate> entry : registeredCaches.entrySet()) {
+                String cacheName = entry.getKey();
+                CachePredicate filter = entry.getValue();
+
+                if (filter.cacheNode(node)) {
+                    allNodesWithCaches.add(node);
+
+                    if(!CU.clientNode(node))
+                        srvNodesWithCaches.add(node);
+
+                    if (!node.isLocal())
+                        rmtNodesWithCaches.add(node);
+
+                    addToMap(allCacheNodes, cacheName, node);
+
+                    if (filter.dataNode(node))
+                        addToMap(affCacheNodes, cacheName, node);
+
+                    if (filter.nearNode(node))
+                        nearEnabledCaches.add(CU.cacheId(cacheName));
+                }
+            }
+        }
+
+        return new DiscoCache(
+            loc,
+            Collections.unmodifiableList(rmtNodes),
+            Collections.unmodifiableList(allNodes),
+            Collections.unmodifiableList(srvNodes),
+            Collections.unmodifiableList(daemonNodes),
+            U.sealList(srvNodesWithCaches),
+            U.sealList(allNodesWithCaches),
+            U.sealList(rmtNodesWithCaches),
+            Collections.unmodifiableMap(allCacheNodes),
+            Collections.unmodifiableMap(affCacheNodes),
+            Collections.unmodifiableMap(nodeMap),
+            Collections.unmodifiableSet(nearEnabledCaches),
+            alives);
+    }
+
+    /**
+     * Adds node to map.
+     *
+     * @param cacheMap Map to add to.
+     * @param cacheName Cache name.
+     * @param rich Node to add
+     */
+    private void addToMap(Map<Integer, List<ClusterNode>> cacheMap, String cacheName, ClusterNode rich) {
+        List<ClusterNode> cacheNodes = cacheMap.get(CU.cacheId(cacheName));
+
+        if (cacheNodes == null) {
+            cacheNodes = new ArrayList<>();
+
+            cacheMap.put(CU.cacheId(cacheName), cacheNodes);
+        }
+
+        cacheNodes.add(rich);
+    }
+
+    /**
      * Updates topology version if current version is smaller than updated.
      *
      * @param updated Updated topology version.
@@ -2048,8 +2130,16 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     lastChk = now;
 
                     if (!segValid) {
-                        discoWrk.addEvent(EVT_NODE_SEGMENTED, AffinityTopologyVersion.NONE, getSpi().getLocalNode(),
-                            Collections.<ClusterNode>emptyList(), null);
+                        List<ClusterNode> empty = Collections.emptyList();
+
+                        ClusterNode node = getSpi().getLocalNode();
+
+                        discoWrk.addEvent(EVT_NODE_SEGMENTED,
+                            AffinityTopologyVersion.NONE,
+                            node,
+                            createDiscoCache(node, empty),
+                            empty,
+                            null);
 
                         lastSegChkRes.set(false);
                     }
@@ -2069,8 +2159,8 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
     /** Worker for discovery events. */
     private class DiscoveryWorker extends GridWorker {
         /** Event queue. */
-        private final BlockingQueue<GridTuple5<Integer, AffinityTopologyVersion, ClusterNode, Collection<ClusterNode>,
-            DiscoveryCustomMessage>> evts = new LinkedBlockingQueue<>();
+        private final BlockingQueue<GridTuple6<Integer, AffinityTopologyVersion, ClusterNode,
+            DiscoCache, Collection<ClusterNode>, DiscoveryCustomMessage>> evts = new LinkedBlockingQueue<>();
 
         /** Node segmented event fired flag. */
         private boolean nodeSegFired;
@@ -2088,10 +2178,11 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
          * @param type Discovery event type. See {@link DiscoveryEvent} for more details.
          * @param topVer Topology version.
          * @param node Remote node this event is connected with.
+         * @param discoCache Discovery cache.
          * @param topSnapshot Topology snapshot.
          */
         @SuppressWarnings("RedundantTypeArguments")
-        private void recordEvent(int type, long topVer, ClusterNode node, Collection<ClusterNode> topSnapshot) {
+        private void recordEvent(int type, long topVer, ClusterNode node, DiscoCache discoCache, Collection<ClusterNode> topSnapshot) {
             assert node != null;
 
             if (ctx.event().isRecordable(type)) {
@@ -2100,7 +2191,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                 evt.node(ctx.discovery().localNode());
                 evt.eventNode(node);
                 evt.type(type);
-
                 evt.topologySnapshot(topVer, U.<ClusterNode, ClusterNode>arrayList(topSnapshot, FILTER_DAEMON));
 
                 if (type == EVT_NODE_METRICS_UPDATED)
@@ -2127,7 +2217,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                 else
                     assert false;
 
-                ctx.event().record(evt);
+                ctx.event().record(evt, discoCache);
             }
         }
 
@@ -2135,6 +2225,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
          * @param type Event type.
          * @param topVer Topology version.
          * @param node Node.
+         * @param discoCache Discovery cache.
          * @param topSnapshot Topology snapshot.
          * @param data Custom message.
          */
@@ -2142,12 +2233,13 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
             int type,
             AffinityTopologyVersion topVer,
             ClusterNode node,
+            DiscoCache discoCache,
             Collection<ClusterNode> topSnapshot,
             @Nullable DiscoveryCustomMessage data
         ) {
             assert node != null : data;
 
-            evts.add(new GridTuple5<>(type, topVer, node, topSnapshot, data));
+            evts.add(new GridTuple6<>(type, topVer, node, discoCache, topSnapshot, data));
         }
 
         /**
@@ -2184,7 +2276,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         /** @throws InterruptedException If interrupted. */
         @SuppressWarnings("DuplicateCondition")
         private void body0() throws InterruptedException {
-            GridTuple5<Integer, AffinityTopologyVersion, ClusterNode, Collection<ClusterNode>,
+            GridTuple6<Integer, AffinityTopologyVersion, ClusterNode, DiscoCache, Collection<ClusterNode>,
                 DiscoveryCustomMessage> evt = evts.take();
 
             int type = evt.get1();
@@ -2317,11 +2409,11 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                         customEvt.node(ctx.discovery().localNode());
                         customEvt.eventNode(node);
                         customEvt.type(type);
-                        customEvt.topologySnapshot(topVer.topologyVersion(), evt.get4());
+                        customEvt.topologySnapshot(topVer.topologyVersion(), evt.get5());
                         customEvt.affinityTopologyVersion(topVer);
-                        customEvt.customMessage(evt.get5());
+                        customEvt.customMessage(evt.get6());
 
-                        ctx.event().record(customEvt);
+                        ctx.event().record(customEvt, evt.get4());
                     }
 
                     return;
@@ -2335,7 +2427,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
                     assert false : "Invalid discovery event: " + type;
             }
 
-            recordEvent(type, topVer.topologyVersion(), node, evt.get4());
+            recordEvent(type, topVer.topologyVersion(), node, evt.get4(), evt.get5());
 
             if (segmented)
                 onSegmentation();
@@ -2545,432 +2637,6 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
         }
     }
 
-    /** Cache for discovery collections. */
-    private class DiscoCache {
-        /** Remote nodes. */
-        private final List<ClusterNode> rmtNodes;
-
-        /** All nodes. */
-        private final List<ClusterNode> allNodes;
-
-        /** All server nodes. */
-        private final List<ClusterNode> srvNodes;
-
-        /** All nodes with at least one cache configured. */
-        @GridToStringInclude
-        private final Collection<ClusterNode> allNodesWithCaches;
-
-        /** All nodes with at least one cache configured. */
-        @GridToStringInclude
-        private final Collection<ClusterNode> rmtNodesWithCaches;
-
-        /** Cache nodes by cache name. */
-        @GridToStringInclude
-        private final Map<String, Collection<ClusterNode>> allCacheNodes;
-
-        /** Remote cache nodes by cache name. */
-        @GridToStringInclude
-        private final Map<String, Collection<ClusterNode>> rmtCacheNodes;
-
-        /** Cache nodes by cache name. */
-        @GridToStringInclude
-        private final Map<String, Collection<ClusterNode>> affCacheNodes;
-
-        /** Caches where at least one node has near cache enabled. */
-        @GridToStringInclude
-        private final Set<String> nearEnabledCaches;
-
-        /** Nodes grouped by version. */
-        private final NavigableMap<IgniteProductVersion, Collection<ClusterNode>> nodesByVer;
-
-        /** Daemon nodes. */
-        private final List<ClusterNode> daemonNodes;
-
-        /** Node map. */
-        private final Map<UUID, ClusterNode> nodeMap;
-
-        /** Local node. */
-        private final ClusterNode loc;
-
-        /** Highest node order. */
-        private final long maxOrder;
-
-        /**
-         * Cached alive nodes list. As long as this collection doesn't accept {@code null}s use {@link
-         * #maskNull(String)} before passing raw cache names to it.
-         */
-        private final ConcurrentMap<String, Collection<ClusterNode>> aliveCacheNodes;
-
-        /**
-         * Cached alive remote nodes list. As long as this collection doesn't accept {@code null}s use {@link
-         * #maskNull(String)} before passing raw cache names to it.
-         */
-        private final ConcurrentMap<String, Collection<ClusterNode>> aliveRmtCacheNodes;
-
-        /**
-         * Cached alive server remote nodes with caches.
-         */
-        private final ConcurrentSkipListMap<ClusterNode, Boolean> aliveSrvNodesWithCaches;
-
-        /**
-         * @param loc Local node.
-         * @param rmts Remote nodes.
-         */
-        private DiscoCache(ClusterNode loc, Collection<ClusterNode> rmts) {
-            this.loc = loc;
-
-            rmtNodes = Collections.unmodifiableList(new ArrayList<>(F.view(rmts, FILTER_DAEMON)));
-
-            assert !rmtNodes.contains(loc) : "Remote nodes collection shouldn't contain local node" +
-                " [rmtNodes=" + rmtNodes + ", loc=" + loc + ']';
-
-            List<ClusterNode> all = new ArrayList<>(rmtNodes.size() + 1);
-
-            if (!loc.isDaemon())
-                all.add(loc);
-
-            all.addAll(rmtNodes);
-
-            Collections.sort(all, GridNodeOrderComparator.INSTANCE);
-
-            allNodes = Collections.unmodifiableList(all);
-
-            Map<String, Collection<ClusterNode>> cacheMap = new HashMap<>(allNodes.size(), 1.0f);
-            Map<String, Collection<ClusterNode>> rmtCacheMap = new HashMap<>(allNodes.size(), 1.0f);
-            Map<String, Collection<ClusterNode>> dhtNodesMap = new HashMap<>(allNodes.size(), 1.0f);
-            Collection<ClusterNode> nodesWithCaches = new HashSet<>(allNodes.size());
-            Collection<ClusterNode> rmtNodesWithCaches = new HashSet<>(allNodes.size());
-
-            aliveCacheNodes = new ConcurrentHashMap8<>(allNodes.size(), 1.0f);
-            aliveRmtCacheNodes = new ConcurrentHashMap8<>(allNodes.size(), 1.0f);
-            aliveSrvNodesWithCaches = new ConcurrentSkipListMap<>(GridNodeOrderComparator.INSTANCE);
-            nodesByVer = new TreeMap<>();
-
-            long maxOrder0 = 0;
-
-            Set<String> nearEnabledSet = new HashSet<>();
-
-            List<ClusterNode> srvNodes = new ArrayList<>();
-
-            for (ClusterNode node : allNodes) {
-                assert node.order() != 0 : "Invalid node order [locNode=" + loc + ", node=" + node + ']';
-                assert !node.isDaemon();
-
-                if (!CU.clientNode(node))
-                    srvNodes.add(node);
-
-                if (node.order() > maxOrder0)
-                    maxOrder0 = node.order();
-
-                boolean hasCaches = false;
-
-                for (Map.Entry<String, CachePredicate> entry : registeredCaches.entrySet()) {
-                    String cacheName = entry.getKey();
-
-                    CachePredicate filter = entry.getValue();
-
-                    if (filter.cacheNode(node)) {
-                        nodesWithCaches.add(node);
-
-                        if (!loc.id().equals(node.id()))
-                            rmtNodesWithCaches.add(node);
-
-                        addToMap(cacheMap, cacheName, node);
-
-                        if (alive(node.id()))
-                            addToMap(aliveCacheNodes, maskNull(cacheName), node);
-
-                        if (filter.dataNode(node))
-                            addToMap(dhtNodesMap, cacheName, node);
-
-                        if (filter.nearNode(node))
-                            nearEnabledSet.add(cacheName);
-
-                        if (!loc.id().equals(node.id())) {
-                            addToMap(rmtCacheMap, cacheName, node);
-
-                            if (alive(node.id()))
-                                addToMap(aliveRmtCacheNodes, maskNull(cacheName), node);
-                        }
-
-                        hasCaches = true;
-                    }
-                }
-
-                if (hasCaches && alive(node.id()) && !CU.clientNode(node))
-                    aliveSrvNodesWithCaches.put(node, Boolean.TRUE);
-
-                IgniteProductVersion nodeVer = U.productVersion(node);
-
-                // Create collection for this version if it does not exist.
-                Collection<ClusterNode> nodes = nodesByVer.get(nodeVer);
-
-                if (nodes == null) {
-                    nodes = new ArrayList<>(allNodes.size());
-
-                    nodesByVer.put(nodeVer, nodes);
-                }
-
-                nodes.add(node);
-            }
-
-            Collections.sort(srvNodes, CU.nodeComparator(true));
-
-            // Need second iteration to add this node to all previous node versions.
-            for (ClusterNode node : allNodes) {
-                IgniteProductVersion nodeVer = U.productVersion(node);
-
-                // Get all versions lower or equal node's version.
-                NavigableMap<IgniteProductVersion, Collection<ClusterNode>> updateView =
-                    nodesByVer.headMap(nodeVer, false);
-
-                for (Collection<ClusterNode> prevVersions : updateView.values())
-                    prevVersions.add(node);
-            }
-
-            maxOrder = maxOrder0;
-
-            allCacheNodes = Collections.unmodifiableMap(cacheMap);
-            rmtCacheNodes = Collections.unmodifiableMap(rmtCacheMap);
-            affCacheNodes = Collections.unmodifiableMap(dhtNodesMap);
-            allNodesWithCaches = Collections.unmodifiableCollection(nodesWithCaches);
-            this.rmtNodesWithCaches = Collections.unmodifiableCollection(rmtNodesWithCaches);
-            nearEnabledCaches = Collections.unmodifiableSet(nearEnabledSet);
-            this.srvNodes = Collections.unmodifiableList(srvNodes);
-
-            daemonNodes = Collections.unmodifiableList(new ArrayList<>(
-                F.view(F.concat(false, loc, rmts), F0.not(FILTER_DAEMON))));
-
-            Map<UUID, ClusterNode> nodeMap = new HashMap<>(allNodes().size() + daemonNodes.size(), 1.0f);
-
-            for (ClusterNode n : F.concat(false, allNodes(), daemonNodes()))
-                nodeMap.put(n.id(), n);
-
-            this.nodeMap = nodeMap;
-        }
-
-        /**
-         * Adds node to map.
-         *
-         * @param cacheMap Map to add to.
-         * @param cacheName Cache name.
-         * @param rich Node to add
-         */
-        private void addToMap(Map<String, Collection<ClusterNode>> cacheMap, String cacheName, ClusterNode rich) {
-            Collection<ClusterNode> cacheNodes = cacheMap.get(cacheName);
-
-            if (cacheNodes == null) {
-                cacheNodes = new ArrayList<>(allNodes.size());
-
-                cacheMap.put(cacheName, cacheNodes);
-            }
-
-            cacheNodes.add(rich);
-        }
-
-        /** @return Local node. */
-        ClusterNode localNode() {
-            return loc;
-        }
-
-        /** @return Remote nodes. */
-        Collection<ClusterNode> remoteNodes() {
-            return rmtNodes;
-        }
-
-        /** @return All nodes. */
-        Collection<ClusterNode> allNodes() {
-            return allNodes;
-        }
-
-        /**
-         * Gets collection of nodes which have version equal or greater than {@code ver}.
-         *
-         * @param ver Version to check.
-         * @return Collection of nodes with version equal or greater than {@code ver}.
-         */
-        Collection<ClusterNode> elderNodes(IgniteProductVersion ver) {
-            Map.Entry<IgniteProductVersion, Collection<ClusterNode>> entry = nodesByVer.ceilingEntry(ver);
-
-            if (entry == null)
-                return Collections.emptyList();
-
-            return entry.getValue();
-        }
-
-        /**
-         * @return Versions map.
-         */
-        NavigableMap<IgniteProductVersion, Collection<ClusterNode>> versionsMap() {
-            return nodesByVer;
-        }
-
-        /**
-         * Gets collection of nodes with at least one cache configured.
-         *
-         * @param topVer Topology version (maximum allowed node order).
-         * @return Collection of nodes.
-         */
-        Collection<ClusterNode> allNodesWithCaches(final long topVer) {
-            return filter(topVer, allNodesWithCaches);
-        }
-
-        /**
-         * Gets all nodes that have cache with given name.
-         *
-         * @param cacheName Cache name.
-         * @param topVer Topology version.
-         * @return Collection of nodes.
-         */
-        Collection<ClusterNode> cacheNodes(@Nullable String cacheName, final long topVer) {
-            return filter(topVer, allCacheNodes.get(cacheName));
-        }
-
-        /**
-         * Gets all remote nodes that have at least one cache configured.
-         *
-         * @param topVer Topology version.
-         * @return Collection of nodes.
-         */
-        Collection<ClusterNode> remoteCacheNodes(final long topVer) {
-            return filter(topVer, rmtNodesWithCaches);
-        }
-
-        /**
-         * Gets all nodes that have cache with given name and should participate in affinity calculation. With
-         * partitioned cache nodes with near-only cache do not participate in affinity node calculation.
-         *
-         * @param cacheName Cache name.
-         * @param topVer Topology version.
-         * @return Collection of nodes.
-         */
-        Collection<ClusterNode> cacheAffinityNodes(@Nullable String cacheName, final long topVer) {
-            return filter(topVer, affCacheNodes.get(cacheName));
-        }
-
-        /**
-         * Gets all alive nodes that have cache with given name.
-         *
-         * @param cacheName Cache name.
-         * @param topVer Topology version.
-         * @return Collection of nodes.
-         */
-        Collection<ClusterNode> aliveCacheNodes(@Nullable String cacheName, final long topVer) {
-            return filter(topVer, aliveCacheNodes.get(maskNull(cacheName)));
-        }
-
-        /**
-         * Gets all alive remote nodes that have cache with given name.
-         *
-         * @param cacheName Cache name.
-         * @param topVer Topology version.
-         * @return Collection of nodes.
-         */
-        Collection<ClusterNode> aliveRemoteCacheNodes(@Nullable String cacheName, final long topVer) {
-            return filter(topVer, aliveRmtCacheNodes.get(maskNull(cacheName)));
-        }
-
-        /**
-         * Checks if cache with given name has at least one node with near cache enabled.
-         *
-         * @param cacheName Cache name.
-         * @return {@code True} if cache with given name has at least one node with near cache enabled.
-         */
-        boolean hasNearCache(@Nullable String cacheName) {
-            return nearEnabledCaches.contains(cacheName);
-        }
-
-        /**
-         * Removes left node from cached alives lists.
-         *
-         * @param leftNode Left node.
-         */
-        void updateAlives(ClusterNode leftNode) {
-            if (leftNode.order() > maxOrder)
-                return;
-
-            filterNodeMap(aliveCacheNodes, leftNode);
-
-            filterNodeMap(aliveRmtCacheNodes, leftNode);
-
-            aliveSrvNodesWithCaches.remove(leftNode);
-        }
-
-        /**
-         * Creates a copy of nodes map without the given node.
-         *
-         * @param map Map to copy.
-         * @param exclNode Node to exclude.
-         */
-        private void filterNodeMap(ConcurrentMap<String, Collection<ClusterNode>> map, final ClusterNode exclNode) {
-            for (String cacheName : registeredCaches.keySet()) {
-                String maskedName = maskNull(cacheName);
-
-                while (true) {
-                    Collection<ClusterNode> oldNodes = map.get(maskedName);
-
-                    if (oldNodes == null || oldNodes.isEmpty())
-                        break;
-
-                    Collection<ClusterNode> newNodes = new ArrayList<>(oldNodes);
-
-                    if (!newNodes.remove(exclNode))
-                        break;
-
-                    if (map.replace(maskedName, oldNodes, newNodes))
-                        break;
-                }
-            }
-        }
-
-        /**
-         * Replaces {@code null} with {@code NULL_CACHE_NAME}.
-         *
-         * @param cacheName Cache name.
-         * @return Masked name.
-         */
-        private String maskNull(@Nullable String cacheName) {
-            return cacheName == null ? NULL_CACHE_NAME : cacheName;
-        }
-
-        /**
-         * @param topVer Topology version.
-         * @param nodes Nodes.
-         * @return Filtered collection (potentially empty, but never {@code null}).
-         */
-        private Collection<ClusterNode> filter(final long topVer, @Nullable Collection<ClusterNode> nodes) {
-            if (nodes == null)
-                return Collections.emptyList();
-
-            // If no filtering needed, return original collection.
-            return nodes.isEmpty() || topVer < 0 || topVer >= maxOrder ?
-                nodes :
-                F.view(nodes, new P1<ClusterNode>() {
-                    @Override public boolean apply(ClusterNode node) {
-                        return node.order() <= topVer;
-                    }
-                });
-        }
-
-        /** @return Daemon nodes. */
-        Collection<ClusterNode> daemonNodes() {
-            return daemonNodes;
-        }
-
-        /**
-         * @param id Node ID.
-         * @return Node.
-         */
-        @Nullable ClusterNode node(UUID id) {
-            return nodeMap.get(id);
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(DiscoCache.class, this, "allNodesWithDaemons", U.toShortString(allNodes));
-        }
-    }
-
     /**
      * Cache predicate.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/DiscoveryEventListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/DiscoveryEventListener.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/DiscoveryEventListener.java
new file mode 100644
index 0000000..963d97e
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/DiscoveryEventListener.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.managers.eventstorage;
+
+import java.util.EventListener;
+import org.apache.ignite.events.DiscoveryEvent;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
+
+/**
+ * Internal listener for discovery events.
+ */
+public interface DiscoveryEventListener extends EventListener {
+    /**
+     * @param evt Discovery event.
+     * @param discoCache Discovery cache.
+     */
+    public void onEvent(DiscoveryEvent evt, DiscoCache discoCache);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageManager.java
index 684e326..f8abd30 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/eventstorage/GridEventStorageManager.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.managers.GridManagerAdapter;
 import org.apache.ignite.internal.managers.communication.GridIoManager;
 import org.apache.ignite.internal.managers.communication.GridMessageListener;
 import org.apache.ignite.internal.managers.deployment.GridDeployment;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.processors.platform.PlatformEventFilterListener;
 import org.apache.ignite.internal.util.GridConcurrentLinkedHashSet;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -79,6 +80,9 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
     /** Local event listeners. */
     private final ConcurrentMap<Integer, Set<GridLocalEventListener>> lsnrs = new ConcurrentHashMap8<>();
 
+    /** Internal discovery listeners. */
+    private final ConcurrentMap<Integer, Set<DiscoveryEventListener>> discoLsnrs = new ConcurrentHashMap8<>();
+
     /** Busy lock to control activity of threads. */
     private final ReadWriteLock busyLock = new ReentrantReadWriteLock();
 
@@ -234,6 +238,7 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
         msgLsnr = null;
 
         lsnrs.clear();
+        discoLsnrs.clear();
     }
 
     /** {@inheritDoc} */
@@ -300,6 +305,30 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
     }
 
     /**
+     * Records discovery events.
+     *
+     * @param evt Event to record.
+     * @param discoCache Discovery cache.
+     */
+    public void record(DiscoveryEvent evt, DiscoCache discoCache) {
+        assert evt != null;
+
+        if (!enterBusy())
+            return;
+
+        try {
+            // Notify internal discovery listeners first.
+            notifyDiscoveryListeners(evt, discoCache);
+
+            // Notify all other registered listeners.
+            record(evt);
+        }
+        finally {
+            leaveBusy();
+        }
+    }
+
+    /**
      * Gets types of enabled user-recordable events.
      *
      * @return Array of types of enabled user-recordable events.
@@ -570,7 +599,7 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
 
         try {
             for (int t : types) {
-                getOrCreate(t).add(lsnr);
+                getOrCreate(lsnrs, t).add(lsnr);
 
                 if (!isRecordable(t))
                     U.warn(log, "Added listener for disabled event type: " + U.gridEventName(t));
@@ -595,14 +624,14 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
             return;
 
         try {
-            getOrCreate(type).add(lsnr);
+            getOrCreate(lsnrs, type).add(lsnr);
 
             if (!isRecordable(type))
                 U.warn(log, "Added listener for disabled event type: " + U.gridEventName(type));
 
             if (types != null) {
                 for (int t : types) {
-                    getOrCreate(t).add(lsnr);
+                    getOrCreate(lsnrs, t).add(lsnr);
 
                     if (!isRecordable(t))
                         U.warn(log, "Added listener for disabled event type: " + U.gridEventName(t));
@@ -615,16 +644,70 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
     }
 
     /**
+     * Adds discovery event listener. Note that this method specifically disallow an empty
+     * array of event type to prevent accidental subscription for all system event that
+     * may lead to a drastic performance decrease.
+     *
+     * @param lsnr Listener to add.
+     * @param types Event types to subscribe listener for.
+     */
+    public void addDiscoveryEventListener(DiscoveryEventListener lsnr, int[] types) {
+        assert lsnr != null;
+        assert types != null;
+        assert types.length > 0;
+
+        if (!enterBusy())
+            return;
+
+        try {
+            for (int t : types) {
+                getOrCreate(discoLsnrs, t).add(lsnr);
+            }
+        }
+        finally {
+            leaveBusy();
+        }
+    }
+
+    /**
+     * Adds discovery event listener.
+     *
+     * @param lsnr Listener to add.
+     * @param type Event type to subscribe listener for.
+     * @param types Additional event types to subscribe listener for.
+     */
+    public void addDiscoveryEventListener(DiscoveryEventListener lsnr, int type, @Nullable int... types) {
+        assert lsnr != null;
+
+        if (!enterBusy())
+            return;
+
+        try {
+            getOrCreate(discoLsnrs, type).add(lsnr);
+
+            if (types != null) {
+                for (int t : types) {
+                    getOrCreate(discoLsnrs, t).add(lsnr);
+                }
+            }
+        }
+        finally {
+            leaveBusy();
+        }
+    }
+
+    /**
+     * @param lsnrs Listeners map.
      * @param type Event type.
      * @return Listeners for given event type.
      */
-    private Collection<GridLocalEventListener> getOrCreate(Integer type) {
-        Set<GridLocalEventListener> set = lsnrs.get(type);
+    private <T> Collection<T> getOrCreate(ConcurrentMap<Integer, Set<T>> lsnrs, Integer type) {
+        Set<T> set = lsnrs.get(type);
 
         if (set == null) {
             set = new GridConcurrentLinkedHashSet<>();
 
-            Set<GridLocalEventListener> prev = lsnrs.putIfAbsent(type, set);
+            Set<T> prev = lsnrs.putIfAbsent(type, set);
 
             if (prev != null)
                 set = prev;
@@ -688,6 +771,38 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
     }
 
     /**
+     * Removes listener for specified events, if any. If no event types provided - it
+     * remove the listener for all its registered events.
+     *
+     * @param lsnr Listener.
+     * @param types Event types.
+     * @return Returns {@code true} if removed.
+     */
+    public boolean removeDiscoveryEventListener(DiscoveryEventListener lsnr, @Nullable int... types) {
+        assert lsnr != null;
+
+        boolean found = false;
+
+        if (F.isEmpty(types)) {
+            for (Set<DiscoveryEventListener> set : discoLsnrs.values())
+                if (set.remove(lsnr))
+                    found = true;
+        }
+        else {
+            assert types != null;
+
+            for (int type : types) {
+                Set<DiscoveryEventListener> set = discoLsnrs.get(type);
+
+                if (set != null && set.remove(lsnr))
+                    found = true;
+            }
+        }
+
+        return found;
+    }
+
+    /**
      *
      * @param p Optional predicate.
      * @param types Event types to wait for.
@@ -780,6 +895,41 @@ public class GridEventStorageManager extends GridManagerAdapter<EventStorageSpi>
     }
 
     /**
+     * @param evt Discovery event
+     * @param cache Discovery cache.
+     */
+    private void notifyDiscoveryListeners(DiscoveryEvent evt, DiscoCache cache) {
+        assert evt != null;
+
+        notifyDiscoveryListeners(discoLsnrs.get(evt.type()), evt, cache);
+    }
+
+    /**
+     * @param set Set of listeners.
+     * @param evt Discovery event.
+     * @param cache Discovery cache.
+     */
+    private void notifyDiscoveryListeners(@Nullable Collection<DiscoveryEventListener> set, DiscoveryEvent evt, DiscoCache cache) {
+        assert evt != null;
+
+        if (!F.isEmpty(set)) {
+            assert set != null;
+
+            for (DiscoveryEventListener lsnr : set) {
+                try {
+                    lsnr.onEvent(evt, cache);
+                }
+                catch (Throwable e) {
+                    U.error(log, "Unexpected exception in listener notification for event: " + evt, e);
+
+                    if (e instanceof Error)
+                        throw (Error)e;
+                }
+            }
+        }
+    }
+
+    /**
      * @param p Grid event predicate.
      * @return Collection of grid events.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
index a388c7a..5070462 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/affinity/GridAffinityAssignmentCache.java
@@ -39,6 +39,7 @@ import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.GridNodeOrderComparator;
 import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.CU;
@@ -252,10 +253,12 @@ public class GridAffinityAssignmentCache {
      *
      * @param topVer Topology version to calculate affinity cache for.
      * @param discoEvt Discovery event that caused this topology version change.
+     * @param discoCache Discovery cache.
      * @return Affinity assignments.
      */
     @SuppressWarnings("IfMayBeConditional")
-    public List<List<ClusterNode>> calculate(AffinityTopologyVersion topVer, DiscoveryEvent discoEvt) {
+    public List<List<ClusterNode>> calculate(AffinityTopologyVersion topVer, DiscoveryEvent discoEvt,
+        DiscoCache discoCache) {
         if (log.isDebugEnabled())
             log.debug("Calculating affinity [topVer=" + topVer + ", locNodeId=" + ctx.localNodeId() +
                 ", discoEvt=" + discoEvt + ']');
@@ -266,7 +269,7 @@ public class GridAffinityAssignmentCache {
         List<ClusterNode> sorted;
 
         if (!locCache) {
-            sorted = new ArrayList<>(ctx.discovery().cacheAffinityNodes(cacheName, topVer));
+            sorted = new ArrayList<>(discoCache.cacheAffinityNodes(cacheId()));
 
             Collections.sort(sorted, GridNodeOrderComparator.INSTANCE);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
index 459723c..c1dde13 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
@@ -387,7 +387,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                 cctx.cache().prepareCacheStart(req, fut.topologyVersion());
 
                 if (fut.isCacheAdded(cacheId, fut.topologyVersion())) {
-                    if (cctx.discovery().cacheAffinityNodes(req.cacheName(), fut.topologyVersion()).isEmpty())
+                    if (fut.discoCache().cacheAffinityNodes(req.cacheName()).isEmpty())
                         U.quietAndWarn(log, "No server nodes found for cache client: " + req.cacheName());
                 }
 
@@ -408,7 +408,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                             assert aff.lastVersion().equals(AffinityTopologyVersion.NONE) : aff.lastVersion();
 
                             List<List<ClusterNode>> assignment = aff.calculate(fut.topologyVersion(),
-                                fut.discoveryEvent());
+                                fut.discoveryEvent(), fut.discoCache());
 
                             aff.initialize(fut.topologyVersion(), assignment);
                         }
@@ -768,7 +768,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
             assert old == null : old;
 
-            List<List<ClusterNode>> newAff = cache.affinity().calculate(fut.topologyVersion(), fut.discoveryEvent());
+            List<List<ClusterNode>> newAff = cache.affinity().calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
             cache.affinity().initialize(fut.topologyVersion(), newAff);
         }
@@ -806,7 +806,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
                     if (cache.affinity().lastVersion().equals(AffinityTopologyVersion.NONE)) {
                         List<List<ClusterNode>> assignment =
-                            cache.affinity().calculate(fut.topologyVersion(), fut.discoveryEvent());
+                            cache.affinity().calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
                         cache.affinity().initialize(fut.topologyVersion(), assignment);
                     }
@@ -832,14 +832,15 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
     private void initAffinity(GridAffinityAssignmentCache aff, GridDhtPartitionsExchangeFuture fut, boolean fetch)
         throws IgniteCheckedException {
         if (!fetch && canCalculateAffinity(aff, fut)) {
-            List<List<ClusterNode>> assignment = aff.calculate(fut.topologyVersion(), fut.discoveryEvent());
+            List<List<ClusterNode>> assignment = aff.calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
             aff.initialize(fut.topologyVersion(), assignment);
         }
         else {
             GridDhtAssignmentFetchFuture fetchFut = new GridDhtAssignmentFetchFuture(cctx,
                 aff.cacheName(),
-                fut.topologyVersion());
+                fut.topologyVersion(),
+                fut.discoCache());
 
             fetchFut.init();
 
@@ -893,7 +894,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
                             CacheHolder cache = cache(fut, cacheDesc);
 
-                            List<List<ClusterNode>> newAff = cache.affinity().calculate(topVer, fut.discoveryEvent());
+                            List<List<ClusterNode>> newAff = cache.affinity().calculate(topVer, fut.discoveryEvent(), fut.discoCache());
 
                             cache.affinity().initialize(topVer, newAff);
                         }
@@ -960,14 +961,15 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
             if (cctx.localNodeId().equals(cacheDesc.receivedFrom())) {
                 List<List<ClusterNode>> assignment =
-                    cacheCtx.affinity().affinityCache().calculate(fut.topologyVersion(), fut.discoveryEvent());
+                    cacheCtx.affinity().affinityCache().calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
                 cacheCtx.affinity().affinityCache().initialize(fut.topologyVersion(), assignment);
             }
             else {
                 GridDhtAssignmentFetchFuture fetchFut = new GridDhtAssignmentFetchFuture(cctx,
                     cacheCtx.name(),
-                    topVer);
+                    topVer,
+                    fut.discoCache());
 
                 fetchFut.init();
 
@@ -1001,7 +1003,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
         GridDhtAffinityAssignmentResponse res = fetchFut.get();
 
         if (res == null) {
-            List<List<ClusterNode>> aff = affCache.calculate(topVer, fut.discoveryEvent());
+            List<List<ClusterNode>> aff = affCache.calculate(topVer, fut.discoveryEvent(), fut.discoCache());
 
             affCache.initialize(topVer, aff);
         }
@@ -1013,7 +1015,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             else {
                 assert !affCache.centralizedAffinityFunction() || !lateAffAssign;
 
-                affCache.calculate(topVer, fut.discoveryEvent());
+                affCache.calculate(topVer, fut.discoveryEvent(), fut.discoCache());
             }
 
             List<List<ClusterNode>> aff = res.affinityAssignment(cctx.discovery());
@@ -1043,7 +1045,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                 if (cacheCtx.isLocal())
                     continue;
 
-                cacheCtx.affinity().affinityCache().calculate(fut.topologyVersion(), fut.discoveryEvent());
+                cacheCtx.affinity().affinityCache().calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
             }
 
             centralizedAff = true;
@@ -1093,7 +1095,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
                 if (cache != null) {
                     if (cache.client())
-                        cache.affinity().calculate(fut.topologyVersion(), fut.discoveryEvent());
+                        cache.affinity().calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
                     return;
                 }
@@ -1133,7 +1135,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
                     GridDhtAssignmentFetchFuture fetchFut = new GridDhtAssignmentFetchFuture(cctx,
                         aff.cacheName(),
-                        prev.topologyVersion());
+                        prev.topologyVersion(),
+                        prev.discoCache());
 
                     fetchFut.init();
 
@@ -1144,7 +1147,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                             throws IgniteCheckedException {
                             fetchAffinity(prev, aff, (GridDhtAssignmentFetchFuture)fetchFut);
 
-                            aff.calculate(fut.topologyVersion(), fut.discoveryEvent());
+                            aff.calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
                             affFut.onDone(fut.topologyVersion());
                         }
@@ -1283,7 +1286,7 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
         assert aff.idealAssignment() != null : "Previous assignment is not available.";
 
-        List<List<ClusterNode>> idealAssignment = aff.calculate(topVer, fut.discoveryEvent());
+        List<List<ClusterNode>> idealAssignment = aff.calculate(topVer, fut.discoveryEvent(), fut.discoCache());
         List<List<ClusterNode>> newAssignment = null;
 
         if (latePrimary) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
index a65d971..24321b2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAffinityManager.java
@@ -28,7 +28,6 @@ import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache;
-import org.apache.ignite.internal.util.GridLeanSet;
 import org.apache.ignite.internal.util.future.GridFinishedFuture;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.lang.IgniteFuture;
@@ -77,7 +76,7 @@ public class GridCacheAffinityManager extends GridCacheManagerAdapter {
     @Override protected void onKernalStart0() throws IgniteCheckedException {
         if (cctx.isLocal())
             // No discovery event needed for local affinity.
-            aff.calculate(LOC_CACHE_TOP_VER, null);
+            aff.calculate(LOC_CACHE_TOP_VER, null, null);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/42346673/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index 695872f..ff7feb8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -48,7 +48,6 @@ import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.events.DiscoveryEvent;
-import org.apache.ignite.events.Event;
 import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
 import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
@@ -57,6 +56,8 @@ import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
 import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
+import org.apache.ignite.internal.managers.discovery.DiscoCache;
+import org.apache.ignite.internal.managers.eventstorage.DiscoveryEventListener;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.affinity.GridAffinityAssignmentCache;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridClientPartitionTopology;
@@ -181,35 +182,33 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
     private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
 
     /** Discovery listener. */
-    private final GridLocalEventListener discoLsnr = new GridLocalEventListener() {
-        @Override public void onEvent(Event evt) {
+    private final DiscoveryEventListener discoLsnr = new DiscoveryEventListener() {
+        @Override public void onEvent(DiscoveryEvent evt, DiscoCache cache) {
             if (!enterBusy())
                 return;
 
             try {
-                DiscoveryEvent e = (DiscoveryEvent)evt;
-
                 ClusterNode loc = cctx.localNode();
 
-                assert e.type() == EVT_NODE_JOINED || e.type() == EVT_NODE_LEFT || e.type() == EVT_NODE_FAILED ||
-                    e.type() == EVT_DISCOVERY_CUSTOM_EVT;
+                assert evt.type() == EVT_NODE_JOINED || evt.type() == EVT_NODE_LEFT || evt.type() == EVT_NODE_FAILED ||
+                    evt.type() == EVT_DISCOVERY_CUSTOM_EVT;
 
-                final ClusterNode n = e.eventNode();
+                final ClusterNode n = evt.eventNode();
 
                 GridDhtPartitionExchangeId exchId = null;
                 GridDhtPartitionsExchangeFuture exchFut = null;
 
-                if (e.type() != EVT_DISCOVERY_CUSTOM_EVT) {
+                if (evt.type() != EVT_DISCOVERY_CUSTOM_EVT) {
                     assert !loc.id().equals(n.id());
 
-                    if (e.type() == EVT_NODE_LEFT || e.type() == EVT_NODE_FAILED) {
+                    if (evt.type() == EVT_NODE_LEFT || evt.type() == EVT_NODE_FAILED) {
                         assert cctx.discovery().node(n.id()) == null;
 
                         // Avoid race b/w initial future add and discovery event.
                         GridDhtPartitionsExchangeFuture initFut = null;
 
                         if (readyTopVer.get().equals(AffinityTopologyVersion.NONE)) {
-                            initFut = exchangeFuture(initialExchangeId(), null, null, null);
+                            initFut = exchangeFuture(initialExchangeId(), null, null, null, null);
 
                             initFut.onNodeLeft(n);
                         }
@@ -220,16 +219,18 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                         }
                     }
 
-                    assert e.type() != EVT_NODE_JOINED || n.order() > loc.order() :
+                    assert evt.type() != EVT_NODE_JOINED || n.order() > loc.order() :
                         "Node joined with smaller-than-local " +
                             "order [newOrder=" + n.order() + ", locOrder=" + loc.order() + ']';
 
-                    exchId = exchangeId(n.id(), affinityTopologyVersion(e), e.type());
+                    exchId = exchangeId(n.id(),
+                        affinityTopologyVersion(evt),
+                        evt.type());
 
-                    exchFut = exchangeFuture(exchId, e, null, null);
+                    exchFut = exchangeFuture(exchId, evt, cache,null, null);
                 }
                 else {
-                    DiscoveryCustomEvent customEvt = (DiscoveryCustomEvent)e;
+                    DiscoveryCustomEvent customEvt = (DiscoveryCustomEvent)evt;
 
                     if (customEvt.customMessage() instanceof DynamicCacheChangeBatch) {
                         DynamicCacheChangeBatch batch = (DynamicCacheChangeBatch)customEvt.customMessage();
@@ -260,9 +261,9 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
                         //todo think about refactoring
                         if (!F.isEmpty(valid) && !(valid.size() == 1 && valid.iterator().next().globalStateChange())) {
-                            exchId = exchangeId(n.id(), affinityTopologyVersion(e), e.type());
+                            exchId = exchangeId(n.id(), affinityTopologyVersion(evt), evt.type());
 
-                            exchFut = exchangeFuture(exchId, e, valid, null);
+                            exchFut = exchangeFuture(exchId, evt, cache, valid, null);
                         }
                     }
                     else if (customEvt.customMessage() instanceof CacheAffinityChangeMessage) {
@@ -270,19 +271,19 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
                         if (msg.exchangeId() == null) {
                             if (msg.exchangeNeeded()) {
-                                exchId = exchangeId(n.id(), affinityTopologyVersion(e), e.type());
+                                exchId = exchangeId(n.id(), affinityTopologyVersion(evt), evt.type());
 
-                                exchFut = exchangeFuture(exchId, e, null, msg);
+                                exchFut = exchangeFuture(exchId, evt, cache, null, msg);
                             }
                         }
                         else
-                            exchangeFuture(msg.exchangeId(), null, null, null).onAffinityChangeMessage(customEvt.eventNode(), msg);
+                            exchangeFuture(msg.exchangeId(), null, null, null, null).onAffinityChangeMessage(customEvt.eventNode(), msg);
                     }
                     else if (customEvt.customMessage() instanceof StartSnapshotOperationAckDiscoveryMessage
                         && !((StartSnapshotOperationAckDiscoveryMessage)customEvt.customMessage()).hasError()) {
-                        exchId = exchangeId(n.id(), affinityTopologyVersion(e), e.type());
+                        exchId = exchangeId(n.id(), affinityTopologyVersion(evt), evt.type());
 
-                        exchFut = exchangeFuture(exchId, e, null, null);
+                        exchFut = exchangeFuture(exchId, evt, null, null, null);
                     }
                 }
 
@@ -291,7 +292,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                         log.debug("Discovery event (will start exchange): " + exchId);
 
                     // Event callback - without this callback future will never complete.
-                    exchFut.onEvent(exchId, e);
+                    exchFut.onEvent(exchId, evt, cache);
 
                     // Start exchange process.
                     addFuture(exchFut);
@@ -313,7 +314,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
         exchWorker = new ExchangeWorker();
 
-        cctx.gridEvents().addLocalEventListener(discoLsnr, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED,
+        cctx.gridEvents().addDiscoveryEventListener(discoLsnr, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED,
             EVT_DISCOVERY_CUSTOM_EVT);
 
         cctx.io().addHandler(0, GridDhtPartitionsSingleMessage.class,
@@ -371,11 +372,14 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
         assert startTime > 0;
 
         // Generate dummy discovery event for local node joining.
-        DiscoveryEvent discoEvt = cctx.discovery().localJoinEvent();
+        T2<DiscoveryEvent, DiscoCache> localJoin = cctx.discovery().localJoin();
+
+        DiscoveryEvent discoEvt = localJoin.get1();
+        DiscoCache discoCache = localJoin.get2();
 
         GridDhtPartitionExchangeId exchId = initialExchangeId();
 
-        GridDhtPartitionsExchangeFuture fut = exchangeFuture(exchId, discoEvt, null, null);
+        GridDhtPartitionsExchangeFuture fut = exchangeFuture(exchId, discoEvt, discoCache, null, null);
 
         if (reconnect)
             reconnectExchangeFut = new GridFutureAdapter<>();
@@ -482,7 +486,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
     /** {@inheritDoc} */
     @Override protected void onKernalStop0(boolean cancel) {
-        cctx.gridEvents().removeLocalEventListener(discoLsnr);
+        cctx.gridEvents().removeDiscoveryEventListener(discoLsnr);
 
         cctx.io().removeHandler(0, GridDhtPartitionsSingleMessage.class);
         cctx.io().removeHandler(0, GridDhtPartitionsFullMessage.class);
@@ -1085,12 +1089,14 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
     /**
      * @param exchId Exchange ID.
      * @param discoEvt Discovery event.
+     * @param cache Discovery data cache.
      * @param reqs Cache change requests.
      * @param affChangeMsg Affinity change message.
      * @return Exchange future.
      */
     private GridDhtPartitionsExchangeFuture exchangeFuture(GridDhtPartitionExchangeId exchId,
         @Nullable DiscoveryEvent discoEvt,
+        @Nullable DiscoCache cache,
         @Nullable Collection<DynamicCacheChangeRequest> reqs,
         @Nullable CacheAffinityChangeMessage affChangeMsg) {
         GridDhtPartitionsExchangeFuture fut;
@@ -1109,7 +1115,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
         }
 
         if (discoEvt != null)
-            fut.onEvent(exchId, discoEvt);
+            fut.onEvent(exchId, discoEvt, cache);
 
         if (stopErr != null)
             fut.onDone(stopErr);
@@ -1265,7 +1271,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                     cctx.database().releaseHistoryForPreloading();
             }
             else
-                exchangeFuture(msg.exchangeId(), null, null, null).onReceive(node, msg);
+                exchangeFuture(msg.exchangeId(), null, null, null, null).onReceive(node, msg);
         }
         finally {
             leaveBusy();
@@ -1318,8 +1324,11 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
             }
             else {
                 if (msg.client()) {
-                    final GridDhtPartitionsExchangeFuture exchFut = exchangeFuture(
-                        msg.exchangeId(), null, null, null);
+                    final GridDhtPartitionsExchangeFuture exchFut = exchangeFuture(msg.exchangeId(),
+                        null,
+                        null,
+                        null,
+                        null);
 
                     exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
                         @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> fut) {
@@ -1329,7 +1338,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                     });
                 }
                 else
-                    exchangeFuture(msg.exchangeId(), null, null, null).onReceive(node, msg);
+                    exchangeFuture(msg.exchangeId(), null, null, null, null).onReceive(node, msg);
             }
         }
         finally {


[31/50] [abbrv] ignite git commit: ignite-4712 Memory leaks in PageMemory

Posted by sb...@apache.org.
ignite-4712 Memory leaks in PageMemory


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 937a1414df54a67be55633cf1a19066708f3c816
Parents: 3b86e29
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Tue Mar 21 20:00:12 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Mar 21 20:00:12 2017 +0300

----------------------------------------------------------------------
 .../database/IgniteDbAbstractTest.java          | 24 +++++++++++++++-
 .../database/IgniteDbPutGetAbstractTest.java    | 29 --------------------
 2 files changed, 23 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/937a1414/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
index cf26187..95ec178 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
@@ -54,6 +54,9 @@ public abstract class IgniteDbAbstractTest extends GridCommonAbstractTest {
      */
     protected abstract boolean indexingEnabled();
 
+    /** */
+    protected boolean client;
+
     /** {@inheritDoc} */
     @SuppressWarnings("unchecked")
     @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
@@ -61,6 +64,9 @@ public abstract class IgniteDbAbstractTest extends GridCommonAbstractTest {
 
         MemoryConfiguration dbCfg = new MemoryConfiguration();
 
+        if (client)
+            cfg.setClientMode(true);
+
         dbCfg.setConcurrencyLevel(Runtime.getRuntime().availableProcessors() * 4);
 
         if (isLargePage())
@@ -121,7 +127,8 @@ public abstract class IgniteDbAbstractTest extends GridCommonAbstractTest {
         ccfg5.setRebalanceMode(SYNC);
         ccfg5.setAffinity(new RendezvousAffinityFunction(false, 32));
 
-        cfg.setCacheConfiguration(ccfg, ccfg2, ccfg3, ccfg4, ccfg5);
+        if (!client)
+            cfg.setCacheConfiguration(ccfg, ccfg2, ccfg3, ccfg4, ccfg5);
 
         TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
 
@@ -149,6 +156,13 @@ public abstract class IgniteDbAbstractTest extends GridCommonAbstractTest {
         // No-op.
     }
 
+    /**
+     * @return {@code True} if cache operations should be called from client node with near cache.
+     */
+    protected boolean withClientNearCache() {
+        return false;
+    }
+
     /** {@inheritDoc} */
     @Override protected void beforeTest() throws Exception {
         deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
@@ -161,6 +175,14 @@ public abstract class IgniteDbAbstractTest extends GridCommonAbstractTest {
 
         startGrids(gridCount());
 
+        if (withClientNearCache()) {
+            client = true;
+
+            startGrid(gridCount());
+
+            client = false;
+        }
+
         awaitPartitionMapExchange();
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/937a1414/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
index 86f1237..cfb9b08 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
@@ -36,14 +36,9 @@ import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.ScanQuery;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.cache.query.SqlQuery;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
-import org.apache.ignite.configuration.CacheConfiguration;
-import org.apache.ignite.configuration.MemoryConfiguration;
-import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
-import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree;
 import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheAdapter;
 import org.apache.ignite.internal.util.GridRandom;
 import org.apache.ignite.internal.util.typedef.PA;
@@ -59,23 +54,6 @@ public abstract class IgniteDbPutGetAbstractTest extends IgniteDbAbstractTest {
     private static final int KEYS_COUNT = 20_000;
 
     /**
-     * @return Node count.
-     */
-    protected abstract int gridCount();
-
-    /**
-     * @return {@code True} if indexing is enabled.
-     */
-    protected abstract boolean indexingEnabled();
-
-    /**
-     * @return {@code True} if cache operations should be called from client node with near cache.
-     */
-    protected boolean withClientNearCache() {
-        return false;
-    }
-
-    /**
      * @return Ignite instance for testing.
      */
     private IgniteEx ig() {
@@ -98,13 +76,6 @@ public abstract class IgniteDbPutGetAbstractTest extends IgniteDbAbstractTest {
     }
 
     /**
-     * @return {@code True} if use large page.
-     */
-    protected boolean isLargePage() {
-        return false;
-    }
-
-    /**
      *
      */
     public void testGradualRandomPutAllRemoveAll() throws Exception {


[47/50] [abbrv] ignite git commit: Multiple optimizations from ignite-gg-8.0.3.ea5-atomicbench.

Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index 7dd1929..a9923f6 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -1971,3 +1971,4 @@ org.apache.ignite.transactions.TransactionRollbackException
 org.apache.ignite.transactions.TransactionState
 org.apache.ignite.transactions.TransactionTimeoutException
 org.apache.ignite.util.AttributeNodeFilter
+org.apache.ignite.internal.util.GridPartitionStateMap
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedAffinitySpreadTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedAffinitySpreadTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedAffinitySpreadTest.java
index 2d46cf4..2784295 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedAffinitySpreadTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCachePartitionedAffinitySpreadTest.java
@@ -76,12 +76,10 @@ public class GridCachePartitionedAffinitySpreadTest extends GridCommonAbstractTe
         Map<ClusterNode, Integer> parts = new HashMap<>(nodes.size());
 
         for (int part = 0; part < aff.getPartitions(); part++) {
-            Collection<ClusterNode> affNodes = aff.assignPartition(null,
-                part,
-                new ArrayList<>(nodes),
-                new HashMap<ClusterNode, byte[]>(),
+            Collection<ClusterNode> affNodes = aff.assignPartition(part,
+                new ArrayList<ClusterNode>(nodes),
                 0,
-                null);
+                new HashMap<UUID, Collection<ClusterNode>>());
 
             assertEquals(1, affNodes.size());
 


[43/50] [abbrv] ignite git commit: Moved updatePartitionSingleMap(...) outside of synchronized block.

Posted by sb...@apache.org.
Moved updatePartitionSingleMap(...) outside of synchronized block.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: f2c9d6cd0f22974aa4e1db99cd519a954b18dd4c
Parents: c540206
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Mon Apr 10 19:00:02 2017 +0300
Committer: Ilya Lantukh <il...@gridgain.com>
Committed: Mon Apr 10 19:00:02 2017 +0300

----------------------------------------------------------------------
 .../dht/preloader/GridDhtPartitionsExchangeFuture.java         | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/f2c9d6cd/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index 28ecacb..b0d776f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -1532,13 +1532,14 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      */
     private void processMessage(ClusterNode node, GridDhtPartitionsSingleMessage msg) {
         boolean allReceived = false;
+        boolean updateSingleMap = false;
 
         synchronized (mux) {
             assert crd != null;
 
             if (crd.isLocal()) {
                 if (remaining.remove(node.id())) {
-                    updatePartitionSingleMap(node, msg);
+                    updateSingleMap = true;
 
                     if (exchangeOnChangeGlobalState && msg.getException() != null)
                         changeGlobalStateExceptions.put(node.id(), msg.getException());
@@ -1550,6 +1551,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                 singleMsgs.put(node, msg);
         }
 
+        if (updateSingleMap)
+            updatePartitionSingleMap(node, msg);
+
         if (allReceived)
             onAllReceived();
     }


[10/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -refactoring (moving messages, new mechanism of registration, etc.)

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-refactoring (moving messages, new mechanism of registration, etc.)


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 4c97f43be8b608f20f2a5a3d40280233cffd46e8
Parents: 0384b66
Author: EdShangGG <es...@gridgain.com>
Authored: Tue Feb 21 16:03:05 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Tue Feb 21 16:03:05 2017 +0300

----------------------------------------------------------------------
 .../communication/GridIoMessageFactory.java     |  15 +-
 .../pagemem/snapshot/SnapshotOperation.java     |  30 +++
 .../SnapshotOperationFinishedMessage.java       | 181 -------------------
 .../pagemem/snapshot/SnapshotOperationType.java |   4 +-
 .../snapshot/SnapshotProgressMessage.java       | 135 --------------
 .../GridChangeGlobalStateMessageResponse.java   |   2 +-
 6 files changed, 36 insertions(+), 331 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/4c97f43b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
index 1574909..6f73682 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessageFactory.java
@@ -33,8 +33,6 @@ import org.apache.ignite.internal.managers.deployment.GridDeploymentInfoBean;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentRequest;
 import org.apache.ignite.internal.managers.deployment.GridDeploymentResponse;
 import org.apache.ignite.internal.managers.eventstorage.GridEventStorageMessage;
-import org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationFinishedMessage;
-import org.apache.ignite.internal.pagemem.snapshot.SnapshotProgressMessage;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridChangeGlobalStateMessageResponse;
 import org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection;
@@ -174,19 +172,9 @@ public class GridIoMessageFactory implements MessageFactory {
         Message msg = null;
 
         switch (type) {
-            case -47:
-                msg = new SnapshotProgressMessage();
-
-                break;
-
-
-            case -46:
-                msg = new GridChangeGlobalStateMessageResponse();
-
-                break;
 
             case -45:
-                msg = new SnapshotOperationFinishedMessage();
+                msg = new GridChangeGlobalStateMessageResponse();
 
                 break;
 
@@ -848,6 +836,7 @@ public class GridIoMessageFactory implements MessageFactory {
             // [-3..119] [124..127] [-23..-27] [-36..-47]- this
             // [120..123] - DR
             // [-4..-22, -30..-35] - SQL
+            // [-46..-50] - Snapshots
             default:
                 if (ext != null) {
                     for (MessageFactory factory : ext) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/4c97f43b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
index 3e13f95..3f84b97 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -17,7 +17,9 @@
  */
 package org.apache.ignite.internal.pagemem.snapshot;
 
+import java.io.File;
 import java.io.Serializable;
+import java.util.Collection;
 import java.util.Set;
 
 /**
@@ -98,6 +100,34 @@ public class SnapshotOperation implements Serializable {
         return extraParam;
     }
 
+
+    /**
+     * @param op Op.
+     */
+    public static Collection<File> getOptionalPathsParameter(SnapshotOperation op) {
+        assert op.type() == SnapshotOperationType.CHECK || op.extraParameter() instanceof Collection;
+
+        return (Collection<File>)op.extraParameter();
+    }
+
+    /**
+     * @param op Op.
+     */
+    public static Boolean getFullSnapshotParameter(SnapshotOperation op) {
+        assert op.type() == SnapshotOperationType.CREATE && op.extraParameter() instanceof Boolean;
+
+        return (Boolean)op.extraParameter();
+    }
+
+    /**
+     * @param op Op.
+     */
+    public static File getMovingPathParameter(SnapshotOperation op) {
+        assert op.type() == SnapshotOperationType.MOVE && op.extraParameter() instanceof File;
+
+        return (File)op.extraParameter();
+    }
+
     @Override public boolean equals(Object o) {
         if (this == o)
             return true;

http://git-wip-us.apache.org/repos/asf/ignite/blob/4c97f43b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java
deleted file mode 100644
index 8986e5c..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationFinishedMessage.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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.pagemem.snapshot;
-
-import java.nio.ByteBuffer;
-import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageReader;
-import org.apache.ignite.plugin.extensions.communication.MessageWriter;
-
-/**
- * Message indicating that snapshot has been finished on a single node.
- */
-public class SnapshotOperationFinishedMessage implements Message {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** */
-    private long snapshotId;
-
-    /** Operation type. */
-    private int operationType;
-
-    /** */
-    private boolean success;
-
-    /** Error message. */
-    private String errorMsg;
-
-    /** */
-    public SnapshotOperationFinishedMessage() {
-    }
-
-    /**
-     * @param snapshotId Snapshot ID.
-     * @param errorMsg
-     */
-    public SnapshotOperationFinishedMessage(long snapshotId, SnapshotOperationType type, boolean success, String errorMsg) {
-        this.snapshotId = snapshotId;
-        this.operationType = type.ordinal();
-        this.success = success;
-        this.errorMsg = errorMsg;
-    }
-
-    /**
-     * @return Snapshot ID.
-     */
-    public long snapshotId() {
-        return snapshotId;
-    }
-
-    /** */
-    public SnapshotOperationType operationType() {
-        return SnapshotOperationType.values()[operationType];
-    }
-
-    /** */
-    public boolean success() {
-        return success;
-    }
-
-    /** */
-    public String errorMessage() {
-        return errorMsg;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
-        writer.setBuffer(buf);
-
-        if (!writer.isHeaderWritten()) {
-            if (!writer.writeHeader(directType(), fieldsCount()))
-                return false;
-
-            writer.onHeaderWritten();
-        }
-
-        switch (writer.state()) {
-            case 0:
-                if (!writer.writeLong("snapshotId", snapshotId))
-                    return false;
-
-                writer.incrementState();
-
-            case 1:
-                if (!writer.writeInt("operationType", operationType))
-                    return false;
-
-                writer.incrementState();
-
-            case 2:
-                if (!writer.writeBoolean("success", success))
-                    return false;
-
-                writer.incrementState();
-
-            case 3:
-                if (!writer.writeString("errorMsg", errorMsg))
-                    return false;
-
-                writer.incrementState();
-
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
-        reader.setBuffer(buf);
-
-        if (!reader.beforeMessageRead())
-            return false;
-
-        switch (reader.state()) {
-            case 0:
-                snapshotId = reader.readLong("snapshotId");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-            case 1:
-                operationType = reader.readInt("operationType");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-            case 2:
-                success = reader.readBoolean("success");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-            case 3:
-                errorMsg = reader.readString("errorMsg");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-        }
-
-        return reader.afterMessageRead(SnapshotOperationFinishedMessage.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte directType() {
-        return -45;
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte fieldsCount() {
-        return 4;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void onAckReceived() {
-        // No-op
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4c97f43b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
index 8866bdb..3fa6d2a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
@@ -26,5 +26,7 @@ public enum SnapshotOperationType {
     /** Move. */
     MOVE,
     /** Delete. */
-    DELETE
+    DELETE,
+    /** Check. */
+    CHECK
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/4c97f43b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotProgressMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotProgressMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotProgressMessage.java
deleted file mode 100644
index 70ea6a9..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotProgressMessage.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.pagemem.snapshot;
-
-import java.nio.ByteBuffer;
-import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageReader;
-import org.apache.ignite.plugin.extensions.communication.MessageWriter;
-
-/**
- * Message for exchange of snapshot creation/restoration progress between nodes.
- */
-public class SnapshotProgressMessage implements Message {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** */
-    private long snapshotId;
-
-    /** */
-    private double progress;
-
-    /** */
-    public SnapshotProgressMessage() {
-    }
-
-    /** */
-    public SnapshotProgressMessage(long snapshotId, double progress) {
-        this.snapshotId = snapshotId;
-        this.progress = progress;
-    }
-
-    /**
-     * @return Snapshot ID.
-     */
-    public long snapshotId() {
-        return snapshotId;
-    }
-
-    /**
-     * @return Snapshot creation/restoration progress.
-     */
-    public double progress() {
-        return progress;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
-        writer.setBuffer(buf);
-
-        if (!writer.isHeaderWritten()) {
-            if (!writer.writeHeader(directType(), fieldsCount()))
-                return false;
-
-            writer.onHeaderWritten();
-        }
-
-        switch (writer.state()) {
-            case 0:
-                if (!writer.writeDouble("progress", progress))
-                    return false;
-
-                writer.incrementState();
-
-            case 1:
-                if (!writer.writeLong("snapshotId", snapshotId))
-                    return false;
-
-                writer.incrementState();
-
-        }
-
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
-        reader.setBuffer(buf);
-
-        if (!reader.beforeMessageRead())
-            return false;
-
-        switch (reader.state()) {
-            case 0:
-                progress = reader.readDouble("progress");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-            case 1:
-                snapshotId = reader.readLong("snapshotId");
-
-                if (!reader.isLastRead())
-                    return false;
-
-                reader.incrementState();
-
-        }
-
-        return reader.afterMessageRead(SnapshotProgressMessage.class);
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte directType() {
-        return -47;
-    }
-
-    /** {@inheritDoc} */
-    @Override public byte fieldsCount() {
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void onAckReceived() {
-        // No-op
-    }
-}

http://git-wip-us.apache.org/repos/asf/ignite/blob/4c97f43b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridChangeGlobalStateMessageResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridChangeGlobalStateMessageResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridChangeGlobalStateMessageResponse.java
index fafc71f..3ad4ef4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridChangeGlobalStateMessageResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridChangeGlobalStateMessageResponse.java
@@ -157,7 +157,7 @@ public class GridChangeGlobalStateMessageResponse extends GridCacheMessage {
 
     /** {@inheritDoc} */
     @Override public byte directType() {
-        return -46;
+        return -45;
     }
 
     /** {@inheritDoc} */


[34/50] [abbrv] ignite git commit: GG-12074 Creating checkpoint during writing snapshots to disc results in "Failed to create checkpoint" AND failed incremental SHAPSHOT command due to crc validation failure

Posted by sb...@apache.org.
GG-12074 Creating checkpoint during writing snapshots to disc results in "Failed to create checkpoint" AND failed incremental SHAPSHOT command due to crc validation failure


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: ef4238fce54dfea5f9a95113a57819b8b08b1b7d
Parents: 6eec695
Author: EdShangGG <es...@gridgain.com>
Authored: Mon Mar 27 20:40:58 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Mon Mar 27 20:40:58 2017 +0300

----------------------------------------------------------------------
 .../internal/pagemem/snapshot/SnapshotOperation.java      | 10 ++++++++++
 1 file changed, 10 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ef4238fc/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
index f3b5eee..93054ec 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -154,4 +154,14 @@ public class SnapshotOperation implements Serializable {
         result = 31 * result + (extraParam != null ? extraParam.hashCode() : 0);
         return result;
     }
+
+    @Override public String toString() {
+        return "SnapshotOperation{" +
+            "type=" + type +
+            ", snapshotId=" + snapshotId +
+            ", cacheNames=" + cacheNames +
+            ", msg='" + msg + '\'' +
+            ", extraParam=" + extraParam +
+            '}';
+    }
 }


[30/50] [abbrv] ignite git commit: ignite-4712 Memory leaks in PageMemory

Posted by sb...@apache.org.
ignite-4712 Memory leaks in PageMemory


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 3b86e29abf6e94cac8eb0208a4a7b81eff628ff2
Parents: 977653f
Author: sboikov <sb...@gridgain.com>
Authored: Thu Mar 16 10:37:02 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Mar 21 19:05:05 2017 +0300

----------------------------------------------------------------------
 .../cache/database/freelist/PagesList.java      | 221 +++++++----
 .../ignite/cache/LargeEntryUpdateTest.java      | 177 +++++++++
 .../database/IgniteDbAbstractTest.java          | 369 +++++++++++++++++++
 .../IgniteDbMemoryLeakAbstractTest.java         | 265 +++++++++++++
 .../IgniteDbMemoryLeakLargeObjectsTest.java     |  56 +++
 .../IgniteDbMemoryLeakLargePagesTest.java       |  33 ++
 .../IgniteDbMemoryLeakNonTransactionalTest.java |  31 ++
 .../database/IgniteDbMemoryLeakTest.java        |  46 +++
 .../IgniteDbMemoryLeakWithExpirationTest.java   |  44 +++
 .../database/IgniteDbPutGetAbstractTest.java    | 328 +----------------
 .../testsuites/IgniteDbMemoryLeakTestSuite.java |  49 +++
 .../database/IgniteDbMemoryLeakIndexedTest.java |  33 ++
 .../IgniteDbMemoryLeakSqlQueryTest.java         |  76 ++++
 ...IgniteDbMemoryLeakWithIndexingTestSuite.java |  40 ++
 14 files changed, 1369 insertions(+), 399 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
index e5430cf..5c66b10 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/freelist/PagesList.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.internal.pagemem.Page;
@@ -51,7 +52,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.jetbrains.annotations.Nullable;
-import org.jsr166.LongAdder8;
 
 import static java.lang.Boolean.FALSE;
 import static java.lang.Boolean.TRUE;
@@ -76,10 +76,7 @@ public abstract class PagesList extends DataStructure {
             Math.min(8, Runtime.getRuntime().availableProcessors() * 2));
 
     /** */
-    private final boolean trackBucketsSize = IgniteSystemProperties.getBoolean("IGNITE_PAGES_LIST_TRACK_SIZE", false);
-
-    /** */
-    protected final LongAdder8[] bucketsSize;
+    protected final AtomicLong[] bucketsSize;
 
     /** Page ID to store list metadata. */
     private final long metaPageId;
@@ -117,7 +114,7 @@ public abstract class PagesList extends DataStructure {
 
             return TRUE;
         }
-    };
+    }
 
     /**
      * @param cacheId Cache ID.
@@ -142,10 +139,10 @@ public abstract class PagesList extends DataStructure {
         this.buckets = buckets;
         this.metaPageId = metaPageId;
 
-        bucketsSize = new LongAdder8[buckets];
+        bucketsSize = new AtomicLong[buckets];
 
         for (int i = 0; i < buckets; i++)
-            bucketsSize[i] = new LongAdder8();
+            bucketsSize[i] = new AtomicLong();
     }
 
     /**
@@ -191,6 +188,7 @@ public abstract class PagesList extends DataStructure {
 
                 for (Map.Entry<Integer, GridLongList> e : bucketsData.entrySet()) {
                     int bucket = e.getKey();
+                    long bucketSize = 0;
 
                     Stripe[] old = getBucket(bucket);
                     assert old == null;
@@ -199,11 +197,43 @@ public abstract class PagesList extends DataStructure {
 
                     Stripe[] tails = new Stripe[upd.length];
 
-                    for (int i = 0; i < upd.length; i++)
-                        tails[i] = new Stripe(upd[i]);
+                    for (int i = 0; i < upd.length; i++) {
+                        long tailId = upd[i];
+
+                        long pageId = tailId;
+                        int cnt = 0;
+
+                        while (pageId != 0L) {
+                            try (Page page = page(pageId)) {
+                                long pageAddr = readLock(page);
+
+                                assert pageAddr != 0L;
+
+                                try {
+                                    PagesListNodeIO io = PagesListNodeIO.VERSIONS.forPage(pageAddr);
+
+                                    cnt += io.getCount(pageAddr);
+                                    pageId = io.getPreviousId(pageAddr);
+
+                                    // In reuse bucket the page itself can be used as a free page.
+                                    if (isReuseBucket(bucket) && pageId != 0L)
+                                        cnt++;
+                                }
+                                finally {
+                                    readUnlock(page, pageAddr);
+                                }
+                            }
+                        }
+
+                        Stripe stripe = new Stripe(tailId, cnt == 0);
+                        tails[i] = stripe;
+                        bucketSize += cnt;
+                    }
 
                     boolean ok = casBucket(bucket, null, tails);
                     assert ok;
+
+                    bucketsSize[bucket].set(bucketSize);
                 }
             }
         }
@@ -363,7 +393,7 @@ public abstract class PagesList extends DataStructure {
             initPage(pageMem, page, this, PagesListNodeIO.VERSIONS.latest(), wal);
         }
 
-        Stripe stripe = new Stripe(pageId);
+        Stripe stripe = new Stripe(pageId, true);
 
         for (;;) {
             Stripe[] old = getBucket(bucket);
@@ -490,25 +520,32 @@ public abstract class PagesList extends DataStructure {
             for (Stripe tail : tails) {
                 long pageId = tail.tailId;
 
-                try (Page page = page(pageId)) {
-                    long pageAddr = readLock(page); // No correctness guaranties.
+                while (pageId != 0L) {
+                    try (Page page = page(pageId)) {
+                        long pageAddr = readLock(page);
 
-                    try {
-                        PagesListNodeIO io = PagesListNodeIO.VERSIONS.forPage(pageAddr);
+                        assert pageAddr != 0L;
 
-                        int cnt = io.getCount(pageAddr);
+                        try {
+                            PagesListNodeIO io = PagesListNodeIO.VERSIONS.forPage(pageAddr);
 
-                        assert cnt >= 0;
+                            res += io.getCount(pageAddr);
+                            pageId = io.getPreviousId(pageAddr);
 
-                        res += cnt;
-                    }
-                    finally {
-                        readUnlock(page, pageAddr);
+                            // In reuse bucket the page itself can be used as a free page.
+                            if (isReuseBucket(bucket) && pageId != 0L)
+                                res++;
+                        }
+                        finally {
+                            readUnlock(page, pageAddr);
+                        }
                     }
                 }
             }
         }
 
+        assert res == bucketsSize[bucket].get() : "Wrong bucket size counter [exp=" + res + ", cntr=" + bucketsSize[bucket].get() + ']';
+
         return res;
     }
 
@@ -600,8 +637,7 @@ public abstract class PagesList extends DataStructure {
         if (idx == -1)
             handlePageFull(pageId, page, pageAddr, io, dataPage, dataPageAddr, bucket);
         else {
-            if (trackBucketsSize)
-                bucketsSize[bucket].increment();
+            bucketsSize[bucket].incrementAndGet();
 
             if (isWalDeltaRecordNeeded(wal, page))
                 wal.log(new PagesListAddPageRecord(cacheId, pageId, dataPageId));
@@ -660,6 +696,9 @@ public abstract class PagesList extends DataStructure {
                     dataPageId,
                     pageId, 0L));
 
+            // In reuse bucket the page itself can be used as a free page.
+            bucketsSize[bucket].incrementAndGet();
+
             updateTail(bucket, pageId, dataPageId);
         }
         else {
@@ -695,14 +734,13 @@ public abstract class PagesList extends DataStructure {
 
                     assert idx != -1;
 
-                    if (trackBucketsSize)
-                        bucketsSize[bucket].increment();
-
                     dataIO.setFreeListPageId(dataPageAddr, nextId);
 
                     if (isWalDeltaRecordNeeded(wal, dataPage))
                         wal.log(new DataPageSetFreeListPageRecord(cacheId, dataPageId, nextId));
 
+                    bucketsSize[bucket].incrementAndGet();
+
                     updateTail(bucket, pageId, nextId);
                 }
                 finally {
@@ -778,6 +816,10 @@ public abstract class PagesList extends DataStructure {
                                 0L
                             ));
 
+                        // In reuse bucket the page itself can be used as a free page.
+                        if (isReuseBucket(bucket))
+                            bucketsSize[bucket].incrementAndGet();
+
                         // Switch to this new page, which is now a part of our list
                         // to add the rest of the bag to the new page.
                         prevPageAddr = nextPageAddr;
@@ -786,12 +828,11 @@ public abstract class PagesList extends DataStructure {
                     }
                 }
                 else {
-                    if (trackBucketsSize)
-                        bucketsSize[bucket].increment();
-
                     // TODO: use single WAL record for bag?
                     if (isWalDeltaRecordNeeded(wal, page))
                         wal.log(new PagesListAddPageRecord(cacheId, prevId, nextId));
+
+                    bucketsSize[bucket].incrementAndGet();
                 }
             }
         }
@@ -816,10 +857,22 @@ public abstract class PagesList extends DataStructure {
     private Stripe getPageForTake(int bucket) {
         Stripe[] tails = getBucket(bucket);
 
-        if (tails == null)
+        if (tails == null || bucketsSize[bucket].get() == 0)
             return null;
 
-        return randomTail(tails);
+        int len = tails.length;
+        int init = randomInt(len);
+        int cur = init;
+
+        while (true) {
+            Stripe stripe = tails[cur];
+
+            if (!stripe.empty)
+                return stripe;
+
+            if ((cur = (cur + 1) % len) == init)
+                return null;
+        }
     }
 
     /**
@@ -873,7 +926,7 @@ public abstract class PagesList extends DataStructure {
         for (int lockAttempt = 0; ;) {
             Stripe stripe = getPageForTake(bucket);
 
-            if (stripe == null || stripe.empty)
+            if (stripe == null)
                 return 0L;
 
             long tailId = stripe.tailId;
@@ -888,24 +941,38 @@ public abstract class PagesList extends DataStructure {
                     continue;
                 }
 
+                if (stripe.empty) {
+                    // Another thread took the last page.
+                    writeUnlock(tail, tailPageAddr, false);
+
+                    if (bucketsSize[bucket].get() > 0) {
+                        lockAttempt--; // Ignore current attempt.
+
+                        continue;
+                    }
+                    else
+                        return 0L;
+                }
+
                 assert PageIO.getPageId(tailPageAddr) == tailId : "tailId = " + tailId + ", tailPageId = " + PageIO.getPageId(tailPageAddr);
                 assert PageIO.getType(tailPageAddr) == PageIO.T_PAGE_LIST_NODE;
 
                 boolean dirty = false;
-                long ret = 0L;
+                long ret;
                 long recycleId = 0L;
 
                 try {
                     PagesListNodeIO io = PagesListNodeIO.VERSIONS.forPage(tailPageAddr);
 
-                    if (io.getNextId(tailPageAddr) != 0)
+                    if (io.getNextId(tailPageAddr) != 0) {
+                        // It is not a tail anymore, retry.
                         continue;
+                    }
 
                     long pageId = io.takeAnyPage(tailPageAddr);
 
                     if (pageId != 0L) {
-                        if (trackBucketsSize)
-                            bucketsSize[bucket].decrement();
+                        bucketsSize[bucket].decrementAndGet();
 
                         if (isWalDeltaRecordNeeded(wal, tail))
                             wal.log(new PagesListRemovePageRecord(cacheId, tailId, pageId));
@@ -914,59 +981,66 @@ public abstract class PagesList extends DataStructure {
 
                         ret = pageId;
 
-                        // If we got an empty page in non-reuse bucket, move it back to reuse list
-                        // to prevent empty page leak to data pages.
-                        if (io.isEmpty(tailPageAddr) && !isReuseBucket(bucket)) {
+                        if (io.isEmpty(tailPageAddr)) {
                             long prevId = io.getPreviousId(tailPageAddr);
 
-                            if (prevId != 0L) {
-                                try (Page prev = page(prevId)) {
-                                    // Lock pages from next to previous.
-                                    Boolean ok = writePage(pageMem, prev, this, cutTail, null, bucket, FALSE);
+                            // If we got an empty page in non-reuse bucket, move it back to reuse list
+                            // to prevent empty page leak to data pages.
+                            if (!isReuseBucket(bucket)) {
+                                if (prevId != 0L) {
+                                    try (Page prev = page(prevId)) {
+                                        // Lock pages from next to previous.
+                                        Boolean ok = writePage(pageMem, prev, this, cutTail, null, bucket, FALSE);
 
-                                    assert ok == TRUE : ok;
-                                }
+                                        assert ok == TRUE : ok;
+                                    }
 
-                                recycleId = recyclePage(tailId, tail, tailPageAddr);
+                                    recycleId = recyclePage(tailId, tail, tailPageAddr);
+                                }
+                                else
+                                    stripe.empty = true;
                             }
+                            else
+                                stripe.empty = prevId == 0L;
                         }
                     }
                     else {
-                        // The tail page is empty. We can unlink and return it if we have a previous page.
-                        long prevId = io.getPreviousId(tailPageAddr);
+                        // The tail page is empty, but stripe is not. It might
+                        // happen only if we are in reuse bucket and it has
+                        // a previous page, so, the current page can be collected
+                        assert isReuseBucket(bucket);
 
-                        if (prevId != 0L) {
-                            // This can only happen if we are in the reuse bucket.
-                            assert isReuseBucket(bucket);
+                        long prevId = io.getPreviousId(tailPageAddr);
 
-                            try (Page prev = page(prevId)) {
-                                // Lock pages from next to previous.
-                                Boolean ok = writePage(pageMem, prev, this, cutTail, null, bucket, FALSE);
+                        assert prevId != 0L;
 
-                                assert ok == TRUE : ok;
-                            }
+                        try (Page prev = page(prevId)) {
+                            // Lock pages from next to previous.
+                            Boolean ok = writePage(pageMem, prev, this, cutTail, null, bucket, FALSE);
 
-                            if (initIoVers != null) {
-                                tailId = PageIdUtils.changeType(tailId, FLAG_DATA);
+                            assert ok == TRUE : ok;
 
-                                PageIO initIo = initIoVers.latest();
+                            bucketsSize[bucket].decrementAndGet();
+                        }
 
-                                initIo.initNewPage(tailPageAddr, tailId, pageSize());
+                        if (initIoVers != null) {
+                            tailId = PageIdUtils.changeType(tailId, FLAG_DATA);
 
-                                if (isWalDeltaRecordNeeded(wal, tail)) {
-                                    wal.log(new InitNewPageRecord(cacheId, tail.id(), initIo.getType(),
-                                        initIo.getVersion(), tailId));
-                                }
-                            }
-                            else
-                                tailId = recyclePage(tailId, tail, tailPageAddr);
+                            PageIO initIo = initIoVers.latest();
 
-                            dirty = true;
+                            initIo.initNewPage(tailPageAddr, tailId, pageSize());
 
-                            ret = tailId;
+                            if (isWalDeltaRecordNeeded(wal, tail)) {
+                                wal.log(new InitNewPageRecord(cacheId, tail.id(), initIo.getType(),
+                                    initIo.getVersion(), tailId));
+                            }
                         }
                         else
-                            stripe.empty = true;
+                            tailId = recyclePage(tailId, tail, tailPageAddr);
+
+                        dirty = true;
+
+                        ret = tailId;
                     }
 
                     // If we do not have a previous page (we are at head), then we still can return
@@ -1026,8 +1100,7 @@ public abstract class PagesList extends DataStructure {
                 if (!rmvd)
                     return false;
 
-                if (trackBucketsSize)
-                    bucketsSize[bucket].decrement();
+                bucketsSize[bucket].decrementAndGet();
 
                 if (isWalDeltaRecordNeeded(wal, page))
                     wal.log(new PagesListRemovePageRecord(cacheId, pageId, dataPageId));
@@ -1312,9 +1385,11 @@ public abstract class PagesList extends DataStructure {
 
         /**
          * @param tailId Tail ID.
+         * @param empty Empty flag.
          */
-        Stripe(long tailId) {
+        Stripe(long tailId, boolean empty) {
             this.tailId = tailId;
+            this.empty = empty;
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/cache/LargeEntryUpdateTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/LargeEntryUpdateTest.java b/modules/core/src/test/java/org/apache/ignite/cache/LargeEntryUpdateTest.java
new file mode 100644
index 0000000..18a1654
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/cache/LargeEntryUpdateTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.cache;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import javax.cache.processor.MutableEntry;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCompute;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.MemoryConfiguration;
+import org.apache.ignite.lang.IgniteFuture;
+import org.apache.ignite.lang.IgniteRunnable;
+import org.apache.ignite.resources.IgniteInstanceResource;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public class LargeEntryUpdateTest extends GridCommonAbstractTest {
+    /**  */
+    private static final int THREAD_COUNT = 10;
+
+    /**  */
+    private static final int PAGE_SIZE = 1 << 10; // 1 kB.
+
+    /**  */
+    private static final int PAGE_CACHE_SIZE = 30 << 20; // 30 MB.
+
+    /**  */
+    private static final String CACHE_PREFIX = "testCache";
+
+    /**  */
+    private static final int CACHE_COUNT = 10;
+
+    /**  */
+    private static final long WAIT_TIMEOUT = 5 * 60_000L; // 5 min.
+
+    /**  */
+    private static final long TEST_TIMEOUT = 10 * 60_000L; // 10 min.
+
+    /**  */
+    private final AtomicBoolean cacheUpdate = new AtomicBoolean();
+
+    /** {@inheritDoc} */
+    @Override protected long getTestTimeout() {
+        return TEST_TIMEOUT;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        cfg.setPublicThreadPoolSize(THREAD_COUNT);
+
+        MemoryConfiguration mem = new MemoryConfiguration();
+
+        mem.setPageSize(PAGE_SIZE);
+        mem.setPageCacheSize(PAGE_CACHE_SIZE);
+
+        cfg.setMemoryConfiguration(mem);
+
+        CacheConfiguration[] ccfgs = new CacheConfiguration[CACHE_COUNT];
+
+        for (int i = 0; i < CACHE_COUNT; ++i) {
+            CacheConfiguration ccfg = new CacheConfiguration();
+            ccfg.setName(CACHE_PREFIX + i);
+            ccfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
+            ccfg.setCacheMode(CacheMode.PARTITIONED);
+            ccfgs[i] = ccfg;
+        }
+
+        cfg.setCacheConfiguration(ccfgs);
+
+        return cfg;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testEntryUpdate() throws Exception {
+        try (Ignite ignite = startGrid()) {
+            for (int i = 0; i < CACHE_COUNT; ++i) {
+                IgniteCache<Long, byte[]> cache = ignite.cache(CACHE_PREFIX + i);
+
+                cache.put(0L, new byte[PAGE_SIZE * 2]);
+            }
+
+            IgniteCompute compute = ignite.compute().withAsync();
+
+            long endTime = System.currentTimeMillis() + WAIT_TIMEOUT;
+
+            int iter = 0;
+
+            while (System.currentTimeMillis() < endTime) {
+                log.info("Iteration: " + iter++);
+
+                cacheUpdate.set(true);
+
+                try {
+                    List<IgniteFuture> futs = new ArrayList<>();
+
+                    for (int i = 0; i < THREAD_COUNT; ++i) {
+                        compute.run(new CacheUpdater());
+
+                        futs.add(compute.future());
+                    }
+
+                    Thread.sleep(30_000);
+
+                    cacheUpdate.set(false);
+
+                    for (IgniteFuture fut : futs)
+                        fut.get();
+                }
+                finally {
+                    cacheUpdate.set(false);
+                }
+            }
+        }
+    }
+
+    /**  */
+    public static class EntryUpdater implements CacheEntryProcessor<Long, byte[], Void> {
+        /**  */
+        public static final EntryUpdater INSTANCE = new EntryUpdater();
+
+        /** {@inheritDoc} */
+        @Override public Void process(MutableEntry<Long, byte[]> entry, Object... args) {
+            entry.setValue(new byte[PAGE_SIZE]);
+
+            return null;
+        }
+    }
+
+    /**  */
+    public class CacheUpdater implements IgniteRunnable {
+        /**  */
+        @IgniteInstanceResource
+        public transient Ignite ignite;
+
+        /** {@inheritDoc} */
+        @Override public void run() {
+            try {
+                while (cacheUpdate.get()) {
+                    for (int i = 0; i < CACHE_COUNT; ++i) {
+                        IgniteCache<Long, byte[]> cache = ignite.cache(CACHE_PREFIX + i);
+
+                        cache.invoke(0L, EntryUpdater.INSTANCE);
+                    }
+                }
+            }
+            catch (Throwable ex) {
+                throw new IgniteException(ex);
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
new file mode 100644
index 0000000..cf26187
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbAbstractTest.java
@@ -0,0 +1,369 @@
+/*
+ * 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.database;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.MemoryConfiguration;
+import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+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;
+
+import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC;
+import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
+import static org.apache.ignite.cache.CacheRebalanceMode.SYNC;
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public abstract class IgniteDbAbstractTest extends GridCommonAbstractTest {
+    /** */
+    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
+
+    /**
+     * @return Node count.
+     */
+    protected abstract int gridCount();
+
+    /**
+     * @return {@code True} if indexing is enabled.
+     */
+    protected abstract boolean indexingEnabled();
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        MemoryConfiguration dbCfg = new MemoryConfiguration();
+
+        dbCfg.setConcurrencyLevel(Runtime.getRuntime().availableProcessors() * 4);
+
+        if (isLargePage())
+            dbCfg.setPageSize(16 * 1024);
+        else
+            dbCfg.setPageSize(1024);
+
+        dbCfg.setPageCacheSize(200 * 1024 * 1024);
+
+        configure(dbCfg);
+
+        cfg.setMemoryConfiguration(dbCfg);
+
+        CacheConfiguration ccfg = new CacheConfiguration();
+
+        if (indexingEnabled())
+            ccfg.setIndexedTypes(Integer.class, DbValue.class);
+
+        ccfg.setAtomicityMode(TRANSACTIONAL);
+        ccfg.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg.setRebalanceMode(SYNC);
+        ccfg.setAffinity(new RendezvousAffinityFunction(false, 32));
+
+        CacheConfiguration ccfg2 = new CacheConfiguration("non-primitive");
+
+        if (indexingEnabled())
+            ccfg2.setIndexedTypes(DbKey.class, DbValue.class);
+
+        ccfg2.setAtomicityMode(TRANSACTIONAL);
+        ccfg2.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg2.setRebalanceMode(SYNC);
+        ccfg2.setAffinity(new RendezvousAffinityFunction(false, 32));
+
+        CacheConfiguration ccfg3 = new CacheConfiguration("large");
+
+        if (indexingEnabled())
+            ccfg3.setIndexedTypes(Integer.class, LargeDbValue.class);
+
+        ccfg3.setAtomicityMode(TRANSACTIONAL);
+        ccfg3.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg3.setRebalanceMode(SYNC);
+        ccfg3.setAffinity(new RendezvousAffinityFunction(false, 32));
+
+        CacheConfiguration ccfg4 = new CacheConfiguration("tiny");
+
+        ccfg4.setAtomicityMode(TRANSACTIONAL);
+        ccfg4.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg4.setRebalanceMode(SYNC);
+        ccfg4.setAffinity(new RendezvousAffinityFunction(1, null));
+
+        CacheConfiguration ccfg5 = new CacheConfiguration("atomic");
+
+        if (indexingEnabled())
+            ccfg5.setIndexedTypes(DbKey.class, DbValue.class);
+
+        ccfg5.setAtomicityMode(ATOMIC);
+        ccfg5.setWriteSynchronizationMode(FULL_SYNC);
+        ccfg5.setRebalanceMode(SYNC);
+        ccfg5.setAffinity(new RendezvousAffinityFunction(false, 32));
+
+        cfg.setCacheConfiguration(ccfg, ccfg2, ccfg3, ccfg4, ccfg5);
+
+        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+
+        discoSpi.setIpFinder(IP_FINDER);
+
+        cfg.setDiscoverySpi(discoSpi);
+        cfg.setMarshaller(null);
+
+        configure(cfg);
+
+        return cfg;
+    }
+
+    /**
+     * @param cfg IgniteConfiguration.
+     */
+    protected void configure(IgniteConfiguration cfg){
+        // No-op.
+    }
+
+    /**
+     * @param mCfg MemoryConfiguration.
+     */
+    protected void configure(MemoryConfiguration mCfg){
+        // No-op.
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
+
+//        long seed = System.currentTimeMillis();
+//
+//        info("Seed: " + seed + "L");
+//
+//        BPlusTree.rnd = new Random(seed);
+
+        startGrids(gridCount());
+
+        awaitPartitionMapExchange();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        BPlusTree.rnd = null;
+
+        stopAllGrids();
+
+        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
+    }
+
+    /**
+     * @return {@code True} if use large page.
+     */
+    protected boolean isLargePage() {
+        return false;
+    }
+
+    /**
+     *
+     */
+    static class DbKey implements Serializable {
+        /** */
+        int val;
+
+        /**
+         * @param val Value.
+         */
+        DbKey(int val) {
+            this.val = val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (o == null || !(o instanceof DbKey))
+                return false;
+
+            DbKey key = (DbKey)o;
+
+            return val == key.val;
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val;
+        }
+    }
+
+    /**
+     *
+     */
+    static class LargeDbKey implements Serializable {
+        /** */
+        int val;
+
+        /** */
+        byte[] data;
+
+        /**
+         * @param val Value.
+         * @param size Key payload size.
+         */
+        LargeDbKey(int val, int size) {
+            this.val = val;
+
+            data = new byte[size];
+
+            Arrays.fill(data, (byte)val);
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (o == null || !(o instanceof LargeDbKey))
+                return false;
+
+            LargeDbKey key = (LargeDbKey)o;
+
+            return val == key.val && Arrays.equals(data, key.data);
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            return val + Arrays.hashCode(data);
+        }
+    }
+
+    /**
+     *
+     */
+    static class DbValue implements Serializable {
+        /** */
+        @QuerySqlField(index = true)
+        int iVal;
+
+        /** */
+        @QuerySqlField(index = true)
+        String sVal;
+
+        /** */
+        @QuerySqlField
+        long lVal;
+
+        /**
+         * @param iVal Integer value.
+         * @param sVal String value.
+         * @param lVal Long value.
+         */
+        DbValue(int iVal, String sVal, long lVal) {
+            this.iVal = iVal;
+            this.sVal = sVal;
+            this.lVal = lVal;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(Object o) {
+            if (this == o)
+                return true;
+
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            DbValue dbVal = (DbValue)o;
+
+            return iVal == dbVal.iVal && lVal == dbVal.lVal &&
+                    !(sVal != null ? !sVal.equals(dbVal.sVal) : dbVal.sVal != null);
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            int res = iVal;
+
+            res = 31 * res + (sVal != null ? sVal.hashCode() : 0);
+            res = 31 * res + (int)(lVal ^ (lVal >>> 32));
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(DbValue.class, this);
+        }
+    }
+
+    /**
+     *
+     */
+    static class LargeDbValue {
+        /** */
+        @QuerySqlField(index = true)
+        String str1;
+
+        /** */
+        @QuerySqlField(index = true)
+        String str2;
+
+        /** */
+        int[] arr;
+
+        /**
+         * @param str1 String 1.
+         * @param str2 String 2.
+         * @param arr Big array.
+         */
+        LargeDbValue(final String str1, final String str2, final int[] arr) {
+            this.str1 = str1;
+            this.str2 = str2;
+            this.arr = arr;
+        }
+
+        /** {@inheritDoc} */
+        @Override public boolean equals(final Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final LargeDbValue that = (LargeDbValue) o;
+
+            if (str1 != null ? !str1.equals(that.str1) : that.str1 != null) return false;
+            if (str2 != null ? !str2.equals(that.str2) : that.str2 != null) return false;
+
+            return Arrays.equals(arr, that.arr);
+
+        }
+
+        /** {@inheritDoc} */
+        @Override public int hashCode() {
+            int res = str1 != null ? str1.hashCode() : 0;
+
+            res = 31 * res + (str2 != null ? str2.hashCode() : 0);
+            res = 31 * res + Arrays.hashCode(arr);
+
+            return res;
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(LargeDbValue.class, this);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakAbstractTest.java
new file mode 100644
index 0000000..2e9d3f9
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakAbstractTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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.database;
+
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.configuration.MemoryConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.cache.database.DataStructure;
+
+import static org.apache.ignite.IgniteSystemProperties.getInteger;
+
+/**
+ * Base class for memory leaks tests.
+ */
+public abstract class IgniteDbMemoryLeakAbstractTest extends IgniteDbAbstractTest {
+    /** */
+    private static final int CONCURRENCY_LEVEL = 8;
+
+    /** */
+    private static final int MIN_PAGE_CACHE_SIZE = 1048576 * CONCURRENCY_LEVEL;
+
+    /** */
+    private volatile Exception ex;
+
+    /** */
+    private long warmUpEndTime;
+
+    /** */
+    private long endTime;
+
+    /** */
+    private long loadedPages;
+
+    /** */
+    private long delta;
+
+    /** */
+    private long probeCnt;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        DataStructure.rnd = null;
+
+        long startTime = System.nanoTime();
+
+        warmUpEndTime = startTime + TimeUnit.SECONDS.toNanos(warmUp());
+
+        endTime = warmUpEndTime + TimeUnit.SECONDS.toNanos(duration());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void configure(IgniteConfiguration cfg) {
+        cfg.setMetricsLogFrequency(5000);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void configure(MemoryConfiguration mCfg) {
+        mCfg.setConcurrencyLevel(CONCURRENCY_LEVEL);
+
+        long size = (1024 * (isLargePage() ? 16 : 1) + 24) * pagesMax();
+
+        mCfg.setPageCacheSize(Math.max(size, MIN_PAGE_CACHE_SIZE));
+    }
+
+    /**
+     * @return Test duration in seconds.
+     */
+    protected int duration() {
+        return getInteger("IGNITE_MEMORY_LEAKS_TEST_DURATION", 300);
+    }
+
+    /**
+     * @return Warm up duration in seconds.
+     */
+    @SuppressWarnings("WeakerAccess")
+    protected int warmUp() {
+        return getInteger("IGNITE_MEMORY_LEAKS_TEST_WARM_UP", 450);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected int gridCount() {
+        return 1;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected boolean indexingEnabled() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long getTestTimeout() {
+        return (warmUp() + duration() + 10) * 1000; // Extra seconds to stop all threads.
+    }
+
+    /**
+     * @param ig Ignite instance.
+     * @return IgniteCache.
+     */
+    protected abstract IgniteCache<Object, Object> cache(IgniteEx ig);
+
+    /**
+     * @return Cache key to perform an operation.
+     */
+    protected abstract Object key();
+
+    /**
+     * @param key Cache key to perform an operation.
+     * @return Cache value to perform an operation.
+     */
+    protected abstract Object value(Object key);
+
+    /**
+     * @param cache IgniteCache.
+     */
+    protected void operation(IgniteCache<Object, Object> cache) {
+        Object key = key();
+        Object val = value(key);
+
+        switch (nextInt(3)) {
+            case 0:
+                cache.getAndPut(key, val);
+
+                break;
+
+            case 1:
+                cache.get(key);
+
+                break;
+
+            case 2:
+                cache.getAndRemove(key);
+        }
+    }
+
+    /**
+     * @param bound Upper bound (exclusive). Must be positive.
+     * @return Random int value.
+     */
+    protected static int nextInt(int bound) {
+        return ThreadLocalRandom.current().nextInt(bound);
+    }
+
+    /**
+     * @return Random int value.
+     */
+    protected static int nextInt() {
+        return ThreadLocalRandom.current().nextInt();
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testMemoryLeak() throws Exception {
+        final IgniteEx ignite = grid(0);
+
+        final IgniteCache<Object, Object> cache = cache(ignite);
+
+        Runnable target = new Runnable() {
+            @Override public void run() {
+                while (ex == null && System.nanoTime() < endTime) {
+                    try {
+                        operation(cache);
+                    }
+                    catch (Exception e) {
+                        ex = e;
+
+                        break;
+                    }
+                }
+            }
+        };
+
+        Thread[] threads = new Thread[CONCURRENCY_LEVEL];
+
+        info("Warming up is started.");
+
+        for (int i = 0; i < threads.length; i++) {
+            threads[i] = new Thread(target);
+            threads[i].start();
+        }
+
+        while (ex == null && System.nanoTime() < warmUpEndTime)
+            Thread.sleep(100);
+
+        if (ex != null)
+            throw ex;
+
+        info("Warming up is ended.");
+
+        while (ex == null && System.nanoTime() < endTime) {
+            try {
+                check(ignite);
+            }
+            catch (Exception e) {
+                ex = e;
+
+                break;
+            }
+
+            Thread.sleep(TimeUnit.SECONDS.toMillis(5));
+        }
+
+        if (ex != null)
+            throw ex;
+    }
+
+    /**
+     * Callback to check the current state.
+     *
+     * @param ig Ignite instance.
+     * @throws Exception If failed.
+     */
+    protected void check(IgniteEx ig) throws Exception {
+        long pagesActual = ig.context().cache().context().database().pageMemory().loadedPages();
+
+        if (loadedPages > 0) {
+            delta += pagesActual - loadedPages;
+
+            int allowedDelta = pagesDelta();
+
+            if (probeCnt++ > 12) { // We need some statistic first. Minimal statistic is taken for a minute.
+                long actualDelta = delta / probeCnt;
+
+                assertTrue(
+                    "Average growth pages in the number is more than expected [allowed=" + allowedDelta + ", actual=" + actualDelta + "]",
+                    actualDelta <= allowedDelta);
+            }
+        }
+
+        loadedPages = pagesActual;
+    }
+
+    /**
+     * @return Maximal allowed pages number.
+     */
+    protected abstract long pagesMax();
+
+    /**
+     * @return Expected average number of pages, on which their total number can grow per 5 seconds.
+     */
+    @SuppressWarnings("WeakerAccess")
+    protected int pagesDelta() {
+        return 3;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargeObjectsTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargeObjectsTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargeObjectsTest.java
new file mode 100644
index 0000000..077a1e1
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargeObjectsTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.database;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.internal.IgniteEx;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakLargeObjectsTest extends IgniteDbMemoryLeakAbstractTest {
+    /** */
+    private final static int[] ARRAY;
+
+    static {
+        ARRAY = new int[1024];
+
+        for (int i = 0; i < ARRAY.length; i++)
+            ARRAY[i] = nextInt();
+    }
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Object, Object> cache(IgniteEx ig) {
+        return ig.cache("large");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Object key() {
+        return new LargeDbKey(nextInt(10_000), 1024);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Object value(Object key) {
+        return new LargeDbValue("test-value-1-" + nextInt(200), "test-value-2-" + nextInt(200), ARRAY);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long pagesMax() {
+        return 35_000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargePagesTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargePagesTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargePagesTest.java
new file mode 100644
index 0000000..540681d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakLargePagesTest.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.processors.database;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakLargePagesTest extends IgniteDbMemoryLeakTest {
+    /** {@inheritDoc} */
+    @Override protected boolean isLargePage() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long pagesMax() {
+        return 4000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakNonTransactionalTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakNonTransactionalTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakNonTransactionalTest.java
new file mode 100644
index 0000000..2a6293d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakNonTransactionalTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.database;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.internal.IgniteEx;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakNonTransactionalTest extends IgniteDbMemoryLeakTest {
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Object, Object> cache(IgniteEx ig) {
+        return ig.cache("atomic");
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakTest.java
new file mode 100644
index 0000000..b8ac8f0
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.database;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.internal.IgniteEx;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakTest extends IgniteDbMemoryLeakAbstractTest {
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Object, Object> cache(IgniteEx ig) {
+        return ig.cache("non-primitive");
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Object key() {
+        return new DbKey(nextInt(200_000));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected Object value(Object key) {
+        return new DbValue(((DbKey)key).val, "test-value-" + nextInt(200), nextInt(500));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long pagesMax() {
+        return 20_000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakWithExpirationTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakWithExpirationTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakWithExpirationTest.java
new file mode 100644
index 0000000..6e0abaf
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakWithExpirationTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.database;
+
+import javax.cache.expiry.CreatedExpiryPolicy;
+import javax.cache.expiry.Duration;
+import javax.cache.expiry.ExpiryPolicy;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.internal.IgniteEx;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakWithExpirationTest extends IgniteDbMemoryLeakTest {
+    /** */
+    private static final ExpiryPolicy EXPIRY = new CreatedExpiryPolicy(new Duration(MILLISECONDS, 10L));
+
+    /** {@inheritDoc} */
+    @Override protected IgniteCache<Object, Object> cache(IgniteEx ig) {
+        return ig.cache("non-primitive").withExpiryPolicy(EXPIRY);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long pagesMax() {
+        return 7000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
index 2c37d8a..86f1237 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java
@@ -17,8 +17,6 @@
 
 package org.apache.ignite.internal.processors.database;
 
-import java.io.Serializable;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
@@ -32,13 +30,8 @@ import javax.cache.Cache;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteDataStreamer;
-import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CachePeekMode;
-import org.apache.ignite.cache.CacheRebalanceMode;
-import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cache.affinity.Affinity;
-import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
-import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.query.QueryCursor;
 import org.apache.ignite.cache.query.ScanQuery;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
@@ -55,22 +48,13 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCach
 import org.apache.ignite.internal.util.GridRandom;
 import org.apache.ignite.internal.util.typedef.PA;
 import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.internal.util.typedef.internal.S;
-import org.apache.ignite.internal.util.typedef.internal.U;
-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.junit.Assert;
 
 /**
  *
  */
-public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest {
-    /** */
-    private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true);
-
+public abstract class IgniteDbPutGetAbstractTest extends IgniteDbAbstractTest {
     /** */
     private static final int KEYS_COUNT = 20_000;
 
@@ -91,121 +75,6 @@ public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest
         return false;
     }
 
-    /** */
-    private boolean client = false;
-
-    /** {@inheritDoc} */
-    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
-        IgniteConfiguration cfg = super.getConfiguration(gridName);
-
-        MemoryConfiguration dbCfg = new MemoryConfiguration();
-
-        if (client)
-            cfg.setClientMode(true);
-
-        if (isLargePage()) {
-            dbCfg.setConcurrencyLevel(Runtime.getRuntime().availableProcessors() * 4);
-
-            dbCfg.setPageSize(16 * 1024);
-
-            dbCfg.setPageCacheSize(200 * 1024 * 1024);
-        }
-        else {
-            dbCfg.setConcurrencyLevel(Runtime.getRuntime().availableProcessors() * 4);
-
-            dbCfg.setPageSize(1024);
-
-            dbCfg.setPageCacheSize(200 * 1024 * 1024);
-        }
-
-        cfg.setMemoryConfiguration(dbCfg);
-
-        CacheConfiguration ccfg = new CacheConfiguration();
-
-        if (indexingEnabled())
-            ccfg.setIndexedTypes(Integer.class, DbValue.class);
-
-        ccfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        ccfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
-        ccfg.setRebalanceMode(CacheRebalanceMode.SYNC);
-        ccfg.setAffinity(new RendezvousAffinityFunction(false, 32));
-
-        CacheConfiguration ccfg2 = new CacheConfiguration("non-primitive");
-
-        if (indexingEnabled())
-            ccfg2.setIndexedTypes(DbKey.class, DbValue.class);
-
-        ccfg2.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        ccfg2.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
-        ccfg2.setRebalanceMode(CacheRebalanceMode.SYNC);
-        ccfg2.setAffinity(new RendezvousAffinityFunction(false, 32));
-
-        CacheConfiguration ccfg3 = new CacheConfiguration("large");
-
-        if (indexingEnabled())
-            ccfg3.setIndexedTypes(Integer.class, LargeDbValue.class);
-
-        ccfg3.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        ccfg3.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
-        ccfg3.setRebalanceMode(CacheRebalanceMode.SYNC);
-        ccfg3.setAffinity(new RendezvousAffinityFunction(false, 32));
-
-        CacheConfiguration ccfg4 = new CacheConfiguration("tiny");
-
-        ccfg4.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        ccfg4.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
-        ccfg4.setRebalanceMode(CacheRebalanceMode.SYNC);
-        ccfg4.setAffinity(new RendezvousAffinityFunction(false, 32));
-
-        final AffinityFunction aff = new RendezvousAffinityFunction(1, null);
-
-        ccfg4.setAffinity(aff);
-
-        if (!client)
-            cfg.setCacheConfiguration(ccfg, ccfg2, ccfg3, ccfg4);
-
-        TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
-
-        discoSpi.setIpFinder(IP_FINDER);
-
-        cfg.setDiscoverySpi(discoSpi);
-        cfg.setMarshaller(null);
-
-        return cfg;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void beforeTest() throws Exception {
-        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
-
-        long seed = System.currentTimeMillis();
-
-        info("Seed: " + seed + "L");
-
-        BPlusTree.rnd = new Random(seed);
-
-        startGrids(gridCount());
-
-        if (withClientNearCache()) {
-            client = true;
-
-            startGrid(gridCount());
-
-            client = false;
-        }
-
-        awaitPartitionMapExchange();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void afterTest() throws Exception {
-        BPlusTree.rnd = null;
-
-        stopAllGrids();
-
-        deleteRecursively(U.resolveWorkDirectory(U.defaultWorkDirectory(), "db", false));
-    }
-
     /**
      * @return Ignite instance for testing.
      */
@@ -243,9 +112,7 @@ public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest
 
         final int cnt = KEYS_COUNT;
 
-        Random rnd = BPlusTree.rnd;
-
-        assert rnd != null;
+        Random rnd = new Random();
 
         Map<Integer, DbValue> map = new HashMap<>();
 
@@ -1369,195 +1236,4 @@ public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest
 
         assertNull(internalCache.peekEx(key));
     }
-
-    /**
-     *
-     */
-    private static class DbKey implements Serializable {
-        /** */
-        private int val;
-
-        /**
-         * @param val Value.
-         */
-        private DbKey(int val) {
-            this.val = val;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean equals(Object o) {
-            if (this == o)
-                return true;
-
-            if (o == null || !(o instanceof DbKey))
-                return false;
-
-            DbKey key = (DbKey)o;
-
-            return val == key.val;
-        }
-
-        /** {@inheritDoc} */
-        @Override public int hashCode() {
-            return val;
-        }
-    }
-
-    /**
-     *
-     */
-    private static class LargeDbKey implements Serializable {
-        /** */
-        private int val;
-
-        /** */
-        private byte[] data;
-
-        /**
-         * @param val Value.
-         * @param size Key payload size.
-         */
-        private LargeDbKey(int val, int size) {
-            this.val = val;
-
-            data = new byte[size];
-
-            Arrays.fill(data, (byte)val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean equals(Object o) {
-            if (this == o)
-                return true;
-
-            if (o == null || !(o instanceof LargeDbKey))
-                return false;
-
-            LargeDbKey key = (LargeDbKey)o;
-
-            return val == key.val && Arrays.equals(data, key.data);
-        }
-
-        /** {@inheritDoc} */
-        @Override public int hashCode() {
-            return val + Arrays.hashCode(data);
-        }
-    }
-
-    /**
-     *
-     */
-    private static class DbValue implements Serializable {
-        /** */
-        @QuerySqlField(index = true)
-        private int iVal;
-
-        /** */
-        @QuerySqlField(index = true)
-        private String sVal;
-
-        /** */
-        @QuerySqlField
-        private long lVal;
-
-        /**
-         * @param iVal Integer value.
-         * @param sVal String value.
-         * @param lVal Long value.
-         */
-        public DbValue(int iVal, String sVal, long lVal) {
-            this.iVal = iVal;
-            this.sVal = sVal;
-            this.lVal = lVal;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean equals(Object o) {
-            if (this == o)
-                return true;
-
-            if (o == null || getClass() != o.getClass())
-                return false;
-
-            DbValue dbVal = (DbValue)o;
-
-            return iVal == dbVal.iVal && lVal == dbVal.lVal &&
-                !(sVal != null ? !sVal.equals(dbVal.sVal) : dbVal.sVal != null);
-        }
-
-        /** {@inheritDoc} */
-        @Override public int hashCode() {
-            int res = iVal;
-
-            res = 31 * res + (sVal != null ? sVal.hashCode() : 0);
-            res = 31 * res + (int)(lVal ^ (lVal >>> 32));
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(DbValue.class, this);
-        }
-    }
-
-    /**
-     *
-     */
-    private static class LargeDbValue {
-        /** */
-        @QuerySqlField(index = true)
-        private String str1;
-
-        /** */
-        @QuerySqlField(index = true)
-        private String str2;
-
-        /** */
-        private int[] arr;
-
-        /**
-         * @param str1 String 1.
-         * @param str2 String 2.
-         * @param arr Big array.
-         */
-        public LargeDbValue(final String str1, final String str2, final int[] arr) {
-            this.str1 = str1;
-            this.str2 = str2;
-            this.arr = arr;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean equals(final Object o) {
-            if (this == o)
-                return true;
-            if (o == null || getClass() != o.getClass())
-                return false;
-
-            final LargeDbValue that = (LargeDbValue)o;
-
-            if (str1 != null ? !str1.equals(that.str1) : that.str1 != null)
-                return false;
-            if (str2 != null ? !str2.equals(that.str2) : that.str2 != null)
-                return false;
-
-            return Arrays.equals(arr, that.arr);
-
-        }
-
-        /** {@inheritDoc} */
-        @Override public int hashCode() {
-            int res = str1 != null ? str1.hashCode() : 0;
-
-            res = 31 * res + (str2 != null ? str2.hashCode() : 0);
-            res = 31 * res + Arrays.hashCode(arr);
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(LargeDbValue.class, this);
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakTestSuite.java
new file mode 100644
index 0000000..f271bd8
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakTestSuite.java
@@ -0,0 +1,49 @@
+/*
+ * 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.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.cache.LargeEntryUpdateTest;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakLargeObjectsTest;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakLargePagesTest;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakNonTransactionalTest;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakTest;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakWithExpirationTest;
+
+/**
+ * Page memory leaks tests.
+ */
+public class IgniteDbMemoryLeakTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("Ignite Db Memory Leaks Test Suite");
+
+        suite.addTestSuite(IgniteDbMemoryLeakTest.class);
+        suite.addTestSuite(IgniteDbMemoryLeakWithExpirationTest.class);
+        suite.addTestSuite(IgniteDbMemoryLeakLargePagesTest.class);
+        suite.addTestSuite(IgniteDbMemoryLeakLargeObjectsTest.class);
+        suite.addTestSuite(IgniteDbMemoryLeakNonTransactionalTest.class);
+
+        suite.addTestSuite(LargeEntryUpdateTest.class);
+
+        return suite;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakIndexedTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakIndexedTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakIndexedTest.java
new file mode 100644
index 0000000..f6a06c9
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakIndexedTest.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.processors.database;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakIndexedTest extends IgniteDbMemoryLeakTest {
+    /** {@inheritDoc} */
+    @Override protected boolean indexingEnabled() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long pagesMax() {
+        return 24_000;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakSqlQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakSqlQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakSqlQueryTest.java
new file mode 100644
index 0000000..57f9fb5
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbMemoryLeakSqlQueryTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.database;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ *
+ */
+public class IgniteDbMemoryLeakSqlQueryTest extends IgniteDbMemoryLeakTest {
+    /** {@inheritDoc} */
+    @Override protected boolean indexingEnabled() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected long pagesMax() {
+        return 24_000;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void operation(IgniteCache<Object, Object> cache) {
+        Object key = key();
+        Object val = value(key);
+
+        switch (nextInt(4)) {
+            case 0:
+                cache.getAndPut(key, val);
+
+                break;
+
+            case 1:
+                cache.get(key);
+
+                break;
+
+            case 2:
+                cache.getAndRemove(key);
+
+                break;
+
+            case 3:
+                cache.query(sqlQuery(cache)).getAll();
+        }
+    }
+
+    /**
+     * @param cache IgniteCache.
+     * @return SqlFieldsQuery.
+     */
+    @NotNull private SqlFieldsQuery sqlQuery(IgniteCache<Object, Object> cache) {
+        String qry = String.format("select _key from \"%s\".DbValue where iVal=?", cache.getName());
+
+        SqlFieldsQuery sqlQry = new SqlFieldsQuery(qry);
+        sqlQry.setArgs(nextInt(200_000));
+
+        return sqlQry;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3b86e29a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakWithIndexingTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakWithIndexingTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakWithIndexingTestSuite.java
new file mode 100644
index 0000000..36cd101
--- /dev/null
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteDbMemoryLeakWithIndexingTestSuite.java
@@ -0,0 +1,40 @@
+/*
+ * 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.testsuites;
+
+import junit.framework.TestSuite;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakIndexedTest;
+import org.apache.ignite.internal.processors.database.IgniteDbMemoryLeakSqlQueryTest;
+
+/**
+ * Page memory leaks tests using indexing.
+ */
+public class IgniteDbMemoryLeakWithIndexingTestSuite extends TestSuite {
+    /**
+     * @return Test suite.
+     * @throws Exception Thrown in case of the failure.
+     */
+    public static TestSuite suite() throws Exception {
+        TestSuite suite = new TestSuite("Ignite Db Memory Leaks With Indexing Test Suite");
+
+        suite.addTestSuite(IgniteDbMemoryLeakSqlQueryTest.class);
+        suite.addTestSuite(IgniteDbMemoryLeakIndexedTest.class);
+
+        return suite;
+    }
+}


[02/50] [abbrv] ignite git commit: GG-11860 Implement snapshot status on platform level -refactoring: extracting snapshot operation

Posted by sb...@apache.org.
GG-11860 Implement snapshot status on platform level
-refactoring: extracting snapshot operation


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 92821167ad884266728a2fae83799d1dfa17e07d
Parents: 63e6a21
Author: EdShangGG <es...@gridgain.com>
Authored: Wed Feb 15 21:11:30 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Wed Feb 15 21:11:30 2017 +0300

----------------------------------------------------------------------
 .../pagemem/snapshot/SnapshotOperation.java     | 100 +++++++++++++++++++
 .../pagemem/snapshot/SnapshotOperationType.java |  30 ++++++
 .../StartFullSnapshotAckDiscoveryMessage.java   |  64 ++----------
 .../StartFullSnapshotDiscoveryMessage.java      |  70 ++++---------
 4 files changed, 157 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/92821167/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
new file mode 100644
index 0000000..8163049
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperation.java
@@ -0,0 +1,100 @@
+/*
+ * 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.pagemem.snapshot;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Description and parameters of snapshot operation
+ */
+public class SnapshotOperation implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** */
+    private final SnapshotOperationType type;
+
+    /**
+     * Snapshot ID (the timestamp of snapshot creation).
+     */
+    private final long snapshotId;
+
+    /** */
+    private final Set<String> cacheNames;
+
+    /** Message. */
+    private final String msg;
+
+    /** Additional parameter. */
+    private final Object extraParam;
+
+    /**
+     * @param type Type.
+     * @param snapshotId Snapshot id.
+     * @param cacheNames Cache names.
+     * @param msg
+     * @param extraParam Additional parameter.
+     */
+    public SnapshotOperation(SnapshotOperationType type, long snapshotId, Set<String> cacheNames, String msg, Object extraParam) {
+        this.type = type;
+        this.snapshotId = snapshotId;
+        this.cacheNames = cacheNames;
+        this.msg = msg;
+        this.extraParam = extraParam;
+    }
+
+    /**
+     *
+     */
+    public SnapshotOperationType type() {
+        return type;
+    }
+
+    /**
+     * Snapshot ID (the timestamp of snapshot creation).
+     *
+     * @return Snapshot ID.
+     */
+    public long id() {
+        return snapshotId;
+    }
+
+    /**
+     * Cache names included to this snapshot.
+     *
+     * @return Cache names.
+     */
+    public Set<String> cacheNames() {
+        return cacheNames;
+    }
+
+    /**
+     * Additional info which was provided by client
+     */
+    public String message() {
+        return msg;
+    }
+
+    /**
+     *
+     */
+    public Object extraParameter() {
+        return extraParam;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/92821167/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
new file mode 100644
index 0000000..8866bdb
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/SnapshotOperationType.java
@@ -0,0 +1,30 @@
+/*
+ * 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.pagemem.snapshot;
+
+/** */
+public enum SnapshotOperationType {
+    /** Create. */
+    CREATE,
+    /** Restore. */
+    RESTORE,
+    /** Move. */
+    MOVE,
+    /** Delete. */
+    DELETE
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/92821167/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
index 08082de..32a3dae 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotAckDiscoveryMessage.java
@@ -35,27 +35,18 @@ public class StartFullSnapshotAckDiscoveryMessage implements DiscoveryCustomMess
     /** */
     private static final long serialVersionUID = 0L;
 
-    /** Message. */
-    private final String msg;
+
+    private SnapshotOperation snapshotOperation;
 
     /** Custom message ID. */
     private IgniteUuid id = IgniteUuid.randomUuid();
 
     /** */
-    private long globalSnapshotId;
-
-    /** */
     private Exception err;
 
     /** */
-    private Collection<String> cacheNames;
-
-    /** */
     private UUID initiatorNodeId;
 
-    /** Full snapshot. */
-    private boolean fullSnapshot;
-
     /** Last full snapshot id for cache. */
     private Map<Integer, Long> lastFullSnapshotIdForCache;
 
@@ -63,43 +54,21 @@ public class StartFullSnapshotAckDiscoveryMessage implements DiscoveryCustomMess
     private Map<Integer, Long> lastSnapshotIdForCache;
 
     /**
-     * @param globalSnapshotId Snapshot ID.
+     * @param snapshotOperation Snapshot Operation.
      * @param err Error.
-     * @param cacheNames Cache names.
      */
     public StartFullSnapshotAckDiscoveryMessage(
-        long globalSnapshotId,
-        boolean fullSnapshot,
+        SnapshotOperation snapshotOperation,
         Map<Integer, Long> lastFullSnapshotIdForCache,
         Map<Integer, Long> lastSnapshotIdForCache,
-        Collection<String> cacheNames,
         Exception err,
-        UUID initiatorNodeId,
-        String msg
+        UUID initiatorNodeId
     ) {
-        this.globalSnapshotId = globalSnapshotId;
-        this.fullSnapshot = fullSnapshot;
+        this.snapshotOperation = snapshotOperation;
         this.lastFullSnapshotIdForCache = lastFullSnapshotIdForCache;
         this.lastSnapshotIdForCache = lastSnapshotIdForCache;
         this.err = err;
-        this.cacheNames = cacheNames;
         this.initiatorNodeId = initiatorNodeId;
-        this.msg = msg;
-
-        for (String cacheName : cacheNames) {
-            int i = CU.cacheId(cacheName);
-
-            if (lastFullSnapshotIdForCache.get(i) == null || lastSnapshotIdForCache.get(i) == null) {
-                throw new AssertionError();
-            }
-        }
-    }
-
-    /**
-     * @return Cache names.
-     */
-    public Collection<String> cacheNames() {
-        return cacheNames;
     }
 
     /** {@inheritDoc} */
@@ -128,25 +97,8 @@ public class StartFullSnapshotAckDiscoveryMessage implements DiscoveryCustomMess
         return err != null;
     }
 
-    /**
-     * @return Snapshot ID.
-     */
-    public long globalSnapshotId() {
-        return globalSnapshotId;
-    }
-
-    /**
-     *
-     */
-    public boolean fullSnapshot() {
-        return fullSnapshot;
-    }
-
-    /**
-     *
-     */
-    public String message() {
-        return msg;
+    public SnapshotOperation snapshotOperation() {
+        return snapshotOperation;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/92821167/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
index bd6d97f..2a977f4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/snapshot/StartFullSnapshotDiscoveryMessage.java
@@ -35,17 +35,11 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
     /** */
     private static final long serialVersionUID = 0L;
 
-    /** Message. */
-    private final String msg;
-
     /** Custom message ID. */
     private IgniteUuid id = IgniteUuid.randomUuid();
 
-    /** Snapshot ID. */
-    private long globalSnapshotId;
-
-    /** */
-    private Collection<String> cacheNames;
+    /** Snapshot operation. */
+    private SnapshotOperation snapshotOperation;
 
     /** */
     private UUID initiatorId;
@@ -53,9 +47,6 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
     /** Error. */
     private Exception err;
 
-    /** Full snapshot. */
-    private boolean fullSnapshot;
-
     /** Last full snapshot id for cache. */
     private Map<Integer, Long> lastFullSnapshotIdForCache = new HashMap<>();
 
@@ -63,21 +54,22 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
     private Map<Integer, Long> lastSnapshotIdForCache = new HashMap<>();
 
     /**
-     * @param cacheNames Cache names.
-     * @param msg message to log
+     * @param snapshotOperation Snapshot operation
+     * @param initiatorId initiator node id
      */
     public StartFullSnapshotDiscoveryMessage(
-        long globalSnapshotId,
-        Collection<String> cacheNames,
-        UUID initiatorId,
-        boolean fullSnapshot,
-        String msg
+        SnapshotOperation snapshotOperation,
+        UUID initiatorId
     ) {
-        this.globalSnapshotId = globalSnapshotId;
-        this.cacheNames = cacheNames;
+        this.snapshotOperation = snapshotOperation;
         this.initiatorId = initiatorId;
-        this.fullSnapshot = fullSnapshot;
-        this.msg = msg;
+    }
+
+    /**
+     *
+     */
+    public SnapshotOperation snapshotOperation() {
+        return snapshotOperation;
     }
 
     /**
@@ -116,27 +108,6 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
     }
 
     /**
-     * @return Backup ID.
-     */
-    public long globalSnapshotId() {
-        return globalSnapshotId;
-    }
-
-    /**
-     * @return Cache names.
-     */
-    public Collection<String> cacheNames() {
-        return cacheNames;
-    }
-
-    /**
-     *
-     */
-    public boolean fullSnapshot() {
-        return fullSnapshot;
-    }
-
-    /**
      * @param cacheId Cache id.
      */
     public Long lastFullSnapshotId(int cacheId) {
@@ -169,14 +140,11 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
     /** {@inheritDoc} */
     @Nullable @Override public DiscoveryCustomMessage ackMessage() {
         return new StartFullSnapshotAckDiscoveryMessage(
-            globalSnapshotId,
-            fullSnapshot,
+            snapshotOperation,
             lastFullSnapshotIdForCache,
             lastSnapshotIdForCache,
-            cacheNames,
             err,
-            initiatorId,
-            msg);
+            initiatorId);
     }
 
     /** {@inheritDoc} */
@@ -185,10 +153,10 @@ public class StartFullSnapshotDiscoveryMessage implements DiscoveryCustomMessage
     }
 
     /**
-     * @param full full snapshot.
+     * @param snapshotOperation new snapshot operation
      */
-    public void fullSnapshot(boolean full) {
-        fullSnapshot = full;
+    public void snapshotOperation(SnapshotOperation snapshotOperation) {
+        this.snapshotOperation = snapshotOperation;
     }
 
     /** {@inheritDoc} */


[32/50] [abbrv] ignite git commit: IGNITE-3477 - Rebuilt classnames.properties

Posted by sb...@apache.org.
IGNITE-3477 - Rebuilt classnames.properties


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 719fb5a914bdcfa42e0db4aa208fa7fd57cca9fc
Parents: 937a141
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Mar 23 16:07:33 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Mar 23 16:07:33 2017 +0300

----------------------------------------------------------------------
 .../resources/META-INF/classnames.properties    | 27 ++++++++++++--------
 1 file changed, 16 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/719fb5a9/modules/core/src/main/resources/META-INF/classnames.properties
----------------------------------------------------------------------
diff --git a/modules/core/src/main/resources/META-INF/classnames.properties b/modules/core/src/main/resources/META-INF/classnames.properties
index 1750276..7dd1929 100644
--- a/modules/core/src/main/resources/META-INF/classnames.properties
+++ b/modules/core/src/main/resources/META-INF/classnames.properties
@@ -16,6 +16,7 @@
 #
 
 org.apache.ignite.IgniteAuthenticationException
+org.apache.ignite.IgniteCacheRestartingException
 org.apache.ignite.IgniteCheckedException
 org.apache.ignite.IgniteClientDisconnectedException
 org.apache.ignite.IgniteDataStreamerTimeoutException
@@ -162,6 +163,8 @@ org.apache.ignite.events.IgfsEvent
 org.apache.ignite.events.JobEvent
 org.apache.ignite.events.SwapSpaceEvent
 org.apache.ignite.events.TaskEvent
+org.apache.ignite.hadoop.HadoopInputSplit
+org.apache.ignite.hadoop.HadoopMapReducePlan
 org.apache.ignite.igfs.IgfsConcurrentModificationException
 org.apache.ignite.igfs.IgfsCorruptedFileException
 org.apache.ignite.igfs.IgfsDirectoryNotEmptyException
@@ -312,13 +315,13 @@ org.apache.ignite.internal.managers.deployment.GridDeploymentPerVersionStore$2
 org.apache.ignite.internal.managers.deployment.GridDeploymentRequest
 org.apache.ignite.internal.managers.deployment.GridDeploymentResponse
 org.apache.ignite.internal.managers.discovery.CustomMessageWrapper
+org.apache.ignite.internal.managers.discovery.DiscoCache$1
+org.apache.ignite.internal.managers.discovery.DiscoCache$2
 org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$1
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$2
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$4$1
-org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$4$2
 org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$6
-org.apache.ignite.internal.managers.discovery.GridDiscoveryManager$DiscoCache$1
 org.apache.ignite.internal.managers.discovery.GridLocalMetrics
 org.apache.ignite.internal.managers.eventstorage.GridEventStorageMessage
 org.apache.ignite.internal.managers.indexing.GridIndexingManager$1
@@ -326,8 +329,8 @@ org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerAdapter
 org.apache.ignite.internal.managers.loadbalancer.GridLoadBalancerManager$1
 org.apache.ignite.internal.mem.OutOfMemoryException
 org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl$Segment
-org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationFinishedMessage
-org.apache.ignite.internal.pagemem.snapshot.SnapshotProgressMessage
+org.apache.ignite.internal.pagemem.snapshot.SnapshotOperation
+org.apache.ignite.internal.pagemem.snapshot.SnapshotOperationType
 org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage
 org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationDiscoveryMessage
 org.apache.ignite.internal.pagemem.wal.StorageException
@@ -381,6 +384,7 @@ org.apache.ignite.internal.processors.cache.CacheObjectImpl
 org.apache.ignite.internal.processors.cache.CacheOperationContext
 org.apache.ignite.internal.processors.cache.CacheOperationFilter
 org.apache.ignite.internal.processors.cache.CachePartialUpdateCheckedException
+org.apache.ignite.internal.processors.cache.CacheStoppedException
 org.apache.ignite.internal.processors.cache.CacheStorePartialUpdateException
 org.apache.ignite.internal.processors.cache.CacheType
 org.apache.ignite.internal.processors.cache.CacheWeakQueryIteratorsHolder$WeakQueryCloseableIterator
@@ -503,6 +507,7 @@ org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$4
 org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$5
 org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$6
 org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$7
+org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$8
 org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeFutureSet
 org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$MessageHandler
 org.apache.ignite.internal.processors.cache.GridCacheProcessor$2
@@ -553,6 +558,7 @@ org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl$8
 org.apache.ignite.internal.processors.cache.IgniteCacheProxy
 org.apache.ignite.internal.processors.cache.IgniteCacheProxy$1
 org.apache.ignite.internal.processors.cache.IgniteCacheProxy$10
+org.apache.ignite.internal.processors.cache.IgniteCacheProxy$12
 org.apache.ignite.internal.processors.cache.IgniteCacheProxy$2
 org.apache.ignite.internal.processors.cache.IgniteCacheProxy$2$1
 org.apache.ignite.internal.processors.cache.IgniteCacheProxy$3
@@ -571,6 +577,7 @@ org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImp
 org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl$MetaDataEntryFilter
 org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl$MetaDataPredicate
 org.apache.ignite.internal.processors.cache.binary.CacheObjectBinaryProcessorImpl$MetadataProcessor
+org.apache.ignite.internal.processors.cache.database.CacheDataRowAdapter$RowData
 org.apache.ignite.internal.processors.cache.database.tree.BPlusTree$Bool
 org.apache.ignite.internal.processors.cache.database.tree.BPlusTree$DestroyBag
 org.apache.ignite.internal.processors.cache.database.tree.BPlusTree$Result
@@ -621,7 +628,6 @@ org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFutu
 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture$2
 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtGetSingleFuture$3
 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException
-org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition$2
 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockFuture$1
 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockFuture$2
 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLockFuture$3
@@ -740,7 +746,6 @@ org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPar
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$1$1
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$2
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$3
-org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$3$1
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$4$1
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$5$1
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander$DemandWorker$1
@@ -770,6 +775,9 @@ org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPre
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader$8
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader$MessageHandler
 org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloaderAssignments
+org.apache.ignite.internal.processors.cache.distributed.dht.preloader.IgniteDhtPartitionCountersMap
+org.apache.ignite.internal.processors.cache.distributed.dht.preloader.IgniteDhtPartitionHistorySuppliersMap
+org.apache.ignite.internal.processors.cache.distributed.dht.preloader.IgniteDhtPartitionsToReloadMap
 org.apache.ignite.internal.processors.cache.distributed.near.CacheVersionedValue
 org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache
 org.apache.ignite.internal.processors.cache.distributed.near.GridNearAtomicCache$1
@@ -1044,7 +1052,6 @@ org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl$Buffer$1
 org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl$Buffer$2
 org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl$Buffer$3
 org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl$DataStreamerPda
-org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl$DefaultIoPolicyResolver
 org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl$IsolatedUpdater
 org.apache.ignite.internal.processors.datastreamer.DataStreamerRequest
 org.apache.ignite.internal.processors.datastreamer.DataStreamerResponse
@@ -1121,13 +1128,10 @@ org.apache.ignite.internal.processors.dr.GridDrType
 org.apache.ignite.internal.processors.dr.IgniteDrDataStreamerCacheUpdater
 org.apache.ignite.internal.processors.hadoop.HadoopDefaultJobInfo
 org.apache.ignite.internal.processors.hadoop.HadoopFileBlock
-org.apache.ignite.hadoop.HadoopInputSplit
 org.apache.ignite.internal.processors.hadoop.HadoopJobId
-org.apache.ignite.internal.processors.hadoop.HadoopJobInfo
 org.apache.ignite.internal.processors.hadoop.HadoopJobPhase
 org.apache.ignite.internal.processors.hadoop.HadoopJobProperty
 org.apache.ignite.internal.processors.hadoop.HadoopJobStatus
-org.apache.ignite.hadoop.HadoopMapReducePlan
 org.apache.ignite.internal.processors.hadoop.HadoopTaskInfo
 org.apache.ignite.internal.processors.hadoop.HadoopTaskType
 org.apache.ignite.internal.processors.hadoop.message.HadoopMessage
@@ -1288,12 +1292,12 @@ org.apache.ignite.internal.processors.platform.websession.PlatformDotNetSessionL
 org.apache.ignite.internal.processors.platform.websession.PlatformDotNetSessionSetAndUnlockProcessor
 org.apache.ignite.internal.processors.query.GridQueryFieldMetadata
 org.apache.ignite.internal.processors.query.GridQueryIndexType
-org.apache.ignite.internal.processors.query.GridQueryProcessor$3
 org.apache.ignite.internal.processors.query.GridQueryProcessor$4
 org.apache.ignite.internal.processors.query.GridQueryProcessor$5
 org.apache.ignite.internal.processors.query.GridQueryProcessor$6
 org.apache.ignite.internal.processors.query.GridQueryProcessor$7
 org.apache.ignite.internal.processors.query.GridQueryProcessor$8
+org.apache.ignite.internal.processors.query.GridQueryProcessor$9
 org.apache.ignite.internal.processors.query.GridQueryProcessor$IndexType
 org.apache.ignite.internal.processors.query.IgniteSQLException
 org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryCancelRequest
@@ -1632,6 +1636,7 @@ org.apache.ignite.internal.util.nio.GridNioException
 org.apache.ignite.internal.util.nio.GridNioMessageTracker
 org.apache.ignite.internal.util.nio.GridNioServer$NioOperation
 org.apache.ignite.internal.util.nio.GridNioServer$RandomBalancer
+org.apache.ignite.internal.util.nio.GridNioServer$ReadWriteSizeBasedBalancer
 org.apache.ignite.internal.util.nio.GridNioServer$SizeBasedBalancer
 org.apache.ignite.internal.util.nio.GridNioSessionMetaKey
 org.apache.ignite.internal.util.nio.ssl.GridNioSslHandler


[37/50] [abbrv] ignite git commit: GG-12081 ConcurrentModificationException in GridDhtPartitionsExchangeFuture

Posted by sb...@apache.org.
GG-12081 ConcurrentModificationException in GridDhtPartitionsExchangeFuture


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 3a7e80164dc6a15f99979063ff214153a637a2f4
Parents: 565602f
Author: EdShangGG <es...@gridgain.com>
Authored: Wed Mar 29 20:41:50 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Wed Mar 29 20:41:50 2017 +0300

----------------------------------------------------------------------
 .../processors/cache/transactions/IgniteTxStateImpl.java         | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3a7e8016/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
index 42aba77..3f3544d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
@@ -56,7 +56,7 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
     private GridLongList activeCacheIds = new GridLongList();
 
     /** Per-transaction read map. */
-    @GridToStringInclude
+    @GridToStringExclude
     protected Map<IgniteTxKey, IgniteTxEntry> txMap;
 
     /** Read view on transaction map. */
@@ -475,6 +475,6 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
 
     /** {@inheritDoc} */
     public String toString() {
-        return S.toString(IgniteTxStateImpl.class, this);
+        return S.toString(IgniteTxStateImpl.class, this, "txMap", allEntriesCopy());
     }
 }


[41/50] [abbrv] ignite git commit: Merge branch 'ignite-gg-11894-postfix' into ignite-gg-8.0.3.ea4

Posted by sb...@apache.org.
Merge branch 'ignite-gg-11894-postfix' into ignite-gg-8.0.3.ea4


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 0f5cadfbe81bdf5d6f8c84accb9b452aa6450b4b
Parents: 3a7e801 9d71e31
Author: Ivan Rakov <iv...@gmail.com>
Authored: Wed Apr 5 16:53:54 2017 +0300
Committer: Ivan Rakov <iv...@gmail.com>
Committed: Wed Apr 5 16:53:54 2017 +0300

----------------------------------------------------------------------
 .../ignite/internal/processors/cache/GridCacheAdapter.java  | 9 +++++++--
 .../ignite/internal/processors/cache/GridCacheGateway.java  | 4 ++--
 .../dht/atomic/GridNearAtomicUpdateResponse.java            | 2 +-
 3 files changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------



[33/50] [abbrv] ignite git commit: GG-12061 Corrupted snapshot causes CHECK to quietly fail with assertion

Posted by sb...@apache.org.
GG-12061 Corrupted snapshot causes CHECK to quietly fail with assertion


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 6eec695f5d1223c73f336f05641e2de7004fc5fa
Parents: 2d3d5eb
Author: EdShangGG <es...@gridgain.com>
Authored: Thu Mar 23 22:25:00 2017 +0300
Committer: EdShangGG <es...@gridgain.com>
Committed: Thu Mar 23 22:25:00 2017 +0300

----------------------------------------------------------------------
 .../delta/MetaPageUpdateLastAllocatedIndex.java |  2 +-
 .../cache/database/tree/io/PageMetaIO.java      | 34 ++++++++++----------
 2 files changed, 18 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/6eec695f/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdateLastAllocatedIndex.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdateLastAllocatedIndex.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdateLastAllocatedIndex.java
index bd9b100..d916be2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdateLastAllocatedIndex.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdateLastAllocatedIndex.java
@@ -44,7 +44,7 @@ public class MetaPageUpdateLastAllocatedIndex extends PageDeltaRecord {
 
         PageMetaIO io = PageMetaIO.VERSIONS.forVersion(PageIO.getVersion(pageAddr));
 
-        io.setLastAllocatedIndex(pageAddr, lastAllocatedIdx);
+        io.setLastPageCount(pageAddr, lastAllocatedIdx);
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/6eec695f/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageMetaIO.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageMetaIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageMetaIO.java
index e768f47..7a5535c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageMetaIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/PageMetaIO.java
@@ -44,13 +44,13 @@ public class PageMetaIO extends PageIO {
     private static final int LAST_SUCCESSFUL_FULL_SNAPSHOT_TAG_OFF = NEXT_SNAPSHOT_TAG_OFF + 8;
 
     /** Last allocated index offset. */
-    private static final int LAST_ALLOCATED_INDEX_OFF = LAST_SUCCESSFUL_FULL_SNAPSHOT_TAG_OFF + 8;
+    private static final int LAST_PAGE_COUNT_OFF = LAST_SUCCESSFUL_FULL_SNAPSHOT_TAG_OFF + 8;
 
     /** Candidate allocated index offset. */
-    private static final int CANDIDATE_ALLOCATED_INDEX_OFF = LAST_ALLOCATED_INDEX_OFF + 4;
+    private static final int CANDIDATE_PAGE_COUNT_OFF = LAST_PAGE_COUNT_OFF + 4;
 
     /** End of page meta. */
-    static final int END_OF_PAGE_META = CANDIDATE_ALLOCATED_INDEX_OFF + 4;
+    static final int END_OF_PAGE_META = CANDIDATE_PAGE_COUNT_OFF + 4;
 
     /** */
     public static final IOVersions<PageMetaIO> VERSIONS = new IOVersions<>(
@@ -82,8 +82,8 @@ public class PageMetaIO extends PageIO {
         setLastSuccessfulSnapshotId(pageAddr, 0);
         setNextSnapshotTag(pageAddr, 1);
         setLastSuccessfulSnapshotTag(pageAddr, 0);
-        setLastAllocatedIndex(pageAddr, 0);
-        setCandidateAllocatedIndex(pageAddr, 0);
+        setLastPageCount(pageAddr, 0);
+        setCandidatePageCount(pageAddr, 0);
     }
 
     /**
@@ -180,38 +180,38 @@ public class PageMetaIO extends PageIO {
 
     /**
      * @param pageAddr Page address.
-     * @param lastAllocatedIdx Last allocated index.
+     * @param pageCnt Last allocated index.
      */
-    public void setLastAllocatedIndex(long pageAddr, int lastAllocatedIdx) {
-        PageUtils.putInt(pageAddr, LAST_ALLOCATED_INDEX_OFF, lastAllocatedIdx);
+    public void setLastPageCount(long pageAddr, int pageCnt) {
+        PageUtils.putInt(pageAddr, LAST_PAGE_COUNT_OFF, pageCnt);
     }
 
     /**
      * @param buf Buffer.
      */
-    public int getLastAllocatedIndex(@NotNull ByteBuffer buf) {
-        return buf.getInt(LAST_ALLOCATED_INDEX_OFF);
+    public int getLastPageCount(@NotNull ByteBuffer buf) {
+        return buf.getInt(LAST_PAGE_COUNT_OFF);
     }
 
     /**
      * @param pageAddr Page address.
      */
-    public int getLastAllocatedIndex(long pageAddr) {
-        return PageUtils.getInt(pageAddr, LAST_ALLOCATED_INDEX_OFF);
+    public int getLastPageCount(long pageAddr) {
+        return PageUtils.getInt(pageAddr, LAST_PAGE_COUNT_OFF);
     }
 
     /**
      * @param pageAddr Page address.
-     * @param previousAllocatedIdx Last allocated index.
+     * @param pageCnt Last page count.
      */
-    public void setCandidateAllocatedIndex(long pageAddr, int previousAllocatedIdx) {
-        PageUtils.putInt(pageAddr, CANDIDATE_ALLOCATED_INDEX_OFF, previousAllocatedIdx);
+    public void setCandidatePageCount(long pageAddr, int pageCnt) {
+        PageUtils.putInt(pageAddr, CANDIDATE_PAGE_COUNT_OFF, pageCnt);
     }
 
     /**
      * @param pageAddr Page address.
      */
-    public int getCandidateAllocatedIndex(long pageAddr) {
-        return PageUtils.getInt(pageAddr, CANDIDATE_ALLOCATED_INDEX_OFF);
+    public int getCandidatePageCount(long pageAddr) {
+        return PageUtils.getInt(pageAddr, CANDIDATE_PAGE_COUNT_OFF);
     }
 }


[26/50] [abbrv] ignite git commit: initial CHECK snapshot test w/o modifications

Posted by sb...@apache.org.
initial CHECK snapshot test w/o modifications


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 22b6a9a954fd9e56fd96ca94d99165f94bf8ec01
Parents: 977653f
Author: Alexandr Kuramshin <ak...@gridgain.com>
Authored: Wed Mar 15 19:18:51 2017 +0700
Committer: Alexandr Kuramshin <ak...@gridgain.com>
Committed: Wed Mar 15 19:18:51 2017 +0700

----------------------------------------------------------------------
 modules/core/src/test/config/log4j-test.xml                  | 8 ++++----
 .../testframework/junits/common/GridCommonAbstractTest.java  | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/22b6a9a9/modules/core/src/test/config/log4j-test.xml
----------------------------------------------------------------------
diff --git a/modules/core/src/test/config/log4j-test.xml b/modules/core/src/test/config/log4j-test.xml
old mode 100644
new mode 100755
index 276de8c..edabff7
--- a/modules/core/src/test/config/log4j-test.xml
+++ b/modules/core/src/test/config/log4j-test.xml
@@ -102,9 +102,9 @@
     </category>
     -->
 
-    <!-- Disable all open source debugging. -->
-    <category name="org">
-        <level value="INFO"/>
+    <!-- Enable GG database debugging. -->
+    <category name="org.gridgain.grid.internal.processors.cache.database">
+        <level value="DEBUG"/>
     </category>
 
     <category name="org.eclipse.jetty">
@@ -113,7 +113,7 @@
 
     <!-- Default settings. -->
     <root>
-        <!-- Print out all debug by default. -->
+        <!-- Print at info by default. -->
         <level value="INFO"/>
 
         <!-- Append to file and console. -->

http://git-wip-us.apache.org/repos/asf/ignite/blob/22b6a9a9/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
old mode 100644
new mode 100755
index d82f1ea..3391b7c
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/common/GridCommonAbstractTest.java
@@ -1452,8 +1452,8 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
             ok = false;
         }
 
-        if (ok)
-            info("Deleted OK: " + file.getAbsolutePath() +
+        if (ok && log().isDebugEnabled()) // too much logging on real data
+            log().debug("Deleted OK: " + file.getAbsolutePath() +
                 (size >= 0 ? "(" + IgniteUtils.readableSize(size, false) + ")" : ""));
 
         return ok;


[48/50] [abbrv] ignite git commit: Multiple optimizations from ignite-gg-8.0.3.ea5-atomicbench.

Posted by sb...@apache.org.
Multiple optimizations from ignite-gg-8.0.3.ea5-atomicbench.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: 52556f4bf6d544a44bfd49b02d84aa32f741813f
Parents: a3ad6e0
Author: Ilya Lantukh <il...@gridgain.com>
Authored: Fri Apr 28 19:40:31 2017 +0300
Committer: Ilya Lantukh <il...@gridgain.com>
Committed: Fri Apr 28 19:40:31 2017 +0300

----------------------------------------------------------------------
 .../apache/ignite/IgniteSystemProperties.java   |   3 +
 .../rendezvous/RendezvousAffinityFunction.java  | 263 +++++++++++--------
 .../discovery/GridDiscoveryManager.java         |   1 +
 .../cache/CacheAffinitySharedManager.java       |  68 +++++
 .../cache/DynamicCacheChangeBatch.java          |  17 ++
 .../GridCachePartitionExchangeManager.java      |  22 +-
 .../processors/cache/GridCacheProcessor.java    |  25 +-
 .../dht/GridClientPartitionTopology.java        |  88 ++++---
 .../dht/GridDhtPartitionTopology.java           |   9 +
 .../dht/GridDhtPartitionTopologyImpl.java       | 104 +++++---
 .../dht/preloader/GridDhtPartitionMap2.java     |  45 +---
 .../GridDhtPartitionsExchangeFuture.java        |  61 ++++-
 .../internal/util/GridPartitionStateMap.java    | 174 ++++++++++++
 .../communication/tcp/TcpCommunicationSpi.java  |  17 +-
 .../resources/META-INF/classnames.properties    |   1 +
 .../GridCachePartitionedAffinitySpreadTest.java |   8 +-
 16 files changed, 669 insertions(+), 237 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/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 0b2fe65..ce2666b 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -552,6 +552,9 @@ public final class IgniteSystemProperties {
      */
     public static final String IGNITE_MAX_INDEX_PAYLOAD_SIZE = "IGNITE_MAX_INDEX_PAYLOAD_SIZE";
 
+    /** */
+    public static final String IGNITE_START_CACHES_ON_JOIN = "IGNITE_START_CACHES_ON_JOIN";
+
     /**
      * Enforces singleton.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
index 25fa3a1..021f4e2 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/affinity/rendezvous/RendezvousAffinityFunction.java
@@ -22,18 +22,16 @@ import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.UUID;
-import org.apache.ignite.Ignite;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.AffinityFunctionContext;
@@ -48,7 +46,6 @@ import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.resources.IgniteInstanceResource;
 import org.apache.ignite.resources.LoggerResource;
 import org.jetbrains.annotations.Nullable;
 
@@ -84,20 +81,6 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /** Comparator. */
     private static final Comparator<IgniteBiTuple<Long, ClusterNode>> COMPARATOR = new HashComparator();
 
-    /** Thread local message digest. */
-    private ThreadLocal<MessageDigest> digest = new ThreadLocal<MessageDigest>() {
-        @Override protected MessageDigest initialValue() {
-            try {
-                return MessageDigest.getInstance("MD5");
-            }
-            catch (NoSuchAlgorithmException e) {
-                assert false : "Should have failed in constructor";
-
-                throw new IgniteException("Failed to obtain message digest (digest was available in constructor)", e);
-            }
-        }
-    };
-
     /** Number of partitions. */
     private int parts;
 
@@ -118,10 +101,6 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /** Hash ID resolver. */
     private AffinityNodeHashResolver hashIdRslvr = null;
 
-    /** Ignite instance. */
-    @IgniteInstanceResource
-    private Ignite ignite;
-
     /** Logger instance. */
     @LoggerResource
     private transient IgniteLogger log;
@@ -186,18 +165,10 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     private RendezvousAffinityFunction(boolean exclNeighbors, int parts,
         IgniteBiPredicate<ClusterNode, ClusterNode> backupFilter) {
         A.ensure(parts > 0, "parts > 0");
-        A.ensure(parts <= CacheConfiguration.MAX_PARTITIONS_COUNT, "parts <=" + CacheConfiguration.MAX_PARTITIONS_COUNT);
 
         this.exclNeighbors = exclNeighbors;
         this.parts = parts;
         this.backupFilter = backupFilter;
-
-        try {
-            MessageDigest.getInstance("MD5");
-        }
-        catch (NoSuchAlgorithmException e) {
-            throw new IgniteException("Failed to obtain MD5 message digest instance.", e);
-        }
     }
 
     /**
@@ -222,7 +193,8 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
      * @param parts Total number of partitions.
      */
     public void setPartitions(int parts) {
-        A.ensure(parts <= CacheConfiguration.MAX_PARTITIONS_COUNT, "parts <= " + CacheConfiguration.MAX_PARTITIONS_COUNT);
+        A.ensure(parts <= CacheConfiguration.MAX_PARTITIONS_COUNT,
+            "parts <= " + CacheConfiguration.MAX_PARTITIONS_COUNT);
 
         this.parts = parts;
     }
@@ -355,116 +327,90 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
     /**
      * Returns collection of nodes (primary first) for specified partition.
      *
-     * @param d Message digest.
      * @param part Partition.
      * @param nodes Nodes.
-     * @param nodesHash Serialized nodes hashes.
      * @param backups Number of backups.
      * @param neighborhoodCache Neighborhood.
      * @return Assignment.
      */
-    public List<ClusterNode> assignPartition(MessageDigest d,
-        int part,
+    public List<ClusterNode> assignPartition(int part,
         List<ClusterNode> nodes,
-        Map<ClusterNode, byte[]> nodesHash,
         int backups,
         @Nullable Map<UUID, Collection<ClusterNode>> neighborhoodCache) {
         if (nodes.size() <= 1)
             return nodes;
 
-        if (d == null)
-            d = digest.get();
-
-        List<IgniteBiTuple<Long, ClusterNode>> lst = new ArrayList<>(nodes.size());
-
-        try {
-            for (int i = 0; i < nodes.size(); i++) {
-                ClusterNode node = nodes.get(i);
-
-                byte[] nodeHashBytes = nodesHash.get(node);
-
-                if (nodeHashBytes == null) {
-                    Object nodeHash = resolveNodeHash(node);
-
-                    byte[] nodeHashBytes0 = U.marshal(ignite.configuration().getMarshaller(), nodeHash);
-
-                    // Add 4 bytes for partition bytes.
-                    nodeHashBytes = new byte[nodeHashBytes0.length + 4];
-
-                    System.arraycopy(nodeHashBytes0, 0, nodeHashBytes, 4, nodeHashBytes0.length);
-
-                    nodesHash.put(node, nodeHashBytes);
-                }
+        IgniteBiTuple<Long, ClusterNode> [] hashArr =
+            (IgniteBiTuple<Long, ClusterNode> [])new IgniteBiTuple[nodes.size()];
 
-                U.intToBytes(part, nodeHashBytes, 0);
+        for (int i = 0; i < nodes.size(); i++) {
+            ClusterNode node = nodes.get(i);
 
-                d.reset();
+            Object nodeHash = resolveNodeHash(node);
 
-                byte[] bytes = d.digest(nodeHashBytes);
+            long hash = hash(nodeHash.hashCode(), part);
 
-                long hash =
-                    (bytes[0] & 0xFFL)
-                        | ((bytes[1] & 0xFFL) << 8)
-                        | ((bytes[2] & 0xFFL) << 16)
-                        | ((bytes[3] & 0xFFL) << 24)
-                        | ((bytes[4] & 0xFFL) << 32)
-                        | ((bytes[5] & 0xFFL) << 40)
-                        | ((bytes[6] & 0xFFL) << 48)
-                        | ((bytes[7] & 0xFFL) << 56);
-
-                lst.add(F.t(hash, node));
-            }
-        }
-        catch (IgniteCheckedException e) {
-            throw new IgniteException(e);
+            hashArr[i] = F.t(hash, node);
         }
 
-        Collections.sort(lst, COMPARATOR);
+        final int primaryAndBackups = backups == Integer.MAX_VALUE ? nodes.size() : Math.min(backups + 1, nodes.size());
 
-        int primaryAndBackups = backups == Integer.MAX_VALUE ? nodes.size() : Math.min(backups + 1, nodes.size());
+        Iterable<ClusterNode> sortedNodes = new LazyLinearSortedContainer(hashArr, primaryAndBackups);
+
+        Iterator<ClusterNode> it = sortedNodes.iterator();
 
         List<ClusterNode> res = new ArrayList<>(primaryAndBackups);
 
-        ClusterNode primary = lst.get(0).get2();
+        Collection<ClusterNode> allNeighbors = new HashSet<>();
+
+        ClusterNode primary = it.next();
 
         res.add(primary);
 
+        if (exclNeighbors)
+            allNeighbors.addAll(neighborhoodCache.get(primary.id()));
+
         // Select backups.
         if (backups > 0) {
-            for (int i = 1; i < lst.size() && res.size() < primaryAndBackups; i++) {
-                IgniteBiTuple<Long, ClusterNode> next = lst.get(i);
-
-                ClusterNode node = next.get2();
+            while (it.hasNext() && res.size() < primaryAndBackups) {
+                ClusterNode node = it.next();
 
                 if (exclNeighbors) {
-                    Collection<ClusterNode> allNeighbors = GridCacheUtils.neighborsForNodes(neighborhoodCache, res);
-
-                    if (!allNeighbors.contains(node))
+                    if (!allNeighbors.contains(node)) {
                         res.add(node);
+
+                        allNeighbors.addAll(neighborhoodCache.get(node.id()));
+                    }
+                }
+                else if ((backupFilter != null && backupFilter.apply(primary, node))
+                    || (affinityBackupFilter != null && affinityBackupFilter.apply(node, res))
+                    || (affinityBackupFilter == null && backupFilter == null) ) {
+                    res.add(node);
+
+                    if (exclNeighbors)
+                        allNeighbors.addAll(neighborhoodCache.get(node.id()));
                 }
-                else if (affinityBackupFilter != null && affinityBackupFilter.apply(node, res))
-                    res.add(next.get2());
-                else if (backupFilter != null && backupFilter.apply(primary, node))
-                    res.add(next.get2());
-                else if (affinityBackupFilter == null && backupFilter == null)
-                    res.add(next.get2());
             }
         }
 
         if (res.size() < primaryAndBackups && nodes.size() >= primaryAndBackups && exclNeighbors) {
             // Need to iterate again in case if there are no nodes which pass exclude neighbors backups criteria.
-            for (int i = 1; i < lst.size() && res.size() < primaryAndBackups; i++) {
-                IgniteBiTuple<Long, ClusterNode> next = lst.get(i);
+            it = sortedNodes.iterator();
 
-                ClusterNode node = next.get2();
+            it.next();
+
+            while (it.hasNext() && res.size() < primaryAndBackups) {
+                ClusterNode node = it.next();
 
                 if (!res.contains(node))
-                    res.add(next.get2());
+                    res.add(node);
             }
 
             if (!exclNeighborsWarn) {
                 LT.warn(log, "Affinity function excludeNeighbors property is ignored " +
-                    "because topology has no enough nodes to assign backups.");
+                        "because topology has no enough nodes to assign backups.",
+                    "Affinity function excludeNeighbors property is ignored " +
+                        "because topology has no enough nodes to assign backups.");
 
                 exclNeighborsWarn = true;
             }
@@ -475,6 +421,31 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
         return res;
     }
 
+    /**
+     * The pack partition number and nodeHash.hashCode to long and mix it by hash function based on the Wang/Jenkins
+     * hash.
+     *
+     * @param key0 Hash key.
+     * @param key1 Hash key.
+     * @see <a href="https://gist.github.com/badboy/6267743#64-bit-mix-functions">64 bit mix functions</a>
+     * @return Long hash key.
+     */
+    private static long hash(int key0, int key1) {
+        long key = (key0 & 0xFFFFFFFFL)
+            | ((key1 & 0xFFFFFFFFL) << 32);
+
+        key = (~key) + (key << 21); // key = (key << 21) - key - 1;
+        key ^= (key >>> 24);
+        key += (key << 3) + (key << 8); // key * 265
+        key ^= (key >>> 14);
+        key += (key << 2) + (key << 4); // key * 21
+        key ^= (key >>> 28);
+        key += (key << 31);
+
+        return key;
+    }
+
+
     /** {@inheritDoc} */
     @Override public void reset() {
         // No-op.
@@ -501,19 +472,10 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
         Map<UUID, Collection<ClusterNode>> neighborhoodCache = exclNeighbors ?
             GridCacheUtils.neighbors(affCtx.currentTopologySnapshot()) : null;
 
-        MessageDigest d = digest.get();
-
         List<ClusterNode> nodes = affCtx.currentTopologySnapshot();
 
-        Map<ClusterNode, byte[]> nodesHash = U.newHashMap(nodes.size());
-
         for (int i = 0; i < parts; i++) {
-            List<ClusterNode> partAssignment = assignPartition(d,
-                i,
-                nodes,
-                nodesHash,
-                affCtx.backups(),
-                neighborhoodCache);
+            List<ClusterNode> partAssignment = assignPartition(i, nodes, affCtx.backups(), neighborhoodCache);
 
             assignments.add(partAssignment);
         }
@@ -556,4 +518,83 @@ public class RendezvousAffinityFunction implements AffinityFunction, Externaliza
                 o1.get2().id().compareTo(o2.get2().id());
         }
     }
+
+    /**
+     * Sorts the initial array with linear sort algorithm array
+     */
+    private static class LazyLinearSortedContainer implements Iterable<ClusterNode> {
+        /** Initial node-hash array. */
+        private final IgniteBiTuple<Long, ClusterNode>[] arr;
+
+        /** Count of the sorted elements */
+        private int sorted;
+
+        /**
+         * @param arr Node / partition hash list.
+         * @param needFirstSortedCnt Estimate count of elements to return by iterator.
+         */
+        LazyLinearSortedContainer(IgniteBiTuple<Long, ClusterNode>[] arr, int needFirstSortedCnt) {
+            this.arr = arr;
+
+            if (needFirstSortedCnt > (int)Math.log(arr.length)) {
+                Arrays.sort(arr, COMPARATOR);
+
+                sorted = arr.length;
+            }
+        }
+
+        /** {@inheritDoc} */
+        @Override public Iterator<ClusterNode> iterator() {
+            return new SortIterator();
+        }
+
+        /**
+         *
+         */
+        private class SortIterator implements Iterator<ClusterNode> {
+            /** Index of the first unsorted element. */
+            private int cur;
+
+            /** {@inheritDoc} */
+            @Override public boolean hasNext() {
+                return cur < arr.length;
+            }
+
+            /** {@inheritDoc} */
+            @Override public ClusterNode next() {
+                if (!hasNext())
+                    throw new NoSuchElementException();
+
+                if (cur < sorted)
+                    return arr[cur++].get2();
+
+                IgniteBiTuple<Long, ClusterNode> min = arr[cur];
+
+                int minIdx = cur;
+
+                for (int i = cur + 1; i < arr.length; i++) {
+                    if (COMPARATOR.compare(arr[i], min) < 0) {
+                        minIdx = i;
+
+                        min = arr[i];
+                    }
+                }
+
+                if (minIdx != cur) {
+                    arr[minIdx] = arr[cur];
+
+                    arr[cur] = min;
+                }
+
+                sorted = cur++;
+
+                return min.get2();
+            }
+
+            /** {@inheritDoc} */
+            @Override public void remove() {
+                throw new UnsupportedOperationException("Remove doesn't supported");
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
index 960a064..8703e29 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java
@@ -88,6 +88,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.G;
 import org.apache.ignite.internal.util.typedef.P1;
 import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.LT;
 import org.apache.ignite.internal.util.typedef.internal.S;

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
index c1dde13..814d7e6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
@@ -29,6 +29,7 @@ import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -91,6 +92,9 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
     private WaitRebalanceInfo waitInfo;
 
     /** */
+    private IgniteLogger exchLog;
+
+    /** */
     private final Object mux = new Object();
 
     /** Pending affinity assignment futures. */
@@ -123,6 +127,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
         lateAffAssign = cctx.kernalContext().config().isLateAffinityAssignment() || cctx.database().persistenceEnabled();
 
         cctx.kernalContext().event().addLocalEventListener(discoLsnr, EVT_NODE_LEFT, EVT_NODE_FAILED);
+
+        exchLog = cctx.logger(GridDhtPartitionsExchangeFuture.EXCHANGE_LOG);
     }
 
     /**
@@ -342,6 +348,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
         throws IgniteCheckedException {
         assert !F.isEmpty(reqs) : fut;
 
+        exchLog.info("onCacheChangeRequest start [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
         for (DynamicCacheChangeRequest req : reqs) {
             Integer cacheId = CU.cacheId(req.cacheName());
 
@@ -384,8 +392,12 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             Integer cacheId = CU.cacheId(req.cacheName());
 
             if (req.start()) {
+                exchLog.info("prepareCacheStart start [topVer=" + fut.topologyVersion() + ", cache=" + req.cacheName() + ']');
+
                 cctx.cache().prepareCacheStart(req, fut.topologyVersion());
 
+                exchLog.info("prepareCacheStart end [topVer=" + fut.topologyVersion() + ", cache=" + req.cacheName() + ']');
+
                 if (fut.isCacheAdded(cacheId, fut.topologyVersion())) {
                     if (fut.discoCache().cacheAffinityNodes(req.cacheName()).isEmpty())
                         U.quietAndWarn(log, "No server nodes found for cache client: " + req.cacheName());
@@ -401,6 +413,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                         if (clientCacheStarted)
                             initAffinity(cacheCtx.affinity().affinityCache(), fut, lateAffAssign);
                         else if (!req.clientStartOnly()) {
+                            exchLog.info("calculateAff start [topVer=" + fut.topologyVersion() + ", cache=" + req.cacheName() + ']');
+
                             assert fut.topologyVersion().equals(cacheCtx.startTopologyVersion());
 
                             GridAffinityAssignmentCache aff = cacheCtx.affinity().affinityCache();
@@ -411,6 +425,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                                 fut.discoveryEvent(), fut.discoCache());
 
                             aff.initialize(fut.topologyVersion(), assignment);
+
+                            exchLog.info("calculateAff end [topVer=" + fut.topologyVersion() + ", cache=" + req.cacheName() + ']');
                         }
                     }
                 }
@@ -487,6 +503,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             }
         }
 
+        exchLog.info("onCacheChangeRequest end [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
         return clientOnly;
     }
 
@@ -564,6 +582,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
         assert msg.topologyVersion() != null && msg.exchangeId() == null : msg;
         assert affCalcVer == null || affCalcVer.equals(msg.topologyVersion());
 
+        exchLog.info("onChangeAffinityMessage start [topVer=" + exchFut.topologyVersion() + ", crd=" + crd + ']');
+
         final AffinityTopologyVersion topVer = exchFut.topologyVersion();
 
         if (log.isDebugEnabled()) {
@@ -631,6 +651,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             if (affCalcVer == null)
                 affCalcVer = msg.topologyVersion();
         }
+
+        exchLog.info("onChangeAffinityMessage end [topVer=" + exchFut.topologyVersion() + ", crd=" + crd + ']');
     }
 
     /**
@@ -832,11 +854,17 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
     private void initAffinity(GridAffinityAssignmentCache aff, GridDhtPartitionsExchangeFuture fut, boolean fetch)
         throws IgniteCheckedException {
         if (!fetch && canCalculateAffinity(aff, fut)) {
+            exchLog.info("initAffinity start [topVer=" + fut.topologyVersion() + ", cache=" + aff.cacheName() + ']');
+
             List<List<ClusterNode>> assignment = aff.calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
 
             aff.initialize(fut.topologyVersion(), assignment);
+
+            exchLog.info("initAffinity end [topVer=" + fut.topologyVersion() + ", cache=" + aff.cacheName() + ']');
         }
         else {
+            exchLog.info("fetchAffinity start [topVer=" + fut.topologyVersion() + ", cache=" + aff.cacheName() + ']');
+
             GridDhtAssignmentFetchFuture fetchFut = new GridDhtAssignmentFetchFuture(cctx,
                 aff.cacheName(),
                 fut.topologyVersion(),
@@ -845,6 +873,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             fetchFut.init();
 
             fetchAffinity(fut, aff, fetchFut);
+
+            exchLog.info("fetchAffinity end [topVer=" + fut.topologyVersion() + ", cache=" + aff.cacheName() + ']');
         }
     }
 
@@ -879,6 +909,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
      * @throws IgniteCheckedException If failed.
      */
     public void onServerJoin(final GridDhtPartitionsExchangeFuture fut, boolean crd) throws IgniteCheckedException {
+        exchLog.info("onServerJoin start [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
         assert !fut.discoveryEvent().eventNode().isClient();
 
         boolean locJoin = fut.discoveryEvent().eventNode().isLocal();
@@ -894,9 +926,13 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
                             CacheHolder cache = cache(fut, cacheDesc);
 
+                            exchLog.info("onServerJoin calc aff start [topVer=" + fut.topologyVersion() + ", cache=" + cache.name() + ']');
+
                             List<List<ClusterNode>> newAff = cache.affinity().calculate(topVer, fut.discoveryEvent(), fut.discoCache());
 
                             cache.affinity().initialize(topVer, newAff);
+
+                            exchLog.info("onServerJoin calc aff end [topVer=" + fut.topologyVersion() + ", cache=" + cache.name() + ']');
                         }
                     });
                 }
@@ -923,6 +959,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                 }
             }
         }
+
+        exchLog.info("onServerJoin end [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
     }
 
     /**
@@ -949,6 +987,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
      * @throws IgniteCheckedException If failed.
      */
     private void fetchAffinityOnJoin(GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException {
+        exchLog.info("fetchAffinityOnJoin start [topVer=" + fut.topologyVersion() + ']');
+
         AffinityTopologyVersion topVer = fut.topologyVersion();
 
         List<GridDhtAssignmentFetchFuture> fetchFuts = new ArrayList<>();
@@ -984,6 +1024,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
 
             fetchAffinity(fut, cctx.cacheContext(cacheId).affinity().affinityCache(), fetchFut);
         }
+
+        exchLog.info("fetchAffinityOnJoin end [topVer=" + fut.topologyVersion() + ']');
     }
 
     /**
@@ -1034,6 +1076,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
      * @return {@code True} if affinity should be assigned by coordinator.
      */
     public boolean onServerLeft(final GridDhtPartitionsExchangeFuture fut) throws IgniteCheckedException {
+        exchLog.info("onServerLeft start [topVer=" + fut.topologyVersion() + ']');
+
         ClusterNode leftNode = fut.discoveryEvent().eventNode();
 
         assert !leftNode.isClient() : leftNode;
@@ -1045,7 +1089,11 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                 if (cacheCtx.isLocal())
                     continue;
 
+                exchLog.info("onServerLeft calc aff start [topVer=" + fut.topologyVersion() + ", cache=" + cacheCtx.name() + ']');
+
                 cacheCtx.affinity().affinityCache().calculate(fut.topologyVersion(), fut.discoveryEvent(), fut.discoCache());
+
+                exchLog.info("onServerLeft calc aff end [topVer=" + fut.topologyVersion() + ", cache=" + cacheCtx.name() + ']');
             }
 
             centralizedAff = true;
@@ -1062,6 +1110,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             this.waitInfo = null;
         }
 
+        exchLog.info("onServerLeft end [topVer=" + fut.topologyVersion() + ']');
+
         return centralizedAff;
     }
 
@@ -1231,6 +1281,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
         final Map<Object, List<List<ClusterNode>>> affCache = new HashMap<>();
 
         if (!crd) {
+            exchLog.info("initAffinityOnNodeJoin start [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
             for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
                 if (cacheCtx.isLocal())
                     continue;
@@ -1240,9 +1292,13 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                 initAffinityOnNodeJoin(fut, cacheCtx.affinity().affinityCache(), null, latePrimary, affCache);
             }
 
+            exchLog.info("initAffinityOnNodeJoin end [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
             return null;
         }
         else {
+            exchLog.info("initAffinityOnNodeJoin start [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
             final WaitRebalanceInfo waitRebalanceInfo = new WaitRebalanceInfo(topVer);
 
             forAllRegisteredCaches(new IgniteInClosureX<DynamicCacheDescriptor>() {
@@ -1255,6 +1311,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
                 }
             });
 
+            exchLog.info("initAffinityOnNodeJoin end [topVer=" + fut.topologyVersion() + ", crd=" + crd + ']');
+
             return waitRebalanceInfo;
         }
     }
@@ -1273,6 +1331,9 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
         boolean latePrimary,
         Map<Object, List<List<ClusterNode>>> affCache)
         throws IgniteCheckedException {
+        exchLog.info("initAffinityOnNodeJoin start [topVer=" + fut.topologyVersion() +
+            ", cache=" + aff.cacheName() + ']');
+
         assert lateAffAssign;
 
         AffinityTopologyVersion topVer = fut.topologyVersion();
@@ -1318,6 +1379,9 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             newAssignment = idealAssignment;
 
         aff.initialize(fut.topologyVersion(), cachedAssignment(aff, newAssignment, affCache));
+
+        exchLog.info("initAffinityOnNodeJoin end [topVer=" + fut.topologyVersion() + ", cache=" +
+            aff.cacheName() + ']');
     }
 
     /**
@@ -1413,6 +1477,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
      */
     private Map<Integer, Map<Integer, List<UUID>>> initAffinityOnNodeLeft0(final GridDhtPartitionsExchangeFuture fut)
         throws IgniteCheckedException {
+        exchLog.info("initAffinityOnNodeLeft start [topVer=" + fut.topologyVersion() + ']');
+
         final AffinityTopologyVersion topVer = fut.topologyVersion();
 
         final WaitRebalanceInfo waitRebalanceInfo = new WaitRebalanceInfo(topVer);
@@ -1531,6 +1597,8 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
             }
         }
 
+        exchLog.info("initAffinityOnNodeLeft end [topVer=" + fut.topologyVersion() + ']');
+
         return assignment;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
index 4dcff9b..0e4373c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/DynamicCacheChangeBatch.java
@@ -47,6 +47,9 @@ public class DynamicCacheChangeBatch implements DiscoveryCustomMessage {
     /** */
     private boolean clientReconnect;
 
+    /** */
+    private boolean startCaches;
+
     /**
      * @param reqs Requests.
      */
@@ -113,6 +116,20 @@ public class DynamicCacheChangeBatch implements DiscoveryCustomMessage {
         return clientReconnect;
     }
 
+    /**
+     * @return {@code True} if required to start all caches on client node.
+     */
+    public boolean startCaches() {
+        return startCaches;
+    }
+
+    /**
+     * @param startCaches {@code True} if required to start all caches on client node.
+     */
+    public void startCaches(boolean startCaches) {
+        this.startCaches = startCaches;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(DynamicCacheChangeBatch.class, this);

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
index ff7feb8..95cb452 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePartitionExchangeManager.java
@@ -54,6 +54,7 @@ import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.events.DiscoveryCustomEvent;
+import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
 import org.apache.ignite.internal.pagemem.snapshot.StartSnapshotOperationAckDiscoveryMessage;
 import org.apache.ignite.internal.managers.discovery.DiscoCache;
@@ -118,7 +119,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.preloa
  */
 public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedManagerAdapter<K, V> {
     /** Exchange history size. */
-    private static final int EXCHANGE_HISTORY_SIZE = 1000;
+    private static final int EXCHANGE_HISTORY_SIZE =
+        IgniteSystemProperties.getInteger("IGNITE_EXCHANGE_HISTORY_SIZE", 1000);
 
     /** Atomic reference for pending timeout object. */
     private AtomicReference<ResendTimeoutObject> pendingResend = new AtomicReference<>();
@@ -221,7 +223,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
 
                     assert evt.type() != EVT_NODE_JOINED || n.order() > loc.order() :
                         "Node joined with smaller-than-local " +
-                            "order [newOrder=" + n.order() + ", locOrder=" + loc.order() + ']';
+                        "order [newOrder=" + n.order() + ", locOrder=" + loc.order() + ']';
 
                     exchId = exchangeId(n.id(),
                         affinityTopologyVersion(evt),
@@ -230,10 +232,10 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                     exchFut = exchangeFuture(exchId, evt, cache,null, null);
                 }
                 else {
-                    DiscoveryCustomEvent customEvt = (DiscoveryCustomEvent)evt;
+                    DiscoveryCustomMessage customMsg = ((DiscoveryCustomEvent)evt).customMessage();
 
-                    if (customEvt.customMessage() instanceof DynamicCacheChangeBatch) {
-                        DynamicCacheChangeBatch batch = (DynamicCacheChangeBatch)customEvt.customMessage();
+                    if (customMsg instanceof DynamicCacheChangeBatch) {
+                        DynamicCacheChangeBatch batch = (DynamicCacheChangeBatch)customMsg;
 
                         Collection<DynamicCacheChangeRequest> valid = new ArrayList<>(batch.requests().size());
 
@@ -266,8 +268,8 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                             exchFut = exchangeFuture(exchId, evt, cache, valid, null);
                         }
                     }
-                    else if (customEvt.customMessage() instanceof CacheAffinityChangeMessage) {
-                        CacheAffinityChangeMessage msg = (CacheAffinityChangeMessage)customEvt.customMessage();
+                    else if (customMsg instanceof CacheAffinityChangeMessage) {
+                        CacheAffinityChangeMessage msg = (CacheAffinityChangeMessage)customMsg;
 
                         if (msg.exchangeId() == null) {
                             if (msg.exchangeNeeded()) {
@@ -277,10 +279,10 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
                             }
                         }
                         else
-                            exchangeFuture(msg.exchangeId(), null, null, null, null).onAffinityChangeMessage(customEvt.eventNode(), msg);
+                            exchangeFuture(msg.exchangeId(), null, null, null, null).onAffinityChangeMessage(evt.eventNode(), msg);
                     }
-                    else if (customEvt.customMessage() instanceof StartSnapshotOperationAckDiscoveryMessage
-                        && !((StartSnapshotOperationAckDiscoveryMessage)customEvt.customMessage()).hasError()) {
+                    else if (customMsg instanceof StartSnapshotOperationAckDiscoveryMessage
+                        && !((StartSnapshotOperationAckDiscoveryMessage)customMsg).hasError()) {
                         exchId = exchangeId(n.id(), affinityTopologyVersion(evt), evt.type());
 
                         exchFut = exchangeFuture(exchId, evt, null, null, null);

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index 2bb1e42..8ad3c8d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -43,6 +43,7 @@ import javax.management.JMException;
 import javax.management.MBeanServer;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteSystemProperties;
 import org.apache.ignite.cache.CacheAtomicWriteOrderMode;
 import org.apache.ignite.cache.CacheExistsException;
 import org.apache.ignite.cache.CacheMode;
@@ -147,6 +148,8 @@ import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
 import static org.apache.ignite.internal.IgniteComponentType.JTA;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CONSISTENCY_CHECK_SKIPPED;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_TX_CONFIG;
+import static org.apache.ignite.internal.processors.cache.GridCacheUtils.affinityNode;
+import static org.apache.ignite.internal.processors.cache.GridCacheUtils.clientNode;
 import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isNearEnabled;
 
 /**
@@ -154,6 +157,10 @@ import static org.apache.ignite.internal.processors.cache.GridCacheUtils.isNearE
  */
 @SuppressWarnings({"unchecked", "TypeMayBeWeakened", "deprecation"})
 public class GridCacheProcessor extends GridProcessorAdapter {
+    /** */
+    private static final boolean startCaches =
+        IgniteSystemProperties.getBoolean(IgniteSystemProperties.IGNITE_START_CACHES_ON_JOIN, false);
+
     /** Null cache name. */
     private static final String NULL_NAME = U.id8(UUID.randomUUID());
 
@@ -816,7 +823,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
                 boolean loc = desc.locallyConfigured();
 
-                if (loc || (desc.receivedOnDiscovery() && CU.affinityNode(locNode, filter))) {
+                if (loc || (desc.receivedOnDiscovery() && (CU.affinityNode(locNode, filter) ||
+                    startAllCachesOnClientStart()))) {
                     boolean started = desc.onStart();
 
                     assert started : "Failed to change started flag for locally configured cache: " + desc;
@@ -2165,6 +2173,9 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         batch.clientReconnect(reconnect);
 
+        if (!reconnect)
+            batch.startCaches(startAllCachesOnClientStart());
+
         //todo check
         // Reset random batch ID so that serialized batches with the same descriptors will be exactly the same.
         batch.id(null);
@@ -2172,6 +2183,13 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         return batch;
     }
 
+    /**
+     * @return {@code True} if need locally start all existing caches on client node start.
+     */
+    private boolean startAllCachesOnClientStart() {
+        return startCaches && ctx.clientNode();
+    }
+
     /** {@inheritDoc} */
     @Override public void onDiscoveryDataReceived(UUID joiningNodeId, UUID rmtNodeId, Serializable data) {
         if (data instanceof DynamicCacheChangeBatch) {
@@ -2276,6 +2294,11 @@ public class GridCacheProcessor extends GridProcessorAdapter {
                             ctx.discovery().addClientNode(cacheName, tup.getKey(), tup.getValue());
                     }
                 }
+
+                if (batch.startCaches()) {
+                    for (Map.Entry<String, DynamicCacheDescriptor> entry : registeredCaches.entrySet())
+                        ctx.discovery().addClientNode(entry.getKey(), joiningNodeId, false);
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
index a96cc43..5c5a3c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridClientPartitionTopology.java
@@ -34,6 +34,7 @@ import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
 import org.apache.ignite.internal.managers.discovery.DiscoCache;
+import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionExchangeId;
@@ -59,6 +60,9 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
  */
 @GridToStringExclude
 public class GridClientPartitionTopology implements GridDhtPartitionTopology {
+    /** */
+    private static final GridDhtPartitionState[] MOVING_STATES = new GridDhtPartitionState[] {MOVING};
+
     /** If true, then check consistency. */
     private static final boolean CONSISTENCY_CHECK = false;
 
@@ -81,7 +85,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     private GridDhtPartitionFullMap node2part;
 
     /** Partition to node map. */
-    private Map<Integer, Set<UUID>> part2node = new HashMap<>();
+    private final Map<Integer, Set<UUID>> part2node = new HashMap<>();
 
     /** */
     private GridDhtPartitionExchangeId lastExchangeId;
@@ -93,7 +97,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     private volatile boolean stopping;
 
     /** A future that will be completed when topology with version topVer will be ready to use. */
-    private GridDhtTopologyFuture topReadyFut;
+    private volatile GridDhtTopologyFuture topReadyFut;
 
     /** */
     private final GridAtomicLong updateSeq = new GridAtomicLong(1);
@@ -225,16 +229,9 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
     /** {@inheritDoc} */
     @Override public GridDhtTopologyFuture topologyVersionFuture() {
-        lock.readLock().lock();
-
-        try {
-            assert topReadyFut != null;
+        assert topReadyFut != null;
 
-            return topReadyFut;
-        }
-        finally {
-            lock.readLock().unlock();
-        }
+        return topReadyFut;
     }
 
     /** {@inheritDoc} */
@@ -425,6 +422,13 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
     }
 
     /** {@inheritDoc} */
+    @Nullable @Override public List<ClusterNode> nodes(int p,
+        AffinityAssignment affAssignment,
+        List<ClusterNode> affNodes) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
     @Override public List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer) {
         lock.readLock().lock();
 
@@ -503,7 +507,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
     /** {@inheritDoc} */
     @Override public List<ClusterNode> owners(int p, AffinityTopologyVersion topVer) {
-        return nodes(p, topVer, OWNING);
+        return nodes(p, topVer, OWNING, null);
     }
 
     /** {@inheritDoc} */
@@ -513,7 +517,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
     /** {@inheritDoc} */
     @Override public List<ClusterNode> moving(int p) {
-        return nodes(p, AffinityTopologyVersion.NONE, MOVING);
+        return nodes(p, AffinityTopologyVersion.NONE, MOVING, null);
     }
 
     /**
@@ -522,7 +526,7 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
      * @return List of nodes in state OWNING or MOVING.
      */
     private List<ClusterNode> ownersAndMoving(int p, AffinityTopologyVersion topVer) {
-        return nodes(p, topVer, OWNING, MOVING);
+        return nodes(p, topVer, OWNING, MOVING_STATES);
     }
 
     /** {@inheritDoc} */
@@ -564,9 +568,12 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
     /** {@inheritDoc} */
     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
-    @Nullable @Override public GridDhtPartitionMap2 update(@Nullable GridDhtPartitionsExchangeFuture exchFut,
-        GridDhtPartitionFullMap partMap, Map<Integer, T2<Long, Long>> cntrMap, Set<Integer> partsToReload) {
-
+    @Nullable @Override public GridDhtPartitionMap2 update(
+        @Nullable GridDhtPartitionsExchangeFuture exchFut,
+        GridDhtPartitionFullMap partMap,
+        Map<Integer, T2<Long, Long>> cntrMap,
+        Set<Integer> partsToReload
+    ) {
         GridDhtPartitionExchangeId exchId = exchFut != null ? exchFut.exchangeId() : null;
 
         if (log.isDebugEnabled())
@@ -624,25 +631,26 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
                 }
             }
 
-            node2part = partMap;
-
-            Map<Integer, Set<UUID>> p2n = new HashMap<>();
+            part2node.clear();
 
             for (Map.Entry<UUID, GridDhtPartitionMap2> e : partMap.entrySet()) {
-                for (Integer p : e.getValue().keySet()) {
-                    Set<UUID> ids = p2n.get(p);
+                for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
+                    if (e0.getValue() != MOVING && e0.getValue() != OWNING)
+                        continue;
+
+                    int p = e0.getKey();
+
+                    Set<UUID> ids = part2node.get(p);
 
                     if (ids == null)
                         // Initialize HashSet to size 3 in anticipation that there won't be
                         // more than 3 nodes per partitions.
-                        p2n.put(p, ids = U.newHashSet(3));
+                        part2node.put(p, ids = U.newHashSet(3));
 
                     ids.add(e.getKey());
                 }
             }
 
-            part2node = p2n;
-
             if (cntrMap != null)
                 this.cntrMap = new HashMap<>(cntrMap);
 
@@ -660,9 +668,11 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
     /** {@inheritDoc} */
     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
-    @Nullable @Override public GridDhtPartitionMap2 update(@Nullable GridDhtPartitionExchangeId exchId,
+    @Nullable @Override public GridDhtPartitionMap2 update(
+        @Nullable GridDhtPartitionExchangeId exchId,
         GridDhtPartitionMap2 parts,
-        Map<Integer, T2<Long, Long>> cntrMap) {
+        Map<Integer, T2<Long, Long>> cntrMap
+    ) {
         if (log.isDebugEnabled())
             log.debug("Updating single partition map [exchId=" + exchId + ", parts=" + mapString(parts) + ']');
 
@@ -716,18 +726,24 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
 
             node2part.put(parts.nodeId(), parts);
 
-            part2node = new HashMap<>(part2node);
-
             // Add new mappings.
-            for (Integer p : parts.keySet()) {
+            for (Map.Entry<Integer,GridDhtPartitionState> e : parts.entrySet()) {
+                int p = e.getKey();
+
                 Set<UUID> ids = part2node.get(p);
 
-                if (ids == null)
-                    // Initialize HashSet to size 3 in anticipation that there won't be
-                    // more than 3 nodes per partition.
-                    part2node.put(p, ids = U.newHashSet(3));
+                if (e.getValue() == MOVING || e.getValue() == OWNING) {
+                    if (ids == null)
+                        // Initialize HashSet to size 3 in anticipation that there won't be
+                        // more than 3 nodes per partition.
+                        part2node.put(p, ids = U.newHashSet(3));
 
-                changed |= ids.add(parts.nodeId());
+                    changed |= ids.add(parts.nodeId());
+                }
+                else {
+                    if (ids != null)
+                        changed |= ids.remove(parts.nodeId());
+                }
             }
 
             // Remove obsolete mappings.
@@ -862,8 +878,6 @@ public class GridClientPartitionTopology implements GridDhtPartitionTopology {
             else
                 node2part = new GridDhtPartitionFullMap(node2part, node2part.updateSequence());
 
-            part2node = new HashMap<>(part2node);
-
             GridDhtPartitionMap2 parts = node2part.remove(nodeId);
 
             if (parts != null) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
index 37c3af9..2bef267 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopology.java
@@ -26,6 +26,7 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.processors.affinity.AffinityAssignment;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionExchangeId;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap;
@@ -191,6 +192,14 @@ public interface GridDhtPartitionTopology {
 
     /**
      * @param p Partition ID.
+     * @param affAssignment Assignments.
+     * @param affNodes Node assigned for given partition by affinity.
+     * @return Collection of all nodes responsible for this partition with primary node being first.
+     */
+    @Nullable public List<ClusterNode> nodes(int p, AffinityAssignment affAssignment, List<ClusterNode> affNodes);
+
+    /**
+     * @param p Partition ID.
      * @return Collection of all nodes who {@code own} this partition.
      */
     public List<ClusterNode> owners(int p);

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
index 36c1ae5..fb09b38 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionTopologyImpl.java
@@ -69,6 +69,9 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
  * Partition topology.
  */
 @GridToStringExclude class GridDhtPartitionTopologyImpl implements GridDhtPartitionTopology {
+    /** */
+    private static final GridDhtPartitionState[] MOVING_STATES = new GridDhtPartitionState[] {MOVING};
+
     /** If true, then check consistency. */
     private static final boolean CONSISTENCY_CHECK = false;
 
@@ -91,7 +94,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     private GridDhtPartitionFullMap node2part;
 
     /** Partition to node map. */
-    private Map<Integer, Set<UUID>> part2node = new HashMap<>();
+    private final Map<Integer, Set<UUID>> part2node;
 
     /** */
     private GridDhtPartitionExchangeId lastExchangeId;
@@ -106,7 +109,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     private volatile boolean stopping;
 
     /** A future that will be completed when topology with version topVer will be ready to use. */
-    private GridDhtTopologyFuture topReadyFut;
+    private volatile GridDhtTopologyFuture topReadyFut;
 
     /** */
     private final GridAtomicLong updateSeq = new GridAtomicLong(1);
@@ -139,6 +142,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         log = cctx.logger(getClass());
 
         locParts = new AtomicReferenceArray<>(cctx.config().getAffinity().partitions());
+
+        part2node = new HashMap<>(cctx.config().getAffinity().partitions(), 1.0f);
     }
 
     /** {@inheritDoc} */
@@ -155,7 +160,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         try {
             node2part = null;
 
-            part2node = new HashMap<>();
+            part2node.clear();
 
             lastExchangeId = null;
 
@@ -245,16 +250,9 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
     /** {@inheritDoc} */
     @Override public GridDhtTopologyFuture topologyVersionFuture() {
-        lock.readLock().lock();
-
-        try {
-            assert topReadyFut != null;
+        assert topReadyFut != null;
 
-            return topReadyFut;
-        }
-        finally {
-            lock.readLock().unlock();
-        }
+        return topReadyFut;
     }
 
     /** {@inheritDoc} */
@@ -753,6 +751,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
             if (part != null && part.state().active())
                 list.add(part);
         }
+
         return list;
     }
 
@@ -827,11 +826,32 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
     }
 
     /** {@inheritDoc} */
+    @Nullable @Override public List<ClusterNode> nodes(int p,
+        AffinityAssignment affAssignment,
+        List<ClusterNode> affNodes) {
+        return nodes0(p, affAssignment, affNodes);
+    }
+
+    /** {@inheritDoc} */
     @Override public List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer) {
         AffinityAssignment affAssignment = cctx.affinity().assignment(topVer);
 
         List<ClusterNode> affNodes = affAssignment.get(p);
 
+        List<ClusterNode> nodes = nodes0(p, affAssignment, affNodes);
+
+        return nodes != null ? nodes : affNodes;
+    }
+
+    /**
+     * @param p Partition.
+     * @param affAssignment Assignments.
+     * @param affNodes Node assigned for given partition by affinity.
+     * @return Nodes responsible for given partition (primary is first).
+     */
+    @Nullable private List<ClusterNode> nodes0(int p, AffinityAssignment affAssignment, List<ClusterNode> affNodes) {
+        AffinityTopologyVersion topVer = affAssignment.topologyVersion();
+
         lock.readLock().lock();
 
         try {
@@ -849,7 +869,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 for (UUID nodeId : nodeIds) {
                     HashSet<UUID> affIds = affAssignment.getIds(p);
 
-                    if (!affIds.contains(nodeId) && hasState(p, nodeId, OWNING, MOVING, RENTING)) {
+                    if (!affIds.contains(nodeId) && hasState(p, nodeId, OWNING, MOVING)) {
                         ClusterNode n = cctx.discovery().node(nodeId);
 
                         if (n != null && (topVer.topologyVersion() < 0 || n.order() <= topVer.topologyVersion())) {
@@ -865,7 +885,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 }
             }
 
-            return nodes != null ? nodes : affNodes;
+            return nodes;
         }
         finally {
             lock.readLock().unlock();
@@ -927,7 +947,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         if (!cctx.rebalanceEnabled())
             return ownersAndMoving(p, topVer);
 
-        return nodes(p, topVer, OWNING);
+        return nodes(p, topVer, OWNING, null);
     }
 
     /** {@inheritDoc} */
@@ -940,7 +960,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
         if (!cctx.rebalanceEnabled())
             return ownersAndMoving(p, AffinityTopologyVersion.NONE);
 
-        return nodes(p, AffinityTopologyVersion.NONE, MOVING);
+        return nodes(p, AffinityTopologyVersion.NONE, MOVING, null);
     }
 
     /**
@@ -949,7 +969,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
      * @return List of nodes in state OWNING or MOVING.
      */
     private List<ClusterNode> ownersAndMoving(int p, AffinityTopologyVersion topVer) {
-        return nodes(p, topVer, OWNING, MOVING);
+        return nodes(p, topVer, OWNING, MOVING_STATES);
     }
 
     /** {@inheritDoc} */
@@ -980,7 +1000,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
     /** {@inheritDoc} */
     @SuppressWarnings({"MismatchedQueryAndUpdateOfCollection"})
-    @Nullable @Override public GridDhtPartitionMap2 update(
+    @Override public GridDhtPartitionMap2 update(
         @Nullable GridDhtPartitionsExchangeFuture exchFut,
         GridDhtPartitionFullMap partMap,
         @Nullable Map<Integer, T2<Long, Long>> cntrMap,
@@ -1078,23 +1098,26 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             node2part = partMap;
 
-            Map<Integer, Set<UUID>> p2n = new HashMap<>(cctx.affinity().partitions(), 1.0f);
+            part2node.clear();
 
             for (Map.Entry<UUID, GridDhtPartitionMap2> e : partMap.entrySet()) {
-                for (Integer p : e.getValue().keySet()) {
-                    Set<UUID> ids = p2n.get(p);
+                for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
+                    if (e0.getValue() != MOVING && e0.getValue() != OWNING)
+                        continue;
+
+                    int p = e0.getKey();
+
+                    Set<UUID> ids = part2node.get(p);
 
                     if (ids == null)
                         // Initialize HashSet to size 3 in anticipation that there won't be
                         // more than 3 nodes per partitions.
-                        p2n.put(p, ids = U.newHashSet(3));
+                        part2node.put(p, ids = U.newHashSet(3));
 
                     ids.add(e.getKey());
                 }
             }
 
-            part2node = p2n;
-
             boolean changed = false;
 
             AffinityTopologyVersion affVer = cctx.affinity().affinityTopologyVersion();
@@ -1273,18 +1296,24 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
             node2part.put(parts.nodeId(), parts);
 
-            part2node = new HashMap<>(part2node);
-
             // Add new mappings.
-            for (Integer p : parts.keySet()) {
+            for (Map.Entry<Integer,GridDhtPartitionState> e : parts.entrySet()) {
+                int p = e.getKey();
+
                 Set<UUID> ids = part2node.get(p);
 
-                if (ids == null)
-                    // Initialize HashSet to size 3 in anticipation that there won't be
-                    // more than 3 nodes per partition.
-                    part2node.put(p, ids = U.newHashSet(3));
+                if (e.getValue() == MOVING || e.getValue() == OWNING) {
+                    if (ids == null)
+                        // Initialize HashSet to size 3 in anticipation that there won't be
+                        // more than 3 nodes per partition.
+                        part2node.put(p, ids = U.newHashSet(3));
 
-                changed |= ids.add(parts.nodeId());
+                    changed |= ids.add(parts.nodeId());
+                }
+                else {
+                    if (ids != null)
+                        changed |= ids.remove(parts.nodeId());
+                }
             }
 
             // Remove obsolete mappings.
@@ -1607,7 +1636,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 List<ClusterNode> affNodes = aff.get(p);
 
                 if (!affNodes.contains(cctx.localNode())) {
-                    List<ClusterNode> nodes = nodes(p, topVer, OWNING);
+                    List<ClusterNode> nodes = nodes(p, topVer, OWNING, null);
                     Collection<UUID> nodeIds = F.nodeIds(nodes);
 
                     // If all affinity nodes are owners, then evict partition from local node.
@@ -1740,12 +1769,12 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
         ClusterNode oldest = discoCache.oldestAliveServerNode();
 
-        assert oldest != null;
+        assert oldest != null || cctx.kernalContext().clientNode();
 
         ClusterNode loc = cctx.localNode();
 
         if (node2part != null) {
-            if (oldest.equals(loc) && !node2part.nodeId().equals(loc.id())) {
+            if (loc.equals(oldest) && !node2part.nodeId().equals(loc.id())) {
                 updateSeq.setIfGreater(node2part.updateSequence());
 
                 node2part = new GridDhtPartitionFullMap(loc.id(), loc.order(), updateSeq.incrementAndGet(),
@@ -1910,7 +1939,8 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
 
     /** {@inheritDoc} */
     @Override public void printMemoryStats(int threshold) {
-        X.println(">>>  Cache partition topology stats [grid=" + cctx.gridName() + ", cache=" + cctx.name() + ']');
+        X.println(">>>  Cache partition topology stats [igniteInstanceName=" + cctx.gridName() +
+            ", cache=" + cctx.name() + ']');
 
         lock.readLock().lock();
 
@@ -1921,7 +1951,7 @@ import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDh
                 if (part == null)
                     continue;
 
-                int size = part.size();
+                int size = part.dataStore().size();
 
                 if (size >= threshold)
                     X.println(">>>   Local partition [part=" + part.id() + ", size=" + size + ']');

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionMap2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionMap2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionMap2.java
index 9837f69..534abb9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionMap2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionMap2.java
@@ -21,13 +21,12 @@ import java.io.Externalizable;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
-import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState;
+import org.apache.ignite.internal.util.GridPartitionStateMap;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteProductVersion;
@@ -54,7 +53,7 @@ public class GridDhtPartitionMap2 implements Comparable<GridDhtPartitionMap2>, E
     protected AffinityTopologyVersion top;
 
     /** */
-    protected Map<Integer, GridDhtPartitionState> map;
+    protected GridPartitionStateMap map;
 
     /** */
     private volatile int moving;
@@ -85,7 +84,8 @@ public class GridDhtPartitionMap2 implements Comparable<GridDhtPartitionMap2>, E
         this.updateSeq = updateSeq;
         this.top = top;
 
-        map = U.newHashMap(m.size());
+        map = new GridPartitionStateMap(m.size());
+        //map = U.newHashMap(m.size());
 
         for (Map.Entry<Integer, GridDhtPartitionState> e : m.entrySet()) {
             GridDhtPartitionState state = e.getValue();
@@ -105,7 +105,7 @@ public class GridDhtPartitionMap2 implements Comparable<GridDhtPartitionMap2>, E
     private GridDhtPartitionMap2(UUID nodeId,
         long updateSeq,
         AffinityTopologyVersion top,
-        Map<Integer, GridDhtPartitionState> map,
+        GridPartitionStateMap map,
         int moving) {
         this.nodeId = nodeId;
         this.updateSeq = updateSeq;
@@ -121,7 +121,7 @@ public class GridDhtPartitionMap2 implements Comparable<GridDhtPartitionMap2>, E
         return new GridDhtPartitionMap2(nodeId,
             updateSeq,
             top,
-            U.<Integer, GridDhtPartitionState>newHashMap(0),
+            new GridPartitionStateMap(0),
             0);
     }
 
@@ -243,25 +243,7 @@ public class GridDhtPartitionMap2 implements Comparable<GridDhtPartitionMap2>, E
 
         out.writeLong(updateSeq);
 
-        int size = map.size();
-
-        out.writeInt(size);
-
-        int i = 0;
-
-        for (Map.Entry<Integer, GridDhtPartitionState> entry : map.entrySet()) {
-            int ordinal = entry.getValue().ordinal();
-
-            assert ordinal == (ordinal & 0xFF);
-            assert entry.getKey() >= 0 && entry.getKey() <= CacheConfiguration.MAX_PARTITIONS_COUNT : entry.getKey();
-
-            out.write(ordinal);
-            out.writeShort((short)(int)entry.getKey());
-
-            i++;
-        }
-
-        assert i == size;
+        out.writeObject(map);
 
         if (top != null) {
             out.writeLong(topologyVersion().topologyVersion());
@@ -279,16 +261,13 @@ public class GridDhtPartitionMap2 implements Comparable<GridDhtPartitionMap2>, E
 
         updateSeq = in.readLong();
 
-        int size = in.readInt();
-
-        map = U.newHashMap(size);
-
-        for (int i = 0; i < size; i++) {
-            int ordinal = in.readByte() & 0xFF;
+        map = (GridPartitionStateMap)in.readObject();
 
-            int part = in.readShort() & 0xFFFF;
+        Set<Map.Entry<Integer, GridDhtPartitionState>> entries = map.entrySet();
 
-            put(part, GridDhtPartitionState.fromOrdinal(ordinal));
+        for (Map.Entry<Integer, GridDhtPartitionState> entry : entries) {
+            if (entry.getValue() == MOVING)
+                moving++;
         }
 
         long ver = in.readLong();

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
index b0d776f..078e67b5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionsExchangeFuture.java
@@ -30,6 +30,7 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReadWriteLock;
 import org.apache.ignite.IgniteCheckedException;
@@ -73,6 +74,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.cluster.GridClusterStateProcessor;
 import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter;
+import org.apache.ignite.internal.util.GridAtomicLong;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -110,6 +112,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     public static final int DUMP_PENDING_OBJECTS_THRESHOLD =
         IgniteSystemProperties.getInteger(IgniteSystemProperties.IGNITE_DUMP_PENDING_OBJECTS_THRESHOLD, 10);
 
+    public static final String EXCHANGE_LOG = "org.apache.ignite.internal.exchange.time";
+
     /** */
     private static final long serialVersionUID = 0L;
 
@@ -189,6 +193,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
     /** Logger. */
     private final IgniteLogger log;
 
+    /** */
+    private final IgniteLogger exchLog;
+
     /** Dynamic cache change requests. */
     private Collection<DynamicCacheChangeRequest> reqs;
 
@@ -258,6 +265,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         this.cctx = cctx;
 
         log = cctx.logger(getClass());
+        exchLog = cctx.logger(EXCHANGE_LOG);
 
         onDone(exchId.topologyVersion());
     }
@@ -282,6 +290,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         this.forcedRebFut = forcedRebFut;
 
         log = cctx.logger(getClass());
+        exchLog = cctx.logger(EXCHANGE_LOG);
 
         reassign = true;
 
@@ -317,6 +326,7 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         this.affChangeMsg = affChangeMsg;
 
         log = cctx.logger(getClass());
+        exchLog = cctx.logger(EXCHANGE_LOG);
 
         initFut = new GridFutureAdapter<>();
 
@@ -535,6 +545,12 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
             skipPreload = cctx.kernalContext().clientNode();
 
+            exchLog.info("Start exchange init [topVer=" + topVer +
+                ", crd=" + crdNode +
+                ", evt=" + discoEvt.type() +
+                ", customEvt=" + (discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT ? ((DiscoveryCustomEvent)discoEvt).customMessage() : null) +
+                ']');
+
             ExchangeType exchange;
 
             if (discoEvt.type() == EVT_DISCOVERY_CUSTOM_EVT) {
@@ -622,6 +638,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                 default:
                     assert false;
             }
+
+            exchLog.info("Finish exchange init [topVer=" + topVer + ", crd=" + crdNode + ']');
         }
         catch (IgniteInterruptedCheckedException e) {
             onDone(e);
@@ -694,6 +712,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      * @throws IgniteCheckedException If failed.
      */
     private void updateTopologies(boolean crd) throws IgniteCheckedException {
+        exchLog.info("updateTopologies start [topVer=" + topologyVersion() + ", crd=" + crd + ']');
+
         for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
             if (cacheCtx.isLocal())
                 continue;
@@ -717,6 +737,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
 
         for (GridClientPartitionTopology top : cctx.exchange().clientTopologies())
             top.updateTopologyVersion(exchId, this, -1, stopping(top.cacheId()));
+
+        exchLog.info("updateTopologies end [topVer=" + topologyVersion() + ", crd=" + crd + ']');
     }
 
     /**
@@ -1126,6 +1148,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      * @throws IgniteCheckedException If failed.
      */
     private void sendLocalPartitions(ClusterNode node) throws IgniteCheckedException {
+        exchLog.info("sendLocalPartitions start [topVer=" + topologyVersion() + ']');
+
         assert node != null;
 
         // Reset lost partition before send local partition to coordinator.
@@ -1162,6 +1186,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
             if (log.isDebugEnabled())
                 log.debug("Node left during partition exchange [nodeId=" + node.id() + ", exchId=" + exchId + ']');
         }
+
+        exchLog.info("sendLocalPartitions end [topVer=" + topologyVersion() + ']');
     }
 
     /**
@@ -1190,6 +1216,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      * @throws IgniteCheckedException If failed.
      */
     private void sendAllPartitions(Collection<ClusterNode> nodes) throws IgniteCheckedException {
+        exchLog.info("sendAllPartitions start [topVer=" + topologyVersion() + ']');
+
         GridDhtPartitionsFullMessage m = createPartitionsMessage(nodes, true);
 
         assert !nodes.contains(cctx.localNode());
@@ -1199,6 +1227,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
                 ", exchId=" + exchId + ", msg=" + m + ']');
 
         cctx.io().safeSend(nodes, m, SYSTEM_POOL, null);
+
+        exchLog.info("sendAllPartitions end [topVer=" + topologyVersion() + ']');
     }
 
     /**
@@ -1313,6 +1343,10 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         cctx.database().releaseHistoryForExchange();
 
         if (super.onDone(res, err) && realExchange) {
+            exchLog.info("exchange finished [topVer=" + topologyVersion() +
+                ", time1=" + duration() +
+                ", time2=" + (U.currentTimeMillis() - initTs) + ']');
+
             if (log.isDebugEnabled())
                 log.debug("Completed partition exchange [localNode=" + cctx.localNodeId() + ", exchange= " + this +
                     "duration=" + duration() + ", durationFromInit=" + (U.currentTimeMillis() - initTs) + ']');
@@ -1526,6 +1560,9 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         }
     }
 
+    @GridToStringExclude
+    private GridAtomicLong maxTime = new GridAtomicLong();
+
     /**
      * @param node Sender node.
      * @param msg Message.
@@ -1534,6 +1571,13 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         boolean allReceived = false;
         boolean updateSingleMap = false;
 
+        long start = U.currentTimeMillis();
+
+        exchLog.info("processSingleMessage start [topVer=" + topologyVersion() +
+            ", fromId=" + node.id() +
+            ", fromOrder=" + node.order() +
+            ']');
+
         synchronized (mux) {
             assert crd != null;
 
@@ -1554,6 +1598,16 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         if (updateSingleMap)
             updatePartitionSingleMap(node, msg);
 
+        long time = U.currentTimeMillis() - start;
+
+        maxTime.setIfGreater(time);
+
+        exchLog.info("processSingleMessage end [topVer=" + topologyVersion() +
+            ", fromId=" + node.id() +
+            ", fromOrder=" + node.order() +
+            ", time=" + time +
+            ", maxTime=" + maxTime.get() + ']');
+
         if (allReceived)
             onAllReceived();
     }
@@ -1917,6 +1971,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         assert msg.exchangeId().equals(exchId) : msg;
         assert msg.lastVersion() != null : msg;
 
+        exchLog.info("processFullMessage start [topVer=" + topologyVersion() + ']');
+
         synchronized (mux) {
             if (crd == null)
                 return;
@@ -1938,6 +1994,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
         if (exchangeOnChangeGlobalState && !F.isEmpty(msg.getExceptionsMap()))
             cctx.kernalContext().state().onFullResponseMessage(msg.getExceptionsMap());
 
+        exchLog.info("processFullMessage end [topVer=" + topologyVersion() + ']');
+
         onDone(exchId.topologyVersion());
     }
 
@@ -1978,7 +2036,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
      * @param msg Partitions single message.
      */
     private void updatePartitionSingleMap(ClusterNode node, GridDhtPartitionsSingleMessage msg) {
-        msgs.put(node.id(), msg);
+        if (cctx.database().persistenceEnabled())
+            msgs.put(node.id(), msg);
 
         for (Map.Entry<Integer, GridDhtPartitionMap2> entry : msg.partitions().entrySet()) {
             Integer cacheId = entry.getKey();

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java
new file mode 100644
index 0000000..72f8469
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridPartitionStateMap.java
@@ -0,0 +1,174 @@
+/*
+ * 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.util;
+
+import java.io.Externalizable;
+import java.io.Serializable;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.BitSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState;
+
+/**
+ * Grid partition state map. States are encoded using bits.
+ * <p>
+ * Null values are prohibited.
+ */
+public class GridPartitionStateMap extends AbstractMap<Integer, GridDhtPartitionState> implements Serializable {
+    /** */
+    private static final long serialVersionUID = 0L;
+
+    /** Required bits to hold all state. Additional zero state is required as well. */
+    private static final int BITS = Integer.SIZE -
+        Integer.numberOfLeadingZeros(GridDhtPartitionState.values().length + 1);
+
+    /** */
+    private final BitSet states;
+
+    /** */
+    private int size;
+
+    /** {@inheritDoc} */
+    @Override public Set<Entry<Integer, GridDhtPartitionState>> entrySet() {
+        return new AbstractSet<Entry<Integer, GridDhtPartitionState>>() {
+            @Override public Iterator<Entry<Integer, GridDhtPartitionState>> iterator() {
+                final int size = states.length() == 0 ? 0 : (states.length() - 1)/ BITS + 1;
+
+                return new Iterator<Entry<Integer, GridDhtPartitionState>>() {
+                    private int next;
+                    private int cur;
+
+                    @Override public boolean hasNext() {
+                        while(state(next) == null && next < size)
+                            next++;
+
+                        return next < size;
+                    }
+
+                    @Override public Entry<Integer, GridDhtPartitionState> next() {
+                        cur = next;
+                        next++;
+
+                        return new Entry<Integer, GridDhtPartitionState>() {
+                            int p = cur;
+
+                            @Override public Integer getKey() {
+                                return p;
+                            }
+
+                            @Override public GridDhtPartitionState getValue() {
+                                return state(p);
+                            }
+
+                            @Override public GridDhtPartitionState setValue(GridDhtPartitionState val) {
+                                return setState(p, val);
+                            }
+                        };
+                    }
+
+                    @Override public void remove() {
+                        setState(cur, null);
+                    }
+                };
+            }
+
+            @Override public int size() {
+                return GridPartitionStateMap.this.size();
+            }
+        };
+    }
+
+    /**
+     * Default constructor.
+     */
+    public GridPartitionStateMap() {
+        states = new BitSet();
+    }
+
+    /**
+     * @param parts Partitions to hold.
+     */
+    public GridPartitionStateMap(int parts) {
+        states = new BitSet(parts);
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridDhtPartitionState put(Integer key, GridDhtPartitionState val) {
+        assert val != null;
+
+        return setState(key, val);
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridDhtPartitionState get(Object key) {
+        return state((Integer)key);
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridDhtPartitionState remove(Object key) {
+        return setState((Integer)key, null);
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean containsKey(Object key) {
+        return state((Integer)key) != null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int size() {
+        return size;
+    }
+
+    /** */
+    private GridDhtPartitionState setState(int part, GridDhtPartitionState st) {
+        GridDhtPartitionState old = state(part);
+
+        if (old == st)
+            return old;
+
+        int off = part * BITS;
+
+        int ist = st == null ? 0 : st.ordinal() + 1; // Reserve all zero bits for empty value
+
+        for (int i = 0; i < BITS; i++) {
+            states.set(off + i, (ist & 1) == 1);
+
+            ist >>>= 1;
+        }
+
+        size += (st == null ? -1 : old == null ? 1 : 0);
+
+        return old;
+    }
+
+    /** */
+    private GridDhtPartitionState state(int part) {
+        int off = part * BITS;
+
+        int st = 0;
+
+        for (int i = 0; i < BITS; i++)
+            st |= ((states.get(off + i) ? 1 : 0) << i);
+
+        return st == 0 ? null : GridDhtPartitionState.values()[st - 1];
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/52556f4b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
index d812c21..47498dd 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/communication/tcp/TcpCommunicationSpi.java
@@ -2784,10 +2784,23 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
 
         // Try to connect first on bound addresses.
         if (isRmtAddrsExist) {
-            List<InetSocketAddress> addrs0 = new ArrayList<>(U.toSocketAddresses(rmtAddrs0, rmtHostNames0, boundPort));
-
             boolean sameHost = U.sameMacs(getSpiContext().localNode(), node);
 
+            List<InetSocketAddress> addrs0;
+
+            Collection<InetSocketAddress> socketAddrs = U.toSocketAddresses(rmtAddrs0, rmtHostNames0, boundPort);
+
+            if (sameHost)
+                addrs0 = new ArrayList<>(socketAddrs);
+            else {
+                addrs0 = new ArrayList<>(socketAddrs.size());
+
+                for (InetSocketAddress addr0 : socketAddrs) {
+                    if (!addr0.getAddress().isLoopbackAddress())
+                        addrs0.add(addr0);
+                }
+            }
+
             Collections.sort(addrs0, U.inetAddressesComparator(sameHost));
 
             addrs = new LinkedHashSet<>(addrs0);


[15/50] [abbrv] ignite git commit: GG-11992 Add EnforceJoinOrder option.

Posted by sb...@apache.org.
GG-11992 Add EnforceJoinOrder option.


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: ef35f4f42bde09ad890e586ecfd61933e7399378
Parents: 1118c72
Author: Alexey Kuznetsov <ak...@gridgain.com>
Authored: Wed Mar 1 23:25:21 2017 +0700
Committer: Alexey Kuznetsov <ak...@gridgain.com>
Committed: Wed Mar 1 23:25:21 2017 +0700

----------------------------------------------------------------------
 .../ignite/internal/visor/query/VisorQueryArg.java  | 16 +++++++++++++++-
 .../ignite/internal/visor/query/VisorQueryJob.java  |  1 +
 .../commands/cache/VisorCacheScanCommand.scala      |  2 +-
 3 files changed, 17 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ef35f4f4/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java
index a5eb3eb..74f5b97 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryArg.java
@@ -35,6 +35,9 @@ public class VisorQueryArg implements Serializable {
     /** Distributed joins enabled flag. */
     private final boolean distributedJoins;
 
+    /** Enforce join order flag. */
+    private final boolean enforceJoinOrder;
+
     /** Flag whether to execute query locally. */
     private final boolean loc;
 
@@ -44,13 +47,17 @@ public class VisorQueryArg implements Serializable {
     /**
      * @param cacheName Cache name for query.
      * @param qryTxt Query text.
+     * @param distributedJoins If {@code true} then distributed joins enabled.
+     * @param enforceJoinOrder If {@code true} then enforce join order.
      * @param loc Flag whether to execute query locally.
      * @param pageSize Result batch size.
      */
-    public VisorQueryArg(String cacheName, String qryTxt, boolean distributedJoins, boolean loc, int pageSize) {
+    public VisorQueryArg(String cacheName, String qryTxt,
+        boolean distributedJoins, boolean enforceJoinOrder, boolean loc, int pageSize) {
         this.cacheName = cacheName;
         this.qryTxt = qryTxt;
         this.distributedJoins = distributedJoins;
+        this.enforceJoinOrder = enforceJoinOrder;
         this.loc = loc;
         this.pageSize = pageSize;
     }
@@ -77,6 +84,13 @@ public class VisorQueryArg implements Serializable {
     }
 
     /**
+     * @return Enforce join order flag.
+     */
+    public boolean enforceJoinOrder() {
+        return enforceJoinOrder;
+    }
+
+    /**
      * @return {@code true} if query should be executed locally.
      */
     public boolean local() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ef35f4f4/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java
index cc1c678..95ac39b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java
@@ -162,6 +162,7 @@ public class VisorQueryJob extends VisorJob<VisorQueryArg, IgniteBiTuple<? exten
                 qry.setPageSize(arg.pageSize());
                 qry.setLocal(arg.local());
                 qry.setDistributedJoins(arg.distributedJoins());
+                qry.setEnforceJoinOrder(arg.enforceJoinOrder());
 
                 long start = U.currentTimeMillis();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ef35f4f4/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheScanCommand.scala
----------------------------------------------------------------------
diff --git a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheScanCommand.scala b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheScanCommand.scala
index 39b2ce4..9668072 100644
--- a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheScanCommand.scala
+++ b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/cache/VisorCacheScanCommand.scala
@@ -139,7 +139,7 @@ class VisorCacheScanCommand {
         val firstPage =
             try
                 executeRandom(groupForDataNode(node, cacheName),
-                    classOf[VisorQueryTask], new VisorQueryArg(cacheName, null, false, false, pageSize)) match {
+                    classOf[VisorQueryTask], new VisorQueryArg(cacheName, null, false, false, false, pageSize)) match {
                     case x if x.get1() != null =>
                         error(x.get1())
 


[18/50] [abbrv] ignite git commit: IGNITE-3477 - Log partition destroy to WAL

Posted by sb...@apache.org.
IGNITE-3477 - Log partition destroy to WAL


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

Branch: refs/heads/ignite-gg-8.0.3.ea6-clients-test
Commit: e4b05d53d52ce3500e409d7275942d92e23db01b
Parents: b51a2f8
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Tue Mar 7 18:01:31 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Mar 7 18:01:31 2017 +0300

----------------------------------------------------------------------
 .../internal/pagemem/wal/record/WALRecord.java  |  5 +-
 .../MetaPageUpdatePartitionDataRecord.java      | 17 +++-
 .../record/delta/PartitionDestroyRecord.java    | 73 ++++++++++++++++++
 .../record/delta/PartitionMetaStateRecord.java  |  2 +-
 .../dht/preloader/GridDhtPartitionDemander.java | 81 ++++++++++----------
 5 files changed, 135 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e4b05d53/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
index 9c2c88a..142f0ee 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/WALRecord.java
@@ -160,7 +160,10 @@ public abstract class WALRecord {
         DATA_PAGE_UPDATE_RECORD,
 
         /** init */
-        BTREE_META_PAGE_INIT_ROOT2
+        BTREE_META_PAGE_INIT_ROOT2,
+
+        /** Partition destroy. */
+        PARTITION_DESTROY
         ;
 
         /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/e4b05d53/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
index 66efc6f..ef57c46 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/MetaPageUpdatePartitionDataRecord.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.pagemem.wal.record.delta;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.processors.cache.database.tree.io.PagePartitionMetaIO;
+import org.apache.ignite.internal.util.typedef.internal.S;
 
 /**
  *
@@ -45,8 +46,15 @@ public class MetaPageUpdatePartitionDataRecord extends PageDeltaRecord {
      * @param pageId Page ID.
      * @param allocatedIdxCandidate Page Allocated index candidate
      */
-    public MetaPageUpdatePartitionDataRecord(int cacheId, long pageId, long updateCntr, long globalRmvId, int partSize,
-        byte state, int allocatedIdxCandidate) {
+    public MetaPageUpdatePartitionDataRecord(
+        int cacheId,
+        long pageId,
+        long updateCntr,
+        long globalRmvId,
+        int partSize,
+        byte state,
+        int allocatedIdxCandidate
+    ) {
         super(cacheId, pageId);
 
         this.updateCntr = updateCntr;
@@ -104,4 +112,9 @@ public class MetaPageUpdatePartitionDataRecord extends PageDeltaRecord {
     @Override public RecordType type() {
         return RecordType.PARTITION_META_PAGE_UPDATE_COUNTERS;
     }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(MetaPageUpdatePartitionDataRecord.class, this);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/e4b05d53/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionDestroyRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionDestroyRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionDestroyRecord.java
new file mode 100644
index 0000000..c3b8200
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionDestroyRecord.java
@@ -0,0 +1,73 @@
+/*
+ * 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.pagemem.wal.record.delta;
+
+import org.apache.ignite.internal.pagemem.wal.record.WALRecord;
+
+/**
+ *
+ */
+public class PartitionDestroyRecord extends WALRecord {
+    /** */
+    private int cacheId;
+
+    /** */
+    private int partId;
+
+    /**
+     * @param cacheId Cache ID.
+     * @param partId Partition ID.
+     */
+    public PartitionDestroyRecord(int cacheId, int partId) {
+        this.cacheId = cacheId;
+        this.partId = partId;
+    }
+
+    /** {@inheritDoc} */
+    @Override public RecordType type() {
+        return RecordType.PARTITION_DESTROY;
+    }
+
+    /**
+     * @return Cache ID.
+     */
+    public int cacheId() {
+        return cacheId;
+    }
+
+    /**
+     * @param cacheId Cache ID.
+     */
+    public void cacheId(int cacheId) {
+        this.cacheId = cacheId;
+    }
+
+    /**
+     * @return Partition ID.
+     */
+    public int partitionId() {
+        return partId;
+    }
+
+    /**
+     * @param partId Partition ID.
+     */
+    public void partitionId(int partId) {
+        this.partId = partId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e4b05d53/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
index fd8b2fd..95e1a56 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/wal/record/delta/PartitionMetaStateRecord.java
@@ -69,7 +69,7 @@ public class PartitionMetaStateRecord extends WALRecord {
     /**
      *
      */
-    public int partId() {
+    public int partitionId() {
         return partId;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/e4b05d53/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 ce43ec4..4f8d13b 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
@@ -778,8 +778,6 @@ public class GridDhtPartitionDemander {
         GridCacheEntryInfo entry,
         AffinityTopologyVersion topVer
     ) throws IgniteCheckedException {
-        cctx.shared().database().checkpointReadLock();
-
         try {
             GridCacheEntryEx cached = null;
 
@@ -800,34 +798,41 @@ public class GridDhtPartitionDemander {
                     return true;
                 }
 
-                if (preloadPred == null || preloadPred.apply(entry)) {
-                    if (cached.initialValue(
-                        entry.value(),
-                        entry.version(),
-                        entry.ttl(),
-                        entry.expireTime(),
-                        true,
-                        topVer,
-                        cctx.isDrEnabled() ? DR_PRELOAD : DR_NONE,
-                        false
-                    )) {
-                        cctx.evicts().touch(cached, topVer); // Start tracking.
-
-                        if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_OBJECT_LOADED) && !cached.isInternal())
-                            cctx.events().addEvent(cached.partition(), cached.key(), cctx.localNodeId(),
-                                (IgniteUuid)null, null, EVT_CACHE_REBALANCE_OBJECT_LOADED, entry.value(), true, null,
-                                false, null, null, null, true);
-                    }
-                    else {
-                        cctx.evicts().touch(cached, topVer); // Start tracking.
+                cctx.shared().database().checkpointReadLock();
 
-                        if (log.isDebugEnabled())
-                            log.debug("Rebalancing entry is already in cache (will ignore) [key=" + cached.key() +
-                                ", part=" + p + ']');
+                try {
+                    if (preloadPred == null || preloadPred.apply(entry)) {
+                        if (cached.initialValue(
+                            entry.value(),
+                            entry.version(),
+                            entry.ttl(),
+                            entry.expireTime(),
+                            true,
+                            topVer,
+                            cctx.isDrEnabled() ? DR_PRELOAD : DR_NONE,
+                            false
+                        )) {
+                            cctx.evicts().touch(cached, topVer); // Start tracking.
+
+                            if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_OBJECT_LOADED) && !cached.isInternal())
+                                cctx.events().addEvent(cached.partition(), cached.key(), cctx.localNodeId(),
+                                    (IgniteUuid)null, null, EVT_CACHE_REBALANCE_OBJECT_LOADED, entry.value(), true, null,
+                                    false, null, null, null, true);
+                        }
+                        else {
+                            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);
+                }
+                finally {
+                    cctx.shared().database().checkpointReadUnlock();
                 }
-                else if (log.isDebugEnabled())
-                    log.debug("Rebalance predicate evaluated to false for entry (will ignore): " + entry);
             }
             catch (GridCacheEntryRemovedException ignored) {
                 if (log.isDebugEnabled())
@@ -848,9 +853,6 @@ public class GridDhtPartitionDemander {
             throw new IgniteCheckedException("Failed to cache rebalanced entry (will stop rebalancing) [local=" +
                 cctx.nodeId() + ", node=" + pick.id() + ", key=" + entry.key() + ", part=" + p + ']', e);
         }
-        finally {
-            cctx.shared().database().checkpointReadUnlock();
-        }
 
         return true;
     }
@@ -911,8 +913,9 @@ public class GridDhtPartitionDemander {
             long updateSeq) {
             assert assigns != null;
 
-            this.exchFut = assigns.exchangeFuture();
-            this.topVer = assigns.topologyVersion();
+            exchFut = assigns.exchangeFuture();
+            topVer = assigns.topologyVersion();
+
             this.cctx = cctx;
             this.log = log;
             this.startedEvtSent = startedEvtSent;
@@ -924,13 +927,13 @@ public class GridDhtPartitionDemander {
          * Dummy future. Will be done by real one.
          */
         public RebalanceFuture() {
-            this.exchFut = null;
-            this.topVer = null;
-            this.cctx = null;
-            this.log = null;
-            this.startedEvtSent = null;
-            this.stoppedEvtSent = null;
-            this.updateSeq = -1;
+            exchFut = null;
+            topVer = null;
+            cctx = null;
+            log = null;
+            startedEvtSent = null;
+            stoppedEvtSent = null;
+            updateSeq = -1;
         }
 
         /**