You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vk...@apache.org on 2015/11/19 05:32:13 UTC
[01/51] ignite git commit: Ignite-1093 "Rebalancing with default
parameters is very slow" fixes.
Repository: ignite
Updated Branches:
refs/heads/ignite-direct-marsh-opt 393b630ef -> 1c697f35f
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 998c720..c634ff5 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
@@ -17,15 +17,18 @@
package org.apache.ignite.internal.processors.cache.distributed.dht.preloader;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ignite.IgniteCheckedException;
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.IgniteInternalFuture;
@@ -47,27 +50,42 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalP
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
import org.apache.ignite.internal.util.GridAtomicLong;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
+import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.GridPlainRunnable;
import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.GPC;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
+import org.jsr166.ConcurrentLinkedDeque8;
+import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST;
import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_UNLOADED;
import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
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.util.GridConcurrentFactory.newMap;
/**
* DHT cache preloader.
*/
public class GridDhtPreloader extends GridCachePreloaderAdapter {
+ /**
+ * Rebalancing was refactored at version 1.5.0, but backward compatibility to previous implementation was saved.
+ * Node automatically chose communication protocol depends on remote node's version.
+ * Backward compatibility may be removed at Ignite 2.x.
+ */
+ public static final IgniteProductVersion REBALANCING_VER_2_SINCE = IgniteProductVersion.fromString("1.5.0");
+
/** Default preload resend timeout. */
public static final long DFLT_PRELOAD_RESEND_TIMEOUT = 1500;
@@ -81,10 +99,10 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
private final ConcurrentMap<IgniteUuid, GridDhtForceKeysFuture<?, ?>> forceKeyFuts = newMap();
/** Partition suppliers. */
- private GridDhtPartitionSupplyPool supplyPool;
+ private GridDhtPartitionSupplier supplier;
/** Partition demanders. */
- private GridDhtPartitionDemandPool demandPool;
+ private GridDhtPartitionDemander demander;
/** Start future. */
private GridFutureAdapter<Object> startFut;
@@ -92,10 +110,19 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
/** Busy lock to prevent activities from accessing exchanger while it's stopping. */
private final ReadWriteLock busyLock = new ReentrantReadWriteLock();
+ /** Demand lock. */
+ private final ReadWriteLock demandLock = new ReentrantReadWriteLock();
+
/** Pending affinity assignment futures. */
private ConcurrentMap<AffinityTopologyVersion, GridDhtAssignmentFetchFuture> pendingAssignmentFetchFuts =
new ConcurrentHashMap8<>();
+ /** */
+ private final ConcurrentLinkedDeque8<GridDhtLocalPartition> partsToEvict = new ConcurrentLinkedDeque8<>();
+
+ /** */
+ private final AtomicInteger partsEvictOwning = new AtomicInteger();
+
/** Discovery listener. */
private final GridLocalEventListener discoLsnr = new GridLocalEventListener() {
@Override public void onEvent(Event evt) {
@@ -179,8 +206,11 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
}
});
- supplyPool = new GridDhtPartitionSupplyPool(cctx, busyLock);
- demandPool = new GridDhtPartitionDemandPool(cctx, busyLock);
+ supplier = new GridDhtPartitionSupplier(cctx);
+ demander = new GridDhtPartitionDemander(cctx, busyLock);
+
+ supplier.start();
+ demander.start();
cctx.events().addListener(discoLsnr, EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED);
}
@@ -197,19 +227,16 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
final long startTopVer = loc.order();
topVer.setIfGreater(startTopVer);
-
- supplyPool.start();
- demandPool.start();
}
/** {@inheritDoc} */
@Override public void preloadPredicate(IgnitePredicate<GridCacheEntryInfo> preloadPred) {
super.preloadPredicate(preloadPred);
- assert supplyPool != null && demandPool != null : "preloadPredicate may be called only after start()";
+ assert supplier != null && demander != null : "preloadPredicate may be called only after start()";
- supplyPool.preloadPredicate(preloadPred);
- demandPool.preloadPredicate(preloadPred);
+ supplier.preloadPredicate(preloadPred);
+ demander.preloadPredicate(preloadPred);
}
/** {@inheritDoc} */
@@ -223,37 +250,109 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
// Acquire write busy lock.
busyLock.writeLock().lock();
- if (supplyPool != null)
- supplyPool.stop();
+ if (supplier != null)
+ supplier.stop();
- if (demandPool != null)
- demandPool.stop();
+ if (demander != null)
+ demander.stop();
top = null;
}
/** {@inheritDoc} */
@Override public void onInitialExchangeComplete(@Nullable Throwable err) {
- if (err == null) {
+ if (err == null)
startFut.onDone();
+ else
+ startFut.onDone(err);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void updateLastExchangeFuture(GridDhtPartitionsExchangeFuture lastFut) {
+ demander.updateLastExchangeFuture(lastFut);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTopologyChanged(AffinityTopologyVersion topVer) {
+ supplier.onTopologyChanged(topVer);
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtPreloaderAssignments assign(GridDhtPartitionsExchangeFuture exchFut) {
+ // No assignments for disabled preloader.
+ GridDhtPartitionTopology top = cctx.dht().topology();
+
+ if (!cctx.rebalanceEnabled())
+ return new GridDhtPreloaderAssignments(exchFut, top.topologyVersion());
+
+ int partCnt = cctx.affinity().partitions();
- final long start = U.currentTimeMillis();
+ assert exchFut.forcePreload() || exchFut.dummyReassign() ||
+ exchFut.exchangeId().topologyVersion().equals(top.topologyVersion()) :
+ "Topology version mismatch [exchId=" + exchFut.exchangeId() +
+ ", topVer=" + top.topologyVersion() + ']';
- final CacheConfiguration cfg = cctx.config();
+ GridDhtPreloaderAssignments assigns = new GridDhtPreloaderAssignments(exchFut, top.topologyVersion());
- if (cfg.getRebalanceDelay() >= 0 && !cctx.kernalContext().clientNode()) {
- U.log(log, "Starting rebalancing in " + cfg.getRebalanceMode() + " mode: " + cctx.name());
+ AffinityTopologyVersion topVer = assigns.topologyVersion();
- demandPool.syncFuture().listen(new CI1<Object>() {
- @Override public void apply(Object t) {
- U.log(log, "Completed rebalancing in " + cfg.getRebalanceMode() + " mode " +
- "[cache=" + cctx.name() + ", time=" + (U.currentTimeMillis() - start) + " ms]");
+ for (int p = 0; p < partCnt; p++) {
+ if (cctx.shared().exchange().hasPendingExchange()) {
+ if (log.isDebugEnabled())
+ log.debug("Skipping assignments creation, exchange worker has pending assignments: " +
+ exchFut.exchangeId());
+
+ break;
+ }
+
+ // If partition belongs to local node.
+ if (cctx.affinity().localNode(p, topVer)) {
+ GridDhtLocalPartition part = top.localPartition(p, topVer, 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.
+ }
+
+ 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);
+ }
}
}
- else
- startFut.onDone(err);
+
+ return assigns;
}
/** {@inheritDoc} */
@@ -267,24 +366,77 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
topVer.set(topVer0);
}
- /** {@inheritDoc} */
- @Override public void onExchangeFutureAdded() {
- demandPool.onExchangeFutureAdded();
+ /**
+ * @param p Partition.
+ * @param topVer Topology version.
+ * @return Picked owners.
+ */
+ private Collection<ClusterNode> pickedOwners(int p, AffinityTopologyVersion topVer) {
+ Collection<ClusterNode> affNodes = cctx.affinity().nodes(p, topVer);
+
+ int affCnt = affNodes.size();
+
+ Collection<ClusterNode> rmts = remoteOwners(p, topVer);
+
+ int rmtCnt = rmts.size();
+
+ if (rmtCnt <= affCnt)
+ return rmts;
+
+ List<ClusterNode> sorted = new ArrayList<>(rmts);
+
+ // Sort in descending order, so nodes with higher order will be first.
+ Collections.sort(sorted, CU.nodeComparator(false));
+
+ // Pick newest nodes.
+ return sorted.subList(0, affCnt);
+ }
+
+ /**
+ * @param p Partition.
+ * @param topVer Topology version.
+ * @return Nodes owning this partition.
+ */
+ private Collection<ClusterNode> remoteOwners(int p, AffinityTopologyVersion topVer) {
+ return F.view(cctx.dht().topology().owners(p, topVer), F.remoteNodes(cctx.nodeId()));
}
/** {@inheritDoc} */
- @Override public void updateLastExchangeFuture(GridDhtPartitionsExchangeFuture lastFut) {
- demandPool.updateLastExchangeFuture(lastFut);
+ public void handleSupplyMessage(int idx, UUID id, final GridDhtPartitionSupplyMessageV2 s) {
+ if (!enterBusy())
+ return;
+
+ try {
+ demandLock.readLock().lock();
+ try {
+ demander.handleSupplyMessage(idx, id, s);
+ }
+ finally {
+ demandLock.readLock().unlock();
+ }
+ }
+ finally {
+ leaveBusy();
+ }
}
/** {@inheritDoc} */
- @Override public GridDhtPreloaderAssignments assign(GridDhtPartitionsExchangeFuture exchFut) {
- return demandPool.assign(exchFut);
+ public void handleDemandMessage(int idx, UUID id, GridDhtPartitionDemandMessage d) {
+ if (!enterBusy())
+ return;
+
+ try {
+ supplier.handleDemandMessage(idx, id, d);
+ }
+ finally {
+ leaveBusy();
+ }
}
/** {@inheritDoc} */
- @Override public void addAssignments(GridDhtPreloaderAssignments assignments, boolean forcePreload) {
- demandPool.addAssignments(assignments, forcePreload);
+ @Override public Callable<Boolean> addAssignments(GridDhtPreloaderAssignments assignments,
+ boolean forcePreload, Collection<String> caches, int cnt) {
+ return demander.addAssignments(assignments, forcePreload, caches, cnt);
}
/**
@@ -296,7 +448,12 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
/** {@inheritDoc} */
@Override public IgniteInternalFuture<?> syncFuture() {
- return cctx.kernalContext().clientNode() ? startFut : demandPool.syncFuture();
+ return cctx.kernalContext().clientNode() ? startFut : demander.syncFuture();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteInternalFuture<Boolean> rebalanceFuture() {
+ return cctx.kernalContext().clientNode() ? new GridFinishedFuture<>(true) : demander.rebalanceFuture();
}
/**
@@ -580,12 +737,19 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
/** {@inheritDoc} */
@Override public void forcePreload() {
- demandPool.forcePreload();
+ demander.forcePreload();
}
/** {@inheritDoc} */
@Override public void unwindUndeploys() {
- demandPool.unwindUndeploys();
+ demandLock.writeLock().lock();
+
+ try {
+ cctx.deploy().unwind(cctx);
+ }
+ finally {
+ demandLock.writeLock().unlock();
+ }
}
/**
@@ -607,6 +771,44 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
}
/** {@inheritDoc} */
+ @Override public void evictPartitionAsync(GridDhtLocalPartition part) {
+ partsToEvict.add(part);
+
+ if (partsEvictOwning.get() == 0 && partsEvictOwning.compareAndSet(0, 1)) {
+ cctx.closures().callLocalSafe(new GPC<Boolean>() {
+ @Override public Boolean call() {
+ boolean locked = true;
+
+ while (locked || !partsToEvict.isEmptyx()) {
+ if (!locked && !partsEvictOwning.compareAndSet(0, 1))
+ return false;
+
+ try {
+ GridDhtLocalPartition part = partsToEvict.poll();
+
+ if (part != null)
+ part.tryEvict();
+ }
+ finally {
+ if (!partsToEvict.isEmptyx())
+ locked = true;
+ else {
+ boolean res = partsEvictOwning.compareAndSet(1, 0);
+
+ assert res;
+
+ locked = false;
+ }
+ }
+ }
+
+ return true;
+ }
+ }, /*system pool*/ true);
+ }
+ }
+
+ /** {@inheritDoc} */
@Override public void dumpDebugInfo() {
if (!forceKeyFuts.isEmpty()) {
U.warn(log, "Pending force key futures [cache=" + cctx.name() +"]:");
@@ -621,6 +823,8 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
for (GridDhtAssignmentFetchFuture fut : pendingAssignmentFetchFuts.values())
U.warn(log, ">>> " + fut);
}
+
+ supplier.dumpDebugInfo();
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java
index 7c5e97c..810bd8c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/DataStructuresProcessor.java
@@ -1292,6 +1292,9 @@ public final class DataStructuresProcessor extends GridProcessorAdapter {
catch (IgniteCheckedException e) {
U.error(log, "Failed to remove count down latch: " + latch0.name(), e);
}
+ finally {
+ ctx.cache().context().txContextReset();
+ }
}
});
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java
index 26a41de..9315d7c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/task/GridTaskWorker.java
@@ -696,7 +696,9 @@ class GridTaskWorker<T, R> extends GridWorker implements GridTimeoutObject {
if (log.isDebugEnabled())
U.warn(log, "Received response for unknown child job (was job presumed failed?): " + res);
- return;
+ selfOccupied = true;
+
+ continue;
}
// Only process 1st response and ignore following ones. This scenario
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridTuple4.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridTuple4.java b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridTuple4.java
index 835cdcb..c95a859 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridTuple4.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridTuple4.java
@@ -239,7 +239,7 @@ public class GridTuple4<V1, V2, V3, V4> implements Iterable<Object>, Externaliza
GridTuple4<?, ?, ?, ?> t = (GridTuple4<?, ?, ?, ?>)o;
- return F.eq(val1, t.val2) && F.eq(val2, t.val2) && F.eq(val3, t.val3) && F.eq(val4, t.val4);
+ return F.eq(val1, t.val1) && F.eq(val2, t.val2) && F.eq(val3, t.val3) && F.eq(val4, t.val4);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
index 6254605..854ce95 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySpi.java
@@ -1956,7 +1956,7 @@ public class TcpDiscoverySpi extends IgniteSpiAdapter implements DiscoverySpi, T
* <p>
* This method is intended for test purposes only.
*/
- void simulateNodeFailure() {
+ protected void simulateNodeFailure() {
impl.simulateNodeFailure();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
index 1b2b84d..f4423f7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheP2pUnmarshallingErrorTest.java
@@ -87,7 +87,7 @@ public class IgniteCacheP2pUnmarshallingErrorTest extends IgniteCacheAbstractTes
}
/** Test key 1. */
- public static class TestKey implements Externalizable {
+ protected static class TestKey implements Externalizable {
/** Field. */
@QuerySqlField(index = true)
private String field;
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheTxNodeFailureSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheTxNodeFailureSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheTxNodeFailureSelfTest.java
index cadd03f..fe0b84e 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheTxNodeFailureSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridCacheTxNodeFailureSelfTest.java
@@ -17,6 +17,11 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import javax.cache.CacheException;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteException;
@@ -46,12 +51,6 @@ import org.apache.ignite.transactions.Transaction;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionRollbackException;
-import javax.cache.CacheException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-
import static org.apache.ignite.transactions.TransactionConcurrency.OPTIMISTIC;
import static org.apache.ignite.transactions.TransactionConcurrency.PESSIMISTIC;
import static org.apache.ignite.transactions.TransactionIsolation.REPEATABLE_READ;
@@ -192,13 +191,13 @@ public class GridCacheTxNodeFailureSelfTest extends GridCommonAbstractTest {
boolean backup,
final boolean commit
) throws Exception {
- startGrids(gridCount());
- awaitPartitionMapExchange();
+ try {
+ startGrids(gridCount());
+ awaitPartitionMapExchange();
- for (int i = 0; i < gridCount(); i++)
- info("Grid " + i + ": " + ignite(i).cluster().localNode().id());
+ for (int i = 0; i < gridCount(); i++)
+ info("Grid " + i + ": " + ignite(i).cluster().localNode().id());
- try {
final Ignite ignite = ignite(0);
final IgniteCache<Object, Object> cache = ignite.cache(null).withNoRetries();
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingAsyncSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingAsyncSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingAsyncSelfTest.java
new file mode 100644
index 0000000..7759c70
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingAsyncSelfTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.rebalancing;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.discovery.tcp.TestTcpDiscoverySpi;
+
+/**
+ *
+ */
+public class GridCacheRebalancingAsyncSelfTest extends GridCacheRebalancingSyncSelfTest {
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration iCfg = super.getConfiguration(gridName);
+
+ for (CacheConfiguration cacheCfg : iCfg.getCacheConfiguration()) {
+ cacheCfg.setRebalanceMode(CacheRebalanceMode.ASYNC);
+ }
+
+ return iCfg;
+ }
+
+ /**
+ * @throws Exception Exception.
+ */
+ public void testNodeFailedAtRebalancing() throws Exception {
+ Ignite ignite = startGrid(0);
+
+ generateData(ignite, 0, 0);
+
+ log.info("Preloading started.");
+
+ startGrid(1);
+
+ GridDhtPartitionDemander.RebalanceFuture fut = (GridDhtPartitionDemander.RebalanceFuture)grid(1).context().
+ cache().internalCache(CACHE_NAME_DHT_REPLICATED).preloader().rebalanceFuture();
+
+ fut.get();
+
+ U.sleep(10);
+
+ ((TestTcpDiscoverySpi)grid(1).configuration().getDiscoverySpi()).simulateNodeFailure();
+
+ waitForRebalancing(0, 3);
+
+ checkSupplyContextMapIsEmpty();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingSyncSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingSyncSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingSyncSelfTest.java
new file mode 100644
index 0000000..8c5cd40
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingSyncSelfTest.java
@@ -0,0 +1,506 @@
+/*
+ * 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.rebalancing;
+
+import java.util.Map;
+import java.util.Random;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemander;
+import org.apache.ignite.internal.util.typedef.G;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public class GridCacheRebalancingSyncSelfTest extends GridCommonAbstractTest {
+ /** */
+ protected static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+ /** */
+ private static int TEST_SIZE = 100_000;
+
+ /** partitioned cache name. */
+ protected static String CACHE_NAME_DHT_PARTITIONED = "cacheP";
+
+ /** partitioned cache 2 name. */
+ protected static String CACHE_NAME_DHT_PARTITIONED_2 = "cacheP2";
+
+ /** replicated cache name. */
+ protected static String CACHE_NAME_DHT_REPLICATED = "cacheR";
+
+ /** replicated cache 2 name. */
+ protected static String CACHE_NAME_DHT_REPLICATED_2 = "cacheR2";
+
+ /** */
+ private volatile boolean concurrentStartFinished;
+
+ /** */
+ private volatile boolean concurrentStartFinished2;
+
+ /** */
+ private volatile boolean concurrentStartFinished3;
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration iCfg = super.getConfiguration(gridName);
+
+ ((TcpDiscoverySpi)iCfg.getDiscoverySpi()).setIpFinder(ipFinder);
+ ((TcpDiscoverySpi)iCfg.getDiscoverySpi()).setForceServerMode(true);
+
+ if (getTestGridName(10).equals(gridName))
+ iCfg.setClientMode(true);
+
+ CacheConfiguration<Integer, Integer> cachePCfg = new CacheConfiguration<>();
+
+ cachePCfg.setName(CACHE_NAME_DHT_PARTITIONED);
+ cachePCfg.setCacheMode(CacheMode.PARTITIONED);
+ cachePCfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+ cachePCfg.setBackups(1);
+ cachePCfg.setRebalanceBatchSize(1);
+ cachePCfg.setRebalanceBatchesPrefetchCount(1);
+ cachePCfg.setRebalanceOrder(2);
+
+ CacheConfiguration<Integer, Integer> cachePCfg2 = new CacheConfiguration<>();
+
+ cachePCfg2.setName(CACHE_NAME_DHT_PARTITIONED_2);
+ cachePCfg2.setCacheMode(CacheMode.PARTITIONED);
+ cachePCfg2.setRebalanceMode(CacheRebalanceMode.SYNC);
+ cachePCfg2.setBackups(1);
+ cachePCfg2.setRebalanceOrder(2);
+ //cachePCfg2.setRebalanceDelay(5000);//Known issue, possible deadlock in case of low priority cache rebalancing delayed.
+
+ CacheConfiguration<Integer, Integer> cacheRCfg = new CacheConfiguration<>();
+
+ cacheRCfg.setName(CACHE_NAME_DHT_REPLICATED);
+ cacheRCfg.setCacheMode(CacheMode.REPLICATED);
+ cacheRCfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+ cacheRCfg.setRebalanceBatchSize(1);
+ cacheRCfg.setRebalanceBatchesPrefetchCount(Integer.MAX_VALUE);
+ ((TcpCommunicationSpi)iCfg.getCommunicationSpi()).setSharedMemoryPort(-1);//Shmem fail fix for Integer.MAX_VALUE.
+
+ CacheConfiguration<Integer, Integer> cacheRCfg2 = new CacheConfiguration<>();
+
+ cacheRCfg2.setName(CACHE_NAME_DHT_REPLICATED_2);
+ cacheRCfg2.setCacheMode(CacheMode.REPLICATED);
+ cacheRCfg2.setRebalanceMode(CacheRebalanceMode.SYNC);
+ cacheRCfg2.setRebalanceOrder(4);
+
+ iCfg.setCacheConfiguration(cachePCfg, cachePCfg2, cacheRCfg, cacheRCfg2);
+
+ iCfg.setRebalanceThreadPoolSize(2);
+
+ return iCfg;
+ }
+
+ /**
+ * @param ignite Ignite.
+ */
+ protected void generateData(Ignite ignite, int from, int iter) {
+ generateData(ignite, CACHE_NAME_DHT_PARTITIONED, from, iter);
+ generateData(ignite, CACHE_NAME_DHT_PARTITIONED_2, from, iter);
+ generateData(ignite, CACHE_NAME_DHT_REPLICATED, from, iter);
+ generateData(ignite, CACHE_NAME_DHT_REPLICATED_2, from, iter);
+ }
+
+ /**
+ * @param ignite Ignite.
+ */
+ protected void generateData(Ignite ignite, String name, int from, int iter) {
+ for (int i = from; i < from + TEST_SIZE; i++) {
+ if (i % (TEST_SIZE / 10) == 0)
+ log.info("Prepared " + i * 100 / (TEST_SIZE) + "% entries (" + TEST_SIZE + ").");
+
+ ignite.cache(name).put(i, i + name.hashCode() + iter);
+ }
+ }
+
+ /**
+ * @param ignite Ignite.
+ * @throws IgniteCheckedException Exception.
+ */
+ protected void checkData(Ignite ignite, int from, int iter) throws IgniteCheckedException {
+ checkData(ignite, CACHE_NAME_DHT_PARTITIONED, from, iter);
+ checkData(ignite, CACHE_NAME_DHT_PARTITIONED_2, from, iter);
+ checkData(ignite, CACHE_NAME_DHT_REPLICATED, from, iter);
+ checkData(ignite, CACHE_NAME_DHT_REPLICATED_2, from, iter);
+ }
+
+ /**
+ * @param ignite Ignite.
+ * @param name Cache name.
+ * @throws IgniteCheckedException Exception.
+ */
+ protected void checkData(Ignite ignite, String name, int from, int iter) throws IgniteCheckedException {
+ for (int i = from; i < from + TEST_SIZE; i++) {
+ if (i % (TEST_SIZE / 10) == 0)
+ log.info("<" + name + "> Checked " + i * 100 / (TEST_SIZE) + "% entries (" + TEST_SIZE + ").");
+
+ assert ignite.cache(name).get(i) != null && ignite.cache(name).get(i).equals(i + name.hashCode() + iter) :
+ i + " value " + (i + name.hashCode() + iter) + " does not match (" + ignite.cache(name).get(i) + ")";
+ }
+ }
+
+ /**
+ * @throws Exception Exception
+ */
+ public void testSimpleRebalancing() throws Exception {
+ Ignite ignite = startGrid(0);
+
+ generateData(ignite, 0, 0);
+
+ log.info("Preloading started.");
+
+ long start = System.currentTimeMillis();
+
+ startGrid(1);
+
+ waitForRebalancing(0, 2);
+ waitForRebalancing(1, 2);
+
+ stopGrid(0);
+
+ waitForRebalancing(1, 3);
+
+ startGrid(2);
+
+ waitForRebalancing(1, 4);
+ waitForRebalancing(2, 4);
+
+ stopGrid(2);
+
+ waitForRebalancing(1, 5);
+
+ long spend = (System.currentTimeMillis() - start) / 1000;
+
+ checkData(grid(1), 0, 0);
+
+ log.info("Spend " + spend + " seconds to rebalance entries.");
+ }
+
+ /**
+ * @throws Exception Exception
+ */
+ public void testLoadRebalancing() throws Exception {
+ final Ignite ignite = startGrid(0);
+
+ startGrid(1);
+
+ generateData(ignite, CACHE_NAME_DHT_PARTITIONED, 0, 0);
+
+ log.info("Preloading started.");
+
+ long start = System.currentTimeMillis();
+
+ concurrentStartFinished = false;
+
+ Thread t1 = new Thread() {
+ @Override public void run() {
+ Random rdm = new Random();
+
+ while (!concurrentStartFinished) {
+ for (int i = 0; i < TEST_SIZE; i++) {
+ if (i % (TEST_SIZE / 10) == 0)
+ log.info("Prepared " + i * 100 / (TEST_SIZE) + "% entries (" + TEST_SIZE + ").");
+
+ int ii = rdm.nextInt(TEST_SIZE);
+
+ ignite.cache(CACHE_NAME_DHT_PARTITIONED).put(ii, ii + CACHE_NAME_DHT_PARTITIONED.hashCode());
+ }
+ }
+ }
+ };
+
+ Thread t2 = new Thread() {
+ @Override public void run() {
+ while (!concurrentStartFinished) {
+ try {
+ checkData(ignite, CACHE_NAME_DHT_PARTITIONED, 0, 0);
+ }
+ catch (IgniteCheckedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ t1.start();
+ t2.start();
+
+ startGrid(2);
+ startGrid(3);
+
+ stopGrid(2);
+
+ startGrid(4);
+
+ waitForRebalancing(3, 6);
+ waitForRebalancing(4, 6);
+
+ concurrentStartFinished = true;
+
+ awaitPartitionMapExchange(true);
+
+ checkSupplyContextMapIsEmpty();
+
+ t1.join();
+ t2.join();
+
+ long spend = (System.currentTimeMillis() - start) / 1000;
+
+ info("Time to rebalance entries: " + spend);
+ }
+
+ /**
+ * @param id Node id.
+ * @param major Major ver.
+ * @param minor Minor ver.
+ * @throws IgniteCheckedException Exception.
+ */
+ protected void waitForRebalancing(int id, int major, int minor) throws IgniteCheckedException {
+ waitForRebalancing(id, new AffinityTopologyVersion(major, minor));
+ }
+
+ /**
+ * @param id Node id.
+ * @param major Major ver.
+ * @throws IgniteCheckedException Exception.
+ */
+ protected void waitForRebalancing(int id, int major) throws IgniteCheckedException {
+ waitForRebalancing(id, new AffinityTopologyVersion(major));
+ }
+
+ /**
+ * @param id Node id.
+ * @param top Topology version.
+ * @throws IgniteCheckedException
+ */
+ protected void waitForRebalancing(int id, AffinityTopologyVersion top) throws IgniteCheckedException {
+ boolean finished = false;
+
+ while (!finished) {
+ finished = true;
+
+ for (GridCacheAdapter c : grid(id).context().cache().internalCaches()) {
+ GridDhtPartitionDemander.RebalanceFuture fut = (GridDhtPartitionDemander.RebalanceFuture)c.preloader().rebalanceFuture();
+ if (fut.topologyVersion() == null || !fut.topologyVersion().equals(top)) {
+ finished = false;
+
+ break;
+ }
+ else if (!fut.get()) {
+ finished = false;
+
+ log.warning("Rebalancing finished with missed partitions.");
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ protected void checkSupplyContextMapIsEmpty() {
+ for (Ignite g : G.allGrids()) {
+ for (GridCacheAdapter c : ((IgniteEx)g).context().cache().internalCaches()) {
+
+ Object supplier = U.field(c.preloader(), "supplier");
+
+ Map map = U.field(supplier, "scMap");
+
+ synchronized (map) {
+ assert map.isEmpty();
+ }
+ }
+ }
+ }
+
+ @Override protected long getTestTimeout() {
+ return 5 * 60_000;
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testComplexRebalancing() throws Exception {
+ final Ignite ignite = startGrid(0);
+
+ generateData(ignite, 0, 0);
+
+ log.info("Preloading started.");
+
+ long start = System.currentTimeMillis();
+
+ concurrentStartFinished = false;
+ concurrentStartFinished2 = false;
+ concurrentStartFinished3 = false;
+
+ Thread t1 = new Thread() {
+ @Override public void run() {
+ try {
+ startGrid(1);
+ startGrid(2);
+
+ while (!concurrentStartFinished2) {
+ U.sleep(10);
+ }
+
+ waitForRebalancing(0, 5, 0);
+ waitForRebalancing(1, 5, 0);
+ waitForRebalancing(2, 5, 0);
+ waitForRebalancing(3, 5, 0);
+ waitForRebalancing(4, 5, 0);
+
+ //New cache should start rebalancing.
+ CacheConfiguration<Integer, Integer> cacheRCfg = new CacheConfiguration<>();
+
+ cacheRCfg.setName(CACHE_NAME_DHT_PARTITIONED + "_NEW");
+ cacheRCfg.setCacheMode(CacheMode.PARTITIONED);
+ cacheRCfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+
+ grid(0).getOrCreateCache(cacheRCfg);
+
+ while (!concurrentStartFinished3) {
+ U.sleep(10);
+ }
+
+ concurrentStartFinished = true;
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ Thread t2 = new Thread() {
+ @Override public void run() {
+ try {
+ startGrid(3);
+ startGrid(4);
+
+ concurrentStartFinished2 = true;
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ Thread t3 = new Thread() {
+ @Override public void run() {
+ generateData(ignite, 0, 1);
+
+ concurrentStartFinished3 = true;
+ }
+ };
+
+ t1.start();
+ t2.start();// Should cancel t1 rebalancing.
+ t3.start();
+
+ t1.join();
+ t2.join();
+ t3.join();
+
+ waitForRebalancing(0, 5, 1);
+ waitForRebalancing(1, 5, 1);
+ waitForRebalancing(2, 5, 1);
+ waitForRebalancing(3, 5, 1);
+ waitForRebalancing(4, 5, 1);
+
+ awaitPartitionMapExchange(true);
+
+ checkSupplyContextMapIsEmpty();
+
+ checkData(grid(4), 0, 1);
+
+ final Ignite ignite3 = grid(3);
+
+ Thread t4 = new Thread() {
+ @Override public void run() {
+ generateData(ignite3, 0, 2);
+
+ }
+ };
+
+ t4.start();
+
+ stopGrid(1);
+
+ waitForRebalancing(0, 6);
+ waitForRebalancing(2, 6);
+ waitForRebalancing(3, 6);
+ waitForRebalancing(4, 6);
+
+ awaitPartitionMapExchange(true);
+
+ checkSupplyContextMapIsEmpty();
+
+ stopGrid(0);
+
+ waitForRebalancing(2, 7);
+ waitForRebalancing(3, 7);
+ waitForRebalancing(4, 7);
+
+ awaitPartitionMapExchange(true);
+
+ checkSupplyContextMapIsEmpty();
+
+ stopGrid(2);
+
+ waitForRebalancing(3, 8);
+ waitForRebalancing(4, 8);
+
+ awaitPartitionMapExchange(true);
+
+ checkSupplyContextMapIsEmpty();
+
+ t4.join();
+
+ stopGrid(3);
+
+ waitForRebalancing(4, 9);
+
+ checkSupplyContextMapIsEmpty();
+
+ long spend = (System.currentTimeMillis() - start) / 1000;
+
+ checkData(grid(4), 0, 2);
+
+ log.info("Spend " + spend + " seconds to rebalance entries.");
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ stopAllGrids();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingUnmarshallingFailedSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingUnmarshallingFailedSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingUnmarshallingFailedSelfTest.java
new file mode 100644
index 0000000..831e82d
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/rebalancing/GridCacheRebalancingUnmarshallingFailedSelfTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.rebalancing;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.ignite.cache.CacheMode;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ *
+ */
+public class GridCacheRebalancingUnmarshallingFailedSelfTest extends GridCommonAbstractTest {
+ /** */
+ protected static TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+ /** partitioned cache name. */
+ protected static String CACHE = "cache";
+
+ /** Allows to change behavior of readExternal method. */
+ protected static AtomicInteger readCnt = new AtomicInteger();
+
+ /** Test key 1. */
+ private static class TestKey implements Externalizable {
+ /** Field. */
+ @QuerySqlField(index = true)
+ private String field;
+
+ /**
+ * @param field Test key 1.
+ */
+ public TestKey(String field) {
+ this.field = field;
+ }
+
+ /** Test key 1. */
+ public TestKey() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ TestKey key = (TestKey)o;
+
+ return !(field != null ? !field.equals(key.field) : key.field != null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return field != null ? field.hashCode() : 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(ObjectOutput out) throws IOException {
+ out.writeObject(field);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ field = (String)in.readObject();
+
+ if (readCnt.decrementAndGet() <= 0)
+ throw new IOException("Class can not be unmarshalled.");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration iCfg = super.getConfiguration(gridName);
+
+ CacheConfiguration<TestKey, Integer> cfg = new CacheConfiguration<>();
+
+ cfg.setName(CACHE);
+ cfg.setCacheMode(CacheMode.PARTITIONED);
+ cfg.setRebalanceMode(CacheRebalanceMode.SYNC);
+ cfg.setBackups(0);
+
+ iCfg.setCacheConfiguration(cfg);
+
+ return iCfg;
+ }
+
+ /**
+ * @throws Exception e.
+ */
+ public void test() throws Exception {
+ readCnt.set(Integer.MAX_VALUE);
+
+ startGrid(0);
+
+ for (int i = 0; i < 100; i++) {
+ grid(0).cache(CACHE).put(new TestKey(String.valueOf(i)), i);
+ }
+
+ readCnt.set(1);
+
+ startGrid(1);
+
+ readCnt.set(Integer.MAX_VALUE);
+
+ for (int i = 0; i < 50; i++) {
+ assert grid(1).cache(CACHE).get(new TestKey(String.valueOf(i))) != null;
+ }
+
+ stopGrid(0);
+
+ for (int i = 50; i < 100; i++) {
+ assert grid(1).cache(CACHE).get(new TestKey(String.valueOf(i))) == null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ stopAllGrids();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadSelfTest.java
index c4ad169..64f1495 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/replicated/preloader/GridCacheReplicatedPreloadSelfTest.java
@@ -142,26 +142,6 @@ public class GridCacheReplicatedPreloadSelfTest extends GridCommonAbstractTest {
}
/**
- * @throws Exception If failed.
- */
- public void testSingleZeroPoolSize() throws Exception {
- preloadMode = SYNC;
- poolSize = 0;
-
- try {
- startGrid(1);
-
- assert false : "Grid should have been failed to start.";
- }
- catch (IgniteCheckedException e) {
- info("Caught expected exception: " + e);
- }
- finally {
- stopAllGrids();
- }
- }
-
- /**
* @throws Exception If test failed.
*/
public void testIntegrity() throws Exception {
@@ -602,4 +582,4 @@ public class GridCacheReplicatedPreloadSelfTest extends GridCommonAbstractTest {
// No-op.
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
index 0280e9c..51d8a2d 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
@@ -511,23 +511,6 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
}
/**
- *
- */
- private static class TestTcpDiscoverySpi extends TcpDiscoverySpi {
- /** */
- private boolean ignorePingResponse;
-
- /** {@inheritDoc} */
- protected void writeToSocket(Socket sock, TcpDiscoveryAbstractMessage msg, long timeout) throws IOException,
- IgniteCheckedException {
- if (msg instanceof TcpDiscoveryPingResponse && ignorePingResponse)
- return;
- else
- super.writeToSocket(sock, msg, timeout);
- }
- }
-
- /**
* @throws Exception If any error occurs.
*/
public void testNodeAdded() throws Exception {
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TestTcpDiscoverySpi.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TestTcpDiscoverySpi.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TestTcpDiscoverySpi.java
new file mode 100644
index 0000000..dbc54bc
--- /dev/null
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TestTcpDiscoverySpi.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.spi.discovery.tcp;
+
+import java.io.IOException;
+import java.net.Socket;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage;
+import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryPingResponse;
+
+/**
+ *
+ */
+public class TestTcpDiscoverySpi extends TcpDiscoverySpi {
+ /** */
+ public boolean ignorePingResponse;
+
+ /** {@inheritDoc} */
+ protected void writeToSocket(Socket sock, TcpDiscoveryAbstractMessage msg, long timeout) throws IOException,
+ IgniteCheckedException {
+ if (msg instanceof TcpDiscoveryPingResponse && ignorePingResponse)
+ return;
+ else
+ super.writeToSocket(sock, msg, timeout);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void simulateNodeFailure() {
+ super.simulateNodeFailure();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index d133a84..41d4b4a 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -77,6 +77,7 @@ import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.spi.checkpoint.sharedfs.SharedFsCheckpointSpi;
import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.TestTcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -1228,7 +1229,7 @@ public abstract class GridAbstractTest extends TestCase {
cfg.setCommunicationSpi(commSpi);
- TcpDiscoverySpi discoSpi = new TcpDiscoverySpi();
+ TcpDiscoverySpi discoSpi = new TestTcpDiscoverySpi();
if (isDebug()) {
discoSpi.setMaxMissedHeartbeats(Integer.MAX_VALUE);
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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
index 28d5c73..71f3ee3 100644
--- 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
@@ -63,6 +63,8 @@ import org.apache.ignite.internal.processors.cache.GridCacheFuture;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.IgniteCacheProxy;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.colocated.GridDhtColocatedCache;
@@ -414,6 +416,15 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
*/
@SuppressWarnings("BusyWait")
protected void awaitPartitionMapExchange() throws InterruptedException {
+ awaitPartitionMapExchange(false);
+ }
+
+ /**
+ * @param waitEvicts If {@code true} will wait for evictions finished.
+ * @throws InterruptedException If interrupted.
+ */
+ @SuppressWarnings("BusyWait")
+ protected void awaitPartitionMapExchange(boolean waitEvicts) throws InterruptedException {
for (Ignite g : G.allGrids()) {
IgniteKernal g0 = (IgniteKernal)g;
@@ -451,7 +462,10 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
int actual = owners.size();
- if (affNodes.size() != owners.size() || !affNodes.containsAll(owners)) {
+ GridDhtLocalPartition loc = top.localPartition(p, readyVer, false);
+
+ if (affNodes.size() != owners.size() || !affNodes.containsAll(owners) ||
+ (waitEvicts && loc != null && loc.state() == GridDhtPartitionState.RENTING)) {
LT.warn(log(), null, "Waiting for topology map update [" +
"grid=" + g.name() +
", cache=" + cfg.getName() +
@@ -484,7 +498,9 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
if (i == 0)
start = System.currentTimeMillis();
- if (System.currentTimeMillis() - start > 30_000)
+ if (System.currentTimeMillis() - start > 30_000) {
+ U.dumpThreads(log);
+
throw new IgniteException("Timeout of waiting for topology map update [" +
"grid=" + g.name() +
", cache=" + cfg.getName() +
@@ -493,6 +509,7 @@ public abstract class GridCommonAbstractTest extends GridAbstractTest {
", p=" + p +
", readVer=" + readyVer +
", locNode=" + g.cluster().localNode() + ']');
+ }
Thread.sleep(200); // Busy wait.
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
index 796c531..c3c3659 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
@@ -49,6 +49,8 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheNea
import org.apache.ignite.internal.processors.cache.distributed.near.GridCacheNearPartitionedP2PEnabledByteArrayValuesSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePutArrayValueSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.near.IgniteTxReentryNearSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingAsyncSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingSyncSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheDaemonNodeReplicatedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedAtomicGetAndTransformStoreSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedBasicApiTest;
@@ -135,6 +137,8 @@ public class IgniteCacheTestSuite3 extends TestSuite {
suite.addTestSuite(IgniteTxReentryColocatedSelfTest.class);
suite.addTestSuite(GridCacheOrderedPreloadingSelfTest.class);
+ suite.addTestSuite(GridCacheRebalancingSyncSelfTest.class);
+ suite.addTestSuite(GridCacheRebalancingAsyncSelfTest.class);
// Test for byte array value special case.
suite.addTestSuite(GridCacheLocalByteArrayValuesSelfTest.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/indexing/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
index 0226046..582bfe3 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/spi/communication/tcp/GridOrderedMessageCancelSelfTest.java
@@ -107,25 +107,33 @@ public class GridOrderedMessageCancelSelfTest extends GridCommonAbstractTest {
* @throws Exception If failed.
*/
public void testTask() throws Exception {
+ Map map = U.field(((IgniteKernal)grid(0)).context().io(), "msgSetMap");
+
+ int initSize = map.size();
+
ComputeTaskFuture<?> fut = executeAsync(compute(grid(0).cluster().forRemotes()), Task.class, null);
- testMessageSet(fut);
+ testMessageSet(fut, initSize, map);
}
/**
* @throws Exception If failed.
*/
public void testTaskException() throws Exception {
+ Map map = U.field(((IgniteKernal)grid(0)).context().io(), "msgSetMap");
+
+ int initSize = map.size();
+
ComputeTaskFuture<?> fut = executeAsync(compute(grid(0).cluster().forRemotes()), FailTask.class, null);
- testMessageSet(fut);
+ testMessageSet(fut, initSize, map);
}
/**
* @param fut Future to cancel.
* @throws Exception If failed.
*/
- private void testMessageSet(IgniteFuture<?> fut) throws Exception {
+ private void testMessageSet(IgniteFuture<?> fut, int initSize, Map map) throws Exception {
cancelLatch.await();
assertTrue(fut.cancel());
@@ -134,11 +142,9 @@ public class GridOrderedMessageCancelSelfTest extends GridCommonAbstractTest {
assertTrue(U.await(finishLatch, 5000, MILLISECONDS));
- Map map = U.field(((IgniteKernal)grid(0)).context().io(), "msgSetMap");
-
info("Map: " + map);
- assertTrue(map.isEmpty());
+ assertEquals(map.size(), initSize);
}
/**
[39/51] ignite git commit: Optimizations for direct marshalling
Posted by vk...@apache.org.
Optimizations for direct marshalling
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6bf335cb
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6bf335cb
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6bf335cb
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 6bf335cb40487f77922b3032cb1a96f6a918f520
Parents: d8096be
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 17 17:38:12 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 17 17:38:12 2015 -0800
----------------------------------------------------------------------
.../org/apache/ignite/internal/direct/DirectByteBufferStream.java | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/6bf335cb/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
index 45a0f4b..c55eaac 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
@@ -303,9 +303,6 @@ public class DirectByteBufferStream {
/** */
private boolean lastFinished;
- /** */
- private boolean lastFinished;
-
/**
* @param msgFactory Message factory.
*/
[19/51] ignite git commit: Minor fix for StreamTransformer (JavaDoc)
Posted by vk...@apache.org.
Minor fix for StreamTransformer (JavaDoc)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9f7286e2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9f7286e2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9f7286e2
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 9f7286e2d41e6bd91106b317c3b25a47292666aa
Parents: 569dd21
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 10 17:47:19 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 10 17:47:19 2015 -0800
----------------------------------------------------------------------
.../main/java/org/apache/ignite/stream/StreamTransformer.java | 5 +++++
1 file changed, 5 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9f7286e2/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java b/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
index 4435c0a..176973e 100644
--- a/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
+++ b/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
@@ -29,6 +29,11 @@ import org.apache.ignite.cache.CacheEntryProcessor;
/**
* Convenience adapter to transform update existing values in streaming cache
* based on the previously cached value.
+ * <p>
+ * This transformer implement {@link EntryProcessor} and internally will call
+ * {@link IgniteCache#invoke(Object, EntryProcessor, Object...)} method. Note
+ * that the value received from the data streamer will be passed to the entry
+ * processor as an argument.
*/
public abstract class StreamTransformer<K, V> implements StreamReceiver<K, V>, EntryProcessor<K, V, Object> {
/** */
[22/51] ignite git commit: Reusing message reader per NIO session
Posted by vk...@apache.org.
Reusing message reader per NIO session
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/7123a73d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/7123a73d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/7123a73d
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 7123a73d1e80d568588a3cf44ea3e513f484093c
Parents: 1f5a409
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Thu Nov 12 21:34:35 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Thu Nov 12 21:34:35 2015 -0800
----------------------------------------------------------------------
.../internal/direct/DirectByteBufferStream.java | 53 ++++----
.../internal/direct/DirectMessageReader.java | 92 ++++++++++---
.../direct/DirectMessageReaderState.java | 128 +++++++++++++++++++
.../internal/direct/DirectMessageWriter.java | 4 +-
.../managers/communication/GridIoManager.java | 45 ++++---
.../internal/util/nio/GridDirectParser.java | 27 ++--
.../extensions/communication/MessageReader.java | 19 ++-
.../testframework/GridSpiTestContext.java | 4 +-
8 files changed, 287 insertions(+), 85 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
index cf56430..dc6e419 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
@@ -32,7 +32,6 @@ import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
-import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
import org.apache.ignite.plugin.extensions.communication.MessageWriter;
import sun.misc.Unsafe;
@@ -220,9 +219,6 @@ public class DirectByteBufferStream {
private final MessageFactory msgFactory;
/** */
- private final MessageFormatter msgFormatter;
-
- /** */
private ByteBuffer buf;
/** */
@@ -288,16 +284,11 @@ public class DirectByteBufferStream {
/** */
private boolean lastFinished;
- /** */
- private MessageReader reader;
-
/**
* @param msgFactory Message factory.
- * @param msgFormatter Message formatter.
*/
- public DirectByteBufferStream(MessageFactory msgFactory, MessageFormatter msgFormatter) {
+ public DirectByteBufferStream(MessageFactory msgFactory) {
this.msgFactory = msgFactory;
- this.msgFormatter = msgFormatter;
}
/**
@@ -942,7 +933,7 @@ public class DirectByteBufferStream {
* @return Message.
*/
@SuppressWarnings("unchecked")
- public <T extends Message> T readMessage() {
+ public <T extends Message> T readMessage(MessageReader reader) {
if (!msgTypeDone) {
if (!buf.hasRemaining()) {
lastFinished = false;
@@ -954,13 +945,21 @@ public class DirectByteBufferStream {
msg = type == Byte.MIN_VALUE ? null : msgFactory.create(type);
- if (msg != null)
- reader = msgFormatter.reader(msgFactory, msg.getClass());
-
msgTypeDone = true;
}
- lastFinished = msg == null || msg.readFrom(buf, reader);
+ if (msg != null) {
+ try {
+ reader.beforeInnerMessageRead();
+
+ lastFinished = msg.readFrom(buf, reader);
+ }
+ finally {
+ reader.afterInnerMessageRead(lastFinished);
+ }
+ }
+ else
+ lastFinished = true;
if (lastFinished) {
Message msg0 = msg;
@@ -977,10 +976,11 @@ public class DirectByteBufferStream {
/**
* @param itemType Component type.
* @param itemCls Component class.
+ * @param reader Reader.
* @return Array.
*/
@SuppressWarnings("unchecked")
- public <T> T[] readObjectArray(MessageCollectionItemType itemType, Class<T> itemCls) {
+ public <T> T[] readObjectArray(MessageCollectionItemType itemType, Class<T> itemCls, MessageReader reader) {
if (readSize == -1) {
int size = readInt();
@@ -995,7 +995,7 @@ public class DirectByteBufferStream {
objArr = itemCls != null ? (Object[])Array.newInstance(itemCls, readSize) : new Object[readSize];
for (int i = readItems; i < readSize; i++) {
- Object item = read(itemType);
+ Object item = read(itemType, reader);
if (!lastFinished)
return null;
@@ -1019,10 +1019,11 @@ public class DirectByteBufferStream {
/**
* @param itemType Item type.
+ * @param reader Reader.
* @return Collection.
*/
@SuppressWarnings("unchecked")
- public <C extends Collection<?>> C readCollection(MessageCollectionItemType itemType) {
+ public <C extends Collection<?>> C readCollection(MessageCollectionItemType itemType, MessageReader reader) {
if (readSize == -1) {
int size = readInt();
@@ -1037,7 +1038,7 @@ public class DirectByteBufferStream {
col = new ArrayList<>(readSize);
for (int i = readItems; i < readSize; i++) {
- Object item = read(itemType);
+ Object item = read(itemType, reader);
if (!lastFinished)
return null;
@@ -1063,11 +1064,12 @@ public class DirectByteBufferStream {
* @param keyType Key type.
* @param valType Value type.
* @param linked Whether linked map should be created.
+ * @param reader Reader.
* @return Map.
*/
@SuppressWarnings("unchecked")
public <M extends Map<?, ?>> M readMap(MessageCollectionItemType keyType, MessageCollectionItemType valType,
- boolean linked) {
+ boolean linked, MessageReader reader) {
if (readSize == -1) {
int size = readInt();
@@ -1083,7 +1085,7 @@ public class DirectByteBufferStream {
for (int i = readItems; i < readSize; i++) {
if (!keyDone) {
- Object key = read(keyType);
+ Object key = read(keyType, reader);
if (!lastFinished)
return null;
@@ -1092,7 +1094,7 @@ public class DirectByteBufferStream {
keyDone = true;
}
- Object val = read(valType);
+ Object val = read(valType, reader);
if (!lastFinished)
return null;
@@ -1389,9 +1391,10 @@ public class DirectByteBufferStream {
/**
* @param type Type.
+ * @param reader Reader.
* @return Value.
*/
- private Object read(MessageCollectionItemType type) {
+ private Object read(MessageCollectionItemType type, MessageReader reader) {
switch (type) {
case BYTE:
return readByte();
@@ -1454,7 +1457,7 @@ public class DirectByteBufferStream {
return readIgniteUuid();
case MSG:
- return readMessage();
+ return readMessage(reader);
default:
throw new IllegalArgumentException("Unknown type: " + type);
@@ -1496,4 +1499,4 @@ public class DirectByteBufferStream {
*/
public T create(int len);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
index 7eaab76..2f91fbd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
@@ -26,7 +26,6 @@ import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
-import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
import org.jetbrains.annotations.Nullable;
@@ -34,26 +33,22 @@ import org.jetbrains.annotations.Nullable;
* Message reader implementation.
*/
public class DirectMessageReader implements MessageReader {
- /** Stream. */
- private final DirectByteBufferStream stream;
+ /** State. */
+ private final DirectMessageReaderState state;
/** Whether last field was fully read. */
private boolean lastRead;
- /** Current state. */
- private int state;
-
/**
* @param msgFactory Message factory.
- * @param msgFormatter Message formatter.
*/
- public DirectMessageReader(MessageFactory msgFactory, MessageFormatter msgFormatter) {
- this.stream = new DirectByteBufferStream(msgFactory, msgFormatter);
+ public DirectMessageReader(MessageFactory msgFactory) {
+ state = new DirectMessageReaderState(msgFactory);
}
/** {@inheritDoc} */
@Override public void setBuffer(ByteBuffer buf) {
- stream.setBuffer(buf);
+ state.stream().setBuffer(buf);
}
/** {@inheritDoc} */
@@ -69,6 +64,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public byte readByte(String name) {
+ DirectByteBufferStream stream = state.stream();
+
byte val = stream.readByte();
lastRead = stream.lastFinished();
@@ -78,6 +75,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public short readShort(String name) {
+ DirectByteBufferStream stream = state.stream();
+
short val = stream.readShort();
lastRead = stream.lastFinished();
@@ -87,6 +86,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public int readInt(String name) {
+ DirectByteBufferStream stream = state.stream();
+
int val = stream.readInt();
lastRead = stream.lastFinished();
@@ -96,6 +97,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public long readLong(String name) {
+ DirectByteBufferStream stream = state.stream();
+
long val = stream.readLong();
lastRead = stream.lastFinished();
@@ -105,6 +108,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public float readFloat(String name) {
+ DirectByteBufferStream stream = state.stream();
+
float val = stream.readFloat();
lastRead = stream.lastFinished();
@@ -114,6 +119,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public double readDouble(String name) {
+ DirectByteBufferStream stream = state.stream();
+
double val = stream.readDouble();
lastRead = stream.lastFinished();
@@ -123,6 +130,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public char readChar(String name) {
+ DirectByteBufferStream stream = state.stream();
+
char val = stream.readChar();
lastRead = stream.lastFinished();
@@ -132,6 +141,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public boolean readBoolean(String name) {
+ DirectByteBufferStream stream = state.stream();
+
boolean val = stream.readBoolean();
lastRead = stream.lastFinished();
@@ -141,6 +152,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public byte[] readByteArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
byte[] arr = stream.readByteArray();
lastRead = stream.lastFinished();
@@ -150,6 +163,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public short[] readShortArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
short[] arr = stream.readShortArray();
lastRead = stream.lastFinished();
@@ -159,6 +174,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public int[] readIntArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
int[] arr = stream.readIntArray();
lastRead = stream.lastFinished();
@@ -168,6 +185,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public long[] readLongArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
long[] arr = stream.readLongArray();
lastRead = stream.lastFinished();
@@ -177,6 +196,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public float[] readFloatArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
float[] arr = stream.readFloatArray();
lastRead = stream.lastFinished();
@@ -186,6 +207,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public double[] readDoubleArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
double[] arr = stream.readDoubleArray();
lastRead = stream.lastFinished();
@@ -195,6 +218,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public char[] readCharArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
char[] arr = stream.readCharArray();
lastRead = stream.lastFinished();
@@ -204,6 +229,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public boolean[] readBooleanArray(String name) {
+ DirectByteBufferStream stream = state.stream();
+
boolean[] arr = stream.readBooleanArray();
lastRead = stream.lastFinished();
@@ -213,6 +240,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public String readString(String name) {
+ DirectByteBufferStream stream = state.stream();
+
String val = stream.readString();
lastRead = stream.lastFinished();
@@ -222,6 +251,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public BitSet readBitSet(String name) {
+ DirectByteBufferStream stream = state.stream();
+
BitSet val = stream.readBitSet();
lastRead = stream.lastFinished();
@@ -231,6 +262,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public UUID readUuid(String name) {
+ DirectByteBufferStream stream = state.stream();
+
UUID val = stream.readUuid();
lastRead = stream.lastFinished();
@@ -240,6 +273,8 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public IgniteUuid readIgniteUuid(String name) {
+ DirectByteBufferStream stream = state.stream();
+
IgniteUuid val = stream.readIgniteUuid();
lastRead = stream.lastFinished();
@@ -249,7 +284,9 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Nullable @Override public <T extends Message> T readMessage(String name) {
- T msg = stream.readMessage();
+ DirectByteBufferStream stream = state.stream();
+
+ T msg = stream.readMessage(this);
lastRead = stream.lastFinished();
@@ -258,7 +295,9 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public <T> T[] readObjectArray(String name, MessageCollectionItemType itemType, Class<T> itemCls) {
- T[] msg = stream.readObjectArray(itemType, itemCls);
+ DirectByteBufferStream stream = state.stream();
+
+ T[] msg = stream.readObjectArray(itemType, itemCls, this);
lastRead = stream.lastFinished();
@@ -267,7 +306,9 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public <C extends Collection<?>> C readCollection(String name, MessageCollectionItemType itemType) {
- C col = stream.readCollection(itemType);
+ DirectByteBufferStream stream = state.stream();
+
+ C col = stream.readCollection(itemType, this);
lastRead = stream.lastFinished();
@@ -277,7 +318,9 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public <M extends Map<?, ?>> M readMap(String name, MessageCollectionItemType keyType,
MessageCollectionItemType valType, boolean linked) {
- M map = stream.readMap(keyType, valType, linked);
+ DirectByteBufferStream stream = state.stream();
+
+ M map = stream.readMap(keyType, valType, linked, this);
lastRead = stream.lastFinished();
@@ -291,11 +334,26 @@ public class DirectMessageReader implements MessageReader {
/** {@inheritDoc} */
@Override public int state() {
- return state;
+ return state.state();
}
/** {@inheritDoc} */
@Override public void incrementState() {
- state++;
+ state.incrementState();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void beforeInnerMessageRead() {
+ state.beforeInnerMessageRead();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void afterInnerMessageRead(boolean finished) {
+ state.afterInnerMessageRead(finished);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void reset() {
+ state.reset();
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
new file mode 100644
index 0000000..d423052
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.direct;
+
+import org.apache.ignite.plugin.extensions.communication.MessageFactory;
+
+/**
+ * Writer state.
+ */
+public class DirectMessageReaderState {
+ /** Initial array size. */
+ private static final int INIT_SIZE = 10;
+
+ /** Message factory. */
+ private final MessageFactory msgFactory;
+
+ /** Stack array. */
+ private StateItem[] stack;
+
+ /** Current position. */
+ private int pos;
+
+ /**
+ * @param msgFactory Message factory.
+ */
+ public DirectMessageReaderState(MessageFactory msgFactory) {
+ this.msgFactory = msgFactory;
+
+ stack = new StateItem[INIT_SIZE];
+
+ stack[0] = new StateItem(msgFactory);
+ }
+
+ /**
+ * @return Current state.
+ */
+ public int state() {
+ return stack[pos].state;
+ }
+
+ /**
+ * Increments state.
+ */
+ public void incrementState() {
+ stack[pos].state++;
+ }
+
+ /**
+ * @return Current stream.
+ */
+ public DirectByteBufferStream stream() {
+ return stack[pos].stream;
+ }
+
+ /**
+ * Callback called before inner message is written.
+ */
+ public void beforeInnerMessageRead() {
+ pos++;
+
+ // Growing never happen for Ignite messages, but we need
+ // to support it for custom messages from plugins.
+ if (pos == stack.length) {
+ StateItem[] stack0 = stack;
+
+ stack = new StateItem[stack.length << 1];
+
+ System.arraycopy(stack0, 0, stack, 0, stack0.length);
+ }
+
+ if (stack[pos] == null)
+ stack[pos] = new StateItem(msgFactory);
+ }
+
+ /**
+ * Callback called after inner message is written.
+ *
+ * @param finished Whether message was fully written.
+ */
+ public void afterInnerMessageRead(boolean finished) {
+ if (finished)
+ stack[pos].state = 0;
+
+ pos--;
+ }
+
+ /**
+ * Resets state.
+ */
+ public void reset() {
+ assert pos == 0;
+
+ stack[0].state = 0;
+ }
+
+ /**
+ * State item.
+ */
+ private static class StateItem {
+ /** Stream. */
+ private final DirectByteBufferStream stream;
+
+ /** State. */
+ private int state;
+
+ /**
+ * @param msgFactory Message factory.
+ */
+ public StateItem(MessageFactory msgFactory) {
+ stream = new DirectByteBufferStream(msgFactory);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
index ea0f37e..3132e3a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
@@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable;
*/
public class DirectMessageWriter implements MessageWriter {
/** Stream. */
- private final DirectByteBufferStream stream = new DirectByteBufferStream(null, null);
+ private final DirectByteBufferStream stream = new DirectByteBufferStream(null);
/** State. */
private final DirectMessageWriterState state = new DirectMessageWriterState();
@@ -260,4 +260,4 @@ public class DirectMessageWriter implements MessageWriter {
@Override public void reset() {
state.reset();
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index b8af8da..3d4fbef 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -17,6 +17,26 @@
package org.apache.ignite.internal.managers.communication;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
import org.apache.ignite.cluster.ClusterNode;
@@ -64,27 +84,6 @@ import org.jetbrains.annotations.Nullable;
import org.jsr166.ConcurrentHashMap8;
import org.jsr166.ConcurrentLinkedDeque8;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Queue;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentLinkedDeque;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
@@ -282,7 +281,7 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
}
@Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
- return new DirectMessageReader(msgFactory, this);
+ return new DirectMessageReader(msgFactory);
}
};
}
@@ -2432,4 +2431,4 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
return S.toString(DelayedMessage.class, this, super.toString());
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
index 987090d..5140cce 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
@@ -58,29 +58,26 @@ public class GridDirectParser implements GridNioParser {
/** {@inheritDoc} */
@Nullable @Override public Object decode(GridNioSession ses, ByteBuffer buf)
throws IOException, IgniteCheckedException {
- Message msg = ses.removeMeta(MSG_META_KEY);
+ MessageReader reader = ses.meta(READER_META_KEY);
- MessageReader reader = null;
+ if (reader == null)
+ ses.addMeta(READER_META_KEY, reader = formatter.reader(msgFactory, null)); // TODO: class in null
- if (msg == null && buf.hasRemaining()) {
- msg = msgFactory.create(buf.get());
+ Message msg = ses.removeMeta(MSG_META_KEY);
- ses.addMeta(READER_META_KEY, reader = formatter.reader(msgFactory, msg.getClass()));
- }
+ if (msg == null && buf.hasRemaining())
+ msg = msgFactory.create(buf.get());
boolean finished = false;
- if (buf.hasRemaining()) {
- if (reader == null)
- reader = ses.meta(READER_META_KEY);
-
- assert reader != null;
-
+ if (buf.hasRemaining())
finished = msg.readFrom(buf, reader);
- }
- if (finished)
+ if (finished) {
+ reader.reset();
+
return msg;
+ }
else {
ses.addMeta(MSG_META_KEY, msg);
@@ -93,4 +90,4 @@ public class GridDirectParser implements GridNioParser {
// No encoding needed for direct messages.
throw new UnsupportedEncodingException();
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageReader.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageReader.java
index d40a384..bfc67fa 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageReader.java
@@ -272,4 +272,21 @@ public interface MessageReader {
* Increments read state.
*/
public void incrementState();
-}
\ No newline at end of file
+
+ /**
+ * Callback called before inner message is read.
+ */
+ public void beforeInnerMessageRead();
+
+ /**
+ * Callback called after inner message is read.
+ *
+ * @param finished Whether message was fully read.
+ */
+ public void afterInnerMessageRead(boolean finished);
+
+ /**
+ * Resets this reader.
+ */
+ public void reset();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/7123a73d/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
index 906a050..d9334eb 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
@@ -497,7 +497,7 @@ public class GridSpiTestContext implements IgniteSpiContext {
}
@Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
- return new DirectMessageReader(factory, this);
+ return new DirectMessageReader(factory);
}
};
}
@@ -573,4 +573,4 @@ public class GridSpiTestContext implements IgniteSpiContext {
this.obj = obj;
}
}
-}
\ No newline at end of file
+}
[17/51] ignite git commit: Merge branch 'ignite-1.5'
Posted by vk...@apache.org.
Merge branch 'ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6a7d079b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6a7d079b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6a7d079b
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 6a7d079b7c357d8120e2ae1fac78d6d492b17681
Parents: 0e1017b 388a892
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 10 16:50:29 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 10 16:50:29 2015 -0800
----------------------------------------------------------------------
.../store/GridCacheStoreManagerAdapter.java | 26 ++++++++++++++------
1 file changed, 19 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
[32/51] ignite git commit: IGNITE-529 Initial implementation
Posted by vk...@apache.org.
IGNITE-529 Initial implementation
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9a5fc056
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9a5fc056
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9a5fc056
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 9a5fc056786494e748c982e0c766fa9842ba523e
Parents: b382062
Author: shtykh_roman <rs...@yahoo.com>
Authored: Tue Nov 17 17:38:12 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Tue Nov 17 17:38:12 2015 +0300
----------------------------------------------------------------------
modules/flume/README.md | 40 ++++
modules/flume/pom.xml | 77 ++++++++
.../ignite/stream/flume/EventTransformer.java | 36 ++++
.../apache/ignite/stream/flume/IgniteSink.java | 186 +++++++++++++++++++
.../stream/flume/IgniteSinkConstants.java | 35 ++++
.../ignite/stream/flume/IgniteSinkTest.java | 142 ++++++++++++++
.../stream/flume/IgniteSinkTestSuite.java | 37 ++++
.../stream/flume/TestEventTransformer.java | 66 +++++++
.../flume/src/test/resources/example-ignite.xml | 71 +++++++
pom.xml | 1 +
10 files changed, 691 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/README.md
----------------------------------------------------------------------
diff --git a/modules/flume/README.md b/modules/flume/README.md
new file mode 100644
index 0000000..2247cf3
--- /dev/null
+++ b/modules/flume/README.md
@@ -0,0 +1,40 @@
+#Flume NG sink
+
+## Setting up and running
+
+1. Create a transformer by implementing EventTransformer interface.
+2. Build it and copy to ${FLUME_HOME}/plugins.d/ignite-sink/lib.
+3. Copy other Ignite-related jar files to ${FLUME_HOME}/plugins.d/ignite-sink/libext to have them as shown below.
+
+```
+plugins.d/
+`-- ignite
+ |-- lib
+ | `-- ignite-flume-transformer-x.x.x.jar <-- your jar
+ `-- libext
+ |-- cache-api-1.0.0.jar
+ |-- ignite-core-x.x.x.jar
+ |-- ignite-flume-x.x.x.jar
+ |-- ignite-spring-x.x.x.jar
+ |-- spring-aop-4.1.0.RELEASE.jar
+ |-- spring-beans-4.1.0.RELEASE.jar
+ |-- spring-context-4.1.0.RELEASE.jar
+ |-- spring-core-4.1.0.RELEASE.jar
+ `-- spring-expression-4.1.0.RELEASE.jar
+```
+
+4. In Flume configuration file, specify Ignite configuration XML file's location with cache properties
+(see [Apache Ignite](https://apacheignite.readme.io/) with cache name specified for cache creation,
+cache name (same as in Ignite configuration file), your EventTransformer's implementation class,
+and, optionally, batch size (default -- 100).
+
+```
+# Describe the sink
+a1.sinks.k1.type = org.apache.ignite.stream.flume.IgniteSink
+a1.sinks.k1.igniteCfg = /some-path/ignite.xml
+a1.sinks.k1.cacheName = testCache
+a1.sinks.k1.eventTransformer = my.company.MyEventTransformer
+a1.sinks.k1.batchSize = 100
+```
+
+After specifying your source and channel (see Flume's docs), you are ready to run a Flume agent.
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/pom.xml
----------------------------------------------------------------------
diff --git a/modules/flume/pom.xml b/modules/flume/pom.xml
new file mode 100644
index 0000000..cd4ee98
--- /dev/null
+++ b/modules/flume/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-parent</artifactId>
+ <version>1</version>
+ <relativePath>../../parent</relativePath>
+ </parent>
+
+ <artifactId>ignite-flume</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <url>http://ignite.apache.org</url>
+
+ <properties>
+ <flume-ng.version>1.6.0</flume-ng.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.flume</groupId>
+ <artifactId>flume-ng-core</artifactId>
+ <version>${flume-ng.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-spring</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-log4j</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java b/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
new file mode 100644
index 0000000..e85a98b
--- /dev/null
+++ b/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
@@ -0,0 +1,36 @@
+/*
+ * 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.stream.flume;
+
+import java.util.List;
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Flume event transformer to convert a list of Flume {@link Event} to cache entries.
+ */
+public interface EventTransformer<Event, K, V> {
+
+ /**
+ * Transforms a list of Flume {@link Event} to cache entries.
+ *
+ * @param events List of Flume events to transform.
+ * @return Cache entries to be written into the grid.
+ */
+ @Nullable Map<K, V> transform(List<Event> events);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSink.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSink.java b/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSink.java
new file mode 100644
index 0000000..e6e7e90
--- /dev/null
+++ b/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSink.java
@@ -0,0 +1,186 @@
+/*
+ * 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.stream.flume;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.flume.Channel;
+import org.apache.flume.Context;
+import org.apache.flume.Event;
+import org.apache.flume.EventDeliveryException;
+import org.apache.flume.FlumeException;
+import org.apache.flume.Transaction;
+import org.apache.flume.conf.Configurable;
+import org.apache.flume.instrumentation.SinkCounter;
+import org.apache.flume.sink.AbstractSink;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Flume sink for Apache Ignite.
+ */
+public class IgniteSink extends AbstractSink implements Configurable {
+ /** Logger. */
+ private static final Logger log = LoggerFactory.getLogger(IgniteSink.class);
+
+ /** Default batch size. */
+ private static final int DFLT_BATCH_SIZE = 100;
+
+ /** Ignite configuration file. */
+ private String springCfgPath;
+
+ /** Cache name. */
+ private String cacheName;
+
+ /** Event transformer implementation class. */
+ private String eventTransformerCls;
+
+ /** Number of events to be written per Flume transaction. */
+ private int batchSize;
+
+ /** Monitoring counter. */
+ private SinkCounter sinkCounter;
+
+ /** Event transformer. */
+ private EventTransformer<Event, Object, Object> eventTransformer;
+
+ /** Ignite instance. */
+ private Ignite ignite;
+
+ /** Empty constructor. */
+ public IgniteSink() {
+ }
+
+ /**
+ * Sink configurations with Ignite-specific settings.
+ *
+ * @param context Context for sink.
+ */
+ @Override public void configure(Context context) {
+ springCfgPath = context.getString(IgniteSinkConstants.CFG_PATH);
+ cacheName = context.getString(IgniteSinkConstants.CFG_CACHE_NAME);
+ eventTransformerCls = context.getString(IgniteSinkConstants.CFG_EVENT_TRANSFORMER);
+ batchSize = context.getInteger(IgniteSinkConstants.CFG_BATCH_SIZE, DFLT_BATCH_SIZE);
+
+ if (sinkCounter == null)
+ sinkCounter = new SinkCounter(getName());
+ }
+
+ /**
+ * Starts a grid and initializes na event transformer.
+ */
+ @SuppressWarnings("unchecked")
+ @Override synchronized public void start() {
+ A.notNull(springCfgPath, "Ignite config file");
+ A.notNull(cacheName, "Cache name");
+ A.notNull(eventTransformerCls, "Event transformer class");
+
+ sinkCounter.start();
+
+ try {
+ if (ignite == null)
+ ignite = Ignition.start(springCfgPath);
+
+ if (eventTransformerCls != null && !eventTransformerCls.isEmpty()) {
+ Class<? extends EventTransformer> clazz =
+ (Class<? extends EventTransformer<Event, Object, Object>>)Class.forName(eventTransformerCls);
+
+ eventTransformer = clazz.newInstance();
+ }
+ }
+ catch (Exception e) {
+ log.error("Failed to start grid", e);
+
+ throw new FlumeException("Failed to start grid", e);
+ }
+
+ super.start();
+ }
+
+ /**
+ * Stops the grid.
+ */
+ @Override synchronized public void stop() {
+ if (ignite != null)
+ ignite.close();
+
+ sinkCounter.stop();
+
+ super.stop();
+ }
+
+ /**
+ * Processes Flume events.
+ */
+ @Override public Status process() throws EventDeliveryException {
+ Channel channel = getChannel();
+
+ Transaction transaction = channel.getTransaction();
+
+ int eventCount = 0;
+
+ try {
+ transaction.begin();
+
+ List<Event> batch = new ArrayList<>(batchSize);
+
+ for (; eventCount < batchSize; ++eventCount) {
+ Event event = channel.take();
+
+ if (event == null) {
+ break;
+ }
+
+ batch.add(event);
+ }
+
+ if (!batch.isEmpty()) {
+ ignite.cache(cacheName).putAll(eventTransformer.transform(batch));
+
+ if (batch.size() < batchSize)
+ sinkCounter.incrementBatchUnderflowCount();
+ else
+ sinkCounter.incrementBatchCompleteCount();
+ }
+ else {
+ sinkCounter.incrementBatchEmptyCount();
+ }
+
+ sinkCounter.addToEventDrainAttemptCount(batch.size());
+
+ transaction.commit();
+
+ sinkCounter.addToEventDrainSuccessCount(batch.size());
+ }
+ catch (Exception e) {
+ log.error("Failed to process events", e);
+
+ transaction.rollback();
+
+ throw new EventDeliveryException(e);
+ }
+ finally {
+ transaction.close();
+ }
+
+ return eventCount == 0 ? Status.BACKOFF : Status.READY;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSinkConstants.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSinkConstants.java b/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSinkConstants.java
new file mode 100644
index 0000000..ddefb24
--- /dev/null
+++ b/modules/flume/src/main/java/org/apache/ignite/stream/flume/IgniteSinkConstants.java
@@ -0,0 +1,35 @@
+/*
+ * 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.stream.flume;
+
+/**
+ * Configuration strings for sending data to cache. Used in Flume agent configuration file.
+ */
+public class IgniteSinkConstants {
+ /** Ignite configuration file path. */
+ public static final String CFG_PATH = "igniteCfg";
+
+ /** Cache name. */
+ public static final String CFG_CACHE_NAME = "cacheName";
+
+ /** Event transformer implementation. */
+ public static final String CFG_EVENT_TRANSFORMER = "eventTransformer";
+
+ /** Batch size. */
+ public static final String CFG_BATCH_SIZE = "batchSize";
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTest.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTest.java b/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTest.java
new file mode 100644
index 0000000..2f33ed4
--- /dev/null
+++ b/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.stream.flume;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import org.apache.flume.Channel;
+import org.apache.flume.Context;
+import org.apache.flume.Sink;
+import org.apache.flume.Transaction;
+import org.apache.flume.channel.MemoryChannel;
+import org.apache.flume.conf.Configurables;
+import org.apache.flume.event.EventBuilder;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.events.Event;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
+
+/**
+ * {@link IgniteSink} test.
+ */
+public class IgniteSinkTest extends GridCommonAbstractTest {
+ /** Number of events to be sent to memory channel. */
+ private static final int EVENT_CNT = 10000;
+
+ /** Cache name. */
+ private static final String CACHE_NAME = "testCache";
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ stopAllGrids();
+ }
+
+ /**
+ * @throws Exception {@link Exception}.
+ */
+ public void testSink() throws Exception {
+ IgniteConfiguration cfg = loadConfiguration("modules/flume/src/test/resources/example-ignite.xml");
+
+ cfg.setClientMode(false);
+
+ final Ignite grid = startGrid("igniteServerNode", cfg);
+
+ Context channelContext = new Context();
+
+ channelContext.put("capacity", String.valueOf(EVENT_CNT));
+ channelContext.put("transactionCapacity", String.valueOf(EVENT_CNT));
+
+ Channel memoryChannel = new MemoryChannel();
+
+ Configurables.configure(memoryChannel, channelContext);
+
+ final CountDownLatch latch = new CountDownLatch(EVENT_CNT);
+
+ final IgnitePredicate<Event> putLsnr = new IgnitePredicate<Event>() {
+ @Override public boolean apply(Event evt) {
+ assert evt != null;
+
+ latch.countDown();
+
+ return true;
+ }
+ };
+
+ IgniteSink sink = new IgniteSink() {
+ // Setting the listener on cache before sink processing starts.
+ @Override synchronized public void start() {
+ super.start();
+
+ grid.events(grid.cluster().forCacheNodes(CACHE_NAME)).localListen(putLsnr, EVT_CACHE_OBJECT_PUT);
+ }
+ };
+
+ sink.setName("IgniteSink");
+ sink.setChannel(memoryChannel);
+
+ Context ctx = new Context();
+
+ ctx.put(IgniteSinkConstants.CFG_CACHE_NAME, CACHE_NAME);
+ ctx.put(IgniteSinkConstants.CFG_PATH, "example-ignite.xml");
+ ctx.put(IgniteSinkConstants.CFG_EVENT_TRANSFORMER, "org.apache.ignite.stream.flume.TestEventTransformer");
+
+ Configurables.configure(sink, ctx);
+
+ sink.start();
+
+ try {
+ Transaction tx = memoryChannel.getTransaction();
+
+ tx.begin();
+
+ for (int i = 0; i < EVENT_CNT; i++)
+ memoryChannel.put(EventBuilder.withBody((String.valueOf(i) + ": " + i).getBytes()));
+
+ tx.commit();
+ tx.close();
+
+ Sink.Status status = Sink.Status.READY;
+
+ while (status != Sink.Status.BACKOFF) {
+ status = sink.process();
+ }
+ }
+ finally {
+ sink.stop();
+ }
+
+ // Checks that 10000 events successfully processed in 10 seconds.
+ assertTrue(latch.await(10, TimeUnit.SECONDS));
+
+ grid.events(grid.cluster().forCacheNodes(CACHE_NAME)).stopLocalListen(putLsnr);
+
+ IgniteCache<String, Integer> cache = grid.cache(CACHE_NAME);
+
+ // Checks that each event was processed properly.
+ for (int i = 0; i < EVENT_CNT; i++) {
+ assertEquals(i, (int)cache.get(String.valueOf(i)));
+ }
+
+ assertEquals(EVENT_CNT, cache.size(CachePeekMode.PRIMARY));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTestSuite.java b/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTestSuite.java
new file mode 100644
index 0000000..ad6d162
--- /dev/null
+++ b/modules/flume/src/test/java/org/apache/ignite/stream/flume/IgniteSinkTestSuite.java
@@ -0,0 +1,37 @@
+/*
+ * 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.stream.flume;
+
+import junit.framework.TestSuite;
+
+/**
+ * Tests for a Flume sink for Ignite.
+ */
+public class IgniteSinkTestSuite extends TestSuite {
+ /**
+ * @return Test suite.
+ * @throws Exception Thrown in case of the failure.
+ */
+ public static TestSuite suite() throws Exception {
+ TestSuite suite = new TestSuite("Apache Flume NG Sink Test Suite");
+
+ suite.addTest(new TestSuite(IgniteSinkTest.class));
+
+ return suite;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/test/java/org/apache/ignite/stream/flume/TestEventTransformer.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/test/java/org/apache/ignite/stream/flume/TestEventTransformer.java b/modules/flume/src/test/java/org/apache/ignite/stream/flume/TestEventTransformer.java
new file mode 100644
index 0000000..c15efbf
--- /dev/null
+++ b/modules/flume/src/test/java/org/apache/ignite/stream/flume/TestEventTransformer.java
@@ -0,0 +1,66 @@
+/*
+ * 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.stream.flume;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.flume.Event;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A test transformer to convert {@link org.apache.flume.Event} to cacheable entries.
+ */
+public class TestEventTransformer implements EventTransformer<Event, String, Integer> {
+
+ /**
+ * Transforms a Flume event to cacheable entries.
+ *
+ * @param event Flume event to transform.
+ * @return Map of cacheable entries.
+ */
+ private Map<String, Integer> transform(Event event) {
+ final Map<String, Integer> map = new HashMap<>();
+
+ String eventStr = new String(event.getBody());
+
+ if (!eventStr.isEmpty()) {
+ String[] tokens = eventStr.split(":"); // Expects column-delimited one line.
+
+ map.put(tokens[0].trim(), Integer.valueOf(tokens[1].trim()));
+ }
+
+ return map;
+ }
+
+ /**
+ * Transforms a list of Flume event to cacheable entries.
+ *
+ * @param events Flume events to transform.
+ * @return Map of cacheable entries.
+ */
+ @Nullable @Override public Map<String, Integer> transform(List<Event> events) {
+ final Map<String, Integer> map = new HashMap<>();
+
+ for (Event event : events) {
+ map.putAll(transform(event));
+ }
+
+ return map;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/modules/flume/src/test/resources/example-ignite.xml
----------------------------------------------------------------------
diff --git a/modules/flume/src/test/resources/example-ignite.xml b/modules/flume/src/test/resources/example-ignite.xml
new file mode 100644
index 0000000..fbb05d3
--- /dev/null
+++ b/modules/flume/src/test/resources/example-ignite.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ Ignite configuration with all defaults and enabled p2p deployment and enabled events.
+ Used for testing IgniteSink running Ignite in a client mode.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+ <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+ <!-- Enable client mode. -->
+ <property name="clientMode" value="true"/>
+
+ <!-- Cache accessed from IgniteSink. -->
+ <property name="cacheConfiguration">
+ <list>
+ <!-- Partitioned cache example configuration with configurations adjusted to server nodes'. -->
+ <bean class="org.apache.ignite.configuration.CacheConfiguration">
+ <property name="atomicityMode" value="ATOMIC"/>
+
+ <property name="name" value="testCache"/>
+ </bean>
+ </list>
+ </property>
+
+ <!-- Enable cache events. -->
+ <property name="includeEventTypes">
+ <list>
+ <!-- Cache events (only EVT_CACHE_OBJECT_PUT for tests). -->
+ <util:constant static-field="org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT"/>
+ </list>
+ </property>
+
+ <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+ <property name="addresses">
+ <list>
+ <value>127.0.0.1:47500</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ </bean>
+ </property>
+ </bean>
+</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/9a5fc056/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5f06555..c40b551 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,7 @@
<module>modules/cloud</module>
<module>modules/mesos</module>
<module>modules/kafka</module>
+ <module>modules/flume</module>
<module>modules/yarn</module>
<module>modules/jms11</module>
<module>modules/mqtt</module>
[50/51] ignite git commit: Direct marshalling backward compatibility
Posted by vk...@apache.org.
Direct marshalling backward compatibility
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/861898e8
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/861898e8
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/861898e8
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 861898e8779b8ffb7d2c32b8ac78109f58325ea2
Parents: 61e488e
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Wed Nov 18 20:27:43 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Nov 18 20:27:43 2015 -0800
----------------------------------------------------------------------
.../managers/communication/GridIoManager.java | 13 ++++++++-----
.../util/nio/GridNioMessageReaderFactory.java | 4 +++-
.../util/nio/GridNioMessageWriterFactory.java | 4 +++-
.../ignite/internal/util/nio/GridNioServer.java | 20 ++++++++++++++++----
.../communication/MessageFormatter.java | 8 ++++++--
.../communication/tcp/TcpCommunicationSpi.java | 10 ++++++----
6 files changed, 42 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/861898e8/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index e8aeb6b..3c33e85 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -284,13 +284,14 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
}
else {
formatter = new MessageFormatter() {
- @Override public MessageWriter writer(UUID rmtNodeId) {
+ @Override public MessageWriter writer(UUID rmtNodeId) throws IgniteCheckedException {
assert rmtNodeId != null;
return new DirectMessageWriter(directProtocolVersion(rmtNodeId));
}
- @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory,
+ Class<? extends Message> msgCls) throws IgniteCheckedException {
assert rmtNodeId != null;
return new DirectMessageReader(msgFactory, directProtocolVersion(rmtNodeId));
@@ -329,14 +330,16 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
*
* @param nodeId Node ID.
* @return Protocol version.
+ * @throws IgniteCheckedException If node doesn't exist.
*/
- private byte directProtocolVersion(UUID nodeId) {
+ private byte directProtocolVersion(UUID nodeId) throws IgniteCheckedException {
assert nodeId != null;
ClusterNode node = ctx.discovery().node(nodeId);
- // TODO: DIRECT - throw exception
- assert node != null;
+ if (node == null)
+ throw new IgniteCheckedException("Failed to define communication protocol version " +
+ "(has node left topology?): " + nodeId);
assert !node.isLocal();
http://git-wip-us.apache.org/repos/asf/ignite/blob/861898e8/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
index 68c887f..cb7e62d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.util.nio;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
@@ -30,6 +31,7 @@ public interface GridNioMessageReaderFactory {
* @param ses Current session.
* @param msgFactory Message factory.
* @return Reader.
+ * @throws IgniteCheckedException In case of error.
*/
- public MessageReader reader(GridNioSession ses, MessageFactory msgFactory);
+ public MessageReader reader(GridNioSession ses, MessageFactory msgFactory) throws IgniteCheckedException;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/861898e8/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java
index 0c251c2..6c4dee4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java
@@ -17,6 +17,7 @@
package org.apache.ignite.internal.util.nio;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.plugin.extensions.communication.MessageWriter;
/**
@@ -28,6 +29,7 @@ public interface GridNioMessageWriterFactory {
*
* @param ses Current session.
* @return Writer.
+ * @throws IgniteCheckedException In case of error.
*/
- public MessageWriter writer(GridNioSession ses);
+ public MessageWriter writer(GridNioSession ses) throws IgniteCheckedException;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/861898e8/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
index c4710ad..384ee1a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
@@ -933,8 +933,14 @@ public class GridNioServer<T> {
MessageWriter writer = ses.meta(MSG_WRITER.ordinal());
- if (writer == null)
- ses.addMeta(MSG_WRITER.ordinal(), writer = writerFactory.writer(ses));
+ if (writer == null) {
+ try {
+ ses.addMeta(MSG_WRITER.ordinal(), writer = writerFactory.writer(ses));
+ }
+ catch (IgniteCheckedException e) {
+ throw new IOException("Failed to create message writer.", e);
+ }
+ }
boolean handshakeFinished = sslFilter.lock(ses);
@@ -1128,8 +1134,14 @@ public class GridNioServer<T> {
MessageWriter writer = ses.meta(MSG_WRITER.ordinal());
- if (writer == null)
- ses.addMeta(MSG_WRITER.ordinal(), writer = writerFactory.writer(ses));
+ if (writer == null) {
+ try {
+ ses.addMeta(MSG_WRITER.ordinal(), writer = writerFactory.writer(ses));
+ }
+ catch (IgniteCheckedException e) {
+ throw new IOException("Failed to create message writer.", e);
+ }
+ }
if (req == null) {
req = (NioOperationFuture<?>)ses.pollFuture();
http://git-wip-us.apache.org/repos/asf/ignite/blob/861898e8/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
index 67dd0d3..111cb55 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
@@ -18,6 +18,7 @@
package org.apache.ignite.plugin.extensions.communication;
import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.plugin.Extension;
/**
@@ -36,8 +37,9 @@ public interface MessageFormatter extends Extension {
*
* @param rmtNodeId Remote node ID.
* @return Message writer.
+ * @throws IgniteCheckedException In case of error.
*/
- public MessageWriter writer(UUID rmtNodeId);
+ public MessageWriter writer(UUID rmtNodeId) throws IgniteCheckedException;
/**
* Creates new message reader instance.
@@ -46,6 +48,8 @@ public interface MessageFormatter extends Extension {
* @param msgFactory Message factory.
* @param msgCls Message class to read.
* @return Message reader.
+ * @throws IgniteCheckedException In case of error.
*/
- public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls);
+ public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls)
+ throws IgniteCheckedException;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/861898e8/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 116998e..795d168 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
@@ -1580,7 +1580,8 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
GridNioMessageReaderFactory readerFactory = new GridNioMessageReaderFactory() {
private MessageFormatter formatter;
- @Override public MessageReader reader(GridNioSession ses, MessageFactory msgFactory) {
+ @Override public MessageReader reader(GridNioSession ses, MessageFactory msgFactory)
+ throws IgniteCheckedException {
if (formatter == null)
formatter = getSpiContext().messageFormatter();
@@ -1596,7 +1597,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
GridNioMessageWriterFactory writerFactory = new GridNioMessageWriterFactory() {
private MessageFormatter formatter;
- @Override public MessageWriter writer(GridNioSession ses) {
+ @Override public MessageWriter writer(GridNioSession ses) throws IgniteCheckedException {
if (formatter == null)
formatter = getSpiContext().messageFormatter();
@@ -2946,7 +2947,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
GridNioMessageWriterFactory writerFactory = new GridNioMessageWriterFactory() {
private MessageFormatter formatter;
- @Override public MessageWriter writer(GridNioSession ses) {
+ @Override public MessageWriter writer(GridNioSession ses) throws IgniteCheckedException {
if (formatter == null)
formatter = getSpiContext().messageFormatter();
@@ -2961,7 +2962,8 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
GridNioMessageReaderFactory readerFactory = new GridNioMessageReaderFactory() {
private MessageFormatter formatter;
- @Override public MessageReader reader(GridNioSession ses, MessageFactory msgFactory) {
+ @Override public MessageReader reader(GridNioSession ses, MessageFactory msgFactory)
+ throws IgniteCheckedException {
if (formatter == null)
formatter = getSpiContext().messageFormatter();
[49/51] ignite git commit: Direct marshalling backward compatibility
Posted by vk...@apache.org.
Direct marshalling backward compatibility
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/61e488ea
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/61e488ea
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/61e488ea
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 61e488ea360481999f244b6f747a79d322e61ef8
Parents: 00986d4
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Wed Nov 18 20:19:17 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Nov 18 20:19:17 2015 -0800
----------------------------------------------------------------------
.../internal/direct/stream/v2/DirectByteBufferStreamImplV2.java | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/61e488ea/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
index c330220..44328f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
@@ -1073,6 +1073,7 @@ public class DirectByteBufferStreamImplV2 implements DirectByteBufferStream {
uuidMost = 0;
uuidLeast = 0;
+ uuidLocId = 0;
return val;
}
[12/51] ignite git commit: Merge remote-tracking branch
'remotes/origin/ignite-1.5'
Posted by vk...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ba2ffb07
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ba2ffb07
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ba2ffb07
Branch: refs/heads/ignite-direct-marsh-opt
Commit: ba2ffb07b936063a84342995ab0875cac97c612e
Parents: ee5a50f 67f8858
Author: Anton Vinogradov <av...@apache.org>
Authored: Tue Nov 10 16:15:52 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Tue Nov 10 16:15:52 2015 +0300
----------------------------------------------------------------------
.../java/org/apache/ignite/IgniteCache.java | 1 +
.../eviction/random/RandomEvictionPolicy.java | 4 +
.../processors/cache/GridCacheAdapter.java | 22 ++-
.../GridCachePartitionExchangeManager.java | 34 ++--
.../processors/cache/IgniteCacheProxy.java | 6 +
.../dht/preloader/GridDhtPartitionDemander.java | 25 ++-
.../GridCacheAtomicReferenceImpl.java | 2 +-
.../store/GridCacheBalancingStoreSelfTest.java | 181 ++++++++++++++++++-
...CacheAtomicReferenceApiSelfAbstractTest.java | 20 +-
modules/rest-http/pom.xml | 11 ++
.../yardstick/config/ignite-store-config.xml | 31 ++--
11 files changed, 291 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
[20/51] ignite git commit: Merge branches 'ignite-1.5' and 'master'
of https://git-wip-us.apache.org/repos/asf/ignite
Posted by vk...@apache.org.
Merge branches 'ignite-1.5' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/84c88e0d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/84c88e0d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/84c88e0d
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 84c88e0d80ce2dcbd614ad5565e677d732f519a3
Parents: 9f7286e 92881e0
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Wed Nov 11 14:32:42 2015 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Nov 11 14:32:42 2015 +0700
----------------------------------------------------------------------
...gniteCachePutRetryTransactionalSelfTest.java | 10 +++++++++
.../org/apache/ignite/yardstick/IgniteNode.java | 23 ++++++++++++++------
2 files changed, 26 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
[07/51] ignite git commit: Ignite-1093 Missed test.
Posted by vk...@apache.org.
Ignite-1093 Missed test.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/280252ef
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/280252ef
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/280252ef
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 280252ef64bb9268e5f3b4e8442b22606bf5587a
Parents: 8b99f65
Author: Anton Vinogradov <av...@apache.org>
Authored: Mon Nov 9 11:48:33 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Mon Nov 9 11:48:33 2015 +0300
----------------------------------------------------------------------
.../java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/280252ef/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
index c3c3659..ea13cdd 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
@@ -51,6 +51,7 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePut
import org.apache.ignite.internal.processors.cache.distributed.near.IgniteTxReentryNearSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingAsyncSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingSyncSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingUnmarshallingFailedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheDaemonNodeReplicatedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedAtomicGetAndTransformStoreSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedBasicApiTest;
@@ -138,6 +139,7 @@ public class IgniteCacheTestSuite3 extends TestSuite {
suite.addTestSuite(GridCacheOrderedPreloadingSelfTest.class);
suite.addTestSuite(GridCacheRebalancingSyncSelfTest.class);
+ suite.addTestSuite(GridCacheRebalancingUnmarshallingFailedSelfTest.class);
suite.addTestSuite(GridCacheRebalancingAsyncSelfTest.class);
// Test for byte array value special case.
[47/51] ignite git commit: Direct marshalling backward compatibility
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v1/DirectByteBufferStreamImplV1.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v1/DirectByteBufferStreamImplV1.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v1/DirectByteBufferStreamImplV1.java
new file mode 100644
index 0000000..bac2da7
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v1/DirectByteBufferStreamImplV1.java
@@ -0,0 +1,1347 @@
+/*
+ * 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.direct.stream.v1;
+
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.UUID;
+import org.apache.ignite.internal.direct.stream.DirectByteBufferStream;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+import org.apache.ignite.plugin.extensions.communication.MessageFactory;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+import sun.misc.Unsafe;
+import sun.nio.ch.DirectBuffer;
+
+/**
+ * Direct marshalling I/O stream (version 1).
+ */
+public class DirectByteBufferStreamImplV1 implements DirectByteBufferStream {
+ /** */
+ private static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+ /** */
+ private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
+
+ /** */
+ private static final long SHORT_ARR_OFF = UNSAFE.arrayBaseOffset(short[].class);
+
+ /** */
+ private static final long INT_ARR_OFF = UNSAFE.arrayBaseOffset(int[].class);
+
+ /** */
+ private static final long LONG_ARR_OFF = UNSAFE.arrayBaseOffset(long[].class);
+
+ /** */
+ private static final long FLOAT_ARR_OFF = UNSAFE.arrayBaseOffset(float[].class);
+
+ /** */
+ private static final long DOUBLE_ARR_OFF = UNSAFE.arrayBaseOffset(double[].class);
+
+ /** */
+ private static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class);
+
+ /** */
+ private static final long BOOLEAN_ARR_OFF = UNSAFE.arrayBaseOffset(boolean[].class);
+
+ /** */
+ private static final byte[] BYTE_ARR_EMPTY = new byte[0];
+
+ /** */
+ private static final short[] SHORT_ARR_EMPTY = new short[0];
+
+ /** */
+ private static final int[] INT_ARR_EMPTY = U.EMPTY_INTS;
+
+ /** */
+ private static final long[] LONG_ARR_EMPTY = U.EMPTY_LONGS;
+
+ /** */
+ private static final float[] FLOAT_ARR_EMPTY = new float[0];
+
+ /** */
+ private static final double[] DOUBLE_ARR_EMPTY = new double[0];
+
+ /** */
+ private static final char[] CHAR_ARR_EMPTY = new char[0];
+
+ /** */
+ private static final boolean[] BOOLEAN_ARR_EMPTY = new boolean[0];
+
+ /** */
+ private static final ArrayCreator<byte[]> BYTE_ARR_CREATOR = new ArrayCreator<byte[]>() {
+ @Override public byte[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return BYTE_ARR_EMPTY;
+
+ default:
+ return new byte[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<short[]> SHORT_ARR_CREATOR = new ArrayCreator<short[]>() {
+ @Override public short[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return SHORT_ARR_EMPTY;
+
+ default:
+ return new short[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<int[]> INT_ARR_CREATOR = new ArrayCreator<int[]>() {
+ @Override public int[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return INT_ARR_EMPTY;
+
+ default:
+ return new int[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<long[]> LONG_ARR_CREATOR = new ArrayCreator<long[]>() {
+ @Override public long[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return LONG_ARR_EMPTY;
+
+ default:
+ return new long[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<float[]> FLOAT_ARR_CREATOR = new ArrayCreator<float[]>() {
+ @Override public float[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return FLOAT_ARR_EMPTY;
+
+ default:
+ return new float[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<double[]> DOUBLE_ARR_CREATOR = new ArrayCreator<double[]>() {
+ @Override public double[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return DOUBLE_ARR_EMPTY;
+
+ default:
+ return new double[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<char[]> CHAR_ARR_CREATOR = new ArrayCreator<char[]>() {
+ @Override public char[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return CHAR_ARR_EMPTY;
+
+ default:
+ return new char[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<boolean[]> BOOLEAN_ARR_CREATOR = new ArrayCreator<boolean[]>() {
+ @Override public boolean[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return BOOLEAN_ARR_EMPTY;
+
+ default:
+ return new boolean[len];
+ }
+ }
+ };
+
+ /** */
+ private static final Object NULL = new Object();
+
+ /** */
+ private final MessageFactory msgFactory;
+
+ /** */
+ private ByteBuffer buf;
+
+ /** */
+ private byte[] heapArr;
+
+ /** */
+ private long baseOff;
+
+ /** */
+ private int arrOff = -1;
+
+ /** */
+ private Object tmpArr;
+
+ /** */
+ private int tmpArrOff;
+
+ /** */
+ private int tmpArrBytes;
+
+ /** */
+ private boolean msgTypeDone;
+
+ /** */
+ private Message msg;
+
+ /** */
+ private Iterator<?> mapIt;
+
+ /** */
+ private Iterator<?> it;
+
+ /** */
+ private Iterator<?> arrIt;
+
+ /** */
+ private Object arrCur = NULL;
+
+ /** */
+ private Object mapCur = NULL;
+
+ /** */
+ private Object cur = NULL;
+
+ /** */
+ private boolean keyDone;
+
+ /** */
+ private int readSize = -1;
+
+ /** */
+ private int readItems;
+
+ /** */
+ private Object[] objArr;
+
+ /** */
+ private Collection<Object> col;
+
+ /** */
+ private Map<Object, Object> map;
+
+ /** */
+ private boolean lastFinished;
+
+ /**
+ * @param msgFactory Message factory.
+ */
+ public DirectByteBufferStreamImplV1(MessageFactory msgFactory) {
+ this.msgFactory = msgFactory;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBuffer(ByteBuffer buf) {
+ assert buf != null;
+
+ if (this.buf != buf) {
+ this.buf = buf;
+
+ heapArr = buf.isDirect() ? null : buf.array();
+ baseOff = buf.isDirect() ? ((DirectBuffer)buf).address() : BYTE_ARR_OFF;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public int remaining() {
+ return buf.remaining();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean lastFinished() {
+ return lastFinished;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByte(byte val) {
+ lastFinished = buf.remaining() >= 1;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putByte(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 1);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShort(short val) {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putShort(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 2);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeInt(int val) {
+ lastFinished = buf.remaining() >= 4;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putInt(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 4);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLong(long val) {
+ lastFinished = buf.remaining() >= 8;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putLong(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 8);
+ }
+ }
+
+ /**
+ * @param val Value.
+ */
+ @Override public void writeFloat(float val) {
+ lastFinished = buf.remaining() >= 4;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putFloat(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 4);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDouble(double val) {
+ lastFinished = buf.remaining() >= 8;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putDouble(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 8);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeChar(char val) {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putChar(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 2);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBoolean(boolean val) {
+ lastFinished = buf.remaining() >= 1;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putBoolean(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 1);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByteArray(byte[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, BYTE_ARR_OFF, val.length, val.length);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByteArray(byte[] val, long off, int len) {
+ if (val != null)
+ lastFinished = writeArray(val, BYTE_ARR_OFF + off, len, len);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShortArray(short[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, SHORT_ARR_OFF, val.length, val.length << 1);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeIntArray(int[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, INT_ARR_OFF, val.length, val.length << 2);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLongArray(long[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, LONG_ARR_OFF, val.length, val.length << 3);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloatArray(float[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, FLOAT_ARR_OFF, val.length, val.length << 2);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDoubleArray(double[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, DOUBLE_ARR_OFF, val.length, val.length << 3);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeCharArray(char[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, CHAR_ARR_OFF, val.length, val.length << 1);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBooleanArray(boolean[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, BOOLEAN_ARR_OFF, val.length, val.length);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeString(String val) {
+ writeByteArray(val != null ? val.getBytes() : null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBitSet(BitSet val) {
+ writeLongArray(val != null ? val.toLongArray() : null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeUuid(UUID val) {
+ writeByteArray(val != null ? U.uuidToBytes(val) : null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeIgniteUuid(IgniteUuid val) {
+ writeByteArray(val != null ? U.igniteUuidToBytes(val) : null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeMessage(Message msg, MessageWriter writer) {
+ if (msg != null) {
+ if (buf.hasRemaining()) {
+ try {
+ writer.beforeInnerMessageWrite();
+
+ lastFinished = msg.writeTo(buf, writer);
+ }
+ finally {
+ writer.afterInnerMessageWrite(lastFinished);
+ }
+ }
+ else
+ lastFinished = false;
+ }
+ else
+ writeByte(Byte.MIN_VALUE);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> void writeObjectArray(T[] arr, MessageCollectionItemType itemType, MessageWriter writer) {
+ if (arr != null) {
+ if (arrIt == null) {
+ writeInt(arr.length);
+
+ if (!lastFinished)
+ return;
+
+ arrIt = arrayIterator(arr);
+ }
+
+ while (arrIt.hasNext() || arrCur != NULL) {
+ if (arrCur == NULL)
+ arrCur = arrIt.next();
+
+ write(itemType, arrCur, writer);
+
+ if (!lastFinished)
+ return;
+
+ arrCur = NULL;
+ }
+
+ arrIt = null;
+ }
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> void writeCollection(Collection<T> col, MessageCollectionItemType itemType,
+ MessageWriter writer) {
+ if (col != null) {
+ if (it == null) {
+ writeInt(col.size());
+
+ if (!lastFinished)
+ return;
+
+ it = col.iterator();
+ }
+
+ while (it.hasNext() || cur != NULL) {
+ if (cur == NULL)
+ cur = it.next();
+
+ write(itemType, cur, writer);
+
+ if (!lastFinished)
+ return;
+
+ cur = NULL;
+ }
+
+ it = null;
+ }
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <K, V> void writeMap(Map<K, V> map, MessageCollectionItemType keyType,
+ MessageCollectionItemType valType, MessageWriter writer) {
+ if (map != null) {
+ if (mapIt == null) {
+ writeInt(map.size());
+
+ if (!lastFinished)
+ return;
+
+ mapIt = map.entrySet().iterator();
+ }
+
+ while (mapIt.hasNext() || mapCur != NULL) {
+ Map.Entry<K, V> e;
+
+ if (mapCur == NULL)
+ mapCur = mapIt.next();
+
+ e = (Map.Entry<K, V>)mapCur;
+
+ if (!keyDone) {
+ write(keyType, e.getKey(), writer);
+
+ if (!lastFinished)
+ return;
+
+ keyDone = true;
+ }
+
+ write(valType, e.getValue(), writer);
+
+ if (!lastFinished)
+ return;
+
+ mapCur = NULL;
+ keyDone = false;
+ }
+
+ mapIt = null;
+ }
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte readByte() {
+ lastFinished = buf.remaining() >= 1;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 1);
+
+ return UNSAFE.getByte(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public short readShort() {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 2);
+
+ return UNSAFE.getShort(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int readInt() {
+ lastFinished = buf.remaining() >= 4;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 4);
+
+ return UNSAFE.getInt(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long readLong() {
+ lastFinished = buf.remaining() >= 8;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 8);
+
+ return UNSAFE.getLong(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public float readFloat() {
+ lastFinished = buf.remaining() >= 4;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 4);
+
+ return UNSAFE.getFloat(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double readDouble() {
+ lastFinished = buf.remaining() >= 8;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 8);
+
+ return UNSAFE.getDouble(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public char readChar() {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 2);
+
+ return UNSAFE.getChar(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean readBoolean() {
+ lastFinished = buf.hasRemaining();
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 1);
+
+ return UNSAFE.getBoolean(heapArr, baseOff + pos);
+ }
+ else
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte[] readByteArray() {
+ return readArray(BYTE_ARR_CREATOR, 0, BYTE_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public short[] readShortArray() {
+ return readArray(SHORT_ARR_CREATOR, 1, SHORT_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int[] readIntArray() {
+ return readArray(INT_ARR_CREATOR, 2, INT_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long[] readLongArray() {
+ return readArray(LONG_ARR_CREATOR, 3, LONG_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public float[] readFloatArray() {
+ return readArray(FLOAT_ARR_CREATOR, 2, FLOAT_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double[] readDoubleArray() {
+ return readArray(DOUBLE_ARR_CREATOR, 3, DOUBLE_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public char[] readCharArray() {
+ return readArray(CHAR_ARR_CREATOR, 1, CHAR_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean[] readBooleanArray() {
+ return readArray(BOOLEAN_ARR_CREATOR, 0, BOOLEAN_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String readString() {
+ byte[] arr = readByteArray();
+
+ return arr != null ? new String(arr) : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public BitSet readBitSet() {
+ long[] arr = readLongArray();
+
+ return arr != null ? BitSet.valueOf(arr) : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public UUID readUuid() {
+ byte[] arr = readByteArray();
+
+ return arr != null ? U.bytesToUuid(arr, 0) : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteUuid readIgniteUuid() {
+ byte[] arr = readByteArray();
+
+ return arr != null ? U.bytesToIgniteUuid(arr, 0) : null;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <T extends Message> T readMessage(MessageReader reader) {
+ if (!msgTypeDone) {
+ if (!buf.hasRemaining()) {
+ lastFinished = false;
+
+ return null;
+ }
+
+ byte type = readByte();
+
+ msg = type == Byte.MIN_VALUE ? null : msgFactory.create(type);
+
+ msgTypeDone = true;
+ }
+
+ lastFinished = msg == null || msg.readFrom(buf, reader);
+
+ if (lastFinished) {
+ Message msg0 = msg;
+
+ msgTypeDone = false;
+ msg = null;
+
+ return (T)msg0;
+ }
+ else
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <T> T[] readObjectArray(MessageCollectionItemType itemType, Class<T> itemCls,
+ MessageReader reader) {
+ if (readSize == -1) {
+ int size = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ readSize = size;
+ }
+
+ if (readSize >= 0) {
+ if (objArr == null)
+ objArr = itemCls != null ? (Object[])Array.newInstance(itemCls, readSize) : new Object[readSize];
+
+ for (int i = readItems; i < readSize; i++) {
+ Object item = read(itemType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ objArr[i] = item;
+
+ readItems++;
+ }
+ }
+
+ readSize = -1;
+ readItems = 0;
+ cur = null;
+
+ T[] objArr0 = (T[])objArr;
+
+ objArr = null;
+
+ return objArr0;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <C extends Collection<?>> C readCollection(MessageCollectionItemType itemType,
+ MessageReader reader) {
+ if (readSize == -1) {
+ int size = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ readSize = size;
+ }
+
+ if (readSize >= 0) {
+ if (col == null)
+ col = new ArrayList<>(readSize);
+
+ for (int i = readItems; i < readSize; i++) {
+ Object item = read(itemType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ col.add(item);
+
+ readItems++;
+ }
+ }
+
+ readSize = -1;
+ readItems = 0;
+ cur = null;
+
+ C col0 = (C)col;
+
+ col = null;
+
+ return col0;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <M extends Map<?, ?>> M readMap(MessageCollectionItemType keyType,
+ MessageCollectionItemType valType, boolean linked, MessageReader reader) {
+ if (readSize == -1) {
+ int size = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ readSize = size;
+ }
+
+ if (readSize >= 0) {
+ if (map == null)
+ map = linked ? U.newLinkedHashMap(readSize) : U.newHashMap(readSize);
+
+ for (int i = readItems; i < readSize; i++) {
+ if (!keyDone) {
+ Object key = read(keyType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ mapCur = key;
+ keyDone = true;
+ }
+
+ Object val = read(valType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ map.put(mapCur, val);
+
+ keyDone = false;
+
+ readItems++;
+ }
+ }
+
+ readSize = -1;
+ readItems = 0;
+ mapCur = null;
+
+ M map0 = (M)map;
+
+ map = null;
+
+ return map0;
+ }
+
+ /**
+ * @param arr Array.
+ * @param off Offset.
+ * @param len Length.
+ * @param bytes Length in bytes.
+ * @return Whether array was fully written
+ */
+ private boolean writeArray(Object arr, long off, int len, int bytes) {
+ assert arr != null;
+ assert arr.getClass().isArray() && arr.getClass().getComponentType().isPrimitive();
+ assert off > 0;
+ assert len >= 0;
+ assert bytes >= 0;
+ assert bytes >= arrOff;
+
+ if (arrOff == -1) {
+ if (buf.remaining() < 4)
+ return false;
+
+ writeInt(len);
+
+ arrOff = 0;
+ }
+
+ int toWrite = bytes - arrOff;
+ int pos = buf.position();
+ int remaining = buf.remaining();
+
+ if (toWrite <= remaining) {
+ UNSAFE.copyMemory(arr, off + arrOff, heapArr, baseOff + pos, toWrite);
+
+ pos += toWrite;
+
+ buf.position(pos);
+
+ arrOff = -1;
+
+ return true;
+ }
+ else {
+ UNSAFE.copyMemory(arr, off + arrOff, heapArr, baseOff + pos, remaining);
+
+ pos += remaining;
+
+ buf.position(pos);
+
+ arrOff += remaining;
+
+ return false;
+ }
+ }
+
+ /**
+ * @param creator Array creator.
+ * @param lenShift Array length shift size.
+ * @param off Base offset.
+ * @return Array or special value if it was not fully read.
+ */
+ @SuppressWarnings("unchecked")
+ private <T> T readArray(ArrayCreator<T> creator, int lenShift, long off) {
+ assert creator != null;
+
+ if (tmpArr == null) {
+ if (buf.remaining() < 4) {
+ lastFinished = false;
+
+ return null;
+ }
+
+ int len = readInt();
+
+ switch (len) {
+ case -1:
+ lastFinished = true;
+
+ return null;
+
+ case 0:
+ lastFinished = true;
+
+ return creator.create(0);
+
+ default:
+ tmpArr = creator.create(len);
+ tmpArrBytes = len << lenShift;
+ }
+ }
+
+ int toRead = tmpArrBytes - tmpArrOff;
+ int remaining = buf.remaining();
+ int pos = buf.position();
+
+ lastFinished = toRead <= remaining;
+
+ if (lastFinished) {
+ UNSAFE.copyMemory(heapArr, baseOff + pos, tmpArr, off + tmpArrOff, toRead);
+
+ buf.position(pos + toRead);
+
+ T arr = (T)tmpArr;
+
+ tmpArr = null;
+ tmpArrBytes = 0;
+ tmpArrOff = 0;
+
+ return arr;
+ }
+ else {
+ UNSAFE.copyMemory(heapArr, baseOff + pos, tmpArr, off + tmpArrOff, remaining);
+
+ buf.position(pos + remaining);
+
+ tmpArrOff += remaining;
+
+ return null;
+ }
+ }
+
+ /**
+ * @param type Type.
+ * @param val Value.
+ * @param writer Writer.
+ */
+ private void write(MessageCollectionItemType type, Object val, MessageWriter writer) {
+ switch (type) {
+ case BYTE:
+ writeByte((Byte)val);
+
+ break;
+
+ case SHORT:
+ writeShort((Short)val);
+
+ break;
+
+ case INT:
+ writeInt((Integer)val);
+
+ break;
+
+ case LONG:
+ writeLong((Long)val);
+
+ break;
+
+ case FLOAT:
+ writeFloat((Float)val);
+
+ break;
+
+ case DOUBLE:
+ writeDouble((Double)val);
+
+ break;
+
+ case CHAR:
+ writeChar((Character)val);
+
+ break;
+
+ case BOOLEAN:
+ writeBoolean((Boolean)val);
+
+ break;
+
+ case BYTE_ARR:
+ writeByteArray((byte[])val);
+
+ break;
+
+ case SHORT_ARR:
+ writeShortArray((short[])val);
+
+ break;
+
+ case INT_ARR:
+ writeIntArray((int[])val);
+
+ break;
+
+ case LONG_ARR:
+ writeLongArray((long[])val);
+
+ break;
+
+ case FLOAT_ARR:
+ writeFloatArray((float[])val);
+
+ break;
+
+ case DOUBLE_ARR:
+ writeDoubleArray((double[])val);
+
+ break;
+
+ case CHAR_ARR:
+ writeCharArray((char[])val);
+
+ break;
+
+ case BOOLEAN_ARR:
+ writeBooleanArray((boolean[])val);
+
+ break;
+
+ case STRING:
+ writeString((String)val);
+
+ break;
+
+ case BIT_SET:
+ writeBitSet((BitSet)val);
+
+ break;
+
+ case UUID:
+ writeUuid((UUID)val);
+
+ break;
+
+ case IGNITE_UUID:
+ writeIgniteUuid((IgniteUuid)val);
+
+ break;
+
+ case MSG:
+ try {
+ if (val != null)
+ writer.beforeInnerMessageWrite();
+
+ writeMessage((Message)val, writer);
+ }
+ finally {
+ if (val != null)
+ writer.afterInnerMessageWrite(lastFinished);
+ }
+
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ /**
+ * @param type Type.
+ * @param reader Reader.
+ * @return Value.
+ */
+ private Object read(MessageCollectionItemType type, MessageReader reader) {
+ switch (type) {
+ case BYTE:
+ return readByte();
+
+ case SHORT:
+ return readShort();
+
+ case INT:
+ return readInt();
+
+ case LONG:
+ return readLong();
+
+ case FLOAT:
+ return readFloat();
+
+ case DOUBLE:
+ return readDouble();
+
+ case CHAR:
+ return readChar();
+
+ case BOOLEAN:
+ return readBoolean();
+
+ case BYTE_ARR:
+ return readByteArray();
+
+ case SHORT_ARR:
+ return readShortArray();
+
+ case INT_ARR:
+ return readIntArray();
+
+ case LONG_ARR:
+ return readLongArray();
+
+ case FLOAT_ARR:
+ return readFloatArray();
+
+ case DOUBLE_ARR:
+ return readDoubleArray();
+
+ case CHAR_ARR:
+ return readCharArray();
+
+ case BOOLEAN_ARR:
+ return readBooleanArray();
+
+ case STRING:
+ return readString();
+
+ case BIT_SET:
+ return readBitSet();
+
+ case UUID:
+ return readUuid();
+
+ case IGNITE_UUID:
+ return readIgniteUuid();
+
+ case MSG:
+ return readMessage(reader);
+
+ default:
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ /**
+ * @param arr Array.
+ * @return Array iterator.
+ */
+ private Iterator<?> arrayIterator(final Object[] arr) {
+ return new Iterator<Object>() {
+ private int idx;
+
+ @Override public boolean hasNext() {
+ return idx < arr.length;
+ }
+
+ @Override public Object next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ return arr[idx++];
+ }
+
+ @Override public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ /**
+ * Array creator.
+ */
+ private static interface ArrayCreator<T> {
+ /**
+ * @param len Array length or {@code -1} if array was not fully read.
+ * @return New array.
+ */
+ public T create(int len);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
new file mode 100644
index 0000000..c330220
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/v2/DirectByteBufferStreamImplV2.java
@@ -0,0 +1,1580 @@
+/*
+ * 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.direct.stream.v2;
+
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.RandomAccess;
+import java.util.UUID;
+import org.apache.ignite.internal.direct.stream.DirectByteBufferStream;
+import org.apache.ignite.internal.util.GridUnsafe;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+import org.apache.ignite.plugin.extensions.communication.MessageFactory;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+import sun.misc.Unsafe;
+import sun.nio.ch.DirectBuffer;
+
+/**
+ * Direct marshalling I/O stream (version 2).
+ */
+public class DirectByteBufferStreamImplV2 implements DirectByteBufferStream {
+ /** */
+ private static final Unsafe UNSAFE = GridUnsafe.unsafe();
+
+ /** */
+ private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
+
+ /** */
+ private static final long SHORT_ARR_OFF = UNSAFE.arrayBaseOffset(short[].class);
+
+ /** */
+ private static final long INT_ARR_OFF = UNSAFE.arrayBaseOffset(int[].class);
+
+ /** */
+ private static final long LONG_ARR_OFF = UNSAFE.arrayBaseOffset(long[].class);
+
+ /** */
+ private static final long FLOAT_ARR_OFF = UNSAFE.arrayBaseOffset(float[].class);
+
+ /** */
+ private static final long DOUBLE_ARR_OFF = UNSAFE.arrayBaseOffset(double[].class);
+
+ /** */
+ private static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class);
+
+ /** */
+ private static final long BOOLEAN_ARR_OFF = UNSAFE.arrayBaseOffset(boolean[].class);
+
+ /** */
+ private static final byte[] BYTE_ARR_EMPTY = new byte[0];
+
+ /** */
+ private static final short[] SHORT_ARR_EMPTY = new short[0];
+
+ /** */
+ private static final int[] INT_ARR_EMPTY = U.EMPTY_INTS;
+
+ /** */
+ private static final long[] LONG_ARR_EMPTY = U.EMPTY_LONGS;
+
+ /** */
+ private static final float[] FLOAT_ARR_EMPTY = new float[0];
+
+ /** */
+ private static final double[] DOUBLE_ARR_EMPTY = new double[0];
+
+ /** */
+ private static final char[] CHAR_ARR_EMPTY = new char[0];
+
+ /** */
+ private static final boolean[] BOOLEAN_ARR_EMPTY = new boolean[0];
+
+ /** */
+ private static final ArrayCreator<byte[]> BYTE_ARR_CREATOR = new ArrayCreator<byte[]>() {
+ @Override public byte[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return BYTE_ARR_EMPTY;
+
+ default:
+ return new byte[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<short[]> SHORT_ARR_CREATOR = new ArrayCreator<short[]>() {
+ @Override public short[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return SHORT_ARR_EMPTY;
+
+ default:
+ return new short[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<int[]> INT_ARR_CREATOR = new ArrayCreator<int[]>() {
+ @Override public int[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return INT_ARR_EMPTY;
+
+ default:
+ return new int[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<long[]> LONG_ARR_CREATOR = new ArrayCreator<long[]>() {
+ @Override public long[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return LONG_ARR_EMPTY;
+
+ default:
+ return new long[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<float[]> FLOAT_ARR_CREATOR = new ArrayCreator<float[]>() {
+ @Override public float[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return FLOAT_ARR_EMPTY;
+
+ default:
+ return new float[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<double[]> DOUBLE_ARR_CREATOR = new ArrayCreator<double[]>() {
+ @Override public double[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return DOUBLE_ARR_EMPTY;
+
+ default:
+ return new double[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<char[]> CHAR_ARR_CREATOR = new ArrayCreator<char[]>() {
+ @Override public char[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return CHAR_ARR_EMPTY;
+
+ default:
+ return new char[len];
+ }
+ }
+ };
+
+ /** */
+ private static final ArrayCreator<boolean[]> BOOLEAN_ARR_CREATOR = new ArrayCreator<boolean[]>() {
+ @Override public boolean[] create(int len) {
+ assert len >= 0;
+
+ switch (len) {
+ case 0:
+ return BOOLEAN_ARR_EMPTY;
+
+ default:
+ return new boolean[len];
+ }
+ }
+ };
+
+ /** */
+ private static final Object NULL = new Object();
+
+ /** */
+ private final MessageFactory msgFactory;
+
+ /** */
+ private ByteBuffer buf;
+
+ /** */
+ private byte[] heapArr;
+
+ /** */
+ private long baseOff;
+
+ /** */
+ private int arrOff = -1;
+
+ /** */
+ private Object tmpArr;
+
+ /** */
+ private int tmpArrOff;
+
+ /** */
+ private int tmpArrBytes;
+
+ /** */
+ private boolean msgTypeDone;
+
+ /** */
+ private Message msg;
+
+ /** */
+ private Iterator<?> mapIt;
+
+ /** */
+ private Iterator<?> it;
+
+ /** */
+ private int arrPos = -1;
+
+ /** */
+ private Object arrCur = NULL;
+
+ /** */
+ private Object mapCur = NULL;
+
+ /** */
+ private Object cur = NULL;
+
+ /** */
+ private boolean keyDone;
+
+ /** */
+ private int readSize = -1;
+
+ /** */
+ private int readItems;
+
+ /** */
+ private Object[] objArr;
+
+ /** */
+ private Collection<Object> col;
+
+ /** */
+ private Map<Object, Object> map;
+
+ /** */
+ private long prim;
+
+ /** */
+ private int primShift;
+
+ /** */
+ private int uuidState;
+
+ /** */
+ private long uuidMost;
+
+ /** */
+ private long uuidLeast;
+
+ /** */
+ private long uuidLocId;
+
+ /** */
+ private boolean lastFinished;
+
+ /**
+ * @param msgFactory Message factory.
+ */
+ public DirectByteBufferStreamImplV2(MessageFactory msgFactory) {
+ this.msgFactory = msgFactory;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void setBuffer(ByteBuffer buf) {
+ assert buf != null;
+
+ if (this.buf != buf) {
+ this.buf = buf;
+
+ heapArr = buf.isDirect() ? null : buf.array();
+ baseOff = buf.isDirect() ? ((DirectBuffer)buf).address() : BYTE_ARR_OFF;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public int remaining() {
+ return buf.remaining();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean lastFinished() {
+ return lastFinished;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByte(byte val) {
+ lastFinished = buf.remaining() >= 1;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putByte(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 1);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShort(short val) {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putShort(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 2);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeInt(int val) {
+ lastFinished = buf.remaining() >= 5;
+
+ if (lastFinished) {
+ if (val == Integer.MAX_VALUE)
+ val = Integer.MIN_VALUE;
+ else
+ val++;
+
+ int pos = buf.position();
+
+ while ((val & 0xFFFF_FF80) != 0) {
+ byte b = (byte)(val | 0x80);
+
+ UNSAFE.putByte(heapArr, baseOff + pos++, b);
+
+ val >>>= 7;
+ }
+
+ UNSAFE.putByte(heapArr, baseOff + pos++, (byte)val);
+
+ buf.position(pos);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLong(long val) {
+ lastFinished = buf.remaining() >= 10;
+
+ if (lastFinished) {
+ if (val == Long.MAX_VALUE)
+ val = Long.MIN_VALUE;
+ else
+ val++;
+
+ int pos = buf.position();
+
+ while ((val & 0xFFFF_FFFF_FFFF_FF80L) != 0) {
+ byte b = (byte)(val | 0x80);
+
+ UNSAFE.putByte(heapArr, baseOff + pos++, b);
+
+ val >>>= 7;
+ }
+
+ UNSAFE.putByte(heapArr, baseOff + pos++, (byte)val);
+
+ buf.position(pos);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloat(float val) {
+ lastFinished = buf.remaining() >= 4;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putFloat(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 4);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDouble(double val) {
+ lastFinished = buf.remaining() >= 8;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putDouble(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 8);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeChar(char val) {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putChar(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 2);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBoolean(boolean val) {
+ lastFinished = buf.remaining() >= 1;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ UNSAFE.putBoolean(heapArr, baseOff + pos, val);
+
+ buf.position(pos + 1);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByteArray(byte[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, BYTE_ARR_OFF, val.length, val.length);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeByteArray(byte[] val, long off, int len) {
+ if (val != null)
+ lastFinished = writeArray(val, BYTE_ARR_OFF + off, len, len);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeShortArray(short[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, SHORT_ARR_OFF, val.length, val.length << 1);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeIntArray(int[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, INT_ARR_OFF, val.length, val.length << 2);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeLongArray(long[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, LONG_ARR_OFF, val.length, val.length << 3);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeFloatArray(float[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, FLOAT_ARR_OFF, val.length, val.length << 2);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeDoubleArray(double[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, DOUBLE_ARR_OFF, val.length, val.length << 3);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeCharArray(char[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, CHAR_ARR_OFF, val.length, val.length << 1);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBooleanArray(boolean[] val) {
+ if (val != null)
+ lastFinished = writeArray(val, BOOLEAN_ARR_OFF, val.length, val.length);
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeString(String val) {
+ writeByteArray(val != null ? val.getBytes() : null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeBitSet(BitSet val) {
+ writeLongArray(val != null ? val.toLongArray() : null);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeUuid(UUID val) {
+ switch (uuidState) {
+ case 0:
+ writeBoolean(val == null);
+
+ if (!lastFinished || val == null)
+ return;
+
+ uuidState++;
+
+ case 1:
+ writeLong(val.getMostSignificantBits());
+
+ if (!lastFinished)
+ return;
+
+ uuidState++;
+
+ case 2:
+ writeLong(val.getLeastSignificantBits());
+
+ if (!lastFinished)
+ return;
+
+ uuidState = 0;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeIgniteUuid(IgniteUuid val) {
+ switch (uuidState) {
+ case 0:
+ writeBoolean(val == null);
+
+ if (!lastFinished || val == null)
+ return;
+
+ uuidState++;
+
+ case 1:
+ writeLong(val.globalId().getMostSignificantBits());
+
+ if (!lastFinished)
+ return;
+
+ uuidState++;
+
+ case 2:
+ writeLong(val.globalId().getLeastSignificantBits());
+
+ if (!lastFinished)
+ return;
+
+ uuidState++;
+
+ case 3:
+ writeLong(val.localId());
+
+ if (!lastFinished)
+ return;
+
+ uuidState = 0;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeMessage(Message msg, MessageWriter writer) {
+ if (msg != null) {
+ if (buf.hasRemaining()) {
+ try {
+ writer.beforeInnerMessageWrite();
+
+ lastFinished = msg.writeTo(buf, writer);
+ }
+ finally {
+ writer.afterInnerMessageWrite(lastFinished);
+ }
+ }
+ else
+ lastFinished = false;
+ }
+ else
+ writeByte(Byte.MIN_VALUE);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> void writeObjectArray(T[] arr, MessageCollectionItemType itemType,
+ MessageWriter writer) {
+ if (arr != null) {
+ int len = arr.length;
+
+ if (arrPos == -1) {
+ writeInt(len);
+
+ if (!lastFinished)
+ return;
+
+ arrPos = 0;
+ }
+
+ while (arrPos < len || arrCur != NULL) {
+ if (arrCur == NULL)
+ arrCur = arr[arrPos++];
+
+ write(itemType, arrCur, writer);
+
+ if (!lastFinished)
+ return;
+
+ arrCur = NULL;
+ }
+
+ arrPos = -1;
+ }
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <T> void writeCollection(Collection<T> col, MessageCollectionItemType itemType,
+ MessageWriter writer) {
+ if (col != null) {
+ if (col instanceof List && col instanceof RandomAccess)
+ writeRandomAccessList((List<T>)col, itemType, writer);
+ else {
+ if (it == null) {
+ writeInt(col.size());
+
+ if (!lastFinished)
+ return;
+
+ it = col.iterator();
+ }
+
+ while (it.hasNext() || cur != NULL) {
+ if (cur == NULL)
+ cur = it.next();
+
+ write(itemType, cur, writer);
+
+ if (!lastFinished)
+ return;
+
+ cur = NULL;
+ }
+
+ it = null;
+ }
+ }
+ else
+ writeInt(-1);
+ }
+
+ /**
+ * @param list List.
+ * @param itemType Component type.
+ * @param writer Writer.
+ */
+ private <T> void writeRandomAccessList(List<T> list, MessageCollectionItemType itemType, MessageWriter writer) {
+ assert list instanceof RandomAccess;
+
+ int size = list.size();
+
+ if (arrPos == -1) {
+ writeInt(size);
+
+ if (!lastFinished)
+ return;
+
+ arrPos = 0;
+ }
+
+ while (arrPos < size || arrCur != NULL) {
+ if (arrCur == NULL)
+ arrCur = list.get(arrPos++);
+
+ write(itemType, arrCur, writer);
+
+ if (!lastFinished)
+ return;
+
+ arrCur = NULL;
+ }
+
+ arrPos = -1;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <K, V> void writeMap(Map<K, V> map, MessageCollectionItemType keyType,
+ MessageCollectionItemType valType, MessageWriter writer) {
+ if (map != null) {
+ if (mapIt == null) {
+ writeInt(map.size());
+
+ if (!lastFinished)
+ return;
+
+ mapIt = map.entrySet().iterator();
+ }
+
+ while (mapIt.hasNext() || mapCur != NULL) {
+ Map.Entry<K, V> e;
+
+ if (mapCur == NULL)
+ mapCur = mapIt.next();
+
+ e = (Map.Entry<K, V>)mapCur;
+
+ if (!keyDone) {
+ write(keyType, e.getKey(), writer);
+
+ if (!lastFinished)
+ return;
+
+ keyDone = true;
+ }
+
+ write(valType, e.getValue(), writer);
+
+ if (!lastFinished)
+ return;
+
+ mapCur = NULL;
+ keyDone = false;
+ }
+
+ mapIt = null;
+ }
+ else
+ writeInt(-1);
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte readByte() {
+ lastFinished = buf.remaining() >= 1;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 1);
+
+ return UNSAFE.getByte(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public short readShort() {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 2);
+
+ return UNSAFE.getShort(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int readInt() {
+ lastFinished = false;
+
+ int val = 0;
+
+ while (buf.hasRemaining()) {
+ int pos = buf.position();
+
+ byte b = UNSAFE.getByte(heapArr, baseOff + pos);
+
+ buf.position(pos + 1);
+
+ prim |= ((long)b & 0x7F) << (7 * primShift);
+
+ if ((b & 0x80) == 0) {
+ lastFinished = true;
+
+ val = (int)prim;
+
+ if (val == Integer.MIN_VALUE)
+ val = Integer.MAX_VALUE;
+ else
+ val--;
+
+ prim = 0;
+ primShift = 0;
+
+ break;
+ }
+ else
+ primShift++;
+ }
+
+ return val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public long readLong() {
+ lastFinished = false;
+
+ long val = 0;
+
+ while (buf.hasRemaining()) {
+ int pos = buf.position();
+
+ byte b = UNSAFE.getByte(heapArr, baseOff + pos);
+
+ buf.position(pos + 1);
+
+ prim |= ((long)b & 0x7F) << (7 * primShift);
+
+ if ((b & 0x80) == 0) {
+ lastFinished = true;
+
+ val = prim;
+
+ if (val == Long.MIN_VALUE)
+ val = Long.MAX_VALUE;
+ else
+ val--;
+
+ prim = 0;
+ primShift = 0;
+
+ break;
+ }
+ else
+ primShift++;
+ }
+
+ return val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public float readFloat() {
+ lastFinished = buf.remaining() >= 4;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 4);
+
+ return UNSAFE.getFloat(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public double readDouble() {
+ lastFinished = buf.remaining() >= 8;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 8);
+
+ return UNSAFE.getDouble(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public char readChar() {
+ lastFinished = buf.remaining() >= 2;
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 2);
+
+ return UNSAFE.getChar(heapArr, baseOff + pos);
+ }
+ else
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean readBoolean() {
+ lastFinished = buf.hasRemaining();
+
+ if (lastFinished) {
+ int pos = buf.position();
+
+ buf.position(pos + 1);
+
+ return UNSAFE.getBoolean(heapArr, baseOff + pos);
+ }
+ else
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte[] readByteArray() {
+ return readArray(BYTE_ARR_CREATOR, 0, BYTE_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public short[] readShortArray() {
+ return readArray(SHORT_ARR_CREATOR, 1, SHORT_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public int[] readIntArray() {
+ return readArray(INT_ARR_CREATOR, 2, INT_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public long[] readLongArray() {
+ return readArray(LONG_ARR_CREATOR, 3, LONG_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public float[] readFloatArray() {
+ return readArray(FLOAT_ARR_CREATOR, 2, FLOAT_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public double[] readDoubleArray() {
+ return readArray(DOUBLE_ARR_CREATOR, 3, DOUBLE_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public char[] readCharArray() {
+ return readArray(CHAR_ARR_CREATOR, 1, CHAR_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean[] readBooleanArray() {
+ return readArray(BOOLEAN_ARR_CREATOR, 0, BOOLEAN_ARR_OFF);
+ }
+
+ /** {@inheritDoc} */
+ @Override public String readString() {
+ byte[] arr = readByteArray();
+
+ return arr != null ? new String(arr) : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public BitSet readBitSet() {
+ long[] arr = readLongArray();
+
+ return arr != null ? BitSet.valueOf(arr) : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public UUID readUuid() {
+ switch (uuidState) {
+ case 0:
+ boolean isNull = readBoolean();
+
+ if (!lastFinished || isNull)
+ return null;
+
+ uuidState++;
+
+ case 1:
+ uuidMost = readLong();
+
+ if (!lastFinished)
+ return null;
+
+ uuidState++;
+
+ case 2:
+ uuidLeast = readLong();
+
+ if (!lastFinished)
+ return null;
+
+ uuidState = 0;
+ }
+
+ UUID val = new UUID(uuidMost, uuidLeast);
+
+ uuidMost = 0;
+ uuidLeast = 0;
+
+ return val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteUuid readIgniteUuid() {
+ switch (uuidState) {
+ case 0:
+ boolean isNull = readBoolean();
+
+ if (!lastFinished || isNull)
+ return null;
+
+ uuidState++;
+
+ case 1:
+ uuidMost = readLong();
+
+ if (!lastFinished)
+ return null;
+
+ uuidState++;
+
+ case 2:
+ uuidLeast = readLong();
+
+ if (!lastFinished)
+ return null;
+
+ uuidState++;
+
+ case 3:
+ uuidLocId = readLong();
+
+ if (!lastFinished)
+ return null;
+
+ uuidState = 0;
+ }
+
+ IgniteUuid val = new IgniteUuid(new UUID(uuidMost, uuidLeast), uuidLocId);
+
+ uuidMost = 0;
+ uuidLeast = 0;
+
+ return val;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <T extends Message> T readMessage(MessageReader reader) {
+ if (!msgTypeDone) {
+ if (!buf.hasRemaining()) {
+ lastFinished = false;
+
+ return null;
+ }
+
+ byte type = readByte();
+
+ msg = type == Byte.MIN_VALUE ? null : msgFactory.create(type);
+
+ msgTypeDone = true;
+ }
+
+ if (msg != null) {
+ try {
+ reader.beforeInnerMessageRead();
+
+ lastFinished = msg.readFrom(buf, reader);
+ }
+ finally {
+ reader.afterInnerMessageRead(lastFinished);
+ }
+ }
+ else
+ lastFinished = true;
+
+ if (lastFinished) {
+ Message msg0 = msg;
+
+ msgTypeDone = false;
+ msg = null;
+
+ return (T)msg0;
+ }
+ else
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <T> T[] readObjectArray(MessageCollectionItemType itemType, Class<T> itemCls,
+ MessageReader reader) {
+ if (readSize == -1) {
+ int size = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ readSize = size;
+ }
+
+ if (readSize >= 0) {
+ if (objArr == null)
+ objArr = itemCls != null ? (Object[])Array.newInstance(itemCls, readSize) : new Object[readSize];
+
+ for (int i = readItems; i < readSize; i++) {
+ Object item = read(itemType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ objArr[i] = item;
+
+ readItems++;
+ }
+ }
+
+ readSize = -1;
+ readItems = 0;
+ cur = null;
+
+ T[] objArr0 = (T[])objArr;
+
+ objArr = null;
+
+ return objArr0;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <C extends Collection<?>> C readCollection(MessageCollectionItemType itemType,
+ MessageReader reader) {
+ if (readSize == -1) {
+ int size = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ readSize = size;
+ }
+
+ if (readSize >= 0) {
+ if (col == null)
+ col = new ArrayList<>(readSize);
+
+ for (int i = readItems; i < readSize; i++) {
+ Object item = read(itemType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ col.add(item);
+
+ readItems++;
+ }
+ }
+
+ readSize = -1;
+ readItems = 0;
+ cur = null;
+
+ C col0 = (C)col;
+
+ col = null;
+
+ return col0;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override public <M extends Map<?, ?>> M readMap(MessageCollectionItemType keyType,
+ MessageCollectionItemType valType, boolean linked, MessageReader reader) {
+ if (readSize == -1) {
+ int size = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ readSize = size;
+ }
+
+ if (readSize >= 0) {
+ if (map == null)
+ map = linked ? U.newLinkedHashMap(readSize) : U.newHashMap(readSize);
+
+ for (int i = readItems; i < readSize; i++) {
+ if (!keyDone) {
+ Object key = read(keyType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ mapCur = key;
+ keyDone = true;
+ }
+
+ Object val = read(valType, reader);
+
+ if (!lastFinished)
+ return null;
+
+ map.put(mapCur, val);
+
+ keyDone = false;
+
+ readItems++;
+ }
+ }
+
+ readSize = -1;
+ readItems = 0;
+ mapCur = null;
+
+ M map0 = (M)map;
+
+ map = null;
+
+ return map0;
+ }
+
+ /**
+ * @param arr Array.
+ * @param off Offset.
+ * @param len Length.
+ * @param bytes Length in bytes.
+ * @return Whether array was fully written.
+ */
+ private boolean writeArray(Object arr, long off, int len, int bytes) {
+ assert arr != null;
+ assert arr.getClass().isArray() && arr.getClass().getComponentType().isPrimitive();
+ assert off > 0;
+ assert len >= 0;
+ assert bytes >= 0;
+ assert bytes >= arrOff;
+
+ if (arrOff == -1) {
+ writeInt(len);
+
+ if (!lastFinished)
+ return false;
+
+ arrOff = 0;
+ }
+
+ int toWrite = bytes - arrOff;
+ int pos = buf.position();
+ int remaining = buf.remaining();
+
+ if (toWrite <= remaining) {
+ if (toWrite > 0) {
+ UNSAFE.copyMemory(arr, off + arrOff, heapArr, baseOff + pos, toWrite);
+
+ buf.position(pos + toWrite);
+ }
+
+ arrOff = -1;
+
+ return true;
+ }
+ else {
+ if (remaining > 0) {
+ UNSAFE.copyMemory(arr, off + arrOff, heapArr, baseOff + pos, remaining);
+
+ buf.position(pos + remaining);
+
+ arrOff += remaining;
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * @param creator Array creator.
+ * @param lenShift Array length shift size.
+ * @param off Base offset.
+ * @return Array or special value if it was not fully read.
+ */
+ @SuppressWarnings("unchecked")
+ private <T> T readArray(ArrayCreator<T> creator, int lenShift, long off) {
+ assert creator != null;
+
+ if (tmpArr == null) {
+ int len = readInt();
+
+ if (!lastFinished)
+ return null;
+
+ switch (len) {
+ case -1:
+ lastFinished = true;
+
+ return null;
+
+ case 0:
+ lastFinished = true;
+
+ return creator.create(0);
+
+ default:
+ tmpArr = creator.create(len);
+ tmpArrBytes = len << lenShift;
+ }
+ }
+
+ int toRead = tmpArrBytes - tmpArrOff;
+ int remaining = buf.remaining();
+ int pos = buf.position();
+
+ lastFinished = toRead <= remaining;
+
+ if (lastFinished) {
+ UNSAFE.copyMemory(heapArr, baseOff + pos, tmpArr, off + tmpArrOff, toRead);
+
+ buf.position(pos + toRead);
+
+ T arr = (T)tmpArr;
+
+ tmpArr = null;
+ tmpArrBytes = 0;
+ tmpArrOff = 0;
+
+ return arr;
+ }
+ else {
+ UNSAFE.copyMemory(heapArr, baseOff + pos, tmpArr, off + tmpArrOff, remaining);
+
+ buf.position(pos + remaining);
+
+ tmpArrOff += remaining;
+
+ return null;
+ }
+ }
+
+ /**
+ * @param type Type.
+ * @param val Value.
+ * @param writer Writer.
+ */
+ private void write(MessageCollectionItemType type, Object val, MessageWriter writer) {
+ switch (type) {
+ case BYTE:
+ writeByte((Byte)val);
+
+ break;
+
+ case SHORT:
+ writeShort((Short)val);
+
+ break;
+
+ case INT:
+ writeInt((Integer)val);
+
+ break;
+
+ case LONG:
+ writeLong((Long)val);
+
+ break;
+
+ case FLOAT:
+ writeFloat((Float)val);
+
+ break;
+
+ case DOUBLE:
+ writeDouble((Double)val);
+
+ break;
+
+ case CHAR:
+ writeChar((Character)val);
+
+ break;
+
+ case BOOLEAN:
+ writeBoolean((Boolean)val);
+
+ break;
+
+ case BYTE_ARR:
+ writeByteArray((byte[])val);
+
+ break;
+
+ case SHORT_ARR:
+ writeShortArray((short[])val);
+
+ break;
+
+ case INT_ARR:
+ writeIntArray((int[])val);
+
+ break;
+
+ case LONG_ARR:
+ writeLongArray((long[])val);
+
+ break;
+
+ case FLOAT_ARR:
+ writeFloatArray((float[])val);
+
+ break;
+
+ case DOUBLE_ARR:
+ writeDoubleArray((double[])val);
+
+ break;
+
+ case CHAR_ARR:
+ writeCharArray((char[])val);
+
+ break;
+
+ case BOOLEAN_ARR:
+ writeBooleanArray((boolean[])val);
+
+ break;
+
+ case STRING:
+ writeString((String)val);
+
+ break;
+
+ case BIT_SET:
+ writeBitSet((BitSet)val);
+
+ break;
+
+ case UUID:
+ writeUuid((UUID)val);
+
+ break;
+
+ case IGNITE_UUID:
+ writeIgniteUuid((IgniteUuid)val);
+
+ break;
+
+ case MSG:
+ try {
+ if (val != null)
+ writer.beforeInnerMessageWrite();
+
+ writeMessage((Message)val, writer);
+ }
+ finally {
+ if (val != null)
+ writer.afterInnerMessageWrite(lastFinished);
+ }
+
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ /**
+ * @param type Type.
+ * @param reader Reader.
+ * @return Value.
+ */
+ private Object read(MessageCollectionItemType type, MessageReader reader) {
+ switch (type) {
+ case BYTE:
+ return readByte();
+
+ case SHORT:
+ return readShort();
+
+ case INT:
+ return readInt();
+
+ case LONG:
+ return readLong();
+
+ case FLOAT:
+ return readFloat();
+
+ case DOUBLE:
+ return readDouble();
+
+ case CHAR:
+ return readChar();
+
+ case BOOLEAN:
+ return readBoolean();
+
+ case BYTE_ARR:
+ return readByteArray();
+
+ case SHORT_ARR:
+ return readShortArray();
+
+ case INT_ARR:
+ return readIntArray();
+
+ case LONG_ARR:
+ return readLongArray();
+
+ case FLOAT_ARR:
+ return readFloatArray();
+
+ case DOUBLE_ARR:
+ return readDoubleArray();
+
+ case CHAR_ARR:
+ return readCharArray();
+
+ case BOOLEAN_ARR:
+ return readBooleanArray();
+
+ case STRING:
+ return readString();
+
+ case BIT_SET:
+ return readBitSet();
+
+ case UUID:
+ return readUuid();
+
+ case IGNITE_UUID:
+ return readIgniteUuid();
+
+ case MSG:
+ return readMessage(reader);
+
+ default:
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ /**
+ * Array creator.
+ */
+ private static interface ArrayCreator<T> {
+ /**
+ * @param len Array length or {@code -1} if array was not fully read.
+ * @return New array.
+ */
+ public T create(int len);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index c3a708c..e8aeb6b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -112,6 +112,12 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
/** Max closed topics to store. */
public static final int MAX_CLOSED_TOPICS = 10240;
+ /** Direct protocol version attribute name. */
+ public static final String DIRECT_PROTO_VER_ATTR = "comm.direct.proto.ver";
+
+ /** Direct protocol version. */
+ public static final byte DIRECT_PROTO_VER = 2;
+
/** Listeners by topic. */
private final ConcurrentMap<Object, GridMessageListener> lsnrMap = new ConcurrentHashMap8<>();
@@ -265,6 +271,8 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
}
});
+ ctx.addNodeAttribute(DIRECT_PROTO_VER_ATTR, DIRECT_PROTO_VER);
+
MessageFormatter[] formatterExt = ctx.plugins().extensions(MessageFormatter.class);
if (formatterExt != null && formatterExt.length > 0) {
@@ -279,13 +287,13 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
@Override public MessageWriter writer(UUID rmtNodeId) {
assert rmtNodeId != null;
- return new DirectMessageWriter();
+ return new DirectMessageWriter(directProtocolVersion(rmtNodeId));
}
@Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
assert rmtNodeId != null;
- return new DirectMessageReader(msgFactory);
+ return new DirectMessageReader(msgFactory, directProtocolVersion(rmtNodeId));
}
};
}
@@ -316,6 +324,33 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
}
/**
+ * Defines which protocol version to use for
+ * communication with the provided node.
+ *
+ * @param nodeId Node ID.
+ * @return Protocol version.
+ */
+ private byte directProtocolVersion(UUID nodeId) {
+ assert nodeId != null;
+
+ ClusterNode node = ctx.discovery().node(nodeId);
+
+ // TODO: DIRECT - throw exception
+ assert node != null;
+
+ assert !node.isLocal();
+
+ Byte attr = node.attribute(DIRECT_PROTO_VER_ATTR);
+
+ byte rmtProtoVer = attr != null ? attr : 1;
+
+ if (rmtProtoVer < DIRECT_PROTO_VER)
+ return rmtProtoVer;
+ else
+ return DIRECT_PROTO_VER;
+ }
+
+ /**
* Processes IO messaging pool extensions.
* @throws IgniteCheckedException On error.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
index dc1a7e6..4025ddd 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
@@ -37,6 +37,7 @@ import org.apache.ignite.events.TaskEvent;
import org.apache.ignite.internal.ClusterMetricsSnapshot;
import org.apache.ignite.internal.direct.DirectMessageReader;
import org.apache.ignite.internal.direct.DirectMessageWriter;
+import org.apache.ignite.internal.managers.communication.GridIoManager;
import org.apache.ignite.internal.managers.communication.GridIoMessageFactory;
import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
@@ -493,11 +494,11 @@ public class GridSpiTestContext implements IgniteSpiContext {
if (formatter == null) {
formatter = new MessageFormatter() {
@Override public MessageWriter writer(UUID rmtNodeId) {
- return new DirectMessageWriter();
+ return new DirectMessageWriter(GridIoManager.DIRECT_PROTO_VER);
}
@Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
- return new DirectMessageReader(msgFactory);
+ return new DirectMessageReader(msgFactory, GridIoManager.DIRECT_PROTO_VER);
}
};
}
[15/51] ignite git commit: Fixed typos
Posted by vk...@apache.org.
Fixed typos
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/946360aa
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/946360aa
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/946360aa
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 946360aa5438d8fabf0a7df4082ffb83346503ea
Parents: ee5a50f
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 10 16:01:46 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 10 16:01:46 2015 -0800
----------------------------------------------------------------------
.../ignite/cache/store/CacheStoreSessionListener.java | 9 +++++----
.../cache/store/jdbc/CacheJdbcStoreSessionListener.java | 8 ++++----
2 files changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/946360aa/modules/core/src/main/java/org/apache/ignite/cache/store/CacheStoreSessionListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/CacheStoreSessionListener.java b/modules/core/src/main/java/org/apache/ignite/cache/store/CacheStoreSessionListener.java
index 8215756..9496d20 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/CacheStoreSessionListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/CacheStoreSessionListener.java
@@ -35,11 +35,12 @@ import org.apache.ignite.configuration.IgniteConfiguration;
* rollback when session is finished.
* <p>
* Cache store session listener allows to implement this and other
- * scenarios providing to callback methods:
+ * scenarios providing two callback methods:
* <ul>
* <li>
* {@link #onSessionStart(CacheStoreSession)} - called
- * before any store operation within a session is invoked.
+ * when a session is created prior to all operations
+ * within his session.
* </li>
* <li>
* {@link #onSessionEnd(CacheStoreSession, boolean)} - called
@@ -47,7 +48,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
* </li>
* </ul>
* <h2>Implementations</h2>
- * Ignites provides several out-of-the-box implementations
+ * Ignite provides several out-of-the-box implementations
* of session listener (refer to individual JavaDocs for more
* details):
* <ul>
@@ -130,4 +131,4 @@ public interface CacheStoreSessionListener {
* should commit, {@code false} for rollback.
*/
public void onSessionEnd(CacheStoreSession ses, boolean commit);
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/946360aa/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreSessionListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreSessionListener.java b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreSessionListener.java
index 2c70d26..6be237e 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreSessionListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/store/jdbc/CacheJdbcStoreSessionListener.java
@@ -37,12 +37,12 @@ import org.apache.ignite.lifecycle.LifecycleAware;
* back) it when session ends.
* <p>
* The connection is saved as a store session
- * {@link CacheStoreSession#attachment() attachment}.
+ * {@link CacheStoreSession#attachment() attachment}.
* The listener guarantees that the connection will be
* available for any store operation. If there is an
* ongoing cache transaction, all operations within this
* transaction will be committed or rolled back only when
- * session ends.
+ * the session ends.
* <p>
* As an example, here is how the {@link CacheStore#write(Cache.Entry)}
* method can be implemented if {@link CacheJdbcStoreSessionListener}
@@ -133,11 +133,11 @@ public class CacheJdbcStoreSessionListener implements CacheStoreSessionListener,
conn.rollback();
}
catch (SQLException e) {
- throw new CacheWriterException("Failed to start store session [tx=" + ses.transaction() + ']', e);
+ throw new CacheWriterException("Failed to end store session [tx=" + ses.transaction() + ']', e);
}
finally {
U.closeQuiet(conn);
}
}
}
-}
\ No newline at end of file
+}
[05/51] ignite git commit: Ignite-1093 "Rebalancing with default
parameters is very slow" fixes.
Posted by vk...@apache.org.
Ignite-1093 "Rebalancing with default parameters is very slow" fixes.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/242d988a
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/242d988a
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/242d988a
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 242d988a077878cca93f7bec85af3438a94e44d7
Parents: 7573003
Author: Anton Vinogradov <av...@apache.org>
Authored: Thu Nov 5 16:15:34 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Thu Nov 5 20:29:29 2015 +0300
----------------------------------------------------------------------
.../configuration/CacheConfiguration.java | 54 +-
.../configuration/IgniteConfiguration.java | 32 +-
.../apache/ignite/internal/IgniteKernal.java | 21 +
.../org/apache/ignite/internal/IgnitionEx.java | 3 +
.../communication/GridIoMessageFactory.java | 10 +-
.../processors/cache/GridCacheIoManager.java | 19 +-
.../processors/cache/GridCacheMapEntry.java | 38 +-
.../GridCachePartitionExchangeManager.java | 164 ++-
.../processors/cache/GridCachePreloader.java | 55 +-
.../cache/GridCachePreloaderAdapter.java | 40 +-
.../processors/cache/GridCacheProcessor.java | 55 +-
.../distributed/dht/GridDhtCacheEntry.java | 11 +-
.../distributed/dht/GridDhtLocalPartition.java | 63 +-
.../dht/GridDhtPartitionsReservation.java | 2 +-
.../GridDhtPartitionDemandMessage.java | 14 +-
.../preloader/GridDhtPartitionDemandPool.java | 1192 ---------------
.../dht/preloader/GridDhtPartitionDemander.java | 1389 ++++++++++++++++++
.../dht/preloader/GridDhtPartitionSupplier.java | 1034 +++++++++++++
.../GridDhtPartitionSupplyMessageV2.java | 380 +++++
.../preloader/GridDhtPartitionSupplyPool.java | 555 -------
.../GridDhtPartitionsExchangeFuture.java | 2 +
.../dht/preloader/GridDhtPreloader.java | 282 +++-
.../datastructures/DataStructuresProcessor.java | 3 +
.../processors/task/GridTaskWorker.java | 4 +-
.../ignite/internal/util/lang/GridTuple4.java | 2 +-
.../spi/discovery/tcp/TcpDiscoverySpi.java | 2 +-
.../IgniteCacheP2pUnmarshallingErrorTest.java | 2 +-
.../dht/GridCacheTxNodeFailureSelfTest.java | 21 +-
.../GridCacheRebalancingAsyncSelfTest.java | 68 +
.../GridCacheRebalancingSyncSelfTest.java | 506 +++++++
...eRebalancingUnmarshallingFailedSelfTest.java | 147 ++
.../GridCacheReplicatedPreloadSelfTest.java | 22 +-
.../spi/discovery/tcp/TcpDiscoverySelfTest.java | 17 -
.../spi/discovery/tcp/TestTcpDiscoverySpi.java | 46 +
.../testframework/junits/GridAbstractTest.java | 3 +-
.../junits/common/GridCommonAbstractTest.java | 21 +-
.../testsuites/IgniteCacheTestSuite3.java | 4 +
.../tcp/GridOrderedMessageCancelSelfTest.java | 18 +-
38 files changed, 4309 insertions(+), 1992 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 374743f..b7276c9 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -69,11 +69,15 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
private static final long serialVersionUID = 0L;
/** Default size of rebalance thread pool. */
+ @Deprecated
public static final int DFLT_REBALANCE_THREAD_POOL_SIZE = 2;
/** Default rebalance timeout (ms).*/
public static final long DFLT_REBALANCE_TIMEOUT = 10000;
+ /** Default rebalance batches prefetch count. */
+ public static final long DFLT_REBALANCE_BATCHES_PREFETCH_COUNT = 2;
+
/** Time in milliseconds to wait between rebalance messages to avoid overloading CPU. */
public static final long DFLT_REBALANCE_THROTTLE = 0;
@@ -174,6 +178,7 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
private String name;
/** Rebalance thread pool size. */
+ @Deprecated
private int rebalancePoolSize = DFLT_REBALANCE_THREAD_POOL_SIZE;
/** Rebalance timeout. */
@@ -254,6 +259,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
/** Rebalance batch size. */
private int rebalanceBatchSize = DFLT_REBALANCE_BATCH_SIZE;
+ /** Rebalance batches prefetch count. */
+ private long rebalanceBatchesPrefetchCount = DFLT_REBALANCE_BATCHES_PREFETCH_COUNT;
+
/** Off-heap memory size. */
private long offHeapMaxMem = DFLT_OFFHEAP_MEMORY;
@@ -394,9 +402,10 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
name = cc.getName();
nearCfg = cc.getNearConfiguration();
nodeFilter = cc.getNodeFilter();
- rebalanceMode = cc.getRebalanceMode();
+ rebalanceBatchesPrefetchCount = cc.getRebalanceBatchesPrefetchCount();
rebalanceBatchSize = cc.getRebalanceBatchSize();
rebalanceDelay = cc.getRebalanceDelay();
+ rebalanceMode = cc.getRebalanceMode();
rebalanceOrder = cc.getRebalanceOrder();
rebalancePoolSize = cc.getRebalanceThreadPoolSize();
rebalanceTimeout = cc.getRebalanceTimeout();
@@ -1036,10 +1045,10 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
* {@link CacheRebalanceMode#SYNC SYNC} or {@link CacheRebalanceMode#ASYNC ASYNC} rebalance modes only.
* <p/>
* If cache rebalance order is positive, rebalancing for this cache will be started only when rebalancing for
- * all caches with smaller rebalance order (except caches with rebalance order {@code 0}) will be completed.
+ * all caches with smaller rebalance order will be completed.
* <p/>
* Note that cache with order {@code 0} does not participate in ordering. This means that cache with
- * rebalance order {@code 1} will never wait for any other caches. All caches with order {@code 0} will
+ * rebalance order {@code 0} will never wait for any other caches. All caches with order {@code 0} will
* be rebalanced right away concurrently with each other and ordered rebalance processes.
* <p/>
* If not set, cache order is 0, i.e. rebalancing is not ordered.
@@ -1088,6 +1097,35 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
}
/**
+ * To gain better rebalancing performance supplier node can provide more than one batch at rebalancing start and
+ * provide one new to each next demand request.
+ *
+ * Gets number of batches generated by supply node at rebalancing start.
+ * Minimum is 1.
+ *
+ * @return batches count
+ */
+ public long getRebalanceBatchesPrefetchCount() {
+ return rebalanceBatchesPrefetchCount;
+ }
+
+ /**
+ * To gain better rebalancing performance supplier node can provide more than one batch at rebalancing start and
+ * provide one new to each next demand request.
+ *
+ * Sets number of batches generated by supply node at rebalancing start.
+ * Minimum is 1.
+ *
+ * @param rebalanceBatchesCnt batches count.
+ * @return {@code this} for chaining.
+ */
+ public CacheConfiguration<K, V> setRebalanceBatchesPrefetchCount(long rebalanceBatchesCnt) {
+ this.rebalanceBatchesPrefetchCount = rebalanceBatchesCnt;
+
+ return this;
+ }
+
+ /**
* Flag indicating whether Ignite should use swap storage by default. By default
* swap is disabled which is defined via {@link #DFLT_SWAP_ENABLED} constant.
*
@@ -1273,24 +1311,22 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
}
/**
- * Gets size of rebalancing thread pool. Note that size serves as a hint and implementation
- * may create more threads for rebalancing than specified here (but never less threads).
- * <p>
- * Default value is {@link #DFLT_REBALANCE_THREAD_POOL_SIZE}.
+ * Use {@link IgniteConfiguration#getRebalanceThreadPoolSize()} instead.
*
* @return Size of rebalancing thread pool.
*/
+ @Deprecated
public int getRebalanceThreadPoolSize() {
return rebalancePoolSize;
}
/**
- * Sets size of rebalancing thread pool. Note that size serves as a hint and implementation may create more threads
- * for rebalancing than specified here (but never less threads).
+ * Use {@link IgniteConfiguration#getRebalanceThreadPoolSize()} instead.
*
* @param rebalancePoolSize Size of rebalancing thread pool.
* @return {@code this} for chaining.
*/
+ @Deprecated
public CacheConfiguration<K, V> setRebalanceThreadPoolSize(int rebalancePoolSize) {
this.rebalancePoolSize = rebalancePoolSize;
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 ecae356..9298c6d 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
@@ -149,6 +149,9 @@ public class IgniteConfiguration {
/** Default keep alive time for public thread pool. */
public static final long DFLT_PUBLIC_KEEP_ALIVE_TIME = 0;
+ /** Default limit of threads used for rebalance. */
+ public static final int DFLT_REBALANCE_THREAD_POOL_SIZE = 1;
+
/** Default max queue capacity of public thread pool. */
public static final int DFLT_PUBLIC_THREADPOOL_QUEUE_CAP = Integer.MAX_VALUE;
@@ -354,6 +357,9 @@ public class IgniteConfiguration {
/** Client mode flag. */
private Boolean clientMode;
+ /** Rebalance thread pool size. */
+ private int rebalanceThreadPoolSize = DFLT_REBALANCE_THREAD_POOL_SIZE;
+
/** Transactions configuration. */
private TransactionConfiguration txCfg = new TransactionConfiguration();
@@ -500,6 +506,7 @@ public class IgniteConfiguration {
p2pPoolSize = cfg.getPeerClassLoadingThreadPoolSize();
pluginCfgs = cfg.getPluginConfigurations();
pubPoolSize = cfg.getPublicThreadPoolSize();
+ rebalanceThreadPoolSize = cfg.getRebalanceThreadPoolSize();
segChkFreq = cfg.getSegmentCheckFrequency();
segPlc = cfg.getSegmentationPolicy();
segResolveAttempts = cfg.getSegmentationResolveAttempts();
@@ -1331,6 +1338,29 @@ public class IgniteConfiguration {
}
/**
+ * Gets Max count of threads can be used at rebalancing.
+ * Minimum is 1.
+ * @return count.
+ */
+ public int getRebalanceThreadPoolSize() {
+ return rebalanceThreadPoolSize;
+ }
+
+ /**
+ * Sets Max count of threads can be used at rebalancing.
+ *
+ * Default is {@code 1} which has minimal impact on the operation of the grid.
+ *
+ * @param size Size.
+ * @return {@code this} for chaining.
+ */
+ public IgniteConfiguration setRebalanceThreadPoolSize(int size) {
+ this.rebalanceThreadPoolSize = size;
+
+ return this;
+ }
+
+ /**
* Returns a collection of life-cycle beans. These beans will be automatically
* notified of grid life-cycle events. Use life-cycle beans whenever you
* want to perform certain logic before and after grid startup and stopping
@@ -2383,4 +2413,4 @@ public class IgniteConfiguration {
@Override public String toString() {
return S.toString(IgniteConfiguration.class, this);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 8603055..dd129da 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -735,6 +735,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
ackEnvironmentVariables();
ackCacheConfiguration();
ackP2pConfiguration();
+ ackRebalanceConfiguration();
// Run background network diagnostics.
GridDiagnostic.runBackgroundCheck(gridName, execSvc, log);
@@ -2147,6 +2148,26 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
/**
*
*/
+ private void ackRebalanceConfiguration() throws IgniteCheckedException {
+ if (cfg.getSystemThreadPoolSize() <= cfg.getRebalanceThreadPoolSize())
+ throw new IgniteCheckedException("Rebalance thread pool size exceed or equals System thread pool size. " +
+ "Change IgniteConfiguration.rebalanceThreadPoolSize property before next start.");
+
+ if (cfg.getRebalanceThreadPoolSize() < 1)
+ throw new IgniteCheckedException("Rebalance thread pool size minimal allowed value is 1. " +
+ "Change IgniteConfiguration.rebalanceThreadPoolSize property before next start.");
+
+ for (CacheConfiguration ccfg : cfg.getCacheConfiguration()){
+ if (ccfg.getRebalanceBatchesPrefetchCount() < 1)
+ throw new IgniteCheckedException("Rebalance batches prefetch count minimal allowed value is 1. " +
+ "Change CacheConfiguration.rebalanceBatchesPrefetchCount property before next start. " +
+ "[cache="+ccfg.getName()+"]");
+ }
+ }
+
+ /**
+ *
+ */
private void ackCacheConfiguration() {
CacheConfiguration[] cacheCfgs = cfg.getCacheConfiguration();
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
index 02b28c5..7d2b2dc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
@@ -2035,6 +2035,7 @@ public class IgnitionEx {
cache.setAffinity(new RendezvousAffinityFunction(false, 20));
cache.setNodeFilter(CacheConfiguration.ALL_NODES);
cache.setStartSize(300);
+ cache.setRebalanceOrder(-2);//Prior to other system caches.
return cache;
}
@@ -2055,6 +2056,7 @@ public class IgnitionEx {
cache.setWriteSynchronizationMode(FULL_SYNC);
cache.setAffinity(new RendezvousAffinityFunction(false, 100));
cache.setNodeFilter(CacheConfiguration.ALL_NODES);
+ cache.setRebalanceOrder(-1);//Prior to user caches.
return cache;
}
@@ -2075,6 +2077,7 @@ public class IgnitionEx {
ccfg.setWriteSynchronizationMode(FULL_SYNC);
ccfg.setCacheMode(cfg.getCacheMode());
ccfg.setNodeFilter(CacheConfiguration.ALL_NODES);
+ ccfg.setRebalanceOrder(-1);//Prior to user caches.
if (cfg.getCacheMode() == PARTITIONED)
ccfg.setBackups(cfg.getBackups());
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 079015c..ae8c753 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
@@ -74,6 +74,7 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.Gri
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemandMessage;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionExchangeId;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessage;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessageV2;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsFullMessage;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsSingleMessage;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsSingleRequest;
@@ -684,7 +685,12 @@ public class GridIoMessageFactory implements MessageFactory {
break;
- // [-3..112] - this
+ case 114:
+ msg = new GridDhtPartitionSupplyMessageV2();
+
+ break;
+
+ // [-3..114] - this
// [120..123] - DR
// [-4..-22] - SQL
default:
@@ -722,4 +728,4 @@ public class GridIoMessageFactory implements MessageFactory {
CUSTOM.put(type, c);
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
index 082f330..2334780 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheIoManager.java
@@ -45,7 +45,6 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNe
import org.apache.ignite.internal.processors.cache.distributed.dht.atomic.GridNearAtomicUpdateResponse;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysRequest;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtForceKeysResponse;
-import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessage;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetFuture;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetRequest;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearGetResponse;
@@ -269,7 +268,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
unmarshall(nodeId, cacheMsg);
if (cacheMsg.classError() != null)
- processFailedMessage(nodeId, cacheMsg);
+ processFailedMessage(nodeId, cacheMsg, c);
else
processMessage(nodeId, cacheMsg, c);
}
@@ -313,7 +312,8 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
* @param msg Message.
* @throws IgniteCheckedException If failed.
*/
- private void processFailedMessage(UUID nodeId, GridCacheMessage msg) throws IgniteCheckedException {
+ private void processFailedMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInClosure<UUID, GridCacheMessage> c)
+ throws IgniteCheckedException {
GridCacheContext ctx = cctx.cacheContext(msg.cacheId());
switch (msg.directType()) {
@@ -412,9 +412,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
break;
case 45: {
- GridDhtPartitionSupplyMessage req = (GridDhtPartitionSupplyMessage)msg;
-
- U.error(log, "Supply message cannot be unmarshalled.", req.classError());
+ processMessage(nodeId,msg,c);// Will be handled by Rebalance Demander.
}
break;
@@ -517,6 +515,12 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
break;
+ case 114: {
+ processMessage(nodeId,msg,c);// Will be handled by Rebalance Demander.
+ }
+
+ break;
+
default:
throw new IgniteCheckedException("Failed to send response to node. Unsupported direct type [message="
+ msg + "]");
@@ -528,8 +532,7 @@ public class GridCacheIoManager extends GridCacheSharedManagerAdapter {
* @param msg Message.
* @param c Closure.
*/
- private void processMessage(UUID nodeId, GridCacheMessage msg,
- IgniteBiInClosure<UUID, GridCacheMessage> c) {
+ private void processMessage(UUID nodeId, GridCacheMessage msg, IgniteBiInClosure<UUID, GridCacheMessage> c) {
try {
// We will not end up with storing a bunch of new UUIDs
// in each cache entry, since node ID is stored in NIO session
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 2111594..ca0995a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -456,7 +456,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (cctx.swap().offheapSwapEvict(key, entry, partition(), evictVer)) {
assert !hasValueUnlocked() : this;
- obsolete = markObsolete0(obsoleteVer, false);
+ obsolete = markObsolete0(obsoleteVer, false, null);
assert obsolete : this;
}
@@ -1364,7 +1364,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
synchronized (this) {
// If entry is still removed.
if (newVer == ver) {
- if (obsoleteVer == null || !(marked = markObsolete0(obsoleteVer, true))) {
+ if (obsoleteVer == null || !(marked = markObsolete0(obsoleteVer, true, null))) {
if (log.isDebugEnabled())
log.debug("Entry could not be marked obsolete (it is still used): " + this);
}
@@ -2481,7 +2481,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
try {
if ((!hasReaders() || readers)) {
// markObsolete will clear the value.
- if (!(marked = markObsolete0(ver, true))) {
+ if (!(marked = markObsolete0(ver, true, null))) {
if (log.isDebugEnabled())
log.debug("Entry could not be marked obsolete (it is still used): " + this);
@@ -2539,7 +2539,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
boolean obsolete;
synchronized (this) {
- obsolete = markObsolete0(ver, true);
+ obsolete = markObsolete0(ver, true, null);
}
if (obsolete)
@@ -2572,7 +2572,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
}
else
- obsolete = markObsolete0(ver, true);
+ obsolete = markObsolete0(ver, true, null);
}
}
}
@@ -2600,7 +2600,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (!this.ver.equals(ver))
return false;
- marked = markObsolete0(ver, true);
+ marked = markObsolete0(ver, true, null);
}
if (marked)
@@ -2623,9 +2623,10 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
*
* @param ver Version.
* @param clear {@code True} to clear.
+ * @param extras Predefined extras.
* @return {@code True} if entry is obsolete, {@code false} if entry is still used by other threads or nodes.
*/
- protected final boolean markObsolete0(GridCacheVersion ver, boolean clear) {
+ protected final boolean markObsolete0(GridCacheVersion ver, boolean clear, GridCacheObsoleteEntryExtras extras) {
assert Thread.holdsLock(this);
if (evictionDisabled()) {
@@ -2646,7 +2647,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
if (mvcc == null || mvcc.isEmpty(ver)) {
obsoleteVer = ver;
- obsoleteVersionExtras(obsoleteVer);
+ obsoleteVersionExtras(obsoleteVer, extras);
if (clear)
value(null);
@@ -2989,7 +2990,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
synchronized (this) {
if (checkExpired()) {
- rmv = markObsolete0(cctx.versions().next(this.ver), true);
+ rmv = markObsolete0(cctx.versions().next(this.ver), true, null);
return null;
}
@@ -3465,7 +3466,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
}
}
else {
- if (markObsolete0(obsoleteVer, true))
+ if (markObsolete0(obsoleteVer, true, null))
obsolete = true; // Success, will return "true".
}
}
@@ -3793,7 +3794,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CacheObject prev = saveOldValueUnlocked(false);
- if (!hasReaders() && markObsolete0(obsoleteVer, false)) {
+ if (!hasReaders() && markObsolete0(obsoleteVer, false, null)) {
if (swap) {
if (!isStartVersion()) {
try {
@@ -3847,7 +3848,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
CacheObject prevVal = saveValueForIndexUnlocked();
- if (!hasReaders() && markObsolete0(obsoleteVer, false)) {
+ if (!hasReaders() && markObsolete0(obsoleteVer, false, null)) {
if (swap) {
if (!isStartVersion()) {
try {
@@ -3923,7 +3924,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
GridCacheBatchSwapEntry ret = null;
try {
- if (!hasReaders() && markObsolete0(obsoleteVer, false)) {
+ if (!hasReaders() && markObsolete0(obsoleteVer, false, null)) {
if (!isStartVersion() && hasValueUnlocked()) {
if (cctx.offheapTiered() && hasOffHeapPointer()) {
if (cctx.swap().offheapEvictionEnabled())
@@ -3982,7 +3983,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
return false;
if (checkExpired()) {
- rmv = markObsolete0(cctx.versions().next(this.ver), true);
+ rmv = markObsolete0(cctx.versions().next(this.ver), true, null);
return false;
}
@@ -4095,9 +4096,12 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
/**
* @param obsoleteVer Obsolete version.
*/
- protected void obsoleteVersionExtras(@Nullable GridCacheVersion obsoleteVer) {
- extras = (extras != null) ? extras.obsoleteVersion(obsoleteVer) : obsoleteVer != null ?
- new GridCacheObsoleteEntryExtras(obsoleteVer) : null;
+ protected void obsoleteVersionExtras(@Nullable GridCacheVersion obsoleteVer, GridCacheObsoleteEntryExtras ext) {
+ extras = (extras != null) ?
+ extras.obsoleteVersion(obsoleteVer) :
+ obsoleteVer != null ?
+ (ext != null) ? ext : new GridCacheObsoleteEntryExtras(obsoleteVer) :
+ null;
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 c8ee6e3..479a0b6 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
@@ -23,10 +23,12 @@ import java.util.Comparator;
import java.util.HashMap;
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.ConcurrentLinkedQueue;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -49,9 +51,11 @@ import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridClientPartitionTopology;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemandMessage;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionExchangeId;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessageV2;
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;
@@ -65,8 +69,10 @@ import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.CI2;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.GPC;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.util.worker.GridWorker;
@@ -75,6 +81,7 @@ 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_AFFINITY_HISTORY_SIZE;
@@ -85,6 +92,7 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STARTED;
import static org.apache.ignite.events.EventType.EVT_NODE_FAILED;
import static org.apache.ignite.events.EventType.EVT_NODE_JOINED;
import static org.apache.ignite.events.EventType.EVT_NODE_LEFT;
+import static org.apache.ignite.internal.GridTopic.TOPIC_CACHE;
import static org.apache.ignite.internal.events.DiscoveryCustomEvent.EVT_DISCOVERY_CUSTOM_EVT;
import static org.apache.ignite.internal.managers.communication.GridIoPolicy.SYSTEM_POOL;
import static org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader.DFLT_PRELOAD_RESEND_TIMEOUT;
@@ -132,6 +140,9 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
/** */
private GridFutureAdapter<?> reconnectExchangeFut;
+ /** */
+ private final Queue<Callable<Boolean>> rebalanceQ = new ConcurrentLinkedDeque8<>();
+
/**
* Partition map futures.
* This set also contains already completed exchange futures to address race conditions when coordinator
@@ -309,6 +320,33 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
exchWorker.futQ.addFirst(fut);
+ if (!cctx.kernalContext().clientNode()) {
+ for (int cnt = 0; cnt < cctx.gridConfig().getRebalanceThreadPoolSize(); cnt++) {
+ final int idx = cnt;
+
+ cctx.io().addOrderedHandler(rebalanceTopic(cnt), new CI2<UUID, GridCacheMessage>() {
+ @Override public void apply(final UUID id, final GridCacheMessage m) {
+ if (!enterBusy())
+ return;
+
+ try {
+ if (m instanceof GridDhtPartitionSupplyMessageV2)
+ cctx.cacheContext(m.cacheId).preloader().handleSupplyMessage(
+ idx, id, (GridDhtPartitionSupplyMessageV2)m);
+ else if (m instanceof GridDhtPartitionDemandMessage)
+ cctx.cacheContext(m.cacheId).preloader().handleDemandMessage(
+ idx, id, (GridDhtPartitionDemandMessage)m);
+ else
+ log.error("Unsupported message type: " + m.getClass().getName());
+ }
+ finally {
+ leaveBusy();
+ }
+ }
+ });
+ }
+ }
+
new IgniteThread(cctx.gridName(), "exchange-worker", exchWorker).start();
if (reconnect) {
@@ -368,6 +406,14 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
}
}
+ /**
+ * @param idx Index.
+ * @return Topic for index.
+ */
+ public static Object rebalanceTopic(int idx) {
+ return TOPIC_CACHE.topic("Rebalance", idx);
+ }
+
/** {@inheritDoc} */
@Override protected void onKernalStop0(boolean cancel) {
cctx.gridEvents().removeLocalEventListener(discoLsnr);
@@ -392,6 +438,11 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
for (AffinityReadyFuture f : readyFuts.values())
f.onDone(stopErr);
+ if (!cctx.kernalContext().clientNode()) {
+ for (int cnt = 0; cnt < cctx.gridConfig().getRebalanceThreadPoolSize(); cnt++)
+ cctx.io().removeOrderedHandler(rebalanceTopic(cnt));
+ }
+
U.cancel(exchWorker);
if (log.isDebugEnabled())
@@ -1015,6 +1066,10 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
}
dumpPendingObjects();
+
+ for (GridCacheContext cacheCtx : cctx.cacheContexts()) {
+ cacheCtx.preloader().dumpDebugInfo();
+ }
}
/**
@@ -1127,9 +1182,15 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
boolean startEvtFired = false;
+ int cnt = 0;
+
+ IgniteInternalFuture asyncStartFut = null;
+
while (!isCancelled()) {
GridDhtPartitionsExchangeFuture exchFut = null;
+ cnt++;
+
try {
boolean preloadFinished = true;
@@ -1244,12 +1305,111 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
}
if (assignsMap != null) {
+ int size = assignsMap.size();
+
+ rebalanceQ.clear();
+
+ NavigableMap<Integer, List<Integer>> orderMap = new TreeMap<>();
+
for (Map.Entry<Integer, GridDhtPreloaderAssignments> e : assignsMap.entrySet()) {
int cacheId = e.getKey();
GridCacheContext<K, V> cacheCtx = cctx.cacheContext(cacheId);
- cacheCtx.preloader().addAssignments(e.getValue(), forcePreload);
+ int order = cacheCtx.config().getRebalanceOrder();
+
+ if (orderMap.get(order) == null)
+ orderMap.put(order, new ArrayList<Integer>(size));
+
+ orderMap.get(order).add(cacheId);
+ }
+
+ Callable<Boolean> marshR = null;
+ List<Callable<Boolean>> orderedRs = new ArrayList<>(size);
+
+ //Ordered rebalance scheduling.
+ for (Integer order : orderMap.keySet()) {
+ for (Integer cacheId : orderMap.get(order)) {
+ GridCacheContext<K, V> cacheCtx = cctx.cacheContext(cacheId);
+
+ List<String> waitList = new ArrayList<>(size - 1);
+
+ for (List<Integer> cIds : orderMap.headMap(order).values()) {
+ for (Integer cId : cIds) {
+ waitList.add(cctx.cacheContext(cId).name());
+ }
+ }
+
+ Callable<Boolean> r = cacheCtx.preloader().addAssignments(
+ assignsMap.get(cacheId), forcePreload, waitList, cnt);
+
+ if (r != null) {
+ U.log(log, "Cache rebalancing scheduled: [cache=" + cacheCtx.name() +
+ ", waitList=" + waitList.toString() + "]");
+
+ if (cacheId == CU.cacheId(GridCacheUtils.MARSH_CACHE_NAME))
+ marshR = r;
+ else
+ orderedRs.add(r);
+ }
+ }
+ }
+
+ if (asyncStartFut != null)
+ asyncStartFut.get(); // Wait for thread stop.
+
+ rebalanceQ.addAll(orderedRs);
+
+ if (marshR != null || !rebalanceQ.isEmpty()) {
+ if (futQ.isEmpty()) {
+ U.log(log, "Starting caches rebalancing [top=" + exchFut.topologyVersion() + "]");
+
+ if (marshR != null)
+ try {
+ marshR.call(); //Marshaller cache rebalancing launches in sync way.
+ }
+ catch (Exception ex) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send initial demand request to node");
+
+ continue;
+ }
+
+ final GridFutureAdapter fut = new GridFutureAdapter();
+
+ asyncStartFut = fut;
+
+ cctx.kernalContext().closure().callLocalSafe(new GPC<Boolean>() {
+ @Override public Boolean call() {
+ try {
+ while (true) {
+ Callable<Boolean> r = rebalanceQ.poll();
+
+ if (r == null)
+ return false;
+
+ if (!r.call())
+ return false;
+ }
+ }
+ catch (Exception ex) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send initial demand request to node");
+
+ return false;
+ }
+ finally {
+ fut.onDone();
+ }
+ }
+ }, /*system pool*/ true);
+ }
+ else {
+ U.log(log, "Obsolete exchange, skipping rebalancing [top=" + exchFut.topologyVersion() + "]");
+ }
+ }
+ else {
+ U.log(log, "Nothing scheduled, skipping rebalancing [top=" + exchFut.topologyVersion() + "]");
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloader.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloader.java
index 1edaef2..1658a89 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloader.java
@@ -18,9 +18,14 @@
package org.apache.ignite.internal.processors.cache;
import java.util.Collection;
+import java.util.UUID;
+import java.util.concurrent.Callable;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemandMessage;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessageV2;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloaderAssignments;
import org.apache.ignite.lang.IgnitePredicate;
@@ -90,8 +95,11 @@ public interface GridCachePreloader {
*
* @param assignments Assignments to add.
* @param forcePreload Force preload flag.
+ * @param caches Rebalancing of these caches will be finished before this started.
+ * @param cnt Counter.
*/
- public void addAssignments(GridDhtPreloaderAssignments assignments, boolean forcePreload);
+ public Callable<Boolean> addAssignments(GridDhtPreloaderAssignments assignments, boolean forcePreload,
+ Collection<String> caches, int cnt);
/**
* @param p Preload predicate.
@@ -115,6 +123,17 @@ public interface GridCachePreloader {
public IgniteInternalFuture<?> syncFuture();
/**
+ * @return Future which will complete when preloading finishes on current topology.
+ *
+ * Future result is {@code true} in case rebalancing successfully finished at current topology.
+ * Future result is {@code false} in case rebalancing cancelled or finished with missed partitions and will be
+ * restarted at current or pending topology.
+ *
+ * Note that topology change creates new futures and finishes previous.
+ */
+ public IgniteInternalFuture<Boolean> rebalanceFuture();
+
+ /**
* Requests that preloader sends the request for the key.
*
* @param keys Keys to request.
@@ -134,7 +153,39 @@ public interface GridCachePreloader {
public void unwindUndeploys();
/**
+ * Handles Supply message.
+ *
+ * @param idx Index.
+ * @param id Node Id.
+ * @param s Supply message.
+ */
+ public void handleSupplyMessage(int idx, UUID id, final GridDhtPartitionSupplyMessageV2 s);
+
+ /**
+ * Handles Demand message.
+ *
+ * @param idx Index.
+ * @param id Node Id.
+ * @param d Demand message.
+ */
+ public void handleDemandMessage(int idx, UUID id, GridDhtPartitionDemandMessage d);
+
+ /**
+ * Evicts partition asynchronously.
+ *
+ * @param part Partition.
+ */
+ public void evictPartitionAsync(GridDhtLocalPartition part);
+
+ /**
+ * Handles new topology.
+ *
+ * @param topVer Topology version.
+ */
+ public void onTopologyChanged(AffinityTopologyVersion topVer);
+
+ /**
* Dumps debug information.
*/
public void dumpDebugInfo();
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloaderAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloaderAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloaderAdapter.java
index 4ec6749..9c0e9f7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloaderAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCachePreloaderAdapter.java
@@ -18,11 +18,16 @@
package org.apache.ignite.internal.processors.cache;
import java.util.Collection;
+import java.util.UUID;
+import java.util.concurrent.Callable;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cache.affinity.AffinityFunction;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionDemandMessage;
+import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionSupplyMessageV2;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloaderAssignments;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
@@ -36,7 +41,7 @@ public class GridCachePreloaderAdapter implements GridCachePreloader {
/** Cache context. */
protected final GridCacheContext<?, ?> cctx;
- /** Logger.*/
+ /** Logger. */
protected final IgniteLogger log;
/** Affinity. */
@@ -113,12 +118,28 @@ public class GridCachePreloaderAdapter implements GridCachePreloader {
}
/** {@inheritDoc} */
+ @Override public IgniteInternalFuture<Boolean> rebalanceFuture() {
+ return new GridFinishedFuture<>(true);
+ }
+
+ /** {@inheritDoc} */
@Override public void unwindUndeploys() {
cctx.deploy().unwind(cctx);
}
/** {@inheritDoc} */
- @Override public IgniteInternalFuture<Object> request(Collection<KeyCacheObject> keys, AffinityTopologyVersion topVer) {
+ @Override public void handleSupplyMessage(int idx, UUID id, GridDhtPartitionSupplyMessageV2 s) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public void handleDemandMessage(int idx, UUID id, GridDhtPartitionDemandMessage d) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteInternalFuture<Object> request(Collection<KeyCacheObject> keys,
+ AffinityTopologyVersion topVer) {
return new GridFinishedFuture<>();
}
@@ -143,7 +164,18 @@ public class GridCachePreloaderAdapter implements GridCachePreloader {
}
/** {@inheritDoc} */
- @Override public void addAssignments(GridDhtPreloaderAssignments assignments, boolean forcePreload) {
+ @Override public Callable<Boolean> addAssignments(GridDhtPreloaderAssignments assignments, boolean forcePreload,
+ Collection<String> caches, int cnt) {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void evictPartitionAsync(GridDhtLocalPartition part) {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTopologyChanged(AffinityTopologyVersion topVer) {
// No-op.
}
@@ -151,4 +183,4 @@ public class GridCachePreloaderAdapter implements GridCachePreloader {
@Override public void dumpDebugInfo() {
// No-op.
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 b2bb6ff..f54f63e 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
@@ -31,9 +31,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
-import java.util.NavigableMap;
import java.util.Set;
-import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -98,7 +96,6 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersionManag
import org.apache.ignite.internal.processors.plugin.CachePluginManager;
import org.apache.ignite.internal.processors.query.GridQueryProcessor;
import org.apache.ignite.internal.util.F0;
-import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -160,12 +157,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
/** Map of proxies. */
private final Map<String, IgniteCacheProxy<?, ?>> jCacheProxies;
- /** Map of preload finish futures grouped by preload order. */
- private final NavigableMap<Integer, IgniteInternalFuture<?>> preloadFuts;
-
- /** Maximum detected rebalance order. */
- private int maxRebalanceOrder;
-
/** Caches stop sequence. */
private final Deque<String> stopSeq;
@@ -207,8 +198,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
caches = new ConcurrentHashMap<>();
jCacheProxies = new ConcurrentHashMap<>();
- preloadFuts = new TreeMap<>();
-
stopSeq = new LinkedList<>();
}
@@ -378,10 +367,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
U.warn(log, "AffinityFunction configuration parameter will be ignored for local cache [cacheName=" +
U.maskName(cc.getName()) + ']');
- if (cc.getRebalanceMode() != CacheRebalanceMode.NONE) {
- assertParameter(cc.getRebalanceThreadPoolSize() > 0, "rebalanceThreadPoolSize > 0");
+ if (cc.getRebalanceMode() != CacheRebalanceMode.NONE)
assertParameter(cc.getRebalanceBatchSize() > 0, "rebalanceBatchSize > 0");
- }
if (cc.getCacheMode() == PARTITIONED || cc.getCacheMode() == REPLICATED) {
if (cc.getAtomicityMode() == ATOMIC && cc.getWriteSynchronizationMode() == FULL_ASYNC)
@@ -591,8 +578,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
"Deployment mode for cache is not CONTINUOUS or SHARED.");
}
- maxRebalanceOrder = validatePreloadOrder(ctx.config().getCacheConfiguration());
-
ctx.discovery().setCustomEventListener(DynamicCacheChangeBatch.class,
new CustomEventListener<DynamicCacheChangeBatch>() {
@Override public void onCustomEvent(ClusterNode snd,
@@ -820,31 +805,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
for (GridCacheSharedManager<?, ?> mgr : sharedCtx.managers())
mgr.onKernalStart(false);
- for (Map.Entry<String, GridCacheAdapter<?, ?>> e : caches.entrySet()) {
- GridCacheAdapter cache = e.getValue();
-
- if (maxRebalanceOrder > 0) {
- CacheConfiguration cfg = cache.configuration();
-
- int order = cfg.getRebalanceOrder();
-
- if (order > 0 && order != maxRebalanceOrder && cfg.getCacheMode() != LOCAL) {
- GridCompoundFuture fut = (GridCompoundFuture)preloadFuts.get(order);
-
- if (fut == null) {
- fut = new GridCompoundFuture<>();
-
- preloadFuts.put(order, fut);
- }
-
- fut.add(cache.preloader().syncFuture());
- }
- }
- }
-
- for (IgniteInternalFuture<?> fut : preloadFuts.values())
- ((GridCompoundFuture<Object, Object>)fut).markInitialized();
-
for (GridCacheAdapter<?, ?> cache : caches.values())
onKernalStart(cache);
@@ -2791,19 +2751,6 @@ public class GridCacheProcessor extends GridProcessorAdapter {
}
/**
- * Gets preload finish future for preload-ordered cache with given order. I.e. will get compound preload future
- * with maximum order less than {@code order}.
- *
- * @param order Cache order.
- * @return Compound preload future or {@code null} if order is minimal order found.
- */
- @Nullable public IgniteInternalFuture<?> orderedPreloadFuture(int order) {
- Map.Entry<Integer, IgniteInternalFuture<?>> entry = preloadFuts.lowerEntry(order);
-
- return entry == null ? null : entry.getValue();
- }
-
- /**
* @param spaceName Space name.
* @param keyBytes Key bytes.
* @param valBytes Value bytes.
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 1b2d834..392ad6a 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
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockCancelledException;
+import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.lang.GridPlainRunnable;
@@ -554,7 +555,11 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
* @return {@code True} if entry was not being used, passed the filter and could be removed.
* @throws IgniteCheckedException If failed to remove from swap.
*/
- public boolean clearInternal(GridCacheVersion ver, boolean swap) throws IgniteCheckedException {
+ public boolean clearInternal(
+ GridCacheVersion ver,
+ boolean swap,
+ GridCacheObsoleteEntryExtras extras
+ ) throws IgniteCheckedException {
boolean rmv = false;
try {
@@ -563,7 +568,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
// Call markObsolete0 to avoid recursive calls to clear if
// we are clearing dht local partition (onMarkedObsolete should not be called).
- if (!markObsolete0(ver, false)) {
+ if (!markObsolete0(ver, false, extras)) {
if (log.isDebugEnabled())
log.debug("Entry could not be marked obsolete (it is still used or has readers): " + this);
@@ -819,4 +824,4 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry {
return S.toString(ReaderId.class, this);
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 749d06a..1516ee4 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
@@ -17,6 +17,17 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicStampedReference;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.cache.CacheException;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.IgniteInternalFuture;
@@ -27,10 +38,10 @@ import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedExceptio
import org.apache.ignite.internal.processors.cache.GridCacheSwapEntry;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
+import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntryExtras;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.query.GridQueryProcessor;
import org.apache.ignite.internal.util.GridCircularBuffer;
-import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.GridCloseableIterator;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -38,7 +49,6 @@ import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
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.GPC;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteUuid;
@@ -46,18 +56,6 @@ import org.jetbrains.annotations.NotNull;
import org.jsr166.ConcurrentHashMap8;
import org.jsr166.LongAdder8;
-import javax.cache.CacheException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.atomic.AtomicStampedReference;
-import java.util.concurrent.locks.ReentrantLock;
-
import static org.apache.ignite.IgniteSystemProperties.IGNITE_ATOMIC_CACHE_DELETE_HISTORY_SIZE;
import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_UNLOADED;
import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.EVICTED;
@@ -286,7 +284,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
}
// Attempt to evict.
- tryEvict(true);
+ tryEvict();
}
/**
@@ -411,7 +409,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
// Decrement reservations.
if (state.compareAndSet(s, s, reservations, --reservations)) {
- tryEvict(true);
+ tryEvict();
break;
}
@@ -477,10 +475,10 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
/**
* @param updateSeq Update sequence.
- * @return Future for evict attempt.
*/
- IgniteInternalFuture<Boolean> tryEvictAsync(boolean updateSeq) {
+ void tryEvictAsync(boolean updateSeq) {
if (map.isEmpty() && !GridQueryProcessor.isEnabled(cctx.config()) &&
+ state.getReference() == RENTING && state.getStamp() == 0 &&
state.compareAndSet(RENTING, EVICTED, 0, 0)) {
if (log.isDebugEnabled())
log.debug("Evicted partition: " + this);
@@ -497,15 +495,9 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
((GridDhtPreloader)cctx.preloader()).onPartitionEvicted(this, updateSeq);
clearDeferredDeletes();
-
- return new GridFinishedFuture<>(true);
}
-
- return cctx.closures().callLocalSafe(new GPC<Boolean>() {
- @Override public Boolean call() {
- return tryEvict(true);
- }
- }, /*system pool*/ true);
+ else
+ cctx.preloader().evictPartitionAsync(this);
}
/**
@@ -521,12 +513,11 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
}
/**
- * @param updateSeq Update sequence.
- * @return {@code True} if entry has been transitioned to state EVICTED.
+ *
*/
- boolean tryEvict(boolean updateSeq) {
+ public void tryEvict() {
if (state.getReference() != RENTING || state.getStamp() != 0 || groupReserved())
- return false;
+ return;
// Attempt to evict partition entries from cache.
clearAll();
@@ -545,14 +536,10 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
rent.onDone();
- ((GridDhtPreloader)cctx.preloader()).onPartitionEvicted(this, updateSeq);
+ ((GridDhtPreloader)cctx.preloader()).onPartitionEvicted(this, true);
clearDeferredDeletes();
-
- return true;
}
-
- return false;
}
/**
@@ -592,7 +579,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
*
*/
void onUnlock() {
- tryEvict(true);
+ tryEvict();
}
/**
@@ -640,6 +627,8 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
it = F.concat(it, unswapIt);
}
+ GridCacheObsoleteEntryExtras extras = new GridCacheObsoleteEntryExtras(clearVer);
+
try {
while (it.hasNext()) {
GridDhtCacheEntry cached = null;
@@ -647,7 +636,7 @@ public class GridDhtLocalPartition implements Comparable<GridDhtLocalPartition>,
try {
cached = it.next();
- if (cached.clearInternal(clearVer, swap)) {
+ if (cached.clearInternal(clearVer, swap, extras)) {
map.remove(cached.key(), cached);
if (!cached.isInternal()) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionsReservation.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionsReservation.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionsReservation.java
index 756326e..d12247e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionsReservation.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtPartitionsReservation.java
@@ -239,7 +239,7 @@ public class GridDhtPartitionsReservation implements GridReservable {
}
/**
- * Must be checked in {@link GridDhtLocalPartition#tryEvict(boolean)}.
+ * Must be checked in {@link GridDhtLocalPartition#tryEvict()}.
* If returns {@code true} this reservation object becomes invalid and partitions
* can be evicted or at least cleared.
* Also this means that after returning {@code true} here method {@link #reserve()} can not
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 7609d98..53c3d90 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
@@ -68,8 +68,6 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
* @param topVer Topology version.
*/
GridDhtPartitionDemandMessage(long updateSeq, @NotNull AffinityTopologyVersion topVer, int cacheId) {
- assert updateSeq > 0;
-
this.cacheId = cacheId;
this.updateSeq = updateSeq;
this.topVer = topVer;
@@ -116,6 +114,13 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
}
/**
+ * @param updateSeq Update sequence.
+ */
+ void updateSequence(long updateSeq) {
+ this.updateSeq = updateSeq;
+ }
+
+ /**
* @return Update sequence.
*/
long updateSequence() {
@@ -325,7 +330,8 @@ public class GridDhtPartitionDemandMessage extends GridCacheMessage {
/** {@inheritDoc} */
@Override public String toString() {
- return S.toString(GridDhtPartitionDemandMessage.class, this, "partCnt", parts.size(), "super",
- super.toString());
+ return S.toString(GridDhtPartitionDemandMessage.class, this,
+ "partCnt", parts != null ? parts.size() : 0,
+ "super", super.toString());
}
}
[04/51] ignite git commit: Ignite-1093 "Rebalancing with default
parameters is very slow" fixes.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java
deleted file mode 100644
index e993a88..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemandPool.java
+++ /dev/null
@@ -1,1192 +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.processors.cache.distributed.dht.preloader;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.BrokenBarrierException;
-import java.util.concurrent.CyclicBarrier;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cache.CacheRebalanceMode;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.events.DiscoveryEvent;
-import org.apache.ignite.internal.IgniteInternalFuture;
-import org.apache.ignite.internal.IgniteInterruptedCheckedException;
-import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
-import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
-import org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection;
-import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
-import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
-import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter;
-import org.apache.ignite.internal.util.GridLeanSet;
-import org.apache.ignite.internal.util.future.GridFutureAdapter;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
-import org.apache.ignite.internal.util.typedef.CI1;
-import org.apache.ignite.internal.util.typedef.CI2;
-import org.apache.ignite.internal.util.typedef.F;
-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;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.util.worker.GridWorker;
-import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.thread.IgniteThread;
-import org.jetbrains.annotations.Nullable;
-
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_LOADED;
-import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_DATA_LOST;
-import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_LOADED;
-import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STOPPED;
-import static org.apache.ignite.internal.GridTopic.TOPIC_CACHE;
-import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.MOVING;
-import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
-import static org.apache.ignite.internal.processors.dr.GridDrType.DR_PRELOAD;
-
-/**
- * Thread pool for requesting partitions from other nodes
- * and populating local cache.
- */
-@SuppressWarnings("NonConstantFieldWithUpperCaseName")
-public class GridDhtPartitionDemandPool {
- /** Dummy message to wake up a blocking queue if a node leaves. */
- private final SupplyMessage DUMMY_TOP = new SupplyMessage();
-
- /** */
- private final GridCacheContext<?, ?> cctx;
-
- /** */
- private final IgniteLogger log;
-
- /** */
- private final ReadWriteLock busyLock;
-
- /** */
- @GridToStringInclude
- private final Collection<DemandWorker> dmdWorkers;
-
- /** Preload predicate. */
- private IgnitePredicate<GridCacheEntryInfo> preloadPred;
-
- /** Future for preload mode {@link CacheRebalanceMode#SYNC}. */
- @GridToStringInclude
- private SyncFuture syncFut;
-
- /** Preload timeout. */
- private final AtomicLong timeout;
-
- /** Allows demand threads to synchronize their step. */
- private CyclicBarrier barrier;
-
- /** Demand lock. */
- private final ReadWriteLock demandLock = new ReentrantReadWriteLock();
-
- /** */
- private int poolSize;
-
- /** Last timeout object. */
- private AtomicReference<GridTimeoutObject> lastTimeoutObj = new AtomicReference<>();
-
- /** Last exchange future. */
- private volatile GridDhtPartitionsExchangeFuture lastExchangeFut;
-
- /**
- * @param cctx Cache context.
- * @param busyLock Shutdown lock.
- */
- public GridDhtPartitionDemandPool(GridCacheContext<?, ?> cctx, ReadWriteLock busyLock) {
- assert cctx != null;
- assert busyLock != null;
-
- this.cctx = cctx;
- this.busyLock = busyLock;
-
- log = cctx.logger(getClass());
-
- boolean enabled = cctx.rebalanceEnabled() && !cctx.kernalContext().clientNode();
-
- poolSize = enabled ? cctx.config().getRebalanceThreadPoolSize() : 0;
-
- if (enabled) {
- barrier = new CyclicBarrier(poolSize);
-
- dmdWorkers = new ArrayList<>(poolSize);
-
- for (int i = 0; i < poolSize; i++)
- dmdWorkers.add(new DemandWorker(i));
-
- syncFut = new SyncFuture(dmdWorkers);
- }
- else {
- dmdWorkers = Collections.emptyList();
-
- syncFut = new SyncFuture(dmdWorkers);
-
- // Calling onDone() immediately since preloading is disabled.
- syncFut.onDone();
- }
-
- timeout = new AtomicLong(cctx.config().getRebalanceTimeout());
- }
-
- /**
- *
- */
- void start() {
- if (poolSize > 0) {
- for (DemandWorker w : dmdWorkers)
- new IgniteThread(cctx.gridName(), "preloader-demand-worker", w).start();
- }
- }
-
- /**
- *
- */
- void stop() {
- U.cancel(dmdWorkers);
-
- if (log.isDebugEnabled())
- log.debug("Before joining on demand workers: " + dmdWorkers);
-
- U.join(dmdWorkers, log);
-
- if (log.isDebugEnabled())
- log.debug("After joining on demand workers: " + dmdWorkers);
-
- lastExchangeFut = null;
-
- lastTimeoutObj.set(null);
- }
-
- /**
- * @return Future for {@link CacheRebalanceMode#SYNC} mode.
- */
- IgniteInternalFuture<?> syncFuture() {
- return syncFut;
- }
-
- /**
- * Sets preload predicate for demand pool.
- *
- * @param preloadPred Preload predicate.
- */
- void preloadPredicate(IgnitePredicate<GridCacheEntryInfo> preloadPred) {
- this.preloadPred = preloadPred;
- }
-
- /**
- * @return Size of this thread pool.
- */
- int poolSize() {
- return poolSize;
- }
-
- /**
- * Wakes up demand workers when new exchange future was added.
- */
- void onExchangeFutureAdded() {
- synchronized (dmdWorkers) {
- for (DemandWorker w : dmdWorkers)
- w.addMessage(DUMMY_TOP);
- }
- }
-
- /**
- * Force preload.
- */
- void forcePreload() {
- GridTimeoutObject obj = lastTimeoutObj.getAndSet(null);
-
- if (obj != null)
- cctx.time().removeTimeoutObject(obj);
-
- final GridDhtPartitionsExchangeFuture exchFut = lastExchangeFut;
-
- if (exchFut != null) {
- if (log.isDebugEnabled())
- log.debug("Forcing rebalance event for future: " + exchFut);
-
- exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
- @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> t) {
- cctx.shared().exchange().forcePreloadExchange(exchFut);
- }
- });
- }
- else if (log.isDebugEnabled())
- log.debug("Ignoring force rebalance request (no topology event happened yet).");
- }
-
- /**
- * @return {@code true} if entered to busy state.
- */
- private boolean enterBusy() {
- if (busyLock.readLock().tryLock())
- return true;
-
- if (log.isDebugEnabled())
- log.debug("Failed to enter to busy state (demander is stopping): " + cctx.nodeId());
-
- return false;
- }
-
- /**
- *
- */
- private void leaveBusy() {
- busyLock.readLock().unlock();
- }
-
- /**
- * @param type Type.
- * @param discoEvt Discovery event.
- */
- private void preloadEvent(int type, DiscoveryEvent discoEvt) {
- preloadEvent(-1, type, discoEvt);
- }
-
- /**
- * @param part Partition.
- * @param type Type.
- * @param discoEvt Discovery event.
- */
- private void preloadEvent(int part, int type, DiscoveryEvent discoEvt) {
- assert discoEvt != null;
-
- cctx.events().addPreloadEvent(part, type, discoEvt.eventNode(), discoEvt.type(), discoEvt.timestamp());
- }
-
- /**
- * @param msg Message to check.
- * @return {@code True} if dummy message.
- */
- private boolean dummyTopology(SupplyMessage msg) {
- return msg == DUMMY_TOP;
- }
-
- /**
- * @param deque Deque to poll from.
- * @param time Time to wait.
- * @param w Worker.
- * @return Polled item.
- * @throws InterruptedException If interrupted.
- */
- @Nullable private <T> T poll(BlockingQueue<T> deque, long time, GridWorker w) throws InterruptedException {
- assert w != null;
-
- // There is currently a case where {@code interrupted}
- // flag on a thread gets flipped during stop which causes the pool to hang. This check
- // will always make sure that interrupted flag gets reset before going into wait conditions.
- // The true fix should actually make sure that interrupted flag does not get reset or that
- // interrupted exception gets propagated. Until we find a real fix, this method should
- // always work to make sure that there is no hanging during stop.
- if (w.isCancelled())
- Thread.currentThread().interrupt();
-
- return deque.poll(time, MILLISECONDS);
- }
-
- /**
- * @param p Partition.
- * @param topVer Topology version.
- * @return Picked owners.
- */
- private Collection<ClusterNode> pickedOwners(int p, AffinityTopologyVersion topVer) {
- Collection<ClusterNode> affNodes = cctx.affinity().nodes(p, topVer);
-
- int affCnt = affNodes.size();
-
- Collection<ClusterNode> rmts = remoteOwners(p, topVer);
-
- int rmtCnt = rmts.size();
-
- if (rmtCnt <= affCnt)
- return rmts;
-
- List<ClusterNode> sorted = new ArrayList<>(rmts);
-
- // Sort in descending order, so nodes with higher order will be first.
- Collections.sort(sorted, CU.nodeComparator(false));
-
- // Pick newest nodes.
- return sorted.subList(0, affCnt);
- }
-
- /**
- * @param p Partition.
- * @param topVer Topology version.
- * @return Nodes owning this partition.
- */
- private Collection<ClusterNode> remoteOwners(int p, AffinityTopologyVersion topVer) {
- return F.view(cctx.dht().topology().owners(p, topVer), F.remoteNodes(cctx.nodeId()));
- }
-
- /**
- * @param assigns Assignments.
- * @param force {@code True} if dummy reassign.
- */
- void addAssignments(final GridDhtPreloaderAssignments assigns, boolean force) {
- if (log.isDebugEnabled())
- log.debug("Adding partition assignments: " + assigns);
-
- long delay = cctx.config().getRebalanceDelay();
-
- if (delay == 0 || force) {
- assert assigns != null;
-
- synchronized (dmdWorkers) {
- for (DemandWorker w : dmdWorkers) {
- w.addAssignments(assigns);
-
- w.addMessage(DUMMY_TOP);
- }
- }
- }
- else if (delay > 0) {
- assert !force;
-
- GridTimeoutObject obj = lastTimeoutObj.get();
-
- if (obj != null)
- cctx.time().removeTimeoutObject(obj);
-
- final GridDhtPartitionsExchangeFuture exchFut = lastExchangeFut;
-
- assert exchFut != null : "Delaying rebalance process without topology event.";
-
- obj = new GridTimeoutObjectAdapter(delay) {
- @Override public void onTimeout() {
- exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
- @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> f) {
- cctx.shared().exchange().forcePreloadExchange(exchFut);
- }
- });
- }
- };
-
- lastTimeoutObj.set(obj);
-
- cctx.time().addTimeoutObject(obj);
- }
- }
-
- /**
- *
- */
- void unwindUndeploys() {
- demandLock.writeLock().lock();
-
- try {
- cctx.deploy().unwind(cctx);
- }
- finally {
- demandLock.writeLock().unlock();
- }
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(GridDhtPartitionDemandPool.class, this);
- }
-
- /**
- *
- */
- private class DemandWorker extends GridWorker {
- /** Worker ID. */
- private int id;
-
- /** Partition-to-node assignments. */
- private final LinkedBlockingDeque<GridDhtPreloaderAssignments> assignQ = new LinkedBlockingDeque<>();
-
- /** Message queue. */
- private final LinkedBlockingDeque<SupplyMessage> msgQ =
- new LinkedBlockingDeque<>();
-
- /** Counter. */
- private long cntr;
-
- /** Hide worker logger and use cache logger instead. */
- private IgniteLogger log = GridDhtPartitionDemandPool.this.log;
-
- /**
- * @param id Worker ID.
- */
- private DemandWorker(int id) {
- super(cctx.gridName(), "preloader-demand-worker", GridDhtPartitionDemandPool.this.log);
-
- assert id >= 0;
-
- this.id = id;
- }
-
- /**
- * @param assigns Assignments.
- */
- void addAssignments(GridDhtPreloaderAssignments assigns) {
- assert assigns != null;
-
- assignQ.offer(assigns);
-
- if (log.isDebugEnabled())
- log.debug("Added assignments to worker: " + this);
- }
-
- /**
- * @return {@code True} if topology changed.
- */
- private boolean topologyChanged() {
- return !assignQ.isEmpty() || cctx.shared().exchange().topologyChanged();
- }
-
- /**
- * @param msg Message.
- */
- private void addMessage(SupplyMessage msg) {
- if (!enterBusy())
- return;
-
- try {
- assert dummyTopology(msg) || msg.supply().workerId() == id;
-
- msgQ.offer(msg);
- }
- finally {
- leaveBusy();
- }
- }
-
- /**
- * @param timeout Timed out value.
- */
- private void growTimeout(long timeout) {
- long newTimeout = (long)(timeout * 1.5D);
-
- // Account for overflow.
- if (newTimeout < 0)
- newTimeout = Long.MAX_VALUE;
-
- // Grow by 50% only if another thread didn't do it already.
- if (GridDhtPartitionDemandPool.this.timeout.compareAndSet(timeout, newTimeout))
- U.warn(log, "Increased rebalancing message timeout from " + timeout + "ms to " +
- newTimeout + "ms.");
- }
-
- /**
- * @param pick Node picked for preloading.
- * @param p Partition.
- * @param entry Preloaded entry.
- * @param topVer Topology version.
- * @return {@code False} if partition has become invalid during preloading.
- * @throws IgniteInterruptedCheckedException If interrupted.
- */
- private boolean preloadEntry(
- ClusterNode pick,
- int p,
- GridCacheEntryInfo entry,
- AffinityTopologyVersion topVer
- ) throws IgniteCheckedException {
- try {
- GridCacheEntryEx cached = null;
-
- try {
- cached = cctx.dht().entryEx(entry.key());
-
- if (log.isDebugEnabled())
- log.debug("Rebalancing key [key=" + entry.key() + ", part=" + p + ", node=" + pick.id() + ']');
-
- if (cctx.dht().isIgfsDataCache() &&
- cctx.dht().igfsDataSpaceUsed() > cctx.dht().igfsDataSpaceMax()) {
- LT.error(log, null, "Failed to rebalance IGFS data cache (IGFS space size exceeded maximum " +
- "value, will ignore rebalance entries): " + name());
-
- if (cached.markObsoleteIfEmpty(null))
- cached.context().cache().removeIfObsolete(cached.key());
-
- 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
- )) {
- 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);
- }
- else 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);
- }
- catch (GridCacheEntryRemovedException ignored) {
- if (log.isDebugEnabled())
- log.debug("Entry has been concurrently removed while rebalancing (will ignore) [key=" +
- cached.key() + ", part=" + p + ']');
- }
- catch (GridDhtInvalidPartitionException ignored) {
- if (log.isDebugEnabled())
- log.debug("Partition became invalid during rebalancing (will ignore): " + p);
-
- return false;
- }
- }
- catch (IgniteInterruptedCheckedException e) {
- throw e;
- }
- catch (IgniteCheckedException e) {
- throw new IgniteCheckedException("Failed to cache rebalanced entry (will stop rebalancing) [local=" +
- cctx.nodeId() + ", node=" + pick.id() + ", key=" + entry.key() + ", part=" + p + ']', e);
- }
-
- return true;
- }
-
- /**
- * @param idx Unique index for this topic.
- * @return Topic for partition.
- */
- public Object topic(long idx) {
- return TOPIC_CACHE.topic(cctx.namexx(), cctx.nodeId(), id, idx);
- }
-
- /**
- * @param node Node to demand from.
- * @param topVer Topology version.
- * @param d Demand message.
- * @param exchFut Exchange future.
- * @return Missed partitions.
- * @throws InterruptedException If interrupted.
- * @throws ClusterTopologyCheckedException If node left.
- * @throws IgniteCheckedException If failed to send message.
- */
- private Set<Integer> demandFromNode(
- ClusterNode node,
- final AffinityTopologyVersion topVer,
- GridDhtPartitionDemandMessage d,
- GridDhtPartitionsExchangeFuture exchFut
- ) throws InterruptedException, IgniteCheckedException {
- GridDhtPartitionTopology top = cctx.dht().topology();
-
- cntr++;
-
- d.topic(topic(cntr));
- d.workerId(id);
-
- Set<Integer> missed = new HashSet<>();
-
- // Get the same collection that will be sent in the message.
- Collection<Integer> remaining = d.partitions();
-
- // Drain queue before processing a new node.
- drainQueue();
-
- if (isCancelled() || topologyChanged())
- return missed;
-
- cctx.io().addOrderedHandler(d.topic(), new CI2<UUID, GridDhtPartitionSupplyMessage>() {
- @Override public void apply(UUID nodeId, GridDhtPartitionSupplyMessage msg) {
- addMessage(new SupplyMessage(nodeId, msg));
- }
- });
-
- try {
- boolean retry;
-
- // DoWhile.
- // =======
- do {
- retry = false;
-
- // Create copy.
- d = new GridDhtPartitionDemandMessage(d, remaining);
-
- long timeout = GridDhtPartitionDemandPool.this.timeout.get();
-
- d.timeout(timeout);
-
- if (log.isDebugEnabled())
- log.debug("Sending demand message [node=" + node.id() + ", demand=" + d + ']');
-
- // Send demand message.
- cctx.io().send(node, d, cctx.ioPolicy());
-
- // While.
- // =====
- while (!isCancelled() && !topologyChanged()) {
- SupplyMessage s = poll(msgQ, timeout, this);
-
- // If timed out.
- if (s == null) {
- if (msgQ.isEmpty()) { // Safety check.
- U.warn(log, "Timed out waiting for partitions to load, will retry in " + timeout +
- " ms (you may need to increase 'networkTimeout' or 'rebalanceBatchSize'" +
- " configuration properties).");
-
- growTimeout(timeout);
-
- // Ordered listener was removed if timeout expired.
- cctx.io().removeOrderedHandler(d.topic());
-
- // Must create copy to be able to work with IO manager thread local caches.
- d = new GridDhtPartitionDemandMessage(d, remaining);
-
- // Create new topic.
- d.topic(topic(++cntr));
-
- // Create new ordered listener.
- cctx.io().addOrderedHandler(d.topic(),
- new CI2<UUID, GridDhtPartitionSupplyMessage>() {
- @Override public void apply(UUID nodeId,
- GridDhtPartitionSupplyMessage msg) {
- addMessage(new SupplyMessage(nodeId, msg));
- }
- });
-
- // Resend message with larger timeout.
- retry = true;
-
- break; // While.
- }
- else
- continue; // While.
- }
-
- // If topology changed.
- if (dummyTopology(s)) {
- if (topologyChanged())
- break; // While.
- else
- continue; // While.
- }
-
- // Check that message was received from expected node.
- if (!s.senderId().equals(node.id())) {
- U.warn(log, "Received supply message from unexpected node [expectedId=" + node.id() +
- ", rcvdId=" + s.senderId() + ", msg=" + s + ']');
-
- continue; // While.
- }
-
- if (log.isDebugEnabled())
- log.debug("Received supply message: " + s);
-
- GridDhtPartitionSupplyMessage supply = s.supply();
-
- // Check whether there were class loading errors on unmarshal
- if (supply.classError() != null) {
- if (log.isDebugEnabled())
- log.debug("Class got undeployed during preloading: " + supply.classError());
-
- retry = true;
-
- // Quit preloading.
- break;
- }
-
- // Preload.
- for (Map.Entry<Integer, CacheEntryInfoCollection> e : supply.infos().entrySet()) {
- int p = e.getKey();
-
- if (cctx.affinity().localNode(p, topVer)) {
- GridDhtLocalPartition part = top.localPartition(p, topVer, true);
-
- assert part != null;
-
- if (part.state() == MOVING) {
- boolean reserved = part.reserve();
-
- assert reserved : "Failed to reserve partition [gridName=" +
- cctx.gridName() + ", cacheName=" + cctx.namex() + ", part=" + part + ']';
-
- part.lock();
-
- try {
- Collection<Integer> invalidParts = new GridLeanSet<>();
-
- // Loop through all received entries and try to preload them.
- for (GridCacheEntryInfo entry : e.getValue().infos()) {
- if (!invalidParts.contains(p)) {
- if (!part.preloadingPermitted(entry.key(), entry.version())) {
- if (log.isDebugEnabled())
- log.debug("Preloading is not permitted for entry due to " +
- "evictions [key=" + entry.key() +
- ", ver=" + entry.version() + ']');
-
- continue;
- }
-
- if (!preloadEntry(node, p, entry, topVer)) {
- invalidParts.add(p);
-
- if (log.isDebugEnabled())
- log.debug("Got entries for invalid partition during " +
- "preloading (will skip) [p=" + p + ", entry=" + entry + ']');
- }
- }
- }
-
- boolean last = supply.last().contains(p);
-
- // If message was last for this partition,
- // then we take ownership.
- if (last) {
- remaining.remove(p);
-
- top.own(part);
-
- if (log.isDebugEnabled())
- log.debug("Finished rebalancing partition: " + part);
-
- if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_PART_LOADED))
- preloadEvent(p, EVT_CACHE_REBALANCE_PART_LOADED,
- exchFut.discoveryEvent());
- }
- }
- finally {
- part.unlock();
- part.release();
- }
- }
- else {
- remaining.remove(p);
-
- if (log.isDebugEnabled())
- log.debug("Skipping rebalancing partition (state is not MOVING): " + part);
- }
- }
- else {
- remaining.remove(p);
-
- if (log.isDebugEnabled())
- log.debug("Skipping rebalancing partition (it does not belong on current node): " + p);
- }
- }
-
- remaining.removeAll(s.supply().missed());
-
- // Only request partitions based on latest topology version.
- for (Integer miss : s.supply().missed())
- if (cctx.affinity().localNode(miss, topVer))
- missed.add(miss);
-
- if (remaining.isEmpty())
- break; // While.
-
- if (s.supply().ack()) {
- retry = true;
-
- break;
- }
- }
- }
- while (retry && !isCancelled() && !topologyChanged());
-
- return missed;
- }
- finally {
- cctx.io().removeOrderedHandler(d.topic());
- }
- }
-
- /**
- * @throws InterruptedException If interrupted.
- */
- private void drainQueue() throws InterruptedException {
- while (!msgQ.isEmpty()) {
- SupplyMessage msg = msgQ.take();
-
- if (log.isDebugEnabled())
- log.debug("Drained supply message: " + msg);
- }
- }
-
- /** {@inheritDoc} */
- @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException {
- try {
- int rebalanceOrder = cctx.config().getRebalanceOrder();
-
- if (!CU.isMarshallerCache(cctx.name())) {
- if (log.isDebugEnabled())
- log.debug("Waiting for marshaller cache preload [cacheName=" + cctx.name() + ']');
-
- try {
- cctx.kernalContext().cache().marshallerCache().preloader().syncFuture().get();
- }
- catch (IgniteInterruptedCheckedException ignored) {
- if (log.isDebugEnabled())
- log.debug("Failed to wait for marshaller cache preload future (grid is stopping): " +
- "[cacheName=" + cctx.name() + ']');
-
- return;
- }
- catch (IgniteCheckedException e) {
- throw new Error("Ordered preload future should never fail: " + e.getMessage(), e);
- }
- }
-
- if (rebalanceOrder > 0) {
- IgniteInternalFuture<?> fut = cctx.kernalContext().cache().orderedPreloadFuture(rebalanceOrder);
-
- try {
- if (fut != null) {
- if (log.isDebugEnabled())
- log.debug("Waiting for dependant caches rebalance [cacheName=" + cctx.name() +
- ", rebalanceOrder=" + rebalanceOrder + ']');
-
- fut.get();
- }
- }
- catch (IgniteInterruptedCheckedException ignored) {
- if (log.isDebugEnabled())
- log.debug("Failed to wait for ordered rebalance future (grid is stopping): " +
- "[cacheName=" + cctx.name() + ", rebalanceOrder=" + rebalanceOrder + ']');
-
- return;
- }
- catch (IgniteCheckedException e) {
- throw new Error("Ordered rebalance future should never fail: " + e.getMessage(), e);
- }
- }
-
- GridDhtPartitionsExchangeFuture exchFut = null;
-
- boolean stopEvtFired = false;
-
- while (!isCancelled()) {
- try {
- barrier.await();
-
- if (id == 0 && exchFut != null && !exchFut.dummy() &&
- cctx.events().isRecordable(EVT_CACHE_REBALANCE_STOPPED)) {
-
- if (!cctx.isReplicated() || !stopEvtFired) {
- preloadEvent(EVT_CACHE_REBALANCE_STOPPED, exchFut.discoveryEvent());
-
- stopEvtFired = true;
- }
- }
- }
- catch (BrokenBarrierException ignore) {
- throw new InterruptedException("Demand worker stopped.");
- }
-
- // Sync up all demand threads at this step.
- GridDhtPreloaderAssignments assigns = null;
-
- while (assigns == null)
- assigns = poll(assignQ, cctx.gridConfig().getNetworkTimeout(), this);
-
- demandLock.readLock().lock();
-
- try {
- exchFut = assigns.exchangeFuture();
-
- // Assignments are empty if preloading is disabled.
- if (assigns.isEmpty())
- continue;
-
- boolean resync = false;
-
- // While.
- // =====
- while (!isCancelled() && !topologyChanged() && !resync) {
- Collection<Integer> missed = new HashSet<>();
-
- // For.
- // ===
- for (ClusterNode node : assigns.keySet()) {
- if (topologyChanged() || isCancelled())
- break; // For.
-
- GridDhtPartitionDemandMessage d = assigns.remove(node);
-
- // If another thread is already processing this message,
- // move to the next node.
- if (d == null)
- continue; // For.
-
- try {
- Set<Integer> set = demandFromNode(node, assigns.topologyVersion(), d, exchFut);
-
- if (!set.isEmpty()) {
- if (log.isDebugEnabled())
- log.debug("Missed partitions from node [nodeId=" + node.id() + ", missed=" +
- set + ']');
-
- missed.addAll(set);
- }
- }
- catch (IgniteInterruptedCheckedException e) {
- throw e;
- }
- catch (ClusterTopologyCheckedException e) {
- if (log.isDebugEnabled())
- log.debug("Node left during rebalancing (will retry) [node=" + node.id() +
- ", msg=" + e.getMessage() + ']');
-
- resync = true;
-
- break; // For.
- }
- catch (IgniteCheckedException e) {
- U.error(log, "Failed to receive partitions from node (rebalancing will not " +
- "fully finish) [node=" + node.id() + ", msg=" + d + ']', e);
- }
- }
-
- // Processed missed entries.
- if (!missed.isEmpty()) {
- if (log.isDebugEnabled())
- log.debug("Reassigning partitions that were missed: " + missed);
-
- assert exchFut.exchangeId() != null;
-
- cctx.shared().exchange().forceDummyExchange(true, exchFut);
- }
- else
- break; // While.
- }
- }
- finally {
- demandLock.readLock().unlock();
-
- syncFut.onWorkerDone(this);
- }
-
- cctx.shared().exchange().scheduleResendPartitions();
- }
- }
- finally {
- // Safety.
- syncFut.onWorkerDone(this);
- }
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(DemandWorker.class, this, "assignQ", assignQ, "msgQ", msgQ, "super", super.toString());
- }
- }
-
- /**
- * Sets last exchange future.
- *
- * @param lastFut Last future to set.
- */
- void updateLastExchangeFuture(GridDhtPartitionsExchangeFuture lastFut) {
- lastExchangeFut = lastFut;
- }
-
- /**
- * @param exchFut Exchange future.
- * @return Assignments of partitions to nodes.
- */
- GridDhtPreloaderAssignments assign(GridDhtPartitionsExchangeFuture exchFut) {
- // No assignments for disabled preloader.
- GridDhtPartitionTopology top = cctx.dht().topology();
-
- if (!cctx.rebalanceEnabled())
- return new GridDhtPreloaderAssignments(exchFut, top.topologyVersion());
-
- int partCnt = cctx.affinity().partitions();
-
- assert exchFut.forcePreload() || exchFut.dummyReassign() ||
- exchFut.exchangeId().topologyVersion().equals(top.topologyVersion()) :
- "Topology version mismatch [exchId=" + exchFut.exchangeId() +
- ", topVer=" + top.topologyVersion() + ']';
-
- GridDhtPreloaderAssignments assigns = new GridDhtPreloaderAssignments(exchFut, top.topologyVersion());
-
- AffinityTopologyVersion topVer = assigns.topologyVersion();
-
- for (int p = 0; p < partCnt; p++) {
- if (cctx.shared().exchange().hasPendingExchange()) {
- if (log.isDebugEnabled())
- log.debug("Skipping assignments creation, exchange worker has pending assignments: " +
- exchFut.exchangeId());
-
- break;
- }
-
- // If partition belongs to local node.
- if (cctx.affinity().localNode(p, topVer)) {
- GridDhtLocalPartition part = top.localPartition(p, topVer, 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.
- }
-
- 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.first(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);
- }
- }
- }
-
- return assigns;
- }
-
- /**
- *
- */
- private class SyncFuture extends GridFutureAdapter<Object> {
- /** */
- private static final long serialVersionUID = 0L;
-
- /** Remaining workers. */
- private Collection<DemandWorker> remaining;
-
- /**
- * @param workers List of workers.
- */
- private SyncFuture(Collection<DemandWorker> workers) {
- assert workers.size() == poolSize();
-
- remaining = Collections.synchronizedList(new LinkedList<>(workers));
- }
-
- /**
- * @param w Worker who iterated through all partitions.
- */
- void onWorkerDone(DemandWorker w) {
- if (isDone())
- return;
-
- if (remaining.remove(w))
- if (log.isDebugEnabled())
- log.debug("Completed full partition iteration for worker [worker=" + w + ']');
-
- if (remaining.isEmpty()) {
- if (log.isDebugEnabled())
- log.debug("Completed sync future.");
-
- onDone();
- }
- }
- }
-
- /**
- * Supply message wrapper.
- */
- private static class SupplyMessage {
- /** Sender ID. */
- private UUID sndId;
-
- /** Supply message. */
- private GridDhtPartitionSupplyMessage supply;
-
- /**
- * Dummy constructor.
- */
- private SupplyMessage() {
- // No-op.
- }
-
- /**
- * @param sndId Sender ID.
- * @param supply Supply message.
- */
- SupplyMessage(UUID sndId, GridDhtPartitionSupplyMessage supply) {
- this.sndId = sndId;
- this.supply = supply;
- }
-
- /**
- * @return Sender ID.
- */
- UUID senderId() {
- return sndId;
- }
-
- /**
- * @return Message.
- */
- GridDhtPartitionSupplyMessage supply() {
- return supply;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return S.toString(SupplyMessage.class, this);
- }
- }
-}
\ No newline at end of file
[34/51] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java
new file mode 100644
index 0000000..22f04a8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java
@@ -0,0 +1,108 @@
+/*
+ * 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.transactions;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class IgniteTxRemoteSingleStateImpl extends IgniteTxRemoteStateAdapter {
+ /** */
+ private IgniteTxEntry entry;
+
+ /** {@inheritDoc} */
+ @Override public void addWriteEntry(IgniteTxKey key, IgniteTxEntry e) {
+ this.entry = e;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void clearEntry(IgniteTxKey key) {
+ if (entry != null && entry.txKey().equals(key))
+ entry = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ if (entry != null && entry.txKey().equals(key))
+ return entry;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return entry != null && entry.txKey().equals(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return Collections.emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return entry != null ? Collections.singleton(entry.txKey()) : Collections.<IgniteTxKey>emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return Collections.emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return entry != null ? Collections.singletonMap(entry.txKey(), entry) :
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return Collections.emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return entry == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public IgniteTxEntry singleWrite() {
+ return entry;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxRemoteSingleStateImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java
new file mode 100644
index 0000000..b8290a1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java
@@ -0,0 +1,34 @@
+/*
+ * 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.transactions;
+
+/**
+ *
+ */
+public interface IgniteTxRemoteState extends IgniteTxState {
+ /**
+ * @param key Key.
+ * @param e Entry.
+ */
+ public void addWriteEntry(IgniteTxKey key, IgniteTxEntry e);
+
+ /**
+ * @param key Entry key.
+ */
+ public void clearEntry(IgniteTxKey key);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
new file mode 100644
index 0000000..e7c4c96
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
@@ -0,0 +1,110 @@
+/*
+ * 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.transactions;
+
+import java.util.Collection;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public abstract class IgniteTxRemoteStateAdapter implements IgniteTxRemoteState {
+ /** {@inheritDoc} */
+ @Override public boolean implicitSingle() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public Integer firstCacheId() {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void awaitLastFut(GridCacheSharedContext cctx) {
+ assert false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException validateTopology(GridCacheSharedContext cctx, GridDhtTopologyFuture topFut) {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sync(GridCacheSharedContext cctx) {
+ assert false;
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNearCache(GridCacheSharedContext cctx) {
+ assert false;
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addActiveCache(GridCacheContext cacheCtx, IgniteTxLocalAdapter tx)
+ throws IgniteCheckedException {
+ assert false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
+ assert false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean storeUsed(GridCacheSharedContext cctx) {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
+ assert false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java
new file mode 100644
index 0000000..32bc646
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java
@@ -0,0 +1,124 @@
+/*
+ * 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.transactions;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ *
+ */
+public class IgniteTxRemoteStateImpl extends IgniteTxRemoteStateAdapter {
+ /** Read set. */
+ @GridToStringInclude
+ protected Map<IgniteTxKey, IgniteTxEntry> readMap;
+
+ /** Write map. */
+ @GridToStringInclude
+ protected Map<IgniteTxKey, IgniteTxEntry> writeMap;
+
+ /**
+ * @param readMap Read map.
+ * @param writeMap Write map.
+ */
+ public IgniteTxRemoteStateImpl(Map<IgniteTxKey, IgniteTxEntry> readMap,
+ Map<IgniteTxKey, IgniteTxEntry> writeMap) {
+ this.readMap = readMap;
+ this.writeMap = writeMap;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ IgniteTxEntry e = writeMap == null ? null : writeMap.get(key);
+
+ if (e == null)
+ e = readMap == null ? null : readMap.get(key);
+
+ return e;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return writeMap.containsKey(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return readMap.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return writeMap.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return writeMap.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return readMap.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return writeMap;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return readMap;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return readMap.isEmpty() && writeMap.isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ public void addWriteEntry(IgniteTxKey key, IgniteTxEntry e) {
+ writeMap.put(key, e);
+ }
+
+ /** {@inheritDoc} */
+ public void clearEntry(IgniteTxKey key) {
+ readMap.remove(key);
+ writeMap.remove(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return F.concat(false, writeEntries(), readEntries());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry singleWrite() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxRemoteStateImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
new file mode 100644
index 0000000..81707ba
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
@@ -0,0 +1,171 @@
+/*
+ * 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.transactions;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public interface IgniteTxState {
+ /**
+ *
+ * @return Flag indicating whether transaction is implicit with only one key.
+ */
+ public boolean implicitSingle();
+
+ /**
+ * @return First tx cache id.
+ */
+ @Nullable public Integer firstCacheId();
+
+ /**
+ * @param cctx Context.
+ * @return cctx Non-null cache context if tx has only one active cache.
+ */
+ @Nullable public GridCacheContext singleCacheContext(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Awaits for previous async operations on active caches to be completed.
+ */
+ public void awaitLastFut(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @param topFut Topology future.
+ * @return Error if validation failed.
+ */
+ public IgniteCheckedException validateTopology(GridCacheSharedContext cctx, GridDhtTopologyFuture topFut);
+
+ /**
+ * @param cctx Context.
+ * @return {@code True} if transaction is fully synchronous.
+ */
+ public boolean sync(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @return {@code True} is tx has active near cache.
+ */
+ public boolean hasNearCache(GridCacheSharedContext cctx);
+
+ /**
+ * @param cacheCtx Ccntext.
+ * @param tx Transaction.
+ * @throws IgniteCheckedException If cache check failed.
+ */
+ public void addActiveCache(GridCacheContext cacheCtx, IgniteTxLocalAdapter tx) throws IgniteCheckedException;
+
+ /**
+ * @param cctx Context.
+ * @param fut Future to finish with error if some cache is stopping.
+ * @return Topology future.
+ */
+ public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut);
+
+ /**
+ * @param cctx Context.
+ */
+ public void topologyReadUnlock(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @return {@code True} if transaction is allowed to use store and transactions spans one or more caches with
+ * store enabled.
+ */
+ public boolean storeUsed(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @return Configured stores for active caches.
+ */
+ public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @param tx Transaction.
+ * @param commit Commit flag.
+ */
+ public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit);
+
+ /**
+ * @param key Key.
+ * @return Entry.
+ */
+ @Nullable public IgniteTxEntry entry(IgniteTxKey key);
+
+ /**
+ * @param key Key.
+ * @return {@code True} if tx has write key.
+ */
+ public boolean hasWriteKey(IgniteTxKey key);
+
+ /**
+ * @return Read entries keys.
+ */
+ public Set<IgniteTxKey> readSet();
+
+ /**
+ * @return Write entries keys.
+ */
+ public Set<IgniteTxKey> writeSet();
+
+ /**
+ * @return Write entries.
+ */
+ public Collection<IgniteTxEntry> writeEntries();
+
+ /**
+ * @return Read entries.
+ */
+ public Collection<IgniteTxEntry> readEntries();
+
+ /**
+ * @return Write entries map.
+ */
+ public Map<IgniteTxKey, IgniteTxEntry> writeMap();
+
+ /**
+ * @return Read entries map.
+ */
+ public Map<IgniteTxKey, IgniteTxEntry> readMap();
+
+ /**
+ * @return All entries.
+ */
+ public Collection<IgniteTxEntry> allEntries();
+
+ /**
+ * @return Non-null entry if tx has only one write entry.
+ */
+ @Nullable public IgniteTxEntry singleWrite();
+
+ /**
+ * @return {@code True} if transaction is empty.
+ */
+ public boolean empty();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/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
new file mode 100644
index 0000000..c95fb19
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
@@ -0,0 +1,375 @@
+/*
+ * 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.transactions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+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.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
+ /** Active cache IDs. */
+ private Set<Integer> activeCacheIds = new HashSet<>();
+ /** Per-transaction read map. */
+
+ @GridToStringInclude
+ protected Map<IgniteTxKey, IgniteTxEntry> txMap;
+
+ /** Read view on transaction map. */
+ @GridToStringExclude
+ protected IgniteTxMap readView;
+
+ /** Write view on transaction map. */
+ @GridToStringExclude
+ protected IgniteTxMap writeView;
+
+ /** {@inheritDoc} */
+ @Override public boolean implicitSingle() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public Integer firstCacheId() {
+ return F.first(activeCacheIds);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
+ if (activeCacheIds.size() == 1) {
+ int cacheId = F.first(activeCacheIds);
+
+ return cctx.cacheContext(cacheId);
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void awaitLastFut(GridCacheSharedContext cctx) {
+ for (Integer cacheId : activeCacheIds)
+ cctx.cacheContext(cacheId).cache().awaitLastFut();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException validateTopology(GridCacheSharedContext cctx,
+ GridDhtTopologyFuture topFut) {
+ StringBuilder invalidCaches = null;
+
+ for (Integer cacheId : activeCacheIds) {
+ GridCacheContext ctx = cctx.cacheContext(cacheId);
+
+ assert ctx != null : cacheId;
+
+ Throwable err = topFut.validateCache(ctx);
+
+ if (err != null) {
+ if (invalidCaches != null)
+ invalidCaches.append(", ");
+ else
+ invalidCaches = new StringBuilder();
+
+ invalidCaches.append(U.maskName(ctx.name()));
+ }
+ }
+
+ if (invalidCaches != null) {
+ return new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
+ invalidCaches.toString());
+ }
+
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (CU.affinityNodes(cacheCtx, topFut.topologyVersion()).isEmpty()) {
+ return new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
+ "partition nodes left the grid): " + cacheCtx.name());
+ }
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sync(GridCacheSharedContext cctx) {
+ for (int cacheId : activeCacheIds) {
+ if (cctx.cacheContext(cacheId).config().getWriteSynchronizationMode() == FULL_SYNC)
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNearCache(GridCacheSharedContext cctx) {
+ for (Integer cacheId : activeCacheIds) {
+ GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
+
+ if (cacheCtx.isNear())
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addActiveCache(GridCacheContext cacheCtx, IgniteTxLocalAdapter tx)
+ throws IgniteCheckedException {
+ GridCacheSharedContext cctx = cacheCtx.shared();
+
+ int cacheId = cacheCtx.cacheId();
+
+ // Check if we can enlist new cache to transaction.
+ if (!activeCacheIds.contains(cacheId)) {
+ String err = cctx.verifyTxCompatibility(tx, activeCacheIds, cacheCtx);
+
+ if (err != null) {
+ StringBuilder cacheNames = new StringBuilder();
+
+ int idx = 0;
+
+ for (Integer activeCacheId : activeCacheIds) {
+ cacheNames.append(cctx.cacheContext(activeCacheId).name());
+
+ if (idx++ < activeCacheIds.size() - 1)
+ cacheNames.append(", ");
+ }
+
+ throw new IgniteCheckedException("Failed to enlist new cache to existing transaction (" +
+ err +
+ ") [activeCaches=[" + cacheNames + "]" +
+ ", cacheName=" + cacheCtx.name() +
+ ", cacheSystem=" + cacheCtx.systemTx() +
+ ", txSystem=" + tx.system() + ']');
+ }
+ else
+ activeCacheIds.add(cacheId);
+
+ if (activeCacheIds.size() == 1)
+ tx.activeCachesDeploymentEnabled(cacheCtx.deploymentEnabled());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
+ if (activeCacheIds.isEmpty())
+ return cctx.exchange().lastTopologyFuture();
+
+ GridCacheContext<?, ?> nonLocCtx = null;
+
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (!cacheCtx.isLocal()) {
+ nonLocCtx = cacheCtx;
+
+ break;
+ }
+ }
+
+ if (nonLocCtx == null)
+ return cctx.exchange().lastTopologyFuture();
+
+ nonLocCtx.topology().readLock();
+
+ if (nonLocCtx.topology().stopping()) {
+ fut.onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
+ nonLocCtx.name()));
+
+ return null;
+ }
+
+ return nonLocCtx.topology().topologyVersionFuture();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
+ if (!activeCacheIds.isEmpty()) {
+ GridCacheContext<?, ?> nonLocCtx = null;
+
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (!cacheCtx.isLocal()) {
+ nonLocCtx = cacheCtx;
+
+ break;
+ }
+ }
+
+ if (nonLocCtx != null)
+ nonLocCtx.topology().readUnlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean storeUsed(GridCacheSharedContext cctx) {
+ if (!activeCacheIds.isEmpty()) {
+ for (int cacheId : activeCacheIds) {
+ CacheStoreManager store = cctx.cacheContext(cacheId).store();
+
+ if (store.configured())
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
+ Collection<Integer> cacheIds = activeCacheIds;
+
+ if (!cacheIds.isEmpty()) {
+ Collection<CacheStoreManager> stores = new ArrayList<>(cacheIds.size());
+
+ for (int cacheId : cacheIds) {
+ CacheStoreManager store = cctx.cacheContext(cacheId).store();
+
+ if (store.configured())
+ stores.add(store);
+ }
+
+ return stores;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
+
+ onTxEnd(cacheCtx, tx, commit);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean init(int txSize) {
+ if (txMap == null) {
+ txMap = U.newLinkedHashMap(txSize > 0 ? txSize : 16);
+
+ readView = new IgniteTxMap(txMap, CU.reads());
+ writeView = new IgniteTxMap(txMap, CU.writes());
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean initialized() {
+ return txMap != null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return txMap == null ? Collections.<IgniteTxEntry>emptySet() : txMap.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ return txMap == null ? null : txMap.get(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return writeView.containsKey(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return txMap == null ? Collections.<IgniteTxKey>emptySet() : readView.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return txMap == null ? Collections.<IgniteTxKey>emptySet() : writeView.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return writeView == null ? Collections.<IgniteTxEntry>emptyList() : writeView.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return readView == null ? Collections.<IgniteTxEntry>emptyList() : readView.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return writeView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : writeView;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return readView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : readView;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return txMap.isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addEntry(IgniteTxEntry entry) {
+ txMap.put(entry.txKey(), entry);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void seal() {
+ if (readView != null)
+ readView.seal();
+
+ if (writeView != null)
+ writeView.seal();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry singleWrite() {
+ return writeView != null && writeView.size() == 1 ? F.firstValue(writeView) : null;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxStateImpl.class, this);
+ }
+}
[44/51] ignite git commit: IGNITE-1790 Implement Apache Camel
streamer.
Posted by vk...@apache.org.
IGNITE-1790 Implement Apache Camel streamer.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c490de38
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c490de38
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c490de38
Branch: refs/heads/ignite-direct-marsh-opt
Commit: c490de38c7b841fe51fec1001368bda096e82100
Parents: 175b7f2
Author: Raul Kripalani <ra...@apache.org>
Authored: Wed Nov 18 18:03:23 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Wed Nov 18 18:03:23 2015 +0000
----------------------------------------------------------------------
modules/camel/pom.xml | 102 +++++
.../ignite/stream/camel/CamelStreamer.java | 237 +++++++++++
.../stream/camel/IgniteCamelStreamerTest.java | 420 +++++++++++++++++++
.../camel/IgniteCamelStreamerTestSuite.java | 48 +++
.../src/test/resources/camel.test.properties | 18 +
.../org/apache/ignite/stream/StreamAdapter.java | 19 +-
pom.xml | 1 +
7 files changed, 835 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/modules/camel/pom.xml
----------------------------------------------------------------------
diff --git a/modules/camel/pom.xml b/modules/camel/pom.xml
new file mode 100644
index 0000000..60f0597
--- /dev/null
+++ b/modules/camel/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<!--
+ POM file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-parent</artifactId>
+ <version>1</version>
+ <relativePath>../../parent</relativePath>
+ </parent>
+
+ <artifactId>ignite-camel</artifactId>
+ <version>1.5.0-SNAPSHOT</version>
+ <url>http://ignite.apache.org</url>
+
+ <properties>
+ <camel.version>2.16.0</camel.version>
+ <guava.version>18.0</guava.version>
+ <okhttp.version>2.5.0</okhttp.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ <version>${camel.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-log4j</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-spring</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-jetty</artifactId>
+ <version>${camel.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>com.squareup.okhttp</groupId>
+ <artifactId>okhttp</artifactId>
+ <version>${okhttp.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
----------------------------------------------------------------------
diff --git a/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java b/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
new file mode 100644
index 0000000..40ed6b3
--- /dev/null
+++ b/modules/camel/src/main/java/org/apache/ignite/stream/camel/CamelStreamer.java
@@ -0,0 +1,237 @@
+/*
+ * 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.stream.camel;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.util.CamelContextHelper;
+import org.apache.camel.util.ServiceHelper;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.stream.StreamAdapter;
+import org.apache.ignite.stream.StreamMultipleTupleExtractor;
+import org.apache.ignite.stream.StreamSingleTupleExtractor;
+
+/**
+ * This streamer consumes messages from an Apache Camel consumer endpoint and feeds them into an Ignite data streamer.
+ *
+ * The only mandatory properties are {@link #endpointUri} and the appropriate stream tuple extractor (either {@link
+ * StreamSingleTupleExtractor} or {@link StreamMultipleTupleExtractor)}.
+ *
+ * The user can also provide a custom {@link CamelContext} in case they want to attach custom components, a {@link
+ * org.apache.camel.component.properties.PropertiesComponent}, set tracers, management strategies, etc.
+ *
+ * @see <a href="http://camel.apache.org">Apache Camel</a>
+ * @see <a href="http://camel.apache.org/components.html">Apache Camel components</a>
+ */
+public class CamelStreamer<K, V> extends StreamAdapter<Exchange, K, V> implements Processor {
+ /** Logger. */
+ private IgniteLogger log;
+
+ /** The Camel Context. */
+ private CamelContext camelCtx;
+
+ /** The endpoint URI to consume from. */
+ private String endpointUri;
+
+ /** Camel endpoint. */
+ private Endpoint endpoint;
+
+ /** Camel consumer. */
+ private Consumer consumer;
+
+ /** A {@link Processor} to generate the response. */
+ private Processor resProc;
+
+ /**
+ * Starts the streamer.
+ *
+ * @throws IgniteException In cases when failed to start the streamer.
+ */
+ public void start() throws IgniteException {
+ // Ensure that the endpoint URI is provided.
+ A.notNullOrEmpty(endpointUri, "endpoint URI must be provided");
+
+ // Check that one and only one tuple extractor is provided.
+ A.ensure(!(getSingleTupleExtractor() == null && getMultipleTupleExtractor() == null),
+ "tuple extractor missing");
+
+ // If a custom CamelContext is not provided, initialize one.
+ if (camelCtx == null)
+ camelCtx = new DefaultCamelContext();
+
+ // If the Camel Context is starting or started, reject this call to start.
+ if (camelCtx.getStatus() == ServiceStatus.Started || camelCtx.getStatus() == ServiceStatus.Starting)
+ throw new IgniteException("Failed to start Camel streamer (CamelContext already started or starting).");
+
+ log = getIgnite().log();
+
+ // Instantiate the Camel endpoint.
+ try {
+ endpoint = CamelContextHelper.getMandatoryEndpoint(camelCtx, endpointUri);
+ }
+ catch (Exception e) {
+ U.error(log, e);
+
+ throw new IgniteException("Failed to start Camel streamer [errMsg=" + e.getMessage() + ']');
+ }
+
+ // Create the Camel consumer.
+ try {
+ consumer = endpoint.createConsumer(this);
+ }
+ catch (Exception e) {
+ U.error(log, e);
+
+ throw new IgniteException("Failed to start Camel streamer [errMsg=" + e.getMessage() + ']');
+ }
+
+ // Start the Camel services.
+ try {
+ ServiceHelper.startServices(camelCtx, endpoint, consumer);
+ }
+ catch (Exception e) {
+ U.error(log, e);
+
+ try {
+ ServiceHelper.stopAndShutdownServices(camelCtx, endpoint, consumer);
+
+ consumer = null;
+ endpoint = null;
+ }
+ catch (Exception e1) {
+ throw new IgniteException("Failed to start Camel streamer; failed to stop the context, endpoint or " +
+ "consumer during rollback of failed initialization [errMsg=" + e.getMessage() + ", stopErrMsg=" +
+ e1.getMessage() + ']');
+ }
+
+ throw new IgniteException("Failed to start Camel streamer [errMsg=" + e.getMessage() + ']');
+ }
+
+ U.log(log, "Started Camel streamer consuming from endpoint URI: " + endpointUri);
+ }
+
+ /**
+ * Stops the streamer.
+ *
+ * @throws IgniteException In cases if failed to stop the streamer.
+ */
+ public void stop() throws IgniteException {
+ // If the Camel Context is stopping or stopped, reject this call to stop.
+ if (camelCtx.getStatus() == ServiceStatus.Stopped || camelCtx.getStatus() == ServiceStatus.Stopping)
+ throw new IgniteException("Failed to stop Camel streamer (CamelContext already stopped or stopping).");
+
+ // Stop Camel services.
+ try {
+ ServiceHelper.stopAndShutdownServices(camelCtx, endpoint, consumer);
+ }
+ catch (Exception e) {
+ throw new IgniteException("Failed to stop Camel streamer [errMsg=" + e.getMessage() + ']');
+ }
+
+ U.log(log, "Stopped Camel streamer, formerly consuming from endpoint URI: " + endpointUri);
+ }
+
+ /**
+ * Processes the incoming {@link Exchange} and adds the tuple(s) to the underlying streamer.
+ *
+ * @param exchange The Camel Exchange.
+ */
+ @Override public void process(Exchange exchange) throws Exception {
+ // Extract and insert the tuple(s).
+ if (getMultipleTupleExtractor() == null) {
+ Map.Entry<K, V> entry = getSingleTupleExtractor().extract(exchange);
+ getStreamer().addData(entry);
+ }
+ else {
+ Map<K, V> entries = getMultipleTupleExtractor().extract(exchange);
+ getStreamer().addData(entries);
+ }
+
+ // If the user has set a response processor, invoke it before finishing.
+ if (resProc != null)
+ resProc.process(exchange);
+ }
+
+ /**
+ * Gets the underlying {@link CamelContext}, whether created automatically by Ignite or the context specified by the
+ * user.
+ *
+ * @return The Camel Context.
+ */
+ public CamelContext getCamelContext() {
+ return camelCtx;
+ }
+
+ /**
+ * Explicitly sets the {@link CamelContext} to use.
+ *
+ * Doing so gives the user the opportunity to attach custom components, a {@link
+ * org.apache.camel.component.properties.PropertiesComponent}, set tracers, management strategies, etc.
+ *
+ * @param camelCtx The Camel Context to use. In most cases, an instance of {@link DefaultCamelContext}.
+ */
+ public void setCamelContext(CamelContext camelCtx) {
+ this.camelCtx = camelCtx;
+ }
+
+ /**
+ * Gets the endpoint URI from which to consume.
+ *
+ * @return The endpoint URI.
+ */
+ public String getEndpointUri() {
+ return endpointUri;
+ }
+
+ /**
+ * Sets the endpoint URI from which to consume. <b>Mandatory.</b>
+ *
+ * @param endpointUri The endpoint URI.
+ */
+ public void setEndpointUri(String endpointUri) {
+ this.endpointUri = endpointUri;
+ }
+
+ /**
+ * Gets the {@link Processor} used to generate the response.
+ *
+ * @return The {@link Processor}.
+ */
+ public Processor getResponseProcessor() {
+ return resProc;
+ }
+
+ /**
+ * Sets the {@link Processor} used to generate the response.
+ *
+ * @param resProc The {@link Processor}.
+ */
+ public void setResponseProcessor(Processor resProc) {
+ this.resProc = resProc;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTest.java
----------------------------------------------------------------------
diff --git a/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTest.java b/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTest.java
new file mode 100644
index 0000000..4795dff
--- /dev/null
+++ b/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTest.java
@@ -0,0 +1,420 @@
+/*
+ * 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.stream.camel;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.ServiceStatus;
+import org.apache.camel.component.properties.PropertiesComponent;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.LifecycleStrategySupport;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteDataStreamer;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.cache.CachePeekMode;
+import org.apache.ignite.events.CacheEvent;
+import org.apache.ignite.internal.util.lang.GridMapEntry;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.lang.IgniteBiPredicate;
+import org.apache.ignite.lang.IgniteInClosure;
+import org.apache.ignite.stream.StreamMultipleTupleExtractor;
+import org.apache.ignite.stream.StreamSingleTupleExtractor;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import com.squareup.okhttp.MediaType;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.RequestBody;
+import com.squareup.okhttp.Response;
+
+import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
+
+/**
+ * Test class for {@link CamelStreamer}.
+ */
+public class IgniteCamelStreamerTest extends GridCommonAbstractTest {
+ /** text/plain media type. */
+ private static final MediaType TEXT_PLAIN = MediaType.parse("text/plain;charset=utf-8");
+
+ /** The test data. */
+ private static final Map<Integer, String> TEST_DATA = new HashMap<>();
+
+ /** The Camel streamer currently under test. */
+ private CamelStreamer<Integer, String> streamer;
+
+ /** The Ignite data streamer. */
+ private IgniteDataStreamer<Integer, String> dataStreamer;
+
+ /** URL where the REST service will be exposed. */
+ private String url;
+
+ /** The UUID of the currently active remote listener. */
+ private UUID remoteLsnr;
+
+ /** The OkHttpClient. */
+ private OkHttpClient httpClient = new OkHttpClient();
+
+ // Initialize the test data.
+ static {
+ for (int i = 0; i < 100; i++)
+ TEST_DATA.put(i, "v" + i);
+ }
+
+ /** Constructor. */
+ public IgniteCamelStreamerTest() {
+ super(true);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override public void beforeTest() throws Exception {
+ grid().<Integer, String>getOrCreateCache(defaultCacheConfiguration());
+
+ // find an available local port
+ try (ServerSocket ss = new ServerSocket(0)) {
+ int port = ss.getLocalPort();
+
+ url = "http://localhost:" + port + "/ignite";
+ }
+
+ // create Camel streamer
+ dataStreamer = grid().dataStreamer(null);
+ streamer = createCamelStreamer(dataStreamer);
+ }
+
+ @Override public void afterTest() throws Exception {
+ try {
+ streamer.stop();
+ }
+ catch (Exception e) {
+ // ignore if already stopped
+ }
+
+ dataStreamer.close();
+
+ grid().cache(null).clear();
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testSendOneEntryPerMessage() throws Exception {
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+
+ // Subscribe to cache PUT events.
+ CountDownLatch latch = subscribeToPutEvents(50);
+
+ // Action time.
+ streamer.start();
+
+ // Send messages.
+ sendMessages(0, 50, false);
+
+ // Assertions.
+ assertTrue(latch.await(10, TimeUnit.SECONDS));
+ assertCacheEntriesLoaded(50);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testMultipleEntriesInOneMessage() throws Exception {
+ streamer.setMultipleTupleExtractor(multipleTupleExtractor());
+
+ // Subscribe to cache PUT events.
+ CountDownLatch latch = subscribeToPutEvents(50);
+
+ // Action time.
+ streamer.start();
+
+ // Send messages.
+ sendMessages(0, 50, true);
+
+ // Assertions.
+ assertTrue(latch.await(10, TimeUnit.SECONDS));
+ assertCacheEntriesLoaded(50);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testResponseProcessorIsCalled() throws Exception {
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+ streamer.setResponseProcessor(new Processor() {
+ @Override public void process(Exchange exchange) throws Exception {
+ exchange.getOut().setBody("Foo bar");
+ }
+ });
+
+ // Subscribe to cache PUT events.
+ CountDownLatch latch = subscribeToPutEvents(50);
+
+ // Action time.
+ streamer.start();
+
+ // Send messages.
+ List<String> responses = sendMessages(0, 50, false);
+
+ for (String r : responses)
+ assertEquals("Foo bar", r);
+
+ // Assertions.
+ assertTrue(latch.await(10, TimeUnit.SECONDS));
+ assertCacheEntriesLoaded(50);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testUserSpecifiedCamelContext() throws Exception {
+ final AtomicInteger cnt = new AtomicInteger();
+
+ // Create a CamelContext with a probe that'll help us know if it has been used.
+ CamelContext context = new DefaultCamelContext();
+ context.setTracing(true);
+ context.addLifecycleStrategy(new LifecycleStrategySupport() {
+ @Override public void onEndpointAdd(Endpoint endpoint) {
+ cnt.incrementAndGet();
+ }
+ });
+
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+ streamer.setCamelContext(context);
+
+ // Subscribe to cache PUT events.
+ CountDownLatch latch = subscribeToPutEvents(50);
+
+ // Action time.
+ streamer.start();
+
+ // Send messages.
+ sendMessages(0, 50, false);
+
+ // Assertions.
+ assertTrue(latch.await(10, TimeUnit.SECONDS));
+ assertCacheEntriesLoaded(50);
+ assertTrue(cnt.get() > 0);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testUserSpecifiedCamelContextWithPropertyPlaceholders() throws Exception {
+ // Create a CamelContext with a custom property placeholder.
+ CamelContext context = new DefaultCamelContext();
+
+ PropertiesComponent pc = new PropertiesComponent("camel.test.properties");
+
+ context.addComponent("properties", pc);
+
+ // Replace the context path in the test URL with the property placeholder.
+ url = url.replaceAll("/ignite", "{{test.contextPath}}");
+
+ // Recreate the Camel streamer with the new URL.
+ streamer = createCamelStreamer(dataStreamer);
+
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+ streamer.setCamelContext(context);
+
+ // Subscribe to cache PUT events.
+ CountDownLatch latch = subscribeToPutEvents(50);
+
+ // Action time.
+ streamer.start();
+
+ // Before sending the messages, get the actual URL after the property placeholder was resolved,
+ // stripping the jetty: prefix from it.
+ url = streamer.getCamelContext().getEndpoints().iterator().next().getEndpointUri().replaceAll("jetty:", "");
+
+ // Send messages.
+ sendMessages(0, 50, false);
+
+ // Assertions.
+ assertTrue(latch.await(10, TimeUnit.SECONDS));
+ assertCacheEntriesLoaded(50);
+ }
+
+ /**
+ * @throws Exception
+ */
+ public void testInvalidEndpointUri() throws Exception {
+ streamer.setSingleTupleExtractor(singleTupleExtractor());
+ streamer.setEndpointUri("abc");
+
+ // Action time.
+ try {
+ streamer.start();
+ fail("Streamer started; should have failed.");
+ }
+ catch (IgniteException e) {
+ assertTrue(streamer.getCamelContext().getStatus() == ServiceStatus.Stopped);
+ assertTrue(streamer.getCamelContext().getEndpointRegistry().size() == 0);
+ }
+ }
+
+ /**
+ * Creates a Camel streamer.
+ */
+ private CamelStreamer<Integer, String> createCamelStreamer(IgniteDataStreamer<Integer, String> dataStreamer) {
+ CamelStreamer<Integer, String> streamer = new CamelStreamer<>();
+
+ streamer.setIgnite(grid());
+ streamer.setStreamer(dataStreamer);
+ streamer.setEndpointUri("jetty:" + url);
+
+ dataStreamer.allowOverwrite(true);
+ dataStreamer.autoFlushFrequency(1);
+
+ return streamer;
+ }
+
+ /**
+ * @throws IOException
+ * @return HTTP response payloads.
+ */
+ private List<String> sendMessages(int fromIdx, int cnt, boolean singleMessage) throws IOException {
+ List<String> responses = Lists.newArrayList();
+
+ if (singleMessage) {
+ StringBuilder sb = new StringBuilder();
+
+ for (int i = fromIdx; i < fromIdx + cnt; i++)
+ sb.append(i).append(",").append(TEST_DATA.get(i)).append("\n");
+
+ Request request = new Request.Builder()
+ .url(url)
+ .post(RequestBody.create(TEXT_PLAIN, sb.toString()))
+ .build();
+
+ Response response = httpClient.newCall(request).execute();
+
+ responses.add(response.body().string());
+ }
+ else {
+ for (int i = fromIdx; i < fromIdx + cnt; i++) {
+ String payload = i + "," + TEST_DATA.get(i);
+
+ Request request = new Request.Builder()
+ .url(url)
+ .post(RequestBody.create(TEXT_PLAIN, payload))
+ .build();
+
+ Response response = httpClient.newCall(request).execute();
+
+ responses.add(response.body().string());
+ }
+ }
+
+ return responses;
+ }
+
+ /**
+ * Returns a {@link StreamSingleTupleExtractor} for testing.
+ */
+ private static StreamSingleTupleExtractor<Exchange, Integer, String> singleTupleExtractor() {
+ return new StreamSingleTupleExtractor<Exchange, Integer, String>() {
+ @Override public Map.Entry<Integer, String> extract(Exchange exchange) {
+ List<String> s = Splitter.on(",").splitToList(exchange.getIn().getBody(String.class));
+
+ return new GridMapEntry<>(Integer.parseInt(s.get(0)), s.get(1));
+ }
+ };
+ }
+
+ /**
+ * Returns a {@link StreamMultipleTupleExtractor} for testing.
+ */
+ private static StreamMultipleTupleExtractor<Exchange, Integer, String> multipleTupleExtractor() {
+ return new StreamMultipleTupleExtractor<Exchange, Integer, String>() {
+ @Override public Map<Integer, String> extract(Exchange exchange) {
+ final Map<String, String> map = Splitter.on("\n")
+ .omitEmptyStrings()
+ .withKeyValueSeparator(",")
+ .split(exchange.getIn().getBody(String.class));
+
+ final Map<Integer, String> answer = new HashMap<>();
+
+ F.forEach(map.keySet(), new IgniteInClosure<String>() {
+ @Override public void apply(String s) {
+ answer.put(Integer.parseInt(s), map.get(s));
+ }
+ });
+
+ return answer;
+ }
+ };
+ }
+
+ /**
+ * Subscribe to cache put events.
+ */
+ private CountDownLatch subscribeToPutEvents(int expect) {
+ Ignite ignite = grid();
+
+ // Listen to cache PUT events and expect as many as messages as test data items
+ final CountDownLatch latch = new CountDownLatch(expect);
+ @SuppressWarnings("serial") IgniteBiPredicate<UUID, CacheEvent> callback =
+ new IgniteBiPredicate<UUID, CacheEvent>() {
+ @Override public boolean apply(UUID uuid, CacheEvent evt) {
+ latch.countDown();
+
+ return true;
+ }
+ };
+
+ remoteLsnr = ignite.events(ignite.cluster().forCacheNodes(null))
+ .remoteListen(callback, null, EVT_CACHE_OBJECT_PUT);
+
+ return latch;
+ }
+
+ /**
+ * Assert a given number of cache entries have been loaded.
+ */
+ private void assertCacheEntriesLoaded(int cnt) {
+ // get the cache and check that the entries are present
+ IgniteCache<Integer, String> cache = grid().cache(null);
+
+ // for each key from 0 to count from the TEST_DATA (ordered by key), check that the entry is present in cache
+ for (Integer key : new ArrayList<>(new TreeSet<>(TEST_DATA.keySet())).subList(0, cnt))
+ assertEquals(TEST_DATA.get(key), cache.get(key));
+
+ // assert that the cache exactly the specified amount of elements
+ assertEquals(cnt, cache.size(CachePeekMode.ALL));
+
+ // remove the event listener
+ grid().events(grid().cluster().forCacheNodes(null)).stopRemoteListen(remoteLsnr);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTestSuite.java b/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTestSuite.java
new file mode 100644
index 0000000..266c9cf
--- /dev/null
+++ b/modules/camel/src/test/java/org/apache/ignite/stream/camel/IgniteCamelStreamerTestSuite.java
@@ -0,0 +1,48 @@
+/*
+ * 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.stream.camel;
+
+import java.util.Set;
+
+import junit.framework.TestSuite;
+
+/**
+ * Camel streamer tests.
+ */
+public class IgniteCamelStreamerTestSuite extends TestSuite {
+ /**
+ * @return {@link IgniteCamelStreamerTest} test suite.
+ * @throws Exception Thrown in case of the failure.
+ */
+ public static TestSuite suite() throws Exception {
+ return suite(null);
+ }
+
+ /**
+ * @param ignoredTests
+ * @return Test suite.
+ * @throws Exception Thrown in case of the failure.
+ */
+ public static TestSuite suite(Set<Class> ignoredTests) throws Exception {
+ TestSuite suite = new TestSuite("IgniteCamelStreamer Test Suite");
+
+ suite.addTestSuite(IgniteCamelStreamerTest.class);
+
+ return suite;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/modules/camel/src/test/resources/camel.test.properties
----------------------------------------------------------------------
diff --git a/modules/camel/src/test/resources/camel.test.properties b/modules/camel/src/test/resources/camel.test.properties
new file mode 100644
index 0000000..30459be
--- /dev/null
+++ b/modules/camel/src/test/resources/camel.test.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+test.contextPath = /ignite-properties
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java b/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
index 2cb7db7..afc1530 100644
--- a/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/stream/StreamAdapter.java
@@ -37,7 +37,6 @@ import org.apache.ignite.IgniteDataStreamer;
* </ol>
*/
public abstract class StreamAdapter<T, K, V> {
-
/** Tuple extractor extracting a single tuple from an event */
private StreamSingleTupleExtractor<T, K, V> singleTupleExtractor;
@@ -99,9 +98,9 @@ public abstract class StreamAdapter<T, K, V> {
*/
@Deprecated
public StreamTupleExtractor<T, K, V> getTupleExtractor() {
- if (singleTupleExtractor instanceof StreamTupleExtractor) {
+ if (singleTupleExtractor instanceof StreamTupleExtractor)
return (StreamTupleExtractor) singleTupleExtractor;
- }
+
throw new IllegalArgumentException("This method is deprecated and only relevant if using an old " +
"StreamTupleExtractor; use getSingleTupleExtractor instead");
}
@@ -112,9 +111,9 @@ public abstract class StreamAdapter<T, K, V> {
*/
@Deprecated
public void setTupleExtractor(StreamTupleExtractor<T, K, V> extractor) {
- if (multipleTupleExtractor != null) {
+ if (multipleTupleExtractor != null)
throw new IllegalArgumentException("Multiple tuple extractor already set; cannot set both types at once.");
- }
+
this.singleTupleExtractor = extractor;
}
@@ -129,9 +128,9 @@ public abstract class StreamAdapter<T, K, V> {
* @param singleTupleExtractor Extractor for key-value tuples from messages.
*/
public void setSingleTupleExtractor(StreamSingleTupleExtractor<T, K, V> singleTupleExtractor) {
- if (multipleTupleExtractor != null) {
+ if (multipleTupleExtractor != null)
throw new IllegalArgumentException("Multiple tuple extractor already set; cannot set both types at once.");
- }
+
this.singleTupleExtractor = singleTupleExtractor;
}
@@ -146,9 +145,9 @@ public abstract class StreamAdapter<T, K, V> {
* @param multipleTupleExtractor Extractor for 1:n tuple extraction.
*/
public void setMultipleTupleExtractor(StreamMultipleTupleExtractor<T, K, V> multipleTupleExtractor) {
- if (singleTupleExtractor != null) {
+ if (singleTupleExtractor != null)
throw new IllegalArgumentException("Single tuple extractor already set; cannot set both types at once.");
- }
+
this.multipleTupleExtractor = multipleTupleExtractor;
}
@@ -188,4 +187,4 @@ public abstract class StreamAdapter<T, K, V> {
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/c490de38/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index c40b551..b9c51b2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,6 +78,7 @@
<module>modules/jms11</module>
<module>modules/mqtt</module>
<module>modules/zookeeper</module>
+ <module>modules/camel</module>
<module>modules/platform</module>
</modules>
[38/51] ignite git commit: Merge branch 'ignite-direct-marsh' into
ignite-direct-marsh-opt
Posted by vk...@apache.org.
Merge branch 'ignite-direct-marsh' into ignite-direct-marsh-opt
Conflicts:
modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d8096be1
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d8096be1
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d8096be1
Branch: refs/heads/ignite-direct-marsh-opt
Commit: d8096be16f32e3158f1bd40485f07feaab20d083
Parents: 393b630 d7747d8
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 17 17:37:25 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 17 17:37:25 2015 -0800
----------------------------------------------------------------------
.../internal/direct/DirectByteBufferStream.java | 52 ++++----
.../internal/direct/DirectMessageReader.java | 92 ++++++++++---
.../direct/DirectMessageReaderState.java | 128 +++++++++++++++++++
.../internal/direct/DirectMessageWriter.java | 2 +-
.../managers/communication/GridIoManager.java | 45 ++++---
.../internal/util/nio/GridDirectParser.java | 27 ++--
.../extensions/communication/MessageReader.java | 19 ++-
.../apache/ignite/stream/StreamTransformer.java | 9 +-
.../testframework/GridSpiTestContext.java | 4 +-
.../testsuites/IgniteCacheTestSuite3.java | 2 +
10 files changed, 297 insertions(+), 83 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/d8096be1/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
----------------------------------------------------------------------
diff --cc modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
index e05e20d,ef9168c..45a0f4b
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
@@@ -290,25 -285,7 +286,25 @@@ public class DirectByteBufferStream
private long prim;
/** */
+ private int primShift;
+
+ /** */
+ private int uuidState;
+
+ /** */
+ private long uuidMost;
+
+ /** */
+ private long uuidLeast;
+
+ /** */
+ private long uuidLocId;
+
+ /** */
+ private boolean lastFinished;
+
+ /** */
- private MessageReader reader;
+ private boolean lastFinished;
/**
* @param msgFactory Message factory.
@@@ -381,17 -356,17 +375,19 @@@
* @param val Value.
*/
public void writeInt(int val) {
- if (val == Integer.MAX_VALUE)
- val = Integer.MIN_VALUE;
- else
- val++;
+ lastFinished = buf.remaining() >= 5;
+ lastFinished = buf.remaining() >= 5;
+
if (lastFinished) {
+ if (val == Integer.MAX_VALUE)
+ val = Integer.MIN_VALUE;
+ else
+ val++;
+
int pos = buf.position();
- while ((val & 0xFFFFFF80) != 0) {
+ while ((val & 0xFFFF_FF80) != 0) {
byte b = (byte)(val | 0x80);
UNSAFE.putByte(heapArr, baseOff + pos++, b);
http://git-wip-us.apache.org/repos/asf/ignite/blob/d8096be1/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
----------------------------------------------------------------------
[37/51] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by vk...@apache.org.
'Single' operations optimizations for tx cache.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3ff71fd7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3ff71fd7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3ff71fd7
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 3ff71fd742efda91fef6ed6d92dac11cc6d00976
Parents: 38e66d9
Author: sboikov <sb...@gridgain.com>
Authored: Tue Nov 17 19:38:05 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Nov 17 19:38:05 2015 +0300
----------------------------------------------------------------------
.../processors/cache/GridCacheAdapter.java | 48 +-
.../processors/cache/GridCacheMapEntry.java | 11 +-
.../cache/GridCacheSharedContext.java | 31 +-
.../distributed/GridDistributedTxMapping.java | 78 -
.../GridDistributedTxRemoteAdapter.java | 136 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 1 -
.../cache/distributed/dht/GridDhtTxLocal.java | 24 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 80 +-
.../cache/distributed/dht/GridDhtTxMapping.java | 134 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 59 +-
.../cache/distributed/dht/GridDhtTxRemote.java | 29 +-
...arOptimisticSerializableTxPrepareFuture.java | 16 -
.../near/GridNearOptimisticTxPrepareFuture.java | 103 +-
...ridNearOptimisticTxPrepareFutureAdapter.java | 72 +-
.../GridNearPessimisticTxPrepareFuture.java | 1 -
.../near/GridNearTransactionalCache.java | 1 -
.../near/GridNearTxFinishFuture.java | 61 +-
.../cache/distributed/near/GridNearTxLocal.java | 109 +-
.../near/GridNearTxPrepareRequest.java | 9 -
.../distributed/near/GridNearTxRemote.java | 26 +-
.../distributed/near/IgniteTxMappings.java | 75 +
.../distributed/near/IgniteTxMappingsImpl.java | 92 ++
.../near/IgniteTxMappingsSingleImpl.java | 101 ++
.../cache/transactions/IgniteInternalTx.java | 12 +-
.../cache/transactions/IgniteTxAdapter.java | 67 +-
.../cache/transactions/IgniteTxHandler.java | 16 +-
.../IgniteTxImplicitSingleStateImpl.java | 259 ++++
.../transactions/IgniteTxLocalAdapter.java | 1388 ++++++++++--------
.../cache/transactions/IgniteTxLocalEx.java | 30 +-
.../cache/transactions/IgniteTxLocalState.java | 44 +
.../transactions/IgniteTxLocalStateAdapter.java | 41 +
.../cache/transactions/IgniteTxManager.java | 18 +-
.../cache/transactions/IgniteTxMap.java | 3 +-
.../cache/transactions/IgniteTxRemoteEx.java | 17 +-
.../IgniteTxRemoteSingleStateImpl.java | 108 ++
.../cache/transactions/IgniteTxRemoteState.java | 34 +
.../IgniteTxRemoteStateAdapter.java | 110 ++
.../transactions/IgniteTxRemoteStateImpl.java | 124 ++
.../cache/transactions/IgniteTxState.java | 171 +++
.../cache/transactions/IgniteTxStateImpl.java | 375 +++++
40 files changed, 2709 insertions(+), 1405 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/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 419ccec..cbb7486 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
@@ -1854,7 +1854,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
V prevVal = syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, filter).get().value();
+ return (V)tx.putAsync(ctx, key, val, true, filter).get().value();
}
@Override public String toString() {
@@ -1909,7 +1909,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, filter)
+ return tx.putAsync(ctx, key, val, true, filter)
.chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@@ -1948,7 +1948,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Boolean stored = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, filter).get().success();
+ return tx.putAsync(ctx, key, val, false, filter).get().success();
}
@Override public String toString() {
@@ -2013,10 +2013,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<EntryProcessorResult<T>>(true) {
@Nullable @Override public EntryProcessorResult<T> op(IgniteTxLocalAdapter tx)
throws IgniteCheckedException {
- Map<? extends K, EntryProcessor<K, V, Object>> invokeMap =
- Collections.singletonMap(key, (EntryProcessor<K, V, Object>) entryProcessor);
-
- IgniteInternalFuture<GridCacheReturn> fut = tx.invokeAsync(ctx, invokeMap, args);
+ IgniteInternalFuture<GridCacheReturn> fut =
+ tx.invokeAsync(ctx, key, (EntryProcessor<K, V, Object>)entryProcessor, args);
Map<K, EntryProcessorResult<T>> resMap = fut.get().value();
@@ -2240,8 +2238,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, filter).chain(
- (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
+ return tx.putAsync(ctx, key, val, false, filter).chain(
+ (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@Override public String toString() {
@@ -2275,7 +2273,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray()).get().value();
+ return (V)tx.putAsync(ctx, key, val, true, ctx.noValArray()).get().value();
}
@Override public String toString() {
@@ -2299,8 +2297,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray())
- .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>) RET2VAL);
+ return tx.putAsync(ctx, key, val, true, ctx.noValArray())
+ .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@Override public String toString() {
@@ -2329,7 +2327,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Boolean stored = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).get().success();
+ return tx.putAsync(ctx, key, val, false, ctx.noValArray()).get().success();
}
@Override public String toString() {
@@ -2358,7 +2356,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<Boolean> fut = asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).chain(
+ return tx.putAsync(ctx, key, val, false, ctx.noValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2384,7 +2382,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).get().value();
+ return (V)tx.putAsync(ctx, key, val, true, ctx.hasValArray()).get().value();
}
@Override public String toString() {
@@ -2408,7 +2406,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).chain(
+ return tx.putAsync(ctx, key, val, true, ctx.hasValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@@ -2434,7 +2432,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).get().success();
+ return tx.putAsync(ctx, key, val, false, ctx.hasValArray()).get().success();
}
@Override public String toString() {
@@ -2454,7 +2452,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).chain(
+ return tx.putAsync(ctx, key, val, false, ctx.hasValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
}
@@ -2481,7 +2479,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (ctx.deploymentEnabled())
ctx.deploy().registerClass(oldVal);
- return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).get()
+ return tx.putAsync(ctx, key, newVal, false, ctx.equalsValArray(oldVal)).get()
.success();
}
@@ -2518,7 +2516,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
}
- return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).chain(
+ return tx.putAsync(ctx, key, newVal, false, ctx.equalsValArray(oldVal)).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2883,8 +2881,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (ctx.deploymentEnabled())
ctx.deploy().registerClass(oldVal);
- return tx.putAllAsync(ctx,
- F.t(key, newVal),
+ return tx.putAsync(ctx,
+ key,
+ newVal,
true,
ctx.equalsValArray(oldVal)).get();
}
@@ -2945,8 +2944,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return new GridFinishedFuture<>(e);
}
- return (IgniteInternalFuture)tx.putAllAsync(ctx,
- F.t(key, newVal),
+ return (IgniteInternalFuture)tx.putAsync(ctx,
+ key,
+ newVal,
true,
ctx.equalsValArray(oldVal));
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index df9f5c4..0786a50 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -74,6 +74,7 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_EXPIRED;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE;
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
/**
@@ -4014,7 +4015,15 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
IgniteInternalTx tx = cctx.tm().localTxx();
- return tx == null || !tx.removed(txKey());
+ if (tx != null) {
+ IgniteTxEntry e = tx.entry(txKey());
+
+ boolean rmvd = e != null && e.op() == DELETE;
+
+ return !rmvd;
+ }
+
+ return true;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
index b37742c..4293b90 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
@@ -582,12 +582,7 @@ public class GridCacheSharedContext<K, V> {
* @throws IgniteCheckedException If failed.
*/
public void endTx(IgniteInternalTx tx) throws IgniteCheckedException {
- Collection<Integer> cacheIds = tx.activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- for (Integer cacheId : cacheIds)
- cacheContext(cacheId).cache().awaitLastFut();
- }
+ tx.txState().awaitLastFut(this);
tx.close();
}
@@ -596,22 +591,17 @@ public class GridCacheSharedContext<K, V> {
* @param tx Transaction to commit.
* @return Commit future.
*/
+ @SuppressWarnings("unchecked")
public IgniteInternalFuture<IgniteInternalTx> commitTxAsync(IgniteInternalTx tx) {
- Collection<Integer> cacheIds = tx.activeCacheIds();
-
- if (cacheIds.isEmpty())
- return tx.commitAsync();
- else if (cacheIds.size() == 1) {
- int cacheId = F.first(cacheIds);
+ GridCacheContext ctx = tx.txState().singleCacheContext(this);
- return cacheContext(cacheId).cache().commitTxAsync(tx);
- }
- else {
- for (Integer cacheId : cacheIds)
- cacheContext(cacheId).cache().awaitLastFut();
+ if (ctx == null) {
+ tx.txState().awaitLastFut(this);
return tx.commitAsync();
}
+ else
+ return ctx.cache().commitTxAsync(tx);
}
/**
@@ -620,12 +610,7 @@ public class GridCacheSharedContext<K, V> {
* @return Rollback future.
*/
public IgniteInternalFuture rollbackTxAsync(IgniteInternalTx tx) throws IgniteCheckedException {
- Collection<Integer> cacheIds = tx.activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- for (Integer cacheId : cacheIds)
- cacheContext(cacheId).cache().awaitLastFut();
- }
+ tx.txState().awaitLastFut(this);
return tx.rollbackAsync();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
index 2d2d935..8c9f181 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
@@ -24,9 +24,7 @@ import java.io.ObjectOutput;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.UUID;
import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -59,15 +57,9 @@ public class GridDistributedTxMapping implements Externalizable {
/** DHT version. */
private GridCacheVersion dhtVer;
- /** Copy on remove flag. */
- private boolean readOnly;
-
/** {@code True} if this is last mapping for node. */
private boolean last;
- /** IDs of backup nodes receiving last prepare request during this mapping. */
- private Collection<UUID> lastBackups;
-
/** {@code True} if mapping is for near caches, {@code false} otherwise. */
private boolean near;
@@ -91,20 +83,6 @@ public class GridDistributedTxMapping implements Externalizable {
}
/**
- * @return IDs of backup nodes receiving last prepare request during this mapping.
- */
- @Nullable public Collection<UUID> lastBackups() {
- return lastBackups;
- }
-
- /**
- * @param lastBackups IDs of backup nodes receiving last prepare request during this mapping.
- */
- public void lastBackups(@Nullable Collection<UUID> lastBackups) {
- this.lastBackups = lastBackups;
- }
-
- /**
* @return {@code True} if this is last mapping for node.
*/
public boolean last() {
@@ -161,17 +139,6 @@ public class GridDistributedTxMapping implements Externalizable {
}
/**
- * @param entries Mapped entries.
- * @param readOnly Flag indicating that passed in collection is read-only.
- */
- public void entries(Collection<IgniteTxEntry> entries, boolean readOnly) {
- this.entries = entries;
-
- // Set copy on remove flag as passed in collection is unmodifiable.
- this.readOnly = true;
- }
-
- /**
* @return {@code True} if lock is explicit.
*/
public boolean explicitLock() {
@@ -221,8 +188,6 @@ public class GridDistributedTxMapping implements Externalizable {
* @param entry Adds entry.
*/
public void add(IgniteTxEntry entry) {
- ensureModifiable();
-
entries.add(entry);
}
@@ -231,48 +196,16 @@ public class GridDistributedTxMapping implements Externalizable {
* @return {@code True} if entry was removed.
*/
public boolean removeEntry(IgniteTxEntry entry) {
- ensureModifiable();
-
return entries.remove(entry);
}
/**
- * @param parts Evicts partitions from mapping.
- */
- public void evictPartitions(@Nullable int[] parts) {
- if (!F.isEmpty(parts)) {
- ensureModifiable();
-
- evictPartitions(parts, entries);
- }
- }
-
- /**
- * @param parts Partitions.
- * @param c Collection.
- */
- private void evictPartitions(int[] parts, Collection<IgniteTxEntry> c) {
- assert parts != null;
-
- for (Iterator<IgniteTxEntry> it = c.iterator(); it.hasNext();) {
- IgniteTxEntry e = it.next();
-
- GridCacheEntryEx cached = e.cached();
-
- if (U.containsIntArray(parts, cached.partition()))
- it.remove();
- }
- }
-
- /**
* @param keys Keys to evict readers for.
*/
public void evictReaders(@Nullable Collection<IgniteTxKey> keys) {
if (keys == null || keys.isEmpty())
return;
- ensureModifiable();
-
evictReaders(keys, entries);
}
@@ -293,17 +226,6 @@ public class GridDistributedTxMapping implements Externalizable {
}
/**
- * Copies collection of entries if it is read-only.
- */
- private void ensureModifiable() {
- if (readOnly) {
- entries = new LinkedHashSet<>(entries);
-
- readOnly = false;
- }
- }
-
- /**
* Whether empty or not.
*
* @return Empty or not.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index 93303c8..0d49584 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -45,6 +45,8 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxAdapter;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteEx;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteState;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxState;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
@@ -85,18 +87,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** */
private static final long serialVersionUID = 0L;
- /** Read set. */
- @GridToStringInclude
- protected Map<IgniteTxKey, IgniteTxEntry> readMap;
-
- /** Write map. */
- @GridToStringInclude
- protected Map<IgniteTxKey, IgniteTxEntry> writeMap;
-
- /** Remote thread ID. */
- @GridToStringInclude
- private long rmtThreadId;
-
/** Explicit versions. */
@GridToStringInclude
private List<GridCacheVersion> explicitVers;
@@ -109,6 +99,10 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
@GridToStringInclude
private AtomicBoolean commitAllowed = new AtomicBoolean(false);
+ /** */
+ @GridToStringInclude
+ protected IgniteTxRemoteState txState;
+
/**
* Empty constructor required for {@link Externalizable}.
*/
@@ -119,7 +113,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/**
* @param ctx Cache registry.
* @param nodeId Node ID.
- * @param rmtThreadId Remote thread ID.
* @param xidVer XID version.
* @param commitVer Commit version.
* @param sys System flag.
@@ -135,7 +128,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
public GridDistributedTxRemoteAdapter(
GridCacheSharedContext<?, ?> ctx,
UUID nodeId,
- long rmtThreadId,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
boolean sys,
@@ -163,7 +155,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
subjId,
taskNameHash);
- this.rmtThreadId = rmtThreadId;
this.invalidate = invalidate;
commitVersion(commitVer);
@@ -173,6 +164,11 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
+ @Override public IgniteTxState txState() {
+ return txState;
+ }
+
+ /** {@inheritDoc} */
@Override public UUID eventNodeId() {
return nodeId;
}
@@ -188,11 +184,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
- @Override public Collection<Integer> activeCacheIds() {
- return Collections.emptyList();
- }
-
- /** {@inheritDoc} */
@Override public boolean activeCachesDeploymentEnabled() {
return false;
}
@@ -201,14 +192,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @return Checks if transaction has no entries.
*/
@Override public boolean empty() {
- return readMap.isEmpty() && writeMap.isEmpty();
- }
-
- /** {@inheritDoc} */
- @Override public boolean removed(IgniteTxKey key) {
- IgniteTxEntry e = writeMap.get(key);
-
- return e != null && e.op() == DELETE;
+ return txState.empty();
}
/** {@inheritDoc} */
@@ -218,12 +202,12 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
- return writeMap;
+ return txState.writeMap();
}
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
- return readMap;
+ return txState.readMap();
}
/** {@inheritDoc} */
@@ -245,12 +229,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public IgniteTxEntry entry(IgniteTxKey key) {
- IgniteTxEntry e = writeMap == null ? null : writeMap.get(key);
-
- if (e == null)
- e = readMap == null ? null : readMap.get(key);
-
- return e;
+ return txState.entry(key);
}
/**
@@ -259,8 +238,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @param key key to be removed.
*/
public void clearEntry(IgniteTxKey key) {
- readMap.remove(key);
- writeMap.remove(key);
+ txState.clearEntry(key);
}
/**
@@ -268,13 +246,19 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @param committedVers Committed versions.
* @param rolledbackVers Rolled back versions.
*/
- @Override public void doneRemote(GridCacheVersion baseVer, Collection<GridCacheVersion> committedVers,
- Collection<GridCacheVersion> rolledbackVers, Collection<GridCacheVersion> pendingVers) {
+ @Override public void doneRemote(GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
+ Collection<GridCacheVersion> pendingVers) {
+ Map<IgniteTxKey, IgniteTxEntry> readMap = txState.readMap();
+
if (readMap != null && !readMap.isEmpty()) {
for (IgniteTxEntry txEntry : readMap.values())
doneRemote(txEntry, baseVer, committedVers, rolledbackVers, pendingVers);
}
+ Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
+
if (writeMap != null && !writeMap.isEmpty()) {
for (IgniteTxEntry txEntry : writeMap.values())
doneRemote(txEntry, baseVer, committedVers, rolledbackVers, pendingVers);
@@ -290,8 +274,10 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @param rolledbackVers Rolled back versions relative to base version.
* @param pendingVers Pending versions.
*/
- private void doneRemote(IgniteTxEntry txEntry, GridCacheVersion baseVer,
- Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers,
+ private void doneRemote(IgniteTxEntry txEntry,
+ GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
Collection<GridCacheVersion> pendingVers) {
while (true) {
GridDistributedCacheEntry entry = (GridDistributedCacheEntry)txEntry.cached();
@@ -337,59 +323,9 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
return started;
}
- /**
- * @return Remote node thread ID.
- */
- @Override public long remoteThreadId() {
- return rmtThreadId;
- }
-
- /**
- * @param e Transaction entry to set.
- * @return {@code True} if value was set.
- */
- @Override public boolean setWriteValue(IgniteTxEntry e) {
- checkInternal(e.txKey());
-
- IgniteTxEntry entry = writeMap.get(e.txKey());
-
- if (entry == null) {
- IgniteTxEntry rmv = readMap.remove(e.txKey());
-
- if (rmv != null) {
- e.cached(rmv.cached());
-
- writeMap.put(e.txKey(), e);
- }
- // If lock is explicit.
- else {
- e.cached(e.context().cache().entryEx(e.key()));
-
- // explicit lock.
- writeMap.put(e.txKey(), e);
- }
- }
- else {
- // Copy values.
- entry.value(e.value(), e.hasWriteValue(), e.hasReadValue());
- entry.entryProcessors(e.entryProcessors());
- entry.op(e.op());
- entry.ttl(e.ttl());
- entry.explicitVersion(e.explicitVersion());
-
- // Conflict resolution stuff.
- entry.conflictVersion(e.conflictVersion());
- entry.conflictExpireTime(e.conflictExpireTime());
- }
-
- addExplicit(e);
-
- return true;
- }
-
/** {@inheritDoc} */
@Override public boolean hasWriteKey(IgniteTxKey key) {
- return writeMap.containsKey(key);
+ return txState.hasWriteKey(key);
}
/** {@inheritDoc} */
@@ -400,27 +336,27 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public Set<IgniteTxKey> readSet() {
- return readMap.keySet();
+ return txState.readSet();
}
/** {@inheritDoc} */
@Override public Set<IgniteTxKey> writeSet() {
- return writeMap.keySet();
+ return txState.writeSet();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> allEntries() {
- return F.concat(false, writeEntries(), readEntries());
+ return txState.allEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> writeEntries() {
- return writeMap.values();
+ return txState.writeEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> readEntries() {
- return readMap.values();
+ return txState.readEntries();
}
/**
@@ -459,7 +395,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
@SuppressWarnings({"CatchGenericClass"})
private void commitIfLocked() throws IgniteCheckedException {
if (state() == COMMITTING) {
- for (IgniteTxEntry txEntry : writeMap.values()) {
+ for (IgniteTxEntry txEntry : writeEntries()) {
assert txEntry != null : "Missing transaction entry for tx: " + this;
while (true) {
@@ -494,6 +430,8 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
if (commitAllowed.compareAndSet(false, true)) {
IgniteCheckedException err = null;
+ Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
+
if (!F.isEmpty(writeMap)) {
// Register this transaction as completed prior to write-phase to
// ensure proper lock ordering for removed entries.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
index 3069afd..fe91e5b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
@@ -228,7 +228,6 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
req.futureId(),
nodeId,
req.nearXidVersion(),
- req.threadId(),
req.topologyVersion(),
req.version(),
/*commitVer*/null,
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
index 44f34aa..2bed931 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
@@ -223,11 +223,6 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
}
/** {@inheritDoc} */
- @Override protected IgniteUuid nearMiniId() {
- return nearMiniId;
- }
-
- /** {@inheritDoc} */
@Override public boolean dht() {
return true;
}
@@ -307,8 +302,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
0,
nearMiniId,
null,
- true,
- null);
+ true);
}
// For pessimistic mode we don't distribute prepare request.
@@ -322,8 +316,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
nearMiniId,
Collections.<IgniteTxKey, GridCacheVersion>emptyMap(),
true,
- needReturnValue(),
- null)))
+ needReturnValue())))
return prepFut.get();
}
else
@@ -378,7 +371,6 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
* @param nearMiniId Near mini future ID.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this is last prepare request.
- * @param lastBackups IDs of backup nodes receiving last prepare request.
* @return Future that will be completed when locks are acquired.
*/
public IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsync(
@@ -388,8 +380,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
long msgId,
IgniteUuid nearMiniId,
Map<UUID, Collection<UUID>> txNodes,
- boolean last,
- Collection<UUID> lastBackups
+ boolean last
) {
// In optimistic mode prepare still can be called explicitly from salvageTx.
GridDhtTxPrepareFuture fut = prepFut.get();
@@ -404,8 +395,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
nearMiniId,
verMap,
last,
- needReturnValue(),
- lastBackups))) {
+ needReturnValue()))) {
GridDhtTxPrepareFuture f = prepFut.get();
assert f.nearMiniId().equals(nearMiniId) : "Wrong near mini id on existing future " +
@@ -443,13 +433,15 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
}
try {
- if (reads != null)
+ if (reads != null) {
for (IgniteTxEntry e : reads)
addEntry(msgId, e);
+ }
- if (writes != null)
+ if (writes != null) {
for (IgniteTxEntry e : writes)
addEntry(msgId, e);
+ }
userPrepare();
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/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 6de8795..70ebf3f 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
@@ -86,9 +86,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
protected volatile boolean mapped;
/** */
- private long dhtThreadId;
-
- /** */
protected boolean explicitLock;
/** Versions of pending locks for entries of this tx. */
@@ -159,7 +156,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
this.explicitLock = explicitLock;
threadId = Thread.currentThread().getId();
- dhtThreadId = threadId;
}
/**
@@ -216,11 +212,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
protected abstract IgniteUuid nearFutureId();
/**
- * @return Near future mini ID.
- */
- protected abstract IgniteUuid nearMiniId();
-
- /**
* Adds reader to cached entry.
*
* @param msgId Message ID.
@@ -260,13 +251,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
- * @return DHT thread ID.
- */
- long dhtThreadId() {
- return dhtThreadId;
- }
-
- /**
* Map explicit locks.
*/
protected void mapExplicitLocks() {
@@ -355,22 +339,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
- * @param nodeId Node ID.
- * @return Mapping.
- */
- GridDistributedTxMapping dhtMapping(UUID nodeId) {
- return dhtMap.get(nodeId);
- }
-
- /**
- * @param nodeId Node ID.
- * @return Mapping.
- */
- GridDistributedTxMapping nearMapping(UUID nodeId) {
- return nearMap.get(nodeId);
- }
-
- /**
* @param mappings Mappings to add.
*/
void addDhtNodeEntryMapping(Map<ClusterNode, List<GridDhtCacheEntry>> mappings) {
@@ -385,19 +353,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
- * @param mappings Mappings to add.
- */
- public void addDhtMapping(Map<UUID, GridDistributedTxMapping> mappings) {
- addMapping0(mappings, dhtMap);
- }
-
- /**
- * @param mappings Mappings to add.
- */
- public void addNearMapping(Map<UUID, GridDistributedTxMapping> mappings) {
- addMapping0(mappings, nearMap);
- }
- /**
* @param nodeId Node ID.
* @return {@code True} if mapping was removed.
*/
@@ -435,7 +390,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
if (log.isDebugEnabled())
log.debug("Removing mapping for entry [nodeId=" + nodeId + ", entry=" + entry + ']');
- IgniteTxEntry txEntry = txMap.get(entry.txKey());
+ IgniteTxEntry txEntry = entry(entry.txKey());
if (txEntry == null)
return false;
@@ -469,7 +424,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
List<GridDhtCacheEntry> entries = mapping.getValue();
for (GridDhtCacheEntry entry : entries) {
- IgniteTxEntry txEntry = txMap.get(entry.txKey());
+ IgniteTxEntry txEntry = entry(entry.txKey());
if (txEntry != null) {
if (m == null)
@@ -481,26 +436,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
}
- /**
- * @param mappings Mappings to add.
- * @param dst Map to add to.
- */
- private void addMapping0(
- Map<UUID, GridDistributedTxMapping> mappings,
- Map<UUID, GridDistributedTxMapping> dst
- ) {
- for (Map.Entry<UUID, GridDistributedTxMapping> entry : mappings.entrySet()) {
- GridDistributedTxMapping targetMapping = dst.get(entry.getKey());
-
- if (targetMapping == null)
- dst.put(entry.getKey(), entry.getValue());
- else {
- for (IgniteTxEntry txEntry : entry.getValue().entries())
- targetMapping.add(txEntry);
- }
- }
- }
-
/** {@inheritDoc} */
@Override public void addInvalidPartition(GridCacheContext ctx, int part) {
assert false : "DHT transaction encountered invalid partition [part=" + part + ", tx=" + this + ']';
@@ -529,7 +464,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
GridDhtCacheAdapter dhtCache = cacheCtx.isNear() ? cacheCtx.near().dht() : cacheCtx.dht();
try {
- IgniteTxEntry existing = txMap.get(e.txKey());
+ IgniteTxEntry existing = entry(e.txKey());
if (existing != null) {
// Must keep NOOP operation if received READ because it means that the lock was sent to a backup node.
@@ -569,7 +504,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
existing.explicitVersion(dhtVer);
}
- txMap.put(existing.txKey(), existing);
+ txState.addEntry(existing);
if (log.isDebugEnabled())
log.debug("Added entry to transaction: " + existing);
@@ -705,7 +640,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
passedKeys,
read,
needRetVal,
- skipped,
accessTtl,
null,
skipStore);
@@ -723,7 +657,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
* @param passedKeys Passed keys.
* @param read {@code True} if read.
* @param needRetVal Return value flag.
- * @param skipped Skipped keys.
* @param accessTtl TTL for read operation.
* @param filter Entry write filter.
* @param skipStore Skip store flag.
@@ -735,13 +668,11 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
final Collection<KeyCacheObject> passedKeys,
final boolean read,
final boolean needRetVal,
- final Set<KeyCacheObject> skipped,
final long accessTtl,
@Nullable final CacheEntryPredicate[] filter,
boolean skipStore) {
if (log.isDebugEnabled())
- log.debug("Before acquiring transaction lock on keys [passedKeys=" + passedKeys + ", skipped=" +
- skipped + ']');
+ log.debug("Before acquiring transaction lock on keys [keys=" + passedKeys + ']');
if (passedKeys.isEmpty())
return new GridFinishedFuture<>(ret);
@@ -768,7 +699,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
postLockWrite(cacheCtx,
passedKeys,
- skipped,
ret,
/*remove*/false,
/*retval*/false,
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
index 55cbe96..9ec35b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
@@ -17,18 +17,15 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
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.processors.cache.distributed.GridDistributedTxMapping;
import org.apache.ignite.internal.util.GridLeanMap;
+import org.apache.ignite.internal.util.GridLeanSet;
import org.apache.ignite.internal.util.typedef.F;
-import org.jetbrains.annotations.Nullable;
+import org.apache.ignite.internal.util.typedef.internal.U;
/**
* DHT transaction mapping.
@@ -37,12 +34,6 @@ public class GridDhtTxMapping {
/** Transaction nodes mapping (primary node -> related backup nodes). */
private final Map<UUID, Collection<UUID>> txNodes = new GridLeanMap<>();
- /** */
- private final List<TxMapping> mappings = new ArrayList<>();
-
- /** */
- private TxMapping last;
-
/**
* Adds information about next mapping.
*
@@ -50,24 +41,26 @@ public class GridDhtTxMapping {
*/
@SuppressWarnings("ConstantConditions")
public void addMapping(List<ClusterNode> nodes) {
- ClusterNode primary = F.first(nodes);
+ assert !F.isEmpty(nodes) : nodes;
- Collection<ClusterNode> backups = F.view(nodes, F.notEqualTo(primary));
+ ClusterNode primary = nodes.get(0);
- if (last == null || !last.primary.equals(primary.id())) {
- last = new TxMapping(primary, backups);
+ int size = nodes.size();
- mappings.add(last);
- }
- else
- last.add(backups);
+ if (size > 1) {
+ Collection<UUID> backups = txNodes.get(primary.id());
- Collection<UUID> storedBackups = txNodes.get(last.primary);
+ if (backups == null) {
+ backups = U.newHashSet(size - 1);
- if (storedBackups == null)
- txNodes.put(last.primary, storedBackups = new HashSet<>());
+ txNodes.put(primary.id(), backups);
+ }
- storedBackups.addAll(last.backups);
+ for (int i = 1; i < size; i++)
+ backups.add(nodes.get(i).id());
+ }
+ else
+ txNodes.put(primary.id(), new GridLeanSet<UUID>());
}
/**
@@ -76,99 +69,4 @@ public class GridDhtTxMapping {
public Map<UUID, Collection<UUID>> transactionNodes() {
return txNodes;
}
-
- /**
- * For each mapping sets flags indicating if mapping is last for node.
- *
- * @param mappings Mappings.
- */
- public void initLast(Collection<GridDistributedTxMapping> mappings) {
- assert this.mappings.size() == mappings.size();
-
- int idx = 0;
-
- for (GridDistributedTxMapping map : mappings) {
- TxMapping mapping = this.mappings.get(idx);
-
- map.lastBackups(lastBackups(mapping, idx));
-
- boolean last = true;
-
- for (int i = idx + 1; i < this.mappings.size(); i++) {
- TxMapping nextMap = this.mappings.get(i);
-
- if (nextMap.primary.equals(mapping.primary)) {
- last = false;
-
- break;
- }
- }
-
- map.last(last);
-
- idx++;
- }
- }
-
- /**
- * @param mapping Mapping.
- * @param idx Mapping index.
- * @return IDs of backup nodes receiving last prepare request during this mapping.
- */
- @Nullable private Collection<UUID> lastBackups(TxMapping mapping, int idx) {
- Collection<UUID> res = null;
-
- for (UUID backup : mapping.backups) {
- boolean foundNext = false;
-
- for (int i = idx + 1; i < mappings.size(); i++) {
- TxMapping nextMap = mappings.get(i);
-
- if (nextMap.primary.equals(mapping.primary) && nextMap.backups.contains(backup)) {
- foundNext = true;
-
- break;
- }
- }
-
- if (!foundNext) {
- if (res == null)
- res = new ArrayList<>(mapping.backups.size());
-
- res.add(backup);
- }
- }
-
- return res;
- }
-
- /**
- */
- private static class TxMapping {
- /** */
- private final UUID primary;
-
- /** */
- private final Set<UUID> backups;
-
- /**
- * @param primary Primary node.
- * @param backups Backup nodes.
- */
- private TxMapping(ClusterNode primary, Iterable<ClusterNode> backups) {
- this.primary = primary.id();
-
- this.backups = new HashSet<>();
-
- add(backups);
- }
-
- /**
- * @param backups Backup nodes.
- */
- private void add(Iterable<ClusterNode> backups) {
- for (ClusterNode n : backups)
- this.backups.add(n.id());
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/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 1d6f633..a67950d 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
@@ -165,9 +165,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
/** {@code True} if this is last prepare operation for node. */
private boolean last;
- /** IDs of backup nodes receiving last prepare request during this prepare. */
- private Collection<UUID> lastBackups;
-
/** Needs return value flag. */
private boolean retVal;
@@ -197,7 +194,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
* @param dhtVerMap DHT versions map.
* @param last {@code True} if this is last prepare operation for node.
* @param retVal Return value flag.
- * @param lastBackups IDs of backup nodes receiving last prepare request during this prepare.
*/
public GridDhtTxPrepareFuture(
GridCacheSharedContext cctx,
@@ -205,8 +201,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
IgniteUuid nearMiniId,
Map<IgniteTxKey, GridCacheVersion> dhtVerMap,
boolean last,
- boolean retVal,
- Collection<UUID> lastBackups
+ boolean retVal
) {
super(REDUCER);
@@ -214,7 +209,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
this.tx = tx;
this.dhtVerMap = dhtVerMap;
this.last = last;
- this.lastBackups = lastBackups;
futId = IgniteUuid.randomUuid();
@@ -864,14 +858,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
}
/**
- * @param backupId Backup node ID.
- * @return {@code True} if backup node receives last prepare request for this transaction.
- */
- private boolean lastBackup(UUID backupId) {
- return lastBackups != null && lastBackups.contains(backupId);
- }
-
- /**
* Checks if this transaction needs previous value for the given tx entry. Will use passed in map to store
* required key or will create new map if passed in map is {@code null}.
*
@@ -1022,18 +1008,15 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
tx.writeVersion(cctx.versions().next(tx.topologyVersion()));
{
- Map<UUID, GridDistributedTxMapping> futDhtMap = new HashMap<>();
- Map<UUID, GridDistributedTxMapping> futNearMap = new HashMap<>();
-
// Assign keys to primary nodes.
if (!F.isEmpty(writes)) {
for (IgniteTxEntry write : writes)
- map(tx.entry(write.txKey()), futDhtMap, futNearMap);
+ map(tx.entry(write.txKey()));
}
if (!F.isEmpty(reads)) {
for (IgniteTxEntry read : reads)
- map(tx.entry(read.txKey()), futDhtMap, futNearMap);
+ map(tx.entry(read.txKey()));
}
}
@@ -1225,14 +1208,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
/**
* @param entry Transaction entry.
- * @param futDhtMap DHT mapping.
- * @param futNearMap Near mapping.
*/
- private void map(
- IgniteTxEntry entry,
- Map<UUID, GridDistributedTxMapping> futDhtMap,
- Map<UUID, GridDistributedTxMapping> futNearMap
- ) {
+ private void map(IgniteTxEntry entry) {
if (entry.cached().isLocal())
return;
@@ -1258,26 +1235,25 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
log.debug("Mapping entry to DHT nodes [nodes=" + U.toShortString(dhtNodes) +
", entry=" + entry + ']');
- Collection<UUID> readers = cached.readers();
+ // Exclude local node.
+ map(entry, F.view(dhtNodes, F.remoteNodes(cctx.localNodeId())), dhtMap);
- Collection<ClusterNode> nearNodes = null;
+ Collection<UUID> readers = cached.readers();
if (!F.isEmpty(readers)) {
- nearNodes = cctx.discovery().nodes(readers, F0.not(F.idForNodeId(tx.nearNodeId())));
+ Collection<ClusterNode> nearNodes =
+ cctx.discovery().nodes(readers, F0.not(F.idForNodeId(tx.nearNodeId())));
if (log.isDebugEnabled())
log.debug("Mapping entry to near nodes [nodes=" + U.toShortString(nearNodes) +
", entry=" + entry + ']');
+
+ // Exclude DHT nodes.
+ map(entry, F.view(nearNodes, F0.notIn(dhtNodes)), nearMap);
}
else if (log.isDebugEnabled())
log.debug("Entry has no near readers: " + entry);
- // Exclude local node.
- map(entry, F.view(dhtNodes, F.remoteNodes(cctx.localNodeId())), dhtMap, futDhtMap);
-
- // Exclude DHT nodes.
- map(entry, F.view(nearNodes, F0.notIn(dhtNodes)), nearMap, futNearMap);
-
break;
}
catch (GridCacheEntryRemovedException ignore) {
@@ -1292,13 +1268,11 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
* @param entry Entry.
* @param nodes Nodes.
* @param globalMap Map.
- * @param locMap Exclude map.
*/
private void map(
IgniteTxEntry entry,
Iterable<ClusterNode> nodes,
- Map<UUID, GridDistributedTxMapping> globalMap,
- Map<UUID, GridDistributedTxMapping> locMap
+ Map<UUID, GridDistributedTxMapping> globalMap
) {
if (nodes != null) {
for (ClusterNode n : nodes) {
@@ -1321,13 +1295,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
globalMap.put(n.id(), global = new GridDistributedTxMapping(n));
global.add(entry);
-
- GridDistributedTxMapping loc = locMap.get(n.id());
-
- if (loc == null)
- locMap.put(n.id(), loc = new GridDistributedTxMapping(n));
-
- loc.add(entry);
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
index e268a88..0cbe10f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
@@ -36,6 +36,8 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxRemoteAdapter;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteSingleStateImpl;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteStateImpl;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.typedef.T2;
@@ -77,7 +79,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
* @param nearNodeId Near node ID.
* @param rmtFutId Remote future ID.
* @param nodeId Node ID.
- * @param rmtThreadId Remote thread ID.
* @param topVer Topology version.
* @param xidVer XID version.
* @param commitVer Commit version.
@@ -96,7 +97,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
UUID nearNodeId,
IgniteUuid rmtFutId,
UUID nodeId,
- long rmtThreadId,
AffinityTopologyVersion topVer,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
@@ -110,12 +110,12 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
GridCacheVersion nearXidVer,
Map<UUID, Collection<UUID>> txNodes,
@Nullable UUID subjId,
- int taskNameHash
+ int taskNameHash,
+ boolean single
) {
super(
ctx,
nodeId,
- rmtThreadId,
xidVer,
commitVer,
sys,
@@ -137,9 +137,10 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
this.nearXidVer = nearXidVer;
this.txNodes = txNodes;
- readMap = Collections.emptyMap();
-
- writeMap = new ConcurrentLinkedHashMap<>(U.capacity(txSize), 0.75f, 1);
+ txState = single ? new IgniteTxRemoteSingleStateImpl() :
+ new IgniteTxRemoteStateImpl(
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap(),
+ new ConcurrentLinkedHashMap<IgniteTxKey, IgniteTxEntry>(U.capacity(txSize), 0.75f, 1));
topologyVersion(topVer);
}
@@ -151,7 +152,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
* @param rmtFutId Remote future ID.
* @param nodeId Node ID.
* @param nearXidVer Near transaction ID.
- * @param rmtThreadId Remote thread ID.
* @param topVer Topology version.
* @param xidVer XID version.
* @param commitVer Commit version.
@@ -169,7 +169,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
IgniteUuid rmtFutId,
UUID nodeId,
GridCacheVersion nearXidVer,
- long rmtThreadId,
AffinityTopologyVersion topVer,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
@@ -186,7 +185,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
super(
ctx,
nodeId,
- rmtThreadId,
xidVer,
commitVer,
sys,
@@ -207,8 +205,9 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
this.nearNodeId = nearNodeId;
this.rmtFutId = rmtFutId;
- readMap = Collections.emptyMap();
- writeMap = new ConcurrentLinkedHashMap<>(U.capacity(txSize), 0.75f, 1);
+ txState = new IgniteTxRemoteStateImpl(
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap(),
+ new ConcurrentLinkedHashMap<IgniteTxKey, IgniteTxEntry>(U.capacity(txSize), 0.75f, 1));
topologyVersion(topVer);
}
@@ -280,6 +279,8 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
@Override public void addInvalidPartition(GridCacheContext cacheCtx, int part) {
super.addInvalidPartition(cacheCtx, part);
+ Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
+
for (Iterator<IgniteTxEntry> it = writeMap.values().iterator(); it.hasNext();) {
IgniteTxEntry e = it.next();
@@ -312,7 +313,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
// Initialize cache entry.
entry.cached(cached);
- writeMap.put(entry.txKey(), entry);
+ txState.addWriteEntry(entry.txKey(), entry);
addExplicit(entry);
}
@@ -356,7 +357,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
txEntry.entryProcessors(entryProcessors);
- writeMap.put(key, txEntry);
+ txState.addWriteEntry(key, txEntry);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
index 5488bb1..29774a5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -29,7 +29,6 @@ import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.cluster.ClusterTopologyException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
-import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -57,7 +56,6 @@ import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P1;
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.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiTuple;
@@ -326,19 +324,6 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
txMapping = new GridDhtTxMapping();
- if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (CU.affinityNodes(cacheCtx, topVer).isEmpty()) {
- onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
- "partition nodes left the grid): " + cacheCtx.name()));
-
- return;
- }
- }
- }
-
Map<IgniteBiTuple<ClusterNode, Boolean>, GridDistributedTxMapping> mappings = new HashMap<>();
for (IgniteTxEntry write : writes)
@@ -437,7 +422,6 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
m.near(),
txMapping.transactionNodes(),
m.last(),
- m.lastBackups(),
tx.onePhaseCommit(),
tx.needReturnValue() && tx.implicit(),
tx.implicitSingle(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index 0002180..791d2f3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -19,7 +19,9 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
import java.util.ArrayDeque;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -28,7 +30,6 @@ import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.cluster.ClusterTopologyException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
-import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -50,7 +51,6 @@ 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.X;
-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.IgniteClosure;
@@ -267,7 +267,12 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
return;
}
- prepare(tx.writeEntries(), topLocked);
+ IgniteTxEntry singleWrite = tx.singleWrite();
+
+ if (singleWrite != null)
+ prepareSingle(singleWrite, topLocked);
+ else
+ prepare(tx.writeEntries(), topLocked);
markInitialized();
}
@@ -280,6 +285,46 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
}
/**
+ * @param write Write.
+ * @param topLocked {@code True} if thread already acquired lock preventing topology change.
+ */
+ private void prepareSingle(IgniteTxEntry write, boolean topLocked) {
+ AffinityTopologyVersion topVer = tx.topologyVersion();
+
+ assert topVer.topologyVersion() > 0;
+
+ txMapping = new GridDhtTxMapping();
+
+ GridDistributedTxMapping mapping = map(write, topVer, null, topLocked);
+
+ if (mapping.node().isLocal()) {
+ if (write.context().isNear())
+ tx.nearLocallyMapped(true);
+ else if (write.context().isColocated())
+ tx.colocatedLocallyMapped(true);
+ }
+
+ if (isDone()) {
+ if (log.isDebugEnabled())
+ log.debug("Abandoning (re)map because future is done: " + this);
+
+ return;
+ }
+
+ tx.addSingleEntryMapping(mapping, write);
+
+ cctx.mvcc().recheckPendingLocks();
+
+ mapping.last(true);
+
+ tx.transactionNodes(txMapping.transactionNodes());
+
+ checkOnePhase();
+
+ proceedPrepare(mapping, null);
+ }
+
+ /**
* @param writes Write entries.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
* @throws IgniteCheckedException If failed.
@@ -294,30 +339,26 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
txMapping = new GridDhtTxMapping();
- Queue<GridDistributedTxMapping> mappings = new ArrayDeque<>();
-
- if (!F.isEmpty(writes)) {
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (CU.affinityNodes(cacheCtx, topVer).isEmpty()) {
- onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
- "partition nodes left the grid): " + cacheCtx.name()));
-
- return;
- }
- }
- }
+ Map<UUID, GridDistributedTxMapping> map = new HashMap<>();
// Assign keys to primary nodes.
GridDistributedTxMapping cur = null;
+ Queue<GridDistributedTxMapping> mappings = new ArrayDeque<>();
+
for (IgniteTxEntry write : writes) {
GridDistributedTxMapping updated = map(write, topVer, cur, topLocked);
if (cur != updated) {
mappings.offer(updated);
+ updated.last(true);
+
+ GridDistributedTxMapping prev = map.put(updated.node().id(), updated);
+
+ if (prev != null)
+ prev.last(false);
+
if (updated.node().isLocal()) {
if (write.context().isNear())
tx.nearLocallyMapped(true);
@@ -340,8 +381,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
cctx.mvcc().recheckPendingLocks();
- txMapping.initLast(mappings);
-
tx.transactionNodes(txMapping.transactionNodes());
checkOnePhase();
@@ -355,14 +394,24 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
* @param mappings Queue of mappings.
*/
private void proceedPrepare(final Queue<GridDistributedTxMapping> mappings) {
- if (isDone())
- return;
-
final GridDistributedTxMapping m = mappings.poll();
if (m == null)
return;
+ proceedPrepare(m, mappings);
+ }
+
+ /**
+ * Continues prepare after previous mapping successfully finished.
+ *
+ * @param m Mapping.
+ * @param mappings Queue of mappings.
+ */
+ private void proceedPrepare(GridDistributedTxMapping m, @Nullable final Queue<GridDistributedTxMapping> mappings) {
+ if (isDone())
+ return;
+
assert !m.empty();
final ClusterNode n = m.node();
@@ -376,7 +425,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
m.near(),
txMapping.transactionNodes(),
m.last(),
- m.lastBackups(),
tx.onePhaseCommit(),
tx.needReturnValue() && tx.implicit(),
tx.implicitSingle(),
@@ -457,7 +505,14 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
) {
GridCacheContext cacheCtx = entry.context();
- List<ClusterNode> nodes = cacheCtx.affinity().nodes(entry.key(), topVer);
+ List<ClusterNode> nodes;
+
+ GridCacheEntryEx cached0 = entry.cached();
+
+ if (cached0.isDht())
+ nodes = cacheCtx.affinity().nodes(cached0.partition(), topVer);
+ else
+ nodes = cacheCtx.affinity().nodes(entry.key(), topVer);
txMapping.addMapping(nodes);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
index fd9183e..6b7244a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
@@ -20,13 +20,11 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
-import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.util.lang.GridPlainRunnable;
import org.apache.ignite.internal.util.typedef.CI1;
-import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
/**
@@ -75,56 +73,14 @@ public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearT
* @return Topology ready future.
*/
protected final GridDhtTopologyFuture topologyReadLock() {
- if (tx.activeCacheIds().isEmpty())
- return cctx.exchange().lastTopologyFuture();
-
- GridCacheContext<?, ?> nonLocCtx = null;
-
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (!cacheCtx.isLocal()) {
- nonLocCtx = cacheCtx;
-
- break;
- }
- }
-
- if (nonLocCtx == null)
- return cctx.exchange().lastTopologyFuture();
-
- nonLocCtx.topology().readLock();
-
- if (nonLocCtx.topology().stopping()) {
- onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
- nonLocCtx.name()));
-
- return null;
- }
-
- return nonLocCtx.topology().topologyVersionFuture();
+ return tx.txState().topologyReadLock(cctx, this);
}
/**
* Releases topology read lock.
*/
protected final void topologyReadUnlock() {
- if (!tx.activeCacheIds().isEmpty()) {
- GridCacheContext<?, ?> nonLocCtx = null;
-
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (!cacheCtx.isLocal()) {
- nonLocCtx = cacheCtx;
-
- break;
- }
- }
-
- if (nonLocCtx != null)
- nonLocCtx.topology().readUnlock();
- }
+ tx.txState().topologyReadUnlock(cctx);
}
/**
@@ -160,28 +116,10 @@ public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearT
}
if (topVer != null) {
- StringBuilder invalidCaches = null;
-
- for (Integer cacheId : tx.activeCacheIds()) {
- GridCacheContext ctx = cctx.cacheContext(cacheId);
-
- assert ctx != null : cacheId;
-
- Throwable err = topFut.validateCache(ctx);
-
- if (err != null) {
- if (invalidCaches != null)
- invalidCaches.append(", ");
- else
- invalidCaches = new StringBuilder();
-
- invalidCaches.append(U.maskName(ctx.name()));
- }
- }
+ IgniteCheckedException err = tx.txState().validateTopology(cctx, topFut);
- if (invalidCaches != null) {
- onDone(new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
- invalidCaches.toString()));
+ if (err != null) {
+ onDone(err);
return;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
index 11d31b2..1554a62 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
@@ -200,7 +200,6 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
m.near(),
txMapping.transactionNodes(),
true,
- txMapping.transactionNodes().get(node.id()),
tx.onePhaseCommit(),
tx.needReturnValue() && tx.implicit(),
tx.implicitSingle(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
index 5ab85b2..e8546ef 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
@@ -315,7 +315,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
nodeId,
req.nearNodeId(),
req.nearXidVersion(),
- req.threadId(),
req.version(),
null,
ctx.systemTx(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index a9dbda2..31aa8c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@ -88,7 +88,7 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
private boolean commit;
/** Node mappings. */
- private Map<UUID, GridDistributedTxMapping> mappings;
+ private IgniteTxMappings mappings;
/** Trackable flag. */
private boolean trackable = true;
@@ -347,8 +347,16 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
try {
if (tx.finish(commit) || (!commit && tx.state() == UNKNOWN)) {
- if ((tx.onePhaseCommit() && needFinishOnePhase()) || (!tx.onePhaseCommit() && mappings != null))
- finish(mappings.values());
+ if ((tx.onePhaseCommit() && needFinishOnePhase()) || (!tx.onePhaseCommit() && mappings != null)) {
+ if (mappings.single()) {
+ GridDistributedTxMapping mapping = mappings.singleMapping();
+
+ if (mapping != null)
+ finish(mapping);
+ }
+ else
+ finish(mappings.mappings());
+ }
markInitialized();
@@ -381,11 +389,10 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
*
*/
private void checkBackup() {
- assert mappings.size() <= 1;
+ GridDistributedTxMapping mapping = mappings.singleMapping();
- for (Map.Entry<UUID, GridDistributedTxMapping> entry : mappings.entrySet()) {
- UUID nodeId = entry.getKey();
- GridDistributedTxMapping mapping = entry.getValue();
+ if (mapping != null) {
+ UUID nodeId = mapping.node().id();
Collection<UUID> backups = tx.transactionNodes().get(nodeId);
@@ -482,25 +489,13 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
*
*/
private boolean needFinishOnePhase() {
- if (F.isEmpty(tx.mappings()))
+ if (tx.mappings().empty())
return false;
- assert tx.mappings().size() == 1;
-
- boolean finish = false;
-
- for (Integer cacheId : tx.activeCacheIds()) {
- GridCacheContext<K, V> cacheCtx = cctx.cacheContext(cacheId);
-
- if (cacheCtx.isNear()) {
- finish = true;
-
- break;
- }
- }
+ boolean finish = tx.txState().hasNearCache(cctx);
if (finish) {
- GridDistributedTxMapping mapping = F.first(tx.mappings().values());
+ GridDistributedTxMapping mapping = tx.mappings().singleMapping();
if (FINISH_NEAR_ONE_PHASE_SINCE.compareTo(mapping.node().version()) > 0)
finish = false;
@@ -520,18 +515,16 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
finishOnePhaseCalled = true;
- // No need to send messages as transaction was already committed on remote node.
- // Finish local mapping only as we need send commit message to backups.
- for (GridDistributedTxMapping m : mappings.values()) {
- if (m.node().isLocal()) {
- IgniteInternalFuture<IgniteInternalTx> fut = cctx.tm().txHandler().finishColocatedLocal(commit, tx);
+ GridDistributedTxMapping locMapping = mappings.localMapping();
- // Add new future.
- if (fut != null)
- add(fut);
+ if (locMapping != null) {
+ // No need to send messages as transaction was already committed on remote node.
+ // Finish local mapping only as we need send commit message to backups.
+ IgniteInternalFuture<IgniteInternalTx> fut = cctx.tm().txHandler().finishColocatedLocal(commit, tx);
- break;
- }
+ // Add new future.
+ if (fut != null)
+ add(fut);
}
}
@@ -544,7 +537,9 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
mapping.dhtVersion(xidVer, xidVer);
- tx.readyNearLocks(mapping, Collections.<GridCacheVersion>emptyList(), Collections.<GridCacheVersion>emptyList(),
+ tx.readyNearLocks(mapping,
+ Collections.<GridCacheVersion>emptyList(),
+ Collections.<GridCacheVersion>emptyList(),
Collections.<GridCacheVersion>emptyList());
}
}
[02/51] ignite git commit: Ignite-1093 "Rebalancing with default
parameters is very slow" fixes.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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
new file mode 100644
index 0000000..865bad8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplier.java
@@ -0,0 +1,1034 @@
+/*
+ * 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.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryInfoCollectSwapListener;
+import org.apache.ignite.internal.processors.cache.GridCacheSwapEntry;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
+import org.apache.ignite.internal.util.lang.GridCloseableIterator;
+import org.apache.ignite.internal.util.typedef.CI2;
+import org.apache.ignite.internal.util.typedef.T3;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.spi.IgniteSpiException;
+
+import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
+
+/**
+ * Thread pool for supplying partitions to demanding nodes.
+ */
+class GridDhtPartitionSupplier {
+ /** */
+ private final GridCacheContext<?, ?> cctx;
+
+ /** */
+ private final IgniteLogger log;
+
+ /** */
+ private GridDhtPartitionTopology top;
+
+ /** */
+ private final boolean depEnabled;
+
+ /** Preload predicate. */
+ private IgnitePredicate<GridCacheEntryInfo> preloadPred;
+
+ /** Supply context map. T2: nodeId, idx, topVer. */
+ private final Map<T3<UUID, Integer, AffinityTopologyVersion>, SupplyContext> scMap = new HashMap<>();
+
+ /**
+ * @param cctx Cache context.
+ */
+ GridDhtPartitionSupplier(GridCacheContext<?, ?> cctx) {
+ assert cctx != null;
+
+ this.cctx = cctx;
+
+ log = cctx.logger(getClass());
+
+ top = cctx.dht().topology();
+
+ depEnabled = cctx.gridDeploy().enabled();
+ }
+
+ /**
+ *
+ */
+ void start() {
+ startOldListeners();
+ }
+
+ /**
+ *
+ */
+ void stop() {
+ synchronized (scMap) {
+ Iterator<T3<UUID, Integer, AffinityTopologyVersion>> it = scMap.keySet().iterator();
+
+ while (it.hasNext()) {
+ T3<UUID, Integer, AffinityTopologyVersion> t = it.next();
+
+ clearContext(scMap.get(t), log);
+
+ it.remove();
+ }
+ }
+
+ stopOldListeners();
+ }
+
+ /**
+ * Clear context.
+ *
+ * @param sc Supply context.
+ * @param log Logger.
+ * @return true in case context was removed.
+ */
+ private static void clearContext(
+ final SupplyContext sc,
+ final IgniteLogger log) {
+ if (sc != null) {
+ final Iterator it = sc.entryIt;
+
+ if (it != null && it instanceof GridCloseableIterator && !((GridCloseableIterator)it).isClosed()) {
+ try {
+ ((GridCloseableIterator)it).close();
+ }
+ catch (IgniteCheckedException e) {
+ log.error("Iterator close failed.", e);
+ }
+ }
+
+ final GridDhtLocalPartition loc = sc.loc;
+
+ if (loc != null) {
+ assert loc.reservations() > 0;
+
+ loc.release();
+ }
+ }
+ }
+
+ /**
+ * Handles new topology.
+ *
+ * @param topVer Topology version.
+ */
+ public void onTopologyChanged(AffinityTopologyVersion topVer) {
+ synchronized (scMap) {
+ Iterator<T3<UUID, Integer, AffinityTopologyVersion>> it = scMap.keySet().iterator();
+
+ while (it.hasNext()) {
+ T3<UUID, Integer, AffinityTopologyVersion> t = it.next();
+
+ if (topVer.compareTo(t.get3()) > 0) {// Clear all obsolete contexts.
+ clearContext(scMap.get(t), log);
+
+ it.remove();
+
+ if (log.isDebugEnabled())
+ log.debug("Supply context removed [node=" + t.get1() + "]");
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets preload predicate for supply pool.
+ *
+ * @param preloadPred Preload predicate.
+ */
+ void preloadPredicate(IgnitePredicate<GridCacheEntryInfo> preloadPred) {
+ this.preloadPred = preloadPred;
+ }
+
+ /**
+ * @param d Demand message.
+ * @param idx Index.
+ * @param id Node uuid.
+ */
+ public void handleDemandMessage(int idx, UUID id, GridDhtPartitionDemandMessage d) {
+ assert d != null;
+ assert id != null;
+
+ AffinityTopologyVersion cutTop = cctx.affinity().affinityTopologyVersion();
+ AffinityTopologyVersion demTop = d.topologyVersion();
+
+ T3<UUID, Integer, AffinityTopologyVersion> scId = new T3<>(id, idx, demTop);
+
+ if (d.updateSequence() == -1) {//Demand node requested context cleanup.
+ synchronized (scMap) {
+ clearContext(scMap.remove(scId), log);
+
+ return;
+ }
+ }
+
+ if (cutTop.compareTo(demTop) > 0) {
+ if (log.isDebugEnabled())
+ log.debug("Demand request cancelled [current=" + cutTop + ", demanded=" + demTop +
+ ", from=" + id + ", idx=" + idx + "]");
+
+ return;
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Demand request accepted [current=" + cutTop + ", demanded=" + demTop +
+ ", from=" + id + ", idx=" + idx + "]");
+
+ GridDhtPartitionSupplyMessageV2 s = new GridDhtPartitionSupplyMessageV2(
+ d.updateSequence(), cctx.cacheId(), d.topologyVersion(), cctx.deploymentEnabled());
+
+ ClusterNode node = cctx.discovery().node(id);
+
+ if (node == null)
+ return; //Context will be cleaned at topology change.
+
+ try {
+ SupplyContext sctx;
+
+ synchronized (scMap) {
+ sctx = scMap.remove(scId);
+
+ assert sctx == null || d.updateSequence() == sctx.updateSeq;
+ }
+
+ // Initial demand request should contain partitions list.
+ if (sctx == null && d.partitions() == null)
+ return;
+
+ assert !(sctx != null && d.partitions() != null);
+
+ long bCnt = 0;
+
+ SupplyContextPhase phase = SupplyContextPhase.NEW;
+
+ boolean newReq = true;
+
+ long maxBatchesCnt = cctx.config().getRebalanceBatchesPrefetchCount();
+
+ if (sctx != null) {
+ phase = sctx.phase;
+
+ maxBatchesCnt = 1;
+ }
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Starting supplying rebalancing [cache=" + cctx.name() +
+ ", fromNode=" + node.id() + ", partitionsCount=" + d.partitions().size() +
+ ", topology=" + d.topologyVersion() + ", updateSeq=" + d.updateSequence() +
+ ", idx=" + idx + "]");
+ }
+
+ Iterator<Integer> partIt = sctx != null ? sctx.partIt : d.partitions().iterator();
+
+ while ((sctx != null && newReq) || partIt.hasNext()) {
+ int part = sctx != null && newReq ? sctx.part : partIt.next();
+
+ newReq = false;
+
+ GridDhtLocalPartition loc;
+
+ if (sctx != null && sctx.loc != null) {
+ loc = sctx.loc;
+
+ assert loc.reservations() > 0;
+ }
+ else {
+ loc = top.localPartition(part, d.topologyVersion(), false);
+
+ if (loc == null || loc.state() != OWNING || !loc.reserve()) {
+ // Reply with partition of "-1" to let sender know that
+ // this node is no longer an owner.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Requested partition is not owned by local node [part=" + part +
+ ", demander=" + id + ']');
+
+ continue;
+ }
+ }
+
+ GridCacheEntryInfoCollectSwapListener swapLsnr = null;
+
+ try {
+ if (phase == SupplyContextPhase.NEW && cctx.isSwapOrOffheapEnabled()) {
+ swapLsnr = new GridCacheEntryInfoCollectSwapListener(log);
+
+ cctx.swap().addOffHeapListener(part, swapLsnr);
+ cctx.swap().addSwapListener(part, swapLsnr);
+ }
+
+ boolean partMissing = false;
+
+ if (phase == SupplyContextPhase.NEW)
+ phase = SupplyContextPhase.ONHEAP;
+
+ if (phase == SupplyContextPhase.ONHEAP) {
+ Iterator<GridDhtCacheEntry> entIt = sctx != null ?
+ (Iterator<GridDhtCacheEntry>)sctx.entryIt : loc.entries().iterator();
+
+ while (entIt.hasNext()) {
+ if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+ // Demander no longer needs this partition, so we send '-1' partition and move on.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Demanding node does not need requested partition [part=" + part +
+ ", nodeId=" + id + ']');
+
+ partMissing = true;
+
+ break;
+ }
+
+ if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
+ if (++bCnt >= maxBatchesCnt) {
+ saveSupplyContext(scId,
+ phase,
+ partIt,
+ part,
+ entIt,
+ swapLsnr,
+ loc,
+ d.topologyVersion(),
+ d.updateSequence());
+
+ swapLsnr = null;
+ loc = null;
+
+ reply(node, d, s, scId);
+
+ return;
+ }
+ else {
+ if (!reply(node, d, s, scId))
+ return;
+
+ s = new GridDhtPartitionSupplyMessageV2(d.updateSequence(),
+ cctx.cacheId(), d.topologyVersion(), cctx.deploymentEnabled());
+ }
+ }
+
+ GridCacheEntryEx e = entIt.next();
+
+ GridCacheEntryInfo info = e.info();
+
+ if (info != null && !info.isNew()) {
+ if (preloadPred == null || preloadPred.apply(info))
+ s.addEntry(part, info, cctx);
+ else if (log.isDebugEnabled())
+ log.debug("Rebalance predicate evaluated to false (will not sender cache entry): " +
+ info);
+ }
+ }
+
+ if (partMissing)
+ continue;
+
+ }
+
+ if (phase == SupplyContextPhase.ONHEAP) {
+ phase = SupplyContextPhase.SWAP;
+
+ if (sctx != null) {
+ sctx = new SupplyContext(
+ phase,
+ partIt,
+ null,
+ swapLsnr,
+ part,
+ loc,
+ d.updateSequence());
+ }
+ }
+
+ if (phase == SupplyContextPhase.SWAP && cctx.isSwapOrOffheapEnabled()) {
+ GridCloseableIterator<Map.Entry<byte[], GridCacheSwapEntry>> iter =
+ sctx != null && sctx.entryIt != null ?
+ (GridCloseableIterator<Map.Entry<byte[], GridCacheSwapEntry>>)sctx.entryIt :
+ cctx.swap().iterator(part);
+
+ // Iterator may be null if space does not exist.
+ if (iter != null) {
+ boolean prepared = false;
+
+ while (iter.hasNext()) {
+ if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+ // Demander no longer needs this partition,
+ // so we send '-1' partition and move on.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Demanding node does not need requested partition " +
+ "[part=" + part + ", nodeId=" + id + ']');
+
+ partMissing = true;
+
+ break; // For.
+ }
+
+ if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
+ if (++bCnt >= maxBatchesCnt) {
+ saveSupplyContext(scId,
+ phase,
+ partIt,
+ part,
+ iter,
+ swapLsnr,
+ loc,
+ d.topologyVersion(),
+ d.updateSequence());
+
+ swapLsnr = null;
+ loc = null;
+
+ reply(node, d, s, scId);
+
+ return;
+ }
+ else {
+ if (!reply(node, d, s, scId))
+ return;
+
+ s = new GridDhtPartitionSupplyMessageV2(d.updateSequence(),
+ cctx.cacheId(), d.topologyVersion(), cctx.deploymentEnabled());
+ }
+ }
+
+ Map.Entry<byte[], GridCacheSwapEntry> e = iter.next();
+
+ GridCacheSwapEntry swapEntry = e.getValue();
+
+ GridCacheEntryInfo info = new GridCacheEntryInfo();
+
+ info.keyBytes(e.getKey());
+ info.ttl(swapEntry.ttl());
+ info.expireTime(swapEntry.expireTime());
+ info.version(swapEntry.version());
+ info.value(swapEntry.value());
+
+ if (preloadPred == null || preloadPred.apply(info))
+ s.addEntry0(part, info, cctx);
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Rebalance predicate evaluated to false (will not send " +
+ "cache entry): " + info);
+
+ continue;
+ }
+
+ // Need to manually prepare cache message.
+ if (depEnabled && !prepared) {
+ ClassLoader ldr = swapEntry.keyClassLoaderId() != null ?
+ cctx.deploy().getClassLoader(swapEntry.keyClassLoaderId()) :
+ swapEntry.valueClassLoaderId() != null ?
+ cctx.deploy().getClassLoader(swapEntry.valueClassLoaderId()) :
+ null;
+
+ if (ldr == null)
+ continue;
+
+ if (ldr instanceof GridDeploymentInfo) {
+ s.prepare((GridDeploymentInfo)ldr);
+
+ prepared = true;
+ }
+ }
+ }
+
+ iter.close();
+
+ if (partMissing)
+ continue;
+ }
+ }
+
+ if (swapLsnr == null && sctx != null)
+ swapLsnr = sctx.swapLsnr;
+
+ // Stop receiving promote notifications.
+ if (swapLsnr != null) {
+ cctx.swap().removeOffHeapListener(part, swapLsnr);
+ cctx.swap().removeSwapListener(part, swapLsnr);
+ }
+
+ if (phase == SupplyContextPhase.SWAP) {
+ phase = SupplyContextPhase.EVICTED;
+
+ if (sctx != null) {
+ sctx = new SupplyContext(
+ phase,
+ partIt,
+ null,
+ null,
+ part,
+ loc,
+ d.updateSequence());
+ }
+ }
+
+ if (phase == SupplyContextPhase.EVICTED && swapLsnr != null) {
+ Collection<GridCacheEntryInfo> entries = swapLsnr.entries();
+
+ swapLsnr = null;
+
+ Iterator<GridCacheEntryInfo> lsnrIt = sctx != null && sctx.entryIt != null ?
+ (Iterator<GridCacheEntryInfo>)sctx.entryIt : entries.iterator();
+
+ while (lsnrIt.hasNext()) {
+ if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+ // Demander no longer needs this partition,
+ // so we send '-1' partition and move on.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Demanding node does not need requested partition " +
+ "[part=" + part + ", nodeId=" + id + ']');
+
+ // No need to continue iteration over swap entries.
+ break;
+ }
+
+ if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
+ if (++bCnt >= maxBatchesCnt) {
+ saveSupplyContext(scId,
+ phase,
+ partIt,
+ part,
+ lsnrIt,
+ swapLsnr,
+ loc,
+ d.topologyVersion(),
+ d.updateSequence());
+
+ loc = null;
+
+ reply(node, d, s, scId);
+
+ return;
+ }
+ else {
+ if (!reply(node, d, s, scId))
+ return;
+
+ s = new GridDhtPartitionSupplyMessageV2(d.updateSequence(),
+ cctx.cacheId(), d.topologyVersion(), cctx.deploymentEnabled());
+ }
+ }
+
+ GridCacheEntryInfo info = lsnrIt.next();
+
+ if (preloadPred == null || preloadPred.apply(info))
+ s.addEntry(part, info, cctx);
+ else if (log.isDebugEnabled())
+ log.debug("Rebalance predicate evaluated to false (will not sender cache entry): " +
+ info);
+ }
+ }
+
+ // Mark as last supply message.
+ s.last(part);
+
+ phase = SupplyContextPhase.NEW;
+
+ sctx = null;
+ }
+ finally {
+ if (loc != null)
+ loc.release();
+
+ if (swapLsnr != null) {
+ cctx.swap().removeOffHeapListener(part, swapLsnr);
+ cctx.swap().removeSwapListener(part, swapLsnr);
+ }
+ }
+ }
+
+ reply(node, d, s, scId);
+
+ if (log.isDebugEnabled())
+ log.debug("Finished supplying rebalancing [cache=" + cctx.name() +
+ ", fromNode=" + node.id() +
+ ", topology=" + d.topologyVersion() + ", updateSeq=" + d.updateSequence() +
+ ", idx=" + idx + "]");
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to send partition supply message to node: " + id, e);
+ }
+ catch (IgniteSpiException e) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send message to node (current node is stopping?) [node=" + node.id() +
+ ", msg=" + e.getMessage() + ']');
+ }
+ }
+
+ /**
+ * @param n Node.
+ * @param d DemandMessage
+ * @param s Supply message.
+ * @return {@code True} if message was sent, {@code false} if recipient left grid.
+ * @throws IgniteCheckedException If failed.
+ */
+ private boolean reply(ClusterNode n,
+ GridDhtPartitionDemandMessage d,
+ GridDhtPartitionSupplyMessageV2 s,
+ T3<UUID, Integer, AffinityTopologyVersion> scId)
+ throws IgniteCheckedException {
+
+ try {
+ if (log.isDebugEnabled())
+ log.debug("Replying to partition demand [node=" + n.id() + ", demand=" + d + ", supply=" + s + ']');
+
+ cctx.io().sendOrderedMessage(n, d.topic(), s, cctx.ioPolicy(), d.timeout());
+
+ // Throttle preloading.
+ if (cctx.config().getRebalanceThrottle() > 0)
+ U.sleep(cctx.config().getRebalanceThrottle());
+
+ return true;
+ }
+ catch (ClusterTopologyCheckedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send partition supply message because node left grid: " + n.id());
+
+ synchronized (scMap) {
+ clearContext(scMap.remove(scId), log);
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * @param t Tuple.
+ * @param phase Phase.
+ * @param partIt Partition it.
+ * @param part Partition.
+ * @param entryIt Entry it.
+ * @param swapLsnr Swap listener.
+ */
+ private void saveSupplyContext(
+ T3<UUID, Integer, AffinityTopologyVersion> t,
+ SupplyContextPhase phase,
+ Iterator<Integer> partIt,
+ int part,
+ Iterator<?> entryIt, GridCacheEntryInfoCollectSwapListener swapLsnr,
+ GridDhtLocalPartition loc,
+ AffinityTopologyVersion topVer,
+ long updateSeq) {
+ synchronized (scMap) {
+ if (cctx.affinity().affinityTopologyVersion().equals(topVer)) {
+ assert scMap.get(t) == null;
+
+ scMap.put(t,
+ new SupplyContext(phase,
+ partIt,
+ entryIt,
+ swapLsnr,
+ part,
+ loc,
+ updateSeq));
+ }
+ else if (loc != null) {
+ assert loc.reservations() > 0;
+
+ loc.release();
+ }
+ }
+ }
+
+ /**
+ * Supply context phase.
+ */
+ private enum SupplyContextPhase {
+ NEW,
+ ONHEAP,
+ SWAP,
+ EVICTED
+ }
+
+ /**
+ * Supply context.
+ */
+ private static class SupplyContext {
+ /** Phase. */
+ private final SupplyContextPhase phase;
+
+ /** Partition iterator. */
+ private final Iterator<Integer> partIt;
+
+ /** Entry iterator. */
+ private final Iterator<?> entryIt;
+
+ /** Swap listener. */
+ private final GridCacheEntryInfoCollectSwapListener swapLsnr;
+
+ /** Partition. */
+ private final int part;
+
+ /** Local partition. */
+ private final GridDhtLocalPartition loc;
+
+ /** Update seq. */
+ private final long updateSeq;
+
+ /**
+ * @param phase Phase.
+ * @param partIt Partition iterator.
+ * @param entryIt Entry iterator.
+ * @param swapLsnr Swap listener.
+ * @param part Partition.
+ */
+ public SupplyContext(SupplyContextPhase phase,
+ Iterator<Integer> partIt,
+ Iterator<?> entryIt,
+ GridCacheEntryInfoCollectSwapListener swapLsnr,
+ int part,
+ GridDhtLocalPartition loc,
+ long updateSeq) {
+ this.phase = phase;
+ this.partIt = partIt;
+ this.entryIt = entryIt;
+ this.swapLsnr = swapLsnr;
+ this.part = part;
+ this.loc = loc;
+ this.updateSeq = updateSeq;
+ }
+ }
+
+ @Deprecated//Backward compatibility. To be removed in future.
+ public void startOldListeners() {
+ if (!cctx.kernalContext().clientNode() && cctx.rebalanceEnabled()) {
+ cctx.io().addHandler(cctx.cacheId(), GridDhtPartitionDemandMessage.class, new CI2<UUID, GridDhtPartitionDemandMessage>() {
+ @Override public void apply(UUID id, GridDhtPartitionDemandMessage m) {
+ processOldDemandMessage(m, id);
+ }
+ });
+ }
+ }
+
+ @Deprecated//Backward compatibility. To be removed in future.
+ public void stopOldListeners() {
+ if (!cctx.kernalContext().clientNode() && cctx.rebalanceEnabled()) {
+
+ cctx.io().removeHandler(cctx.cacheId(), GridDhtPartitionDemandMessage.class);
+ }
+ }
+
+ /**
+ * @param d D.
+ * @param id Id.
+ */
+ @Deprecated//Backward compatibility. To be removed in future.
+ private void processOldDemandMessage(GridDhtPartitionDemandMessage d, UUID id) {
+ GridDhtPartitionSupplyMessage s = new GridDhtPartitionSupplyMessage(d.workerId(),
+ d.updateSequence(), cctx.cacheId(), cctx.deploymentEnabled());
+
+ ClusterNode node = cctx.node(id);
+
+ long preloadThrottle = cctx.config().getRebalanceThrottle();
+
+ boolean ack = false;
+
+ try {
+ for (int part : d.partitions()) {
+ GridDhtLocalPartition loc = top.localPartition(part, d.topologyVersion(), false);
+
+ if (loc == null || loc.state() != OWNING || !loc.reserve()) {
+ // Reply with partition of "-1" to let sender know that
+ // this node is no longer an owner.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Requested partition is not owned by local node [part=" + part +
+ ", demander=" + id + ']');
+
+ continue;
+ }
+
+ GridCacheEntryInfoCollectSwapListener swapLsnr = null;
+
+ try {
+ if (cctx.isSwapOrOffheapEnabled()) {
+ swapLsnr = new GridCacheEntryInfoCollectSwapListener(log);
+
+ cctx.swap().addOffHeapListener(part, swapLsnr);
+ cctx.swap().addSwapListener(part, swapLsnr);
+ }
+
+ boolean partMissing = false;
+
+ for (GridCacheEntryEx e : loc.entries()) {
+ if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+ // Demander no longer needs this partition, so we send '-1' partition and move on.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Demanding node does not need requested partition [part=" + part +
+ ", nodeId=" + id + ']');
+
+ partMissing = true;
+
+ break;
+ }
+
+ if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
+ ack = true;
+
+ if (!replyOld(node, d, s))
+ return;
+
+ // Throttle preloading.
+ if (preloadThrottle > 0)
+ U.sleep(preloadThrottle);
+
+ s = new GridDhtPartitionSupplyMessage(d.workerId(), d.updateSequence(),
+ cctx.cacheId(), cctx.deploymentEnabled());
+ }
+
+ GridCacheEntryInfo info = e.info();
+
+ if (info != null && !info.isNew()) {
+ if (preloadPred == null || preloadPred.apply(info))
+ s.addEntry(part, info, cctx);
+ else if (log.isDebugEnabled())
+ log.debug("Rebalance predicate evaluated to false (will not sender cache entry): " +
+ info);
+ }
+ }
+
+ if (partMissing)
+ continue;
+
+ if (cctx.isSwapOrOffheapEnabled()) {
+ GridCloseableIterator<Map.Entry<byte[], GridCacheSwapEntry>> iter =
+ cctx.swap().iterator(part);
+
+ // Iterator may be null if space does not exist.
+ if (iter != null) {
+ try {
+ boolean prepared = false;
+
+ for (Map.Entry<byte[], GridCacheSwapEntry> e : iter) {
+ if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+ // Demander no longer needs this partition,
+ // so we send '-1' partition and move on.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Demanding node does not need requested partition " +
+ "[part=" + part + ", nodeId=" + id + ']');
+
+ partMissing = true;
+
+ break; // For.
+ }
+
+ if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
+ ack = true;
+
+ if (!replyOld(node, d, s))
+ return;
+
+ // Throttle preloading.
+ if (preloadThrottle > 0)
+ U.sleep(preloadThrottle);
+
+ s = new GridDhtPartitionSupplyMessage(d.workerId(),
+ d.updateSequence(), cctx.cacheId(), cctx.deploymentEnabled());
+ }
+
+ GridCacheSwapEntry swapEntry = e.getValue();
+
+ GridCacheEntryInfo info = new GridCacheEntryInfo();
+
+ info.keyBytes(e.getKey());
+ info.ttl(swapEntry.ttl());
+ info.expireTime(swapEntry.expireTime());
+ info.version(swapEntry.version());
+ info.value(swapEntry.value());
+
+ if (preloadPred == null || preloadPred.apply(info))
+ s.addEntry0(part, info, cctx);
+ else {
+ if (log.isDebugEnabled())
+ log.debug("Rebalance predicate evaluated to false (will not send " +
+ "cache entry): " + info);
+
+ continue;
+ }
+
+ // Need to manually prepare cache message.
+ if (depEnabled && !prepared) {
+ ClassLoader ldr = swapEntry.keyClassLoaderId() != null ?
+ cctx.deploy().getClassLoader(swapEntry.keyClassLoaderId()) :
+ swapEntry.valueClassLoaderId() != null ?
+ cctx.deploy().getClassLoader(swapEntry.valueClassLoaderId()) :
+ null;
+
+ if (ldr == null)
+ continue;
+
+ if (ldr instanceof GridDeploymentInfo) {
+ s.prepare((GridDeploymentInfo)ldr);
+
+ prepared = true;
+ }
+ }
+ }
+
+ if (partMissing)
+ continue;
+ }
+ finally {
+ iter.close();
+ }
+ }
+ }
+
+ // Stop receiving promote notifications.
+ if (swapLsnr != null) {
+ cctx.swap().removeOffHeapListener(part, swapLsnr);
+ cctx.swap().removeSwapListener(part, swapLsnr);
+ }
+
+ if (swapLsnr != null) {
+ Collection<GridCacheEntryInfo> entries = swapLsnr.entries();
+
+ swapLsnr = null;
+
+ for (GridCacheEntryInfo info : entries) {
+ if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
+ // Demander no longer needs this partition,
+ // so we send '-1' partition and move on.
+ s.missed(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Demanding node does not need requested partition " +
+ "[part=" + part + ", nodeId=" + id + ']');
+
+ // No need to continue iteration over swap entries.
+ break;
+ }
+
+ if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
+ ack = true;
+
+ if (!replyOld(node, d, s))
+ return;
+
+ s = new GridDhtPartitionSupplyMessage(d.workerId(),
+ d.updateSequence(),
+ cctx.cacheId(),
+ cctx.deploymentEnabled());
+ }
+
+ if (preloadPred == null || preloadPred.apply(info))
+ s.addEntry(part, info, cctx);
+ else if (log.isDebugEnabled())
+ log.debug("Rebalance predicate evaluated to false (will not sender cache entry): " +
+ info);
+ }
+ }
+
+ // Mark as last supply message.
+ s.last(part);
+
+ if (ack) {
+ s.markAck();
+
+ break; // Partition for loop.
+ }
+ }
+ finally {
+ loc.release();
+
+ if (swapLsnr != null) {
+ cctx.swap().removeOffHeapListener(part, swapLsnr);
+ cctx.swap().removeSwapListener(part, swapLsnr);
+ }
+ }
+ }
+
+ replyOld(node, d, s);
+ }
+ catch (IgniteCheckedException e) {
+ U.error(log, "Failed to send partition supply message to node: " + node.id(), e);
+ }
+ }
+
+ /**
+ * @param n Node.
+ * @param d Demand message.
+ * @param s Supply message.
+ * @return {@code True} if message was sent, {@code false} if recipient left grid.
+ * @throws IgniteCheckedException If failed.
+ */
+ @Deprecated//Backward compatibility. To be removed in future.
+ private boolean replyOld(ClusterNode n, GridDhtPartitionDemandMessage d, GridDhtPartitionSupplyMessage s)
+ throws IgniteCheckedException {
+ try {
+ if (log.isDebugEnabled())
+ log.debug("Replying to partition demand [node=" + n.id() + ", demand=" + d + ", supply=" + s + ']');
+
+ cctx.io().sendOrderedMessage(n, d.topic(), s, cctx.ioPolicy(), d.timeout());
+
+ return true;
+ }
+ catch (ClusterTopologyCheckedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send partition supply message because node left grid: " + n.id());
+
+ return false;
+ }
+ }
+
+ /**
+ * Dumps debug information.
+ */
+ public void dumpDebugInfo() {
+ synchronized (scMap) {
+ if (!scMap.isEmpty()) {
+ U.warn(log, "Rebalancing supplier reserved following partitions:");
+
+ for (SupplyContext sc : scMap.values()) {
+ if (sc.loc != null)
+ U.warn(log, ">>> " + sc.loc);
+ }
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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
new file mode 100644
index 0000000..41454f9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyMessageV2.java
@@ -0,0 +1,380 @@
+/*
+ * 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.Externalizable;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.GridDirectCollection;
+import org.apache.ignite.internal.GridDirectMap;
+import org.apache.ignite.internal.GridDirectTransient;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
+import org.apache.ignite.internal.processors.cache.GridCacheMessage;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+
+/**
+ * Partition supply message.
+ */
+public class GridDhtPartitionSupplyMessageV2 extends GridCacheMessage implements GridCacheDeployable {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** Update sequence. */
+ private long updateSeq;
+
+ /** Topology version. */
+ private AffinityTopologyVersion topVer;
+
+ /** Partitions that have been fully sent. */
+ @GridDirectCollection(int.class)
+ private Collection<Integer> last;
+
+ /** Partitions which were not found. */
+ @GridToStringInclude
+ @GridDirectCollection(int.class)
+ private Collection<Integer> missed;
+
+ /** Entries. */
+ @GridDirectMap(keyType = int.class, valueType = CacheEntryInfoCollection.class)
+ private Map<Integer, CacheEntryInfoCollection> infos;
+
+ /** Message size. */
+ @GridDirectTransient
+ private int msgSize;
+
+ /**
+ * @param updateSeq Update sequence for this node.
+ * @param cacheId Cache ID.
+ * @param addDepInfo Deployment info flag.
+ */
+ GridDhtPartitionSupplyMessageV2(long updateSeq, int cacheId, AffinityTopologyVersion topVer, boolean addDepInfo) {
+ this.cacheId = cacheId;
+ this.updateSeq = updateSeq;
+ this.topVer = topVer;
+ this.addDepInfo = addDepInfo; }
+
+ /**
+ * Empty constructor required for {@link Externalizable}.
+ */
+ public GridDhtPartitionSupplyMessageV2() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean ignoreClassErrors() {
+ return true;
+ }
+
+ /**
+ * @return Update sequence.
+ */
+ long updateSequence() {
+ return updateSeq;
+ }
+
+ /**
+ * @return Topology version for which demand message is sent.
+ */
+ @Override public AffinityTopologyVersion topologyVersion() {
+ return topVer;
+ }
+
+ /**
+ * @return Flag to indicate last message for partition.
+ */
+ Collection<Integer> last() {
+ return last == null ? Collections.<Integer>emptySet() : last;
+ }
+
+ /**
+ * @param p Partition which was fully sent.
+ */
+ void last(int p) {
+ if (last == null)
+ last = new HashSet<>();
+
+ if (last.add(p)) {
+ msgSize += 4;
+
+ // If partition is empty, we need to add it.
+ if (!infos().containsKey(p)) {
+ CacheEntryInfoCollection infoCol = new CacheEntryInfoCollection();
+
+ infoCol.init();
+
+ infos().put(p, infoCol);
+ }
+ }
+ }
+
+ /**
+ * @param p Missed partition.
+ */
+ void missed(int p) {
+ if (missed == null)
+ missed = new HashSet<>();
+
+ if (missed.add(p))
+ msgSize += 4;
+ }
+
+ /**
+ * @return Missed partitions.
+ */
+ Collection<Integer> missed() {
+ return missed == null ? Collections.<Integer>emptySet() : missed;
+ }
+
+ /**
+ * @return Entries.
+ */
+ Map<Integer, CacheEntryInfoCollection> infos() {
+ if (infos == null)
+ infos = new HashMap<>();
+
+ return infos;
+ }
+
+ /**
+ * @return Message size.
+ */
+ int messageSize() {
+ return msgSize;
+ }
+
+ /**
+ * @param p Partition.
+ * @param info Entry to add.
+ * @param ctx Cache context.
+ * @throws IgniteCheckedException If failed.
+ */
+ void addEntry(int p, GridCacheEntryInfo info, GridCacheContext ctx) throws IgniteCheckedException {
+ assert info != null;
+
+ marshalInfo(info, ctx);
+
+ msgSize += info.marshalledSize(ctx);
+
+ CacheEntryInfoCollection infoCol = infos().get(p);
+
+ if (infoCol == null) {
+ msgSize += 4;
+
+ infos().put(p, infoCol = new CacheEntryInfoCollection());
+
+ infoCol.init();
+ }
+
+ infoCol.add(info);
+ }
+
+ /**
+ * @param p Partition.
+ * @param info Entry to add.
+ * @param ctx Cache context.
+ * @throws IgniteCheckedException If failed.
+ */
+ 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);
+
+ msgSize += info.marshalledSize(ctx);
+
+ CacheEntryInfoCollection infoCol = infos().get(p);
+
+ if (infoCol == null) {
+ msgSize += 4;
+
+ infos().put(p, infoCol = new CacheEntryInfoCollection());
+
+ infoCol.init();
+ }
+
+ infoCol.add(info);
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException {
+ super.finishUnmarshal(ctx, ldr);
+
+ GridCacheContext cacheCtx = ctx.cacheContext(cacheId);
+
+ for (CacheEntryInfoCollection col : infos().values()) {
+ List<GridCacheEntryInfo> entries = col.infos();
+
+ for (int i = 0; i < entries.size(); i++)
+ entries.get(i).unmarshal(cacheCtx, ldr);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean addDeploymentInfo() {
+ return addDepInfo;
+ }
+
+ /**
+ * @return Number of entries in message.
+ */
+ public int size() {
+ return infos().size();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean writeTo(ByteBuffer buf, MessageWriter writer) {
+ writer.setBuffer(buf);
+
+ if (!super.writeTo(buf, writer))
+ return false;
+
+ if (!writer.isHeaderWritten()) {
+ if (!writer.writeHeader(directType(), fieldsCount()))
+ return false;
+
+ writer.onHeaderWritten();
+ }
+
+ switch (writer.state()) {
+ case 3:
+ if (!writer.writeMap("infos", infos, MessageCollectionItemType.INT, MessageCollectionItemType.MSG))
+ return false;
+
+ writer.incrementState();
+
+ case 4:
+ if (!writer.writeCollection("last", last, MessageCollectionItemType.INT))
+ return false;
+
+ writer.incrementState();
+
+ case 5:
+ if (!writer.writeCollection("missed", missed, MessageCollectionItemType.INT))
+ return false;
+
+ writer.incrementState();
+
+ case 6:
+ if (!writer.writeMessage("topVer", topVer))
+ return false;
+
+ writer.incrementState();
+
+ case 7:
+ if (!writer.writeLong("updateSeq", updateSeq))
+ return false;
+
+ writer.incrementState();
+
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean readFrom(ByteBuffer buf, MessageReader reader) {
+ reader.setBuffer(buf);
+
+ if (!reader.beforeMessageRead())
+ return false;
+
+ if (!super.readFrom(buf, reader))
+ return false;
+
+ switch (reader.state()) {
+ case 3:
+ infos = reader.readMap("infos", MessageCollectionItemType.INT, MessageCollectionItemType.MSG, false);
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 4:
+ last = reader.readCollection("last", MessageCollectionItemType.INT);
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 5:
+ missed = reader.readCollection("missed", MessageCollectionItemType.INT);
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 6:
+ topVer = reader.readMessage("topVer");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 7:
+ updateSeq = reader.readLong("updateSeq");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ }
+
+ return reader.afterMessageRead(GridDhtPartitionSupplyMessageV2.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte directType() {
+ return 114;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte fieldsCount() {
+ return 8;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridDhtPartitionSupplyMessageV2.class, this,
+ "size", size(),
+ "parts", infos().keySet(),
+ "super", super.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
deleted file mode 100644
index 28a73b1..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionSupplyPool.java
+++ /dev/null
@@ -1,555 +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.processors.cache.distributed.dht.preloader;
-
-import java.io.Externalizable;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.locks.ReadWriteLock;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.IgniteLogger;
-import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.internal.IgniteInterruptedCheckedException;
-import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
-import org.apache.ignite.internal.managers.deployment.GridDeploymentInfo;
-import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryInfoCollectSwapListener;
-import org.apache.ignite.internal.processors.cache.GridCacheSwapEntry;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
-import org.apache.ignite.internal.util.lang.GridCloseableIterator;
-import org.apache.ignite.internal.util.typedef.CI2;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.internal.util.worker.GridWorker;
-import org.apache.ignite.lang.IgniteBiTuple;
-import org.apache.ignite.lang.IgnitePredicate;
-import org.apache.ignite.thread.IgniteThread;
-import org.jetbrains.annotations.Nullable;
-
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
-
-/**
- * Thread pool for supplying partitions to demanding nodes.
- */
-class GridDhtPartitionSupplyPool {
- /** */
- private final GridCacheContext<?, ?> cctx;
-
- /** */
- private final IgniteLogger log;
-
- /** */
- private final ReadWriteLock busyLock;
-
- /** */
- private GridDhtPartitionTopology top;
-
- /** */
- private final Collection<SupplyWorker> workers = new LinkedList<>();
-
- /** */
- private final BlockingQueue<DemandMessage> queue = new LinkedBlockingDeque<>();
-
- /** */
- private final boolean depEnabled;
-
- /** Preload predicate. */
- private IgnitePredicate<GridCacheEntryInfo> preloadPred;
-
- /**
- * @param cctx Cache context.
- * @param busyLock Shutdown lock.
- */
- GridDhtPartitionSupplyPool(GridCacheContext<?, ?> cctx, ReadWriteLock busyLock) {
- assert cctx != null;
- assert busyLock != null;
-
- this.cctx = cctx;
- this.busyLock = busyLock;
-
- log = cctx.logger(getClass());
-
- top = cctx.dht().topology();
-
- if (!cctx.kernalContext().clientNode()) {
- int poolSize = cctx.rebalanceEnabled() ? cctx.config().getRebalanceThreadPoolSize() : 0;
-
- for (int i = 0; i < poolSize; i++)
- workers.add(new SupplyWorker());
-
- cctx.io().addHandler(cctx.cacheId(), GridDhtPartitionDemandMessage.class, new CI2<UUID, GridDhtPartitionDemandMessage>() {
- @Override public void apply(UUID id, GridDhtPartitionDemandMessage m) {
- processDemandMessage(id, m);
- }
- });
- }
-
- depEnabled = cctx.gridDeploy().enabled();
- }
-
- /**
- *
- */
- void start() {
- for (SupplyWorker w : workers)
- new IgniteThread(cctx.gridName(), "preloader-supply-worker", w).start();
- }
-
- /**
- *
- */
- void stop() {
- U.cancel(workers);
- U.join(workers, log);
-
- top = null;
- }
-
- /**
- * Sets preload predicate for supply pool.
- *
- * @param preloadPred Preload predicate.
- */
- void preloadPredicate(IgnitePredicate<GridCacheEntryInfo> preloadPred) {
- this.preloadPred = preloadPred;
- }
-
- /**
- * @return Size of this thread pool.
- */
- int poolSize() {
- return cctx.config().getRebalanceThreadPoolSize();
- }
-
- /**
- * @return {@code true} if entered to busy state.
- */
- private boolean enterBusy() {
- if (busyLock.readLock().tryLock())
- return true;
-
- if (log.isDebugEnabled())
- log.debug("Failed to enter to busy state (supplier is stopping): " + cctx.nodeId());
-
- return false;
- }
-
- /**
- * @param nodeId Sender node ID.
- * @param d Message.
- */
- private void processDemandMessage(UUID nodeId, GridDhtPartitionDemandMessage d) {
- if (!enterBusy())
- return;
-
- try {
- if (cctx.rebalanceEnabled()) {
- if (log.isDebugEnabled())
- log.debug("Received partition demand [node=" + nodeId + ", demand=" + d + ']');
-
- queue.offer(new DemandMessage(nodeId, d));
- }
- else
- U.warn(log, "Received partition demand message when rebalancing is disabled (will ignore): " + d);
- }
- finally {
- leaveBusy();
- }
- }
-
- /**
- *
- */
- private void leaveBusy() {
- busyLock.readLock().unlock();
- }
-
- /**
- * @param deque Deque to poll from.
- * @param w Worker.
- * @return Polled item.
- * @throws InterruptedException If interrupted.
- */
- @Nullable private <T> T poll(BlockingQueue<T> deque, GridWorker w) throws InterruptedException {
- assert w != null;
-
- // There is currently a case where {@code interrupted}
- // flag on a thread gets flipped during stop which causes the pool to hang. This check
- // will always make sure that interrupted flag gets reset before going into wait conditions.
- // The true fix should actually make sure that interrupted flag does not get reset or that
- // interrupted exception gets propagated. Until we find a real fix, this method should
- // always work to make sure that there is no hanging during stop.
- if (w.isCancelled())
- Thread.currentThread().interrupt();
-
- return deque.poll(2000, MILLISECONDS);
- }
-
- /**
- * Supply work.
- */
- private class SupplyWorker extends GridWorker {
- /** Hide worker logger and use cache logger. */
- private IgniteLogger log = GridDhtPartitionSupplyPool.this.log;
-
- /**
- * Default constructor.
- */
- private SupplyWorker() {
- super(cctx.gridName(), "preloader-supply-worker", GridDhtPartitionSupplyPool.this.log);
- }
-
- /** {@inheritDoc} */
- @Override protected void body() throws InterruptedException, IgniteInterruptedCheckedException {
- while (!isCancelled()) {
- DemandMessage msg = poll(queue, this);
-
- if (msg == null)
- continue;
-
- ClusterNode node = cctx.discovery().node(msg.senderId());
-
- if (node == null) {
- if (log.isDebugEnabled())
- log.debug("Received message from non-existing node (will ignore): " + msg);
-
- continue;
- }
-
- processMessage(msg, node);
- }
- }
-
- /**
- * @param msg Message.
- * @param node Demander.
- */
- private void processMessage(DemandMessage msg, ClusterNode node) {
- assert msg != null;
- assert node != null;
-
- GridDhtPartitionDemandMessage d = msg.message();
-
- GridDhtPartitionSupplyMessage s = new GridDhtPartitionSupplyMessage(d.workerId(),
- d.updateSequence(), cctx.cacheId(), cctx.deploymentEnabled());
-
- long preloadThrottle = cctx.config().getRebalanceThrottle();
-
- boolean ack = false;
-
- try {
- for (int part : d.partitions()) {
- GridDhtLocalPartition loc = top.localPartition(part, d.topologyVersion(), false);
-
- if (loc == null || loc.state() != OWNING || !loc.reserve()) {
- // Reply with partition of "-1" to let sender know that
- // this node is no longer an owner.
- s.missed(part);
-
- if (log.isDebugEnabled())
- log.debug("Requested partition is not owned by local node [part=" + part +
- ", demander=" + msg.senderId() + ']');
-
- continue;
- }
-
- GridCacheEntryInfoCollectSwapListener swapLsnr = null;
-
- try {
- if (cctx.isSwapOrOffheapEnabled()) {
- swapLsnr = new GridCacheEntryInfoCollectSwapListener(log);
-
- cctx.swap().addOffHeapListener(part, swapLsnr);
- cctx.swap().addSwapListener(part, swapLsnr);
- }
-
- boolean partMissing = false;
-
- for (GridCacheEntryEx e : loc.entries()) {
- if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
- // Demander no longer needs this partition, so we send '-1' partition and move on.
- s.missed(part);
-
- if (log.isDebugEnabled())
- log.debug("Demanding node does not need requested partition [part=" + part +
- ", nodeId=" + msg.senderId() + ']');
-
- partMissing = true;
-
- break;
- }
-
- if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
- ack = true;
-
- if (!reply(node, d, s))
- return;
-
- // Throttle preloading.
- if (preloadThrottle > 0)
- U.sleep(preloadThrottle);
-
- s = new GridDhtPartitionSupplyMessage(d.workerId(), d.updateSequence(),
- cctx.cacheId(), cctx.deploymentEnabled());
- }
-
- GridCacheEntryInfo info = e.info();
-
- if (info != null && !info.isNew()) {
- if (preloadPred == null || preloadPred.apply(info))
- s.addEntry(part, info, cctx);
- else if (log.isDebugEnabled())
- log.debug("Rebalance predicate evaluated to false (will not sender cache entry): " +
- info);
- }
- }
-
- if (partMissing)
- continue;
-
- if (cctx.isSwapOrOffheapEnabled()) {
- GridCloseableIterator<Map.Entry<byte[], GridCacheSwapEntry>> iter =
- cctx.swap().iterator(part);
-
- // Iterator may be null if space does not exist.
- if (iter != null) {
- try {
- boolean prepared = false;
-
- for (Map.Entry<byte[], GridCacheSwapEntry> e : iter) {
- if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
- // Demander no longer needs this partition,
- // so we send '-1' partition and move on.
- s.missed(part);
-
- if (log.isDebugEnabled())
- log.debug("Demanding node does not need requested partition " +
- "[part=" + part + ", nodeId=" + msg.senderId() + ']');
-
- partMissing = true;
-
- break; // For.
- }
-
- if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
- ack = true;
-
- if (!reply(node, d, s))
- return;
-
- // Throttle preloading.
- if (preloadThrottle > 0)
- U.sleep(preloadThrottle);
-
- s = new GridDhtPartitionSupplyMessage(d.workerId(),
- d.updateSequence(), cctx.cacheId(), cctx.deploymentEnabled());
- }
-
- GridCacheSwapEntry swapEntry = e.getValue();
-
- GridCacheEntryInfo info = new GridCacheEntryInfo();
-
- info.keyBytes(e.getKey());
- info.ttl(swapEntry.ttl());
- info.expireTime(swapEntry.expireTime());
- info.version(swapEntry.version());
- info.value(swapEntry.value());
-
- if (preloadPred == null || preloadPred.apply(info))
- s.addEntry0(part, info, cctx);
- else {
- if (log.isDebugEnabled())
- log.debug("Rebalance predicate evaluated to false (will not send " +
- "cache entry): " + info);
-
- continue;
- }
-
- // Need to manually prepare cache message.
- if (depEnabled && !prepared) {
- ClassLoader ldr = swapEntry.keyClassLoaderId() != null ?
- cctx.deploy().getClassLoader(swapEntry.keyClassLoaderId()) :
- swapEntry.valueClassLoaderId() != null ?
- cctx.deploy().getClassLoader(swapEntry.valueClassLoaderId()) :
- null;
-
- if (ldr == null)
- continue;
-
- if (ldr instanceof GridDeploymentInfo) {
- s.prepare((GridDeploymentInfo)ldr);
-
- prepared = true;
- }
- }
- }
-
- if (partMissing)
- continue;
- }
- finally {
- iter.close();
- }
- }
- }
-
- // Stop receiving promote notifications.
- if (swapLsnr != null) {
- cctx.swap().removeOffHeapListener(part, swapLsnr);
- cctx.swap().removeSwapListener(part, swapLsnr);
- }
-
- if (swapLsnr != null) {
- Collection<GridCacheEntryInfo> entries = swapLsnr.entries();
-
- swapLsnr = null;
-
- for (GridCacheEntryInfo info : entries) {
- if (!cctx.affinity().belongs(node, part, d.topologyVersion())) {
- // Demander no longer needs this partition,
- // so we send '-1' partition and move on.
- s.missed(part);
-
- if (log.isDebugEnabled())
- log.debug("Demanding node does not need requested partition " +
- "[part=" + part + ", nodeId=" + msg.senderId() + ']');
-
- // No need to continue iteration over swap entries.
- break;
- }
-
- if (s.messageSize() >= cctx.config().getRebalanceBatchSize()) {
- ack = true;
-
- if (!reply(node, d, s))
- return;
-
- s = new GridDhtPartitionSupplyMessage(d.workerId(),
- d.updateSequence(),
- cctx.cacheId(), cctx.deploymentEnabled());
- }
-
- if (preloadPred == null || preloadPred.apply(info))
- s.addEntry(part, info, cctx);
- else if (log.isDebugEnabled())
- log.debug("Rebalance predicate evaluated to false (will not sender cache entry): " +
- info);
- }
- }
-
- // Mark as last supply message.
- s.last(part);
-
- if (ack) {
- s.markAck();
-
- break; // Partition for loop.
- }
- }
- finally {
- loc.release();
-
- if (swapLsnr != null) {
- cctx.swap().removeOffHeapListener(part, swapLsnr);
- cctx.swap().removeSwapListener(part, swapLsnr);
- }
- }
- }
-
- reply(node, d, s);
- }
- catch (IgniteCheckedException e) {
- U.error(log, "Failed to send partition supply message to node: " + node.id(), e);
- }
- }
-
- /**
- * @param n Node.
- * @param d Demand message.
- * @param s Supply message.
- * @return {@code True} if message was sent, {@code false} if recipient left grid.
- * @throws IgniteCheckedException If failed.
- */
- private boolean reply(ClusterNode n, GridDhtPartitionDemandMessage d, GridDhtPartitionSupplyMessage s)
- throws IgniteCheckedException {
- try {
- if (log.isDebugEnabled())
- log.debug("Replying to partition demand [node=" + n.id() + ", demand=" + d + ", supply=" + s + ']');
-
- cctx.io().sendOrderedMessage(n, d.topic(), s, cctx.ioPolicy(), d.timeout());
-
- return true;
- }
- catch (ClusterTopologyCheckedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Failed to send partition supply message because node left grid: " + n.id());
-
- return false;
- }
- }
- }
-
- /**
- * Demand message wrapper.
- */
- private static class DemandMessage extends IgniteBiTuple<UUID, GridDhtPartitionDemandMessage> {
- /** */
- private static final long serialVersionUID = 0L;
-
- /**
- * @param sndId Sender ID.
- * @param msg Message.
- */
- DemandMessage(UUID sndId, GridDhtPartitionDemandMessage msg) {
- super(sndId, msg);
- }
-
- /**
- * Empty constructor required for {@link Externalizable}.
- */
- public DemandMessage() {
- // No-op.
- }
-
- /**
- * @return Sender ID.
- */
- UUID senderId() {
- return get1();
- }
-
- /**
- * @return Message.
- */
- public GridDhtPartitionDemandMessage message() {
- return get2();
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return "DemandMessage [senderId=" + senderId() + ", msg=" + message() + ']';
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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 cef38e8..2f2944d 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
@@ -742,6 +742,8 @@ public class GridDhtPartitionsExchangeFuture extends GridFutureAdapter<AffinityT
// Must initialize topology after we get discovery event.
initTopology(cacheCtx);
+ cacheCtx.preloader().onTopologyChanged(exchId.topologyVersion());
+
cacheCtx.preloader().updateLastExchangeFuture(this);
}
[28/51] ignite git commit: ignite-1865: Need to add tests on
SpringResource annotation
Posted by vk...@apache.org.
ignite-1865: Need to add tests on SpringResource annotation
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/db221f52
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/db221f52
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/db221f52
Branch: refs/heads/ignite-direct-marsh-opt
Commit: db221f52ef895d475e399f8cec49b75aeba4817d
Parents: dc32789
Author: Roman Shtykh <ap...@gmail.com>
Authored: Mon Nov 16 14:34:24 2015 +0300
Committer: dmagda <ma...@gmail.com>
Committed: Mon Nov 16 14:34:24 2015 +0300
----------------------------------------------------------------------
.../GridSpringResourceInjectionSelfTest.java | 143 +++++++++++++++++++
.../processors/resource/spring-resource.xml | 27 ++++
.../testsuites/IgniteResourceSelfTestSuite.java | 2 +
3 files changed, 172 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/db221f52/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
new file mode 100644
index 0000000..968c8c4
--- /dev/null
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/GridSpringResourceInjectionSelfTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.resource;
+
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteSpring;
+import org.apache.ignite.lang.IgniteCallable;
+import org.apache.ignite.resources.SpringResource;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * Tests for injected resource.
+ */
+public class GridSpringResourceInjectionSelfTest extends GridCommonAbstractTest {
+ /** Bean name. */
+ private static final String DUMMY_BEAN = "dummyResourceBean";
+
+ /** Test grid with Spring context. */
+ private static Ignite grid;
+
+ /** {@inheritDoc} */
+ @Override public void beforeTestsStarted() throws Exception {
+ grid = IgniteSpring.start(new ClassPathXmlApplicationContext(
+ "/org/apache/ignite/internal/processors/resource/spring-resource.xml"));
+ }
+
+ /** {@inheritDoc} */
+ @Override public void afterTestsStopped() throws Exception {
+ stopAllGrids();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testClosureField() throws Exception {
+ grid.compute().call(new IgniteCallable<Object>() {
+ @SpringResource(resourceName = DUMMY_BEAN)
+ private transient DummyResourceBean dummyResourceBean;
+
+ @Override public Object call() throws Exception {
+ assertNotNull(dummyResourceBean);
+
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Resource injection with non-existing resource name.
+ */
+ public void testClosureFieldWithWrongResourceName() throws Exception {
+ try {
+ grid.compute().call(new IgniteCallable<Object>() {
+ @SpringResource(resourceName = "")
+ private transient DummyResourceBean dummyResourceBean;
+
+ @Override public Object call() throws Exception {
+ assertNull(dummyResourceBean);
+
+ return null;
+ }
+ });
+ }
+ catch (IgniteException e) {
+ if (e.getMessage().contains("No bean named '' is defined"))
+ return;
+ }
+
+ fail();
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testClosureMethod() throws Exception {
+ grid.compute().call(new IgniteCallable<Object>() {
+ private DummyResourceBean dummyResourceBean;
+
+ @SpringResource(resourceName = DUMMY_BEAN)
+ private void setDummyResourceBean(DummyResourceBean dummyResourceBean) {
+ assertNotNull(dummyResourceBean);
+
+ this.dummyResourceBean = dummyResourceBean;
+ }
+
+ @Override public Object call() throws Exception {
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Resource injection with non-existing resource name.
+ */
+ public void testClosureMethodWithWrongResourceName() throws Exception {
+ try {
+ grid.compute().call(new IgniteCallable<Object>() {
+ private DummyResourceBean dummyResourceBean;
+
+ @SpringResource(resourceName = "")
+ private void setDummyResourceBean(DummyResourceBean dummyResourceBean) {
+ }
+
+ @Override public Object call() throws Exception {
+ assertNull(dummyResourceBean);
+
+ return null;
+ }
+ });
+ }
+ catch (IgniteException e) {
+ if (e.getMessage().contains("No bean named '' is defined"))
+ return;
+ }
+
+ fail();
+ }
+
+ /**
+ * Dummy resource bean.
+ */
+ public static class DummyResourceBean {
+ public DummyResourceBean() {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/db221f52/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
new file mode 100644
index 0000000..3abb521
--- /dev/null
+++ b/modules/spring/src/test/java/org/apache/ignite/internal/processors/resource/spring-resource.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+ <bean id="dummyResourceBean"
+ class="org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest$DummyResourceBean">
+ </bean>
+</beans>
http://git-wip-us.apache.org/repos/asf/ignite/blob/db221f52/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteResourceSelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteResourceSelfTestSuite.java b/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteResourceSelfTestSuite.java
index 5ad93e8..742190b 100644
--- a/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteResourceSelfTestSuite.java
+++ b/modules/spring/src/test/java/org/apache/ignite/testsuites/IgniteResourceSelfTestSuite.java
@@ -21,6 +21,7 @@ import junit.framework.TestSuite;
import org.apache.ignite.internal.processors.resource.GridLoggerInjectionSelfTest;
import org.apache.ignite.internal.processors.resource.GridResourceProcessorSelfTest;
import org.apache.ignite.internal.processors.resource.GridServiceInjectionSelfTest;
+import org.apache.ignite.internal.processors.resource.GridSpringResourceInjectionSelfTest;
/**
* Ignite resource injection test Suite.
@@ -37,6 +38,7 @@ public class IgniteResourceSelfTestSuite extends TestSuite {
suite.addTest(new TestSuite(GridResourceProcessorSelfTest.class));
suite.addTest(new TestSuite(GridLoggerInjectionSelfTest.class));
suite.addTest(new TestSuite(GridServiceInjectionSelfTest.class));
+ suite.addTest(new TestSuite(GridSpringResourceInjectionSelfTest.class));
return suite;
}
[13/51] ignite git commit: Merge remote-tracking branch
'remotes/origin/ignite-1.5'
Posted by vk...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4e45b981
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4e45b981
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4e45b981
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 4e45b981d271ce19dc5d12a53ea5a2423661f425
Parents: ba2ffb0 2b6fc49
Author: Anton Vinogradov <av...@apache.org>
Authored: Tue Nov 10 16:55:52 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Tue Nov 10 16:55:52 2015 +0300
----------------------------------------------------------------------
.../processors/cache/GridCachePartitionExchangeManager.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
[08/51] ignite git commit: Merge remote-tracking branch
'remotes/origin/ignite-1.5'
Posted by vk...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5d760a8b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5d760a8b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5d760a8b
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 5d760a8bf29dac32f653b2d3d5ce01e39e5225d2
Parents: 280252e a4848a7
Author: Anton Vinogradov <av...@apache.org>
Authored: Mon Nov 9 13:35:18 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Mon Nov 9 13:35:18 2015 +0300
----------------------------------------------------------------------
.../managers/communication/GridIoMessage.java | 4 +-
.../processors/cache/GridCacheContext.java | 29 +--
.../processors/cache/GridCacheEntryEx.java | 4 +-
.../processors/cache/GridCacheMapEntry.java | 55 ++--
.../processors/cache/GridCacheMvccManager.java | 145 +++++------
.../distributed/GridDistributedCacheEntry.java | 2 +-
.../distributed/GridDistributedTxMapping.java | 8 +-
.../GridDistributedTxRemoteAdapter.java | 5 +-
.../distributed/dht/GridDhtLockFuture.java | 7 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 13 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 43 ++--
.../distributed/dht/GridDhtTxPrepareFuture.java | 78 +++---
.../cache/distributed/dht/GridDhtTxRemote.java | 45 ++--
.../dht/atomic/GridDhtAtomicCache.java | 1 -
.../dht/colocated/GridDhtColocatedCache.java | 7 +-
.../near/GridNearOptimisticTxPrepareFuture.java | 11 +-
.../near/GridNearTransactionalCache.java | 7 +-
.../near/GridNearTxFinishFuture.java | 157 ++++++------
.../cache/distributed/near/GridNearTxLocal.java | 21 +-
.../cache/transactions/IgniteInternalTx.java | 3 +-
.../cache/transactions/IgniteTxAdapter.java | 251 ++++++++++---------
.../cache/transactions/IgniteTxHandler.java | 37 +--
.../transactions/IgniteTxLocalAdapter.java | 26 +-
.../cache/transactions/IgniteTxManager.java | 171 ++++++-------
.../GridBoundedConcurrentLinkedHashMap.java | 7 +-
.../GridBoundedConcurrentLinkedHashSet.java | 7 +-
.../util/GridBoundedConcurrentOrderedMap.java | 39 +--
.../internal/util/GridConcurrentFactory.java | 11 +-
.../util/GridConcurrentLinkedHashSet.java | 9 +-
.../ignite/internal/util/IgniteUuidCache.java | 6 +-
.../util/future/GridCompoundFuture.java | 155 ++++++++----
.../java/org/jsr166/ConcurrentHashMap8.java | 2 +-
.../java/org/jsr166/ConcurrentLinkedDeque8.java | 2 +-
.../org/jsr166/ConcurrentLinkedHashMap.java | 195 +++++++++++---
.../GridCacheAffinityBackupsSelfTest.java | 8 +
.../cache/GridCacheAbstractFullApiSelfTest.java | 2 +-
.../GridCacheMissingCommitVersionSelfTest.java | 40 +--
.../processors/cache/GridCacheTestEntryEx.java | 3 +-
...achePartitionedMultiNodeFullApiSelfTest.java | 2 +-
.../continuous/GridEventConsumeSelfTest.java | 2 +-
...dBoundedConcurrentLinkedHashMapSelfTest.java | 2 +-
.../GridConcurrentLinkedHashMapSelfTest.java | 62 ++++-
.../junits/common/GridCommonAbstractTest.java | 4 +-
...rrentLinkedHashMapMultiThreadedSelfTest.java | 104 ++++----
.../yardstick/cache/IgnitePutTxBenchmark.java | 10 +
.../cache/IgnitePutTxPrimaryOnlyBenchmark.java | 65 +++++
.../IgnitePutTxSkipLocalBackupBenchmark.java | 65 +++++
.../cache/WaitMapExchangeFinishCallable.java | 95 +++++++
48 files changed, 1220 insertions(+), 807 deletions(-)
----------------------------------------------------------------------
[25/51] ignite git commit: Merge remote-tracking branch
'upstream/master' into ignite-direct-marsh
Posted by vk...@apache.org.
Merge remote-tracking branch 'upstream/master' into ignite-direct-marsh
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4cc5c9f7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4cc5c9f7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4cc5c9f7
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 4cc5c9f70ffe22eaa80ba74fe009bc652e4f75e4
Parents: 7123a73 3a8c19e
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Sun Nov 15 22:28:59 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Sun Nov 15 22:28:59 2015 -0800
----------------------------------------------------------------------
.../store/jdbc/CacheAbstractJdbcStore.java | 34 +++++++++++---------
.../dht/preloader/GridDhtPartitionSupplier.java | 3 ++
.../apache/ignite/stream/StreamTransformer.java | 9 ++++--
.../testsuites/IgniteCacheTestSuite3.java | 2 ++
.../scala/org/apache/ignite/visor/visor.scala | 3 +-
5 files changed, 32 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
[43/51] ignite git commit: Performance optimizations - reviewed by
Yakov.
Posted by vk...@apache.org.
Performance optimizations - reviewed by Yakov.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/175b7f24
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/175b7f24
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/175b7f24
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 175b7f24e1d62a90e7a7159ad670036216e6d278
Parents: 4c9ea58
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Wed Nov 18 19:20:45 2015 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Wed Nov 18 19:20:45 2015 +0300
----------------------------------------------------------------------
.../ignite/codegen/MessageCodeGenerator.java | 11 +-
.../communication/GridIoMessageFactory.java | 6 +
.../discovery/GridDiscoveryManager.java | 2 +-
.../cache/GridCacheDeploymentManager.java | 2 +-
.../processors/cache/GridCacheGateway.java | 1 -
.../processors/cache/GridCacheMvcc.java | 7 --
.../processors/cache/GridCacheMvccManager.java | 42 -------
.../GridCachePartitionExchangeManager.java | 55 ++++++++-
.../cache/GridCacheSharedContext.java | 7 +-
.../distributed/GridCacheTxRecoveryFuture.java | 41 +++++--
.../distributed/GridDistributedBaseMessage.java | 56 ---------
.../distributed/GridDistributedLockRequest.java | 6 -
.../GridDistributedLockResponse.java | 32 +-----
.../GridDistributedTxPrepareRequest.java | 67 +++++++++--
.../distributed/dht/GridDhtLockFuture.java | 63 ++++++----
.../distributed/dht/GridDhtLockRequest.java | 2 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 5 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 9 ++
.../distributed/dht/GridDhtTxPrepareFuture.java | 60 ++++++----
.../dht/GridDhtTxPrepareRequest.java | 54 ++++-----
.../dht/colocated/GridDhtColocatedCache.java | 2 +-
.../colocated/GridDhtColocatedLockFuture.java | 55 ++++++---
.../distributed/near/GridNearLockFuture.java | 56 ++++++---
.../distributed/near/GridNearLockRequest.java | 4 +-
...arOptimisticSerializableTxPrepareFuture.java | 91 +++++++++------
.../near/GridNearOptimisticTxPrepareFuture.java | 50 +++++---
.../GridNearPessimisticTxPrepareFuture.java | 39 +++++--
.../near/GridNearTransactionalCache.java | 7 +-
.../near/GridNearTxFinishFuture.java | 18 ++-
.../cache/distributed/near/GridNearTxLocal.java | 15 ---
.../near/GridNearTxPrepareFutureAdapter.java | 14 ++-
.../near/GridNearTxPrepareRequest.java | 52 ++++-----
.../cache/transactions/IgniteInternalTx.java | 1 +
.../cache/transactions/IgniteTxAdapter.java | 1 +
.../cache/transactions/IgniteTxEntry.java | 9 +-
.../IgniteTxImplicitSingleStateImpl.java | 7 ++
.../transactions/IgniteTxLocalAdapter.java | 12 +-
.../cache/transactions/IgniteTxManager.java | 1 +
.../IgniteTxRemoteStateAdapter.java | 5 +
.../cache/transactions/IgniteTxState.java | 6 +
.../cache/transactions/IgniteTxStateImpl.java | 69 ++++++++---
.../clock/GridClockSyncProcessor.java | 28 ++++-
.../internal/util/UUIDCollectionMessage.java | 114 +++++++++++++++++++
.../util/future/GridCompoundFuture.java | 15 ++-
.../ignite/internal/util/lang/GridFunc.java | 8 +-
.../ignite/internal/util/nio/GridNioServer.java | 13 ++-
.../IgniteCacheTxStoreSessionTest.java | 2 +-
.../testsuites/IgniteCacheTestSuite3.java | 2 +
48 files changed, 805 insertions(+), 419 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
----------------------------------------------------------------------
diff --git a/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java b/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
index 8d9a3f5..74c71c4 100644
--- a/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
+++ b/modules/codegen/src/main/java/org/apache/ignite/codegen/MessageCodeGenerator.java
@@ -43,6 +43,10 @@ import org.apache.ignite.internal.GridDirectCollection;
import org.apache.ignite.internal.GridDirectMap;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.IgniteCodeGeneratingFail;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxPrepareRequest;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTxPrepareRequest;
+import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxPrepareRequest;
+import org.apache.ignite.internal.util.UUIDCollectionMessage;
import org.apache.ignite.internal.util.typedef.internal.SB;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteUuid;
@@ -165,7 +169,12 @@ public class MessageCodeGenerator {
MessageCodeGenerator gen = new MessageCodeGenerator(srcDir);
- gen.generateAll(true);
+ gen.generateAndWrite(GridDistributedTxPrepareRequest.class);
+ gen.generateAndWrite(GridDhtTxPrepareRequest.class);
+ gen.generateAndWrite(GridNearTxPrepareRequest.class);
+ gen.generateAndWrite(UUIDCollectionMessage.class);
+
+// gen.generateAll(true);
// gen.generateAndWrite(DataStreamerEntry.class);
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 ae8c753..2503eda 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
@@ -121,6 +121,7 @@ import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultRe
import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskResultResponse;
import org.apache.ignite.internal.util.GridByteArrayList;
import org.apache.ignite.internal.util.GridLongList;
+import org.apache.ignite.internal.util.UUIDCollectionMessage;
import org.apache.ignite.lang.IgniteOutClosure;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
@@ -690,6 +691,11 @@ public class GridIoMessageFactory implements MessageFactory {
break;
+ case 115:
+ msg = new UUIDCollectionMessage();
+
+ break;
+
// [-3..114] - this
// [120..123] - DR
// [-4..-22] - SQL
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 cd2f49c..4880338 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
@@ -2136,7 +2136,7 @@ public class GridDiscoveryManager extends GridManagerAdapter<DiscoverySpi> {
customEvt.node(ctx.discovery().localNode());
customEvt.eventNode(node);
customEvt.type(type);
- customEvt.topologySnapshot(topVer.topologyVersion(), null);
+ customEvt.topologySnapshot(topVer.topologyVersion(), evt.get4());
customEvt.affinityTopologyVersion(topVer);
customEvt.customMessage(evt.get5());
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java
index 40c5b0f..35e8b75 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheDeploymentManager.java
@@ -164,7 +164,7 @@ public class GridCacheDeploymentManager<K, V> extends GridCacheSharedManagerAdap
* Callback on method enter.
*/
public void onEnter() {
- if (!locDepOwner && depEnabled && !ignoreOwnership.get()
+ if (depEnabled && !locDepOwner && !ignoreOwnership.get()
&& !cctx.kernalContext().job().internal()) {
ClassLoader ldr = Thread.currentThread().getContextClassLoader();
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 0eac5ba..1562d70 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
@@ -109,7 +109,6 @@ public class GridCacheGateway<K, V> {
rwLock.readLock();
return checkState(true, false);
-
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
index 12583ad..adcbf92 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java
@@ -348,9 +348,6 @@ public final class GridCacheMvcc {
reassign();
- if (cand.local())
- cctx.mvcc().removeLocal(cand);
-
return true;
}
}
@@ -596,8 +593,6 @@ public final class GridCacheMvcc {
);
if (serOrder == null) {
- cctx.mvcc().addLocal(cand);
-
boolean add = add0(cand);
assert add : cand;
@@ -605,8 +600,6 @@ public final class GridCacheMvcc {
else {
if (!add0(cand))
return null;
-
- cctx.mvcc().addLocal(cand);
}
return cand;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
index 2c14209..8562f37 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java
@@ -29,7 +29,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentSkipListSet;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cluster.ClusterNode;
@@ -92,9 +91,6 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
private GridBoundedConcurrentLinkedHashSet<GridCacheVersion> rmvLocks =
new GridBoundedConcurrentLinkedHashSet<>(MAX_REMOVED_LOCKS, MAX_REMOVED_LOCKS, 0.75f, 16, PER_SEGMENT_Q);
- /** Current local candidates. */
- private Collection<GridCacheMvccCandidate> dhtLocCands = new ConcurrentSkipListSet<>();
-
/** Locked keys. */
@GridToStringExclude
private final ConcurrentMap<IgniteTxKey, GridDistributedCacheEntry> locked = newMap();
@@ -707,43 +703,6 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
}
/**
- * @param cand Local lock.
- * @return {@code True} if added.
- */
- public boolean addLocal(GridCacheMvccCandidate cand) {
- assert cand.key() != null : cand;
- assert cand.local() : cand;
-
- if (cand.dhtLocal() && dhtLocCands.add(cand)) {
- if (log.isDebugEnabled())
- log.debug("Added local candidate: " + cand);
-
- return true;
- }
-
- return false;
- }
-
- /**
- *
- * @param cand Local candidate to remove.
- * @return {@code True} if removed.
- */
- public boolean removeLocal(GridCacheMvccCandidate cand) {
- assert cand.key() != null : cand;
- assert cand.local() : cand;
-
- if (cand.dhtLocal() && dhtLocCands.remove(cand)) {
- if (log.isDebugEnabled())
- log.debug("Removed local candidate: " + cand);
-
- return true;
- }
-
- return false;
- }
-
- /**
* @param cacheCtx Cache context.
* @param cand Cache lock candidate to add.
* @return {@code True} if added as a result of this operation,
@@ -953,7 +912,6 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter {
X.println(">>> ");
X.println(">>> Mvcc manager memory stats [grid=" + cctx.gridName() + ']');
X.println(">>> rmvLocksSize: " + rmvLocks.sizex());
- X.println(">>> dhtLocCandsSize: " + dhtLocCands.size());
X.println(">>> lockedSize: " + locked.size());
X.println(">>> futsSize: " + futs.size());
X.println(">>> near2dhtSize: " + near2dht.size());
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 81ff028..e19b310 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,6 +30,7 @@ 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;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
@@ -66,6 +67,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager;
import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
import org.apache.ignite.internal.util.GridListSet;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.lang.IgnitePair;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.CI1;
@@ -77,6 +79,7 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.util.worker.GridWorker;
import org.apache.ignite.lang.IgniteBiInClosure;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.thread.IgniteThread;
import org.jetbrains.annotations.Nullable;
@@ -134,6 +137,10 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
private final ConcurrentMap<AffinityTopologyVersion, AffinityReadyFuture> readyFuts = new ConcurrentHashMap8<>();
/** */
+ private final ConcurrentSkipListMap<AffinityTopologyVersion, IgnitePair<IgniteProductVersion>> nodeVers =
+ new ConcurrentSkipListMap<>();
+
+ /** */
private final AtomicReference<AffinityTopologyVersion> readyTopVer =
new AtomicReference<>(AffinityTopologyVersion.NONE);
@@ -572,6 +579,30 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
}
/**
+ * Gets minimum node version for the given topology version.
+ *
+ * @param topVer Topology version to get minimum node version for.
+ * @return Minimum node version.
+ */
+ public IgniteProductVersion minimumNodeVersion(AffinityTopologyVersion topVer) {
+ IgnitePair<IgniteProductVersion> vers = nodeVers.get(topVer);
+
+ return vers == null ? cctx.localNode().version() : vers.get1();
+ }
+
+ /**
+ * Gets maximum node version for the given topology version.
+ *
+ * @param topVer Topology version to get maximum node version for.
+ * @return Maximum node version.
+ */
+ public IgniteProductVersion maximumNodeVersion(AffinityTopologyVersion topVer) {
+ IgnitePair<IgniteProductVersion> vers = nodeVers.get(topVer);
+
+ return vers == null ? cctx.localNode().version() : vers.get2();
+ }
+
+ /**
* @return {@code true} if entered to busy state.
*/
private boolean enterBusy() {
@@ -832,6 +863,28 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
if (log.isDebugEnabled())
log.debug("Exchange done [topVer=" + topVer + ", fut=" + exchFut + ", err=" + err + ']');
+ IgniteProductVersion minVer = cctx.localNode().version();
+ IgniteProductVersion maxVer = cctx.localNode().version();
+
+ if (err == null) {
+ if (!F.isEmpty(exchFut.discoveryEvent().topologyNodes())) {
+ for (ClusterNode node : exchFut.discoveryEvent().topologyNodes()) {
+ IgniteProductVersion ver = node.version();
+
+ if (ver.compareTo(minVer) < 0)
+ minVer = ver;
+
+ if (ver.compareTo(maxVer) > 0)
+ maxVer = ver;
+ }
+ }
+ }
+
+ nodeVers.put(topVer, new IgnitePair<>(minVer, maxVer));
+
+ for (AffinityTopologyVersion oldVer : nodeVers.headMap(new AffinityTopologyVersion(topVer.topologyVersion() - 10, 0)).keySet())
+ nodeVers.remove(oldVer);
+
if (err == null) {
while (true) {
AffinityTopologyVersion readyVer = readyTopVer.get();
@@ -1050,7 +1103,7 @@ public class GridCachePartitionExchangeManager<K, V> extends GridCacheSharedMana
int cnt = 0;
- for (GridDhtPartitionsExchangeFuture fut : exchFuts) {
+ for (GridDhtPartitionsExchangeFuture fut : exchFuts.values()) {
U.warn(log, ">>> " + fut);
if (++cnt == 10)
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
index 4293b90..608829a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
@@ -44,6 +44,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxManager;
import org.apache.ignite.internal.processors.cache.transactions.TransactionMetricsAdapter;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionManager;
import org.apache.ignite.internal.processors.timeout.GridTimeoutProcessor;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -533,7 +534,7 @@ public class GridCacheSharedContext<K, V> {
* @param cacheCtx Cache context.
* @return Error message if transactions are incompatible.
*/
- @Nullable public String verifyTxCompatibility(IgniteInternalTx tx, Iterable<Integer> activeCacheIds,
+ @Nullable public String verifyTxCompatibility(IgniteInternalTx tx, GridLongList activeCacheIds,
GridCacheContext<K, V> cacheCtx) {
if (cacheCtx.systemTx() && !tx.system())
return "system cache can be enlisted only in system transaction";
@@ -541,7 +542,9 @@ public class GridCacheSharedContext<K, V> {
if (!cacheCtx.systemTx() && tx.system())
return "non-system cache can't be enlisted in system transaction";
- for (Integer cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext<K, V> activeCacheCtx = cacheContext(cacheId);
if (cacheCtx.systemTx()) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
index b266c4d..01c4867 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridCacheTxRecoveryFuture.java
@@ -342,20 +342,45 @@ public class GridCacheTxRecoveryFuture extends GridCompoundIdentityFuture<Boolea
*/
public void onResult(UUID nodeId, GridCacheTxRecoveryResponse res) {
if (!isDone()) {
- for (IgniteInternalFuture<Boolean> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture f = (MiniFuture)fut;
+ MiniFuture mini = miniFuture(res.miniId());
- if (f.futureId().equals(res.miniId())) {
- assert f.nodeId().equals(nodeId);
+ if (mini != null) {
+ assert mini.nodeId().equals(nodeId);
- f.onResult(res);
+ mini.onResult(res);
+ }
+ }
+ }
- break;
- }
+ /**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<Boolean> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
}
}
}
+
+ return null;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
index f4a16dc..ebbc9ae 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedBaseMessage.java
@@ -21,13 +21,10 @@ import java.io.Externalizable;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
-import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridDirectCollection;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.processors.cache.GridCacheDeployable;
import org.apache.ignite.internal.processors.cache.GridCacheMessage;
-import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
-import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionable;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
@@ -49,15 +46,6 @@ public abstract class GridDistributedBaseMessage extends GridCacheMessage implem
@GridToStringInclude
protected GridCacheVersion ver;
- /**
- * Candidates for every key ordered in the order of keys. These
- * can be either local-only candidates in case of lock acquisition,
- * or pending candidates in case of transaction commit.
- */
- @GridToStringInclude
- @GridDirectTransient
- private Collection<GridCacheMvccCandidate>[] candsByIdx;
-
/** */
@GridToStringExclude
private byte[] candsByIdxBytes;
@@ -108,23 +96,6 @@ public abstract class GridDistributedBaseMessage extends GridCacheMessage implem
this.ver = ver;
}
- /** {@inheritDoc}
- * @param ctx*/
- @Override public void prepareMarshal(GridCacheSharedContext ctx) throws IgniteCheckedException {
- super.prepareMarshal(ctx);
-
- if (candsByIdx != null)
- candsByIdxBytes = ctx.marshaller().marshal(candsByIdx);
- }
-
- /** {@inheritDoc} */
- @Override public void finishUnmarshal(GridCacheSharedContext ctx, ClassLoader ldr) throws IgniteCheckedException {
- super.finishUnmarshal(ctx, ldr);
-
- if (candsByIdxBytes != null)
- candsByIdx = ctx.marshaller().unmarshal(candsByIdxBytes, ldr);
- }
-
/** {@inheritDoc} */
@Override public boolean addDeploymentInfo() {
return addDepInfo;
@@ -169,33 +140,6 @@ public abstract class GridDistributedBaseMessage extends GridCacheMessage implem
}
/**
- * @param idx Key index.
- * @param candsByIdx List of candidates for that key.
- */
- @SuppressWarnings({"unchecked"})
- public void candidatesByIndex(int idx, Collection<GridCacheMvccCandidate> candsByIdx) {
- assert idx < cnt;
-
- // If nothing to add.
- if (candsByIdx == null || candsByIdx.isEmpty())
- return;
-
- if (this.candsByIdx == null)
- this.candsByIdx = new Collection[cnt];
-
- this.candsByIdx[idx] = candsByIdx;
- }
-
- /**
- * @param idx Key index.
- * @return Candidates for given key.
- */
- public Collection<GridCacheMvccCandidate> candidatesByIndex(int idx) {
- return candsByIdx == null ||
- candsByIdx[idx] == null ? Collections.<GridCacheMvccCandidate>emptyList() : candsByIdx[idx];
- }
-
- /**
* @return Count of keys referenced in candidates array (needed only locally for optimization).
*/
public int keysCount() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
index 2899e25..b584f8a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockRequest.java
@@ -19,14 +19,12 @@ package org.apache.ignite.internal.processors.cache.distributed;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridDirectCollection;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -261,14 +259,12 @@ public class GridDistributedLockRequest extends GridDistributedBaseMessage {
*
* @param key Key.
* @param retVal Flag indicating whether value should be returned.
- * @param cands Candidates.
* @param ctx Context.
* @throws IgniteCheckedException If failed.
*/
public void addKeyBytes(
KeyCacheObject key,
boolean retVal,
- @Nullable Collection<GridCacheMvccCandidate> cands,
GridCacheContext ctx
) throws IgniteCheckedException {
if (keys == null)
@@ -276,8 +272,6 @@ public class GridDistributedLockRequest extends GridDistributedBaseMessage {
keys.add(key);
- candidatesByIndex(idx, cands);
-
retVals[idx] = retVal;
idx++;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
index cdd58b5..bb3f9ff 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedLockResponse.java
@@ -26,7 +26,6 @@ import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridDirectCollection;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.processors.cache.CacheObject;
-import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -156,34 +155,11 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
}
/**
- * @param idx Index of locked flag.
- * @return Value of locked flag at given index.
- */
- public boolean isCurrentlyLocked(int idx) {
- assert idx >= 0;
-
- Collection<GridCacheMvccCandidate> cands = candidatesByIndex(idx);
-
- for (GridCacheMvccCandidate cand : cands)
- if (cand.owner())
- return true;
-
- return false;
- }
-
- /**
- * @param idx Candidates index.
- * @param cands Collection of candidates.
* @param committedVers Committed versions relative to lock version.
* @param rolledbackVers Rolled back versions relative to lock version.
*/
- public void setCandidates(int idx, Collection<GridCacheMvccCandidate> cands,
- Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers) {
- assert idx >= 0;
-
+ public void setCandidates(Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers) {
completedVersions(committedVers, rolledbackVers);
-
- candidatesByIndex(idx, cands);
}
/**
@@ -218,9 +194,6 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
prepareMarshalCacheObjects(vals, ctx.cacheContext(cacheId));
-// if (F.isEmpty(valBytes) && !F.isEmpty(vals))
-// valBytes = marshalValuesCollection(vals, ctx);
-
if (err != null)
errBytes = ctx.marshaller().marshal(err);
}
@@ -231,9 +204,6 @@ public class GridDistributedLockResponse extends GridDistributedBaseMessage {
finishUnmarshalCacheObjects(vals, ctx.cacheContext(cacheId), ldr);
-// if (F.isEmpty(vals) && !F.isEmpty(valBytes))
-// vals = unmarshalValueBytesCollection(valBytes, ctx, ldr);
-
if (errBytes != null)
err = ctx.marshaller().unmarshal(errBytes, ldr);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
index 533c8ca..95176ff 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxPrepareRequest.java
@@ -27,6 +27,7 @@ import java.util.Map;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.GridDirectCollection;
+import org.apache.ignite.internal.GridDirectMap;
import org.apache.ignite.internal.GridDirectTransient;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
@@ -34,9 +35,13 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
+import org.apache.ignite.internal.util.UUIDCollectionMessage;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.C1;
+import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
import org.apache.ignite.plugin.extensions.communication.MessageWriter;
@@ -52,6 +57,23 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
/** */
private static final long serialVersionUID = 0L;
+ /** Version in which direct marshalling of tx nodes was introduced. */
+ public static final IgniteProductVersion TX_NODES_DIRECT_MARSHALLABLE_SINCE = IgniteProductVersion.fromString("1.5.0");
+
+ /** Collection to message converter. */
+ public static final C1<Collection<UUID>, UUIDCollectionMessage> COL_TO_MSG = new C1<Collection<UUID>, UUIDCollectionMessage>() {
+ @Override public UUIDCollectionMessage apply(Collection<UUID> uuids) {
+ return new UUIDCollectionMessage(uuids);
+ }
+ };
+
+ /** Message to collection converter. */
+ public static final C1<UUIDCollectionMessage, Collection<UUID>> MSG_TO_COL = new C1<UUIDCollectionMessage, Collection<UUID>>() {
+ @Override public Collection<UUID> apply(UUIDCollectionMessage msg) {
+ return msg.uuids();
+ }
+ };
+
/** Thread ID. */
@GridToStringInclude
private long threadId;
@@ -106,6 +128,10 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
@GridDirectTransient
private Map<UUID, Collection<UUID>> txNodes;
+ /** Tx nodes direct marshallable message. */
+ @GridDirectMap(keyType = UUID.class, valueType = UUIDCollectionMessage.class)
+ private Map<UUID, UUIDCollectionMessage> txNodesMsg;
+
/** */
private byte[] txNodesBytes;
@@ -302,8 +328,16 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
dhtVerVals = dhtVers.values();
}
- if (txNodes != null)
- txNodesBytes = ctx.marshaller().marshal(txNodes);
+ // Marshal txNodes only if there is a node in topology with an older version.
+ if (ctx.exchange().minimumNodeVersion(topologyVersion())
+ .compareTo(TX_NODES_DIRECT_MARSHALLABLE_SINCE) < 0) {
+ if (txNodes != null && txNodesBytes == null)
+ txNodesBytes = ctx.marshaller().marshal(txNodes);
+ }
+ else {
+ if (txNodesMsg == null)
+ txNodesMsg = F.viewReadOnly(txNodes, COL_TO_MSG);
+ }
}
/** {@inheritDoc} */
@@ -334,7 +368,10 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
}
}
- if (txNodesBytes != null)
+ if (txNodesMsg != null)
+ txNodes = F.viewReadOnly(txNodesMsg, MSG_TO_COL);
+
+ if (txNodesBytes != null && txNodes == null)
txNodes = ctx.marshaller().unmarshal(txNodesBytes, ldr);
}
@@ -431,18 +468,24 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
writer.incrementState();
case 19:
- if (!writer.writeInt("txSize", txSize))
+ if (!writer.writeMap("txNodesMsg", txNodesMsg, MessageCollectionItemType.UUID, MessageCollectionItemType.MSG))
return false;
writer.incrementState();
case 20:
- if (!writer.writeMessage("writeVer", writeVer))
+ if (!writer.writeInt("txSize", txSize))
return false;
writer.incrementState();
case 21:
+ if (!writer.writeMessage("writeVer", writeVer))
+ return false;
+
+ writer.incrementState();
+
+ case 22:
if (!writer.writeCollection("writes", writes, MessageCollectionItemType.MSG))
return false;
@@ -569,7 +612,7 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
reader.incrementState();
case 19:
- txSize = reader.readInt("txSize");
+ txNodesMsg = reader.readMap("txNodesMsg", MessageCollectionItemType.UUID, MessageCollectionItemType.MSG, false);
if (!reader.isLastRead())
return false;
@@ -577,7 +620,7 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
reader.incrementState();
case 20:
- writeVer = reader.readMessage("writeVer");
+ txSize = reader.readInt("txSize");
if (!reader.isLastRead())
return false;
@@ -585,6 +628,14 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
reader.incrementState();
case 21:
+ writeVer = reader.readMessage("writeVer");
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ case 22:
writes = reader.readCollection("writes", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
@@ -604,7 +655,7 @@ public class GridDistributedTxPrepareRequest extends GridDistributedBaseMessage
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 22;
+ return 23;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 579d701..7284fd4 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
@@ -380,10 +380,9 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
* @return Lock candidate.
* @throws GridCacheEntryRemovedException If entry was removed.
* @throws GridDistributedLockCancelledException If lock is canceled.
- * @throws IgniteCheckedException If failed.
*/
@Nullable public GridCacheMvccCandidate addEntry(GridDhtCacheEntry entry)
- throws GridCacheEntryRemovedException, GridDistributedLockCancelledException, IgniteCheckedException {
+ throws GridCacheEntryRemovedException, GridDistributedLockCancelledException {
if (log.isDebugEnabled())
log.debug("Adding entry: " + entry);
@@ -529,35 +528,57 @@ public final class GridDhtLockFuture extends GridCompoundIdentityFuture<Boolean>
if (log.isDebugEnabled())
log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']');
- boolean found = false;
+ MiniFuture mini = miniFuture(res.miniId());
- for (IgniteInternalFuture<Boolean> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture mini = (MiniFuture)fut;
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
- if (mini.futureId().equals(res.miniId())) {
- assert mini.node().id().equals(nodeId);
+ if (log.isDebugEnabled())
+ log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
- if (log.isDebugEnabled())
- log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
+ mini.onResult(res);
- found = true;
+ if (log.isDebugEnabled())
+ log.debug("Futures after processed lock response [fut=" + this + ", mini=" + mini +
+ ", res=" + res + ']');
- mini.onResult(res);
+ return;
+ }
- if (log.isDebugEnabled())
- log.debug("Futures after processed lock response [fut=" + this + ", mini=" + mini +
- ", res=" + res + ']');
+ U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res +
+ ", fut=" + this + ']');
+ }
+ }
- break;
- }
+ /**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<Boolean> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
}
}
-
- if (!found)
- U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res +
- ", fut=" + this + ']');
}
+
+ return null;
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
index 91ab1ca..18281d0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLockRequest.java
@@ -236,7 +236,7 @@ public class GridDhtLockRequest extends GridDistributedLockRequest {
) throws IgniteCheckedException {
invalidateEntries.set(idx, invalidateEntry);
- addKeyBytes(key, false, null, ctx);
+ addKeyBytes(key, false, ctx);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
index fe91e5b..35f63e3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
@@ -39,7 +39,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
-import org.apache.ignite.internal.processors.cache.GridCacheFilterFailedException;
import org.apache.ignite.internal.processors.cache.GridCacheLockTimeoutException;
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheReturn;
@@ -187,8 +186,6 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
IgniteTxKey txKey = ctx.txKey(key);
- assert F.isEmpty(req.candidatesByIndex(i));
-
if (log.isDebugEnabled())
log.debug("Unmarshalled key: " + key);
@@ -671,7 +668,7 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
if (log.isDebugEnabled())
log.debug("Got removed entry when adding lock (will retry): " + entry);
}
- catch (IgniteCheckedException | GridDistributedLockCancelledException e) {
+ catch (GridDistributedLockCancelledException e) {
if (log.isDebugEnabled())
log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 70ebf3f..55ca12d 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
@@ -181,6 +181,15 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
+ * Gets flag that indicates that originating node has a near cache that participates in this transaction.
+ *
+ * @return Has near cache flag.
+ */
+ public boolean nearOnOriginatingNode() {
+ return nearOnOriginatingNode;
+ }
+
+ /**
* @return {@code True} if explicit lock transaction.
*/
public boolean explicitLock() {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 a67950d..d081c0c 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
@@ -450,20 +450,45 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
*/
public void onResult(UUID nodeId, GridDhtTxPrepareResponse res) {
if (!isDone()) {
- for (IgniteInternalFuture<IgniteInternalTx> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture f = (MiniFuture)fut;
+ MiniFuture mini = miniFuture(res.miniId());
- if (f.futureId().equals(res.miniId())) {
- assert f.node().id().equals(nodeId);
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
- f.onResult(res);
+ mini.onResult(res);
+ }
+ }
+ }
- break;
- }
+ /**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<IgniteInternalTx> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
}
}
}
+
+ return null;
}
/**
@@ -693,7 +718,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
tx.activeCachesDeploymentEnabled());
if (prepErr == null) {
- addDhtValues(res);
+ if (tx.needReturnValue() || tx.nearOnOriginatingNode() || tx.hasInterceptor())
+ addDhtValues(res);
GridCacheVersion min = tx.minVersion();
@@ -949,7 +975,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
}
}
}
- catch (GridCacheEntryRemovedException e) {
+ catch (GridCacheEntryRemovedException ignore) {
assert false : "Got removed exception on entry with dht local candidate: " + entries;
}
@@ -1072,18 +1098,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
GridCacheContext<?, ?> cacheCtx = cached.context();
- if (entry.explicitVersion() == null) {
- GridCacheMvccCandidate added = cached.candidate(version());
-
- assert added != null : "Null candidate for non-group-lock entry " +
- "[added=" + added + ", entry=" + entry + ']';
- assert added.dhtLocal() : "Got non-dht-local candidate for prepare future" +
- "[added=" + added + ", entry=" + entry + ']';
-
- if (added != null && added.ownerVersion() != null)
- req.owned(entry.txKey(), added.ownerVersion());
- }
-
// Do not invalidate near entry on originating transaction node.
req.invalidateNearEntry(idx, !tx.nearNodeId().equals(n.id()) &&
cached.readerId(n.id()) != null);
@@ -1092,7 +1106,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
List<ClusterNode> owners = cacheCtx.topology().owners(cached.partition(),
tx != null ? tx.topologyVersion() : cacheCtx.affinity().affinityTopologyVersion());
- // Do not preload if local node is partition owner.
+ // Do not preload if local node is a partition owner.
if (!owners.contains(cctx.localNode()))
req.markKeyForPreload(idx);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
index fcd66c2..394ff89 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareRequest.java
@@ -345,79 +345,79 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
}
switch (writer.state()) {
- case 22:
+ case 23:
if (!writer.writeIgniteUuid("futId", futId))
return false;
writer.incrementState();
- case 23:
+ case 24:
if (!writer.writeBitSet("invalidateNearEntries", invalidateNearEntries))
return false;
writer.incrementState();
- case 24:
+ case 25:
if (!writer.writeBoolean("last", last))
return false;
writer.incrementState();
- case 25:
+ case 26:
if (!writer.writeIgniteUuid("miniId", miniId))
return false;
writer.incrementState();
- case 26:
+ case 27:
if (!writer.writeUuid("nearNodeId", nearNodeId))
return false;
writer.incrementState();
- case 27:
+ case 28:
if (!writer.writeCollection("nearWrites", nearWrites, MessageCollectionItemType.MSG))
return false;
writer.incrementState();
- case 28:
+ case 29:
if (!writer.writeMessage("nearXidVer", nearXidVer))
return false;
writer.incrementState();
- case 29:
+ case 30:
if (!writer.writeCollection("ownedKeys", ownedKeys, MessageCollectionItemType.MSG))
return false;
writer.incrementState();
- case 30:
+ case 31:
if (!writer.writeCollection("ownedVals", ownedVals, MessageCollectionItemType.MSG))
return false;
writer.incrementState();
- case 31:
+ case 32:
if (!writer.writeBitSet("preloadKeys", preloadKeys))
return false;
writer.incrementState();
- case 32:
+ case 33:
if (!writer.writeUuid("subjId", subjId))
return false;
writer.incrementState();
- case 33:
+ case 34:
if (!writer.writeInt("taskNameHash", taskNameHash))
return false;
writer.incrementState();
- case 34:
+ case 35:
if (!writer.writeMessage("topVer", topVer))
return false;
@@ -439,7 +439,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
return false;
switch (reader.state()) {
- case 22:
+ case 23:
futId = reader.readIgniteUuid("futId");
if (!reader.isLastRead())
@@ -447,7 +447,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 23:
+ case 24:
invalidateNearEntries = reader.readBitSet("invalidateNearEntries");
if (!reader.isLastRead())
@@ -455,7 +455,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 24:
+ case 25:
last = reader.readBoolean("last");
if (!reader.isLastRead())
@@ -463,7 +463,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 25:
+ case 26:
miniId = reader.readIgniteUuid("miniId");
if (!reader.isLastRead())
@@ -471,7 +471,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 26:
+ case 27:
nearNodeId = reader.readUuid("nearNodeId");
if (!reader.isLastRead())
@@ -479,7 +479,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 27:
+ case 28:
nearWrites = reader.readCollection("nearWrites", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
@@ -487,7 +487,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 28:
+ case 29:
nearXidVer = reader.readMessage("nearXidVer");
if (!reader.isLastRead())
@@ -495,7 +495,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 29:
+ case 30:
ownedKeys = reader.readCollection("ownedKeys", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
@@ -503,7 +503,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 30:
+ case 31:
ownedVals = reader.readCollection("ownedVals", MessageCollectionItemType.MSG);
if (!reader.isLastRead())
@@ -511,7 +511,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 31:
+ case 32:
preloadKeys = reader.readBitSet("preloadKeys");
if (!reader.isLastRead())
@@ -519,7 +519,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 32:
+ case 33:
subjId = reader.readUuid("subjId");
if (!reader.isLastRead())
@@ -527,7 +527,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 33:
+ case 34:
taskNameHash = reader.readInt("taskNameHash");
if (!reader.isLastRead())
@@ -535,7 +535,7 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 34:
+ case 35:
topVer = reader.readMessage("topVer");
if (!reader.isLastRead())
@@ -555,6 +555,6 @@ public class GridDhtTxPrepareRequest extends GridDistributedTxPrepareRequest {
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 35;
+ return 36;
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
index 83c220d..7131aa5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedCache.java
@@ -873,7 +873,7 @@ public class GridDhtColocatedCache<K, V> extends GridDhtTransactionalCacheAdapte
if (log.isDebugEnabled())
log.debug("Got removed entry when adding lock (will retry): " + entry);
}
- catch (IgniteCheckedException | GridDistributedLockCancelledException e) {
+ catch (GridDistributedLockCancelledException e) {
if (log.isDebugEnabled())
log.debug("Failed to add entry [err=" + e + ", entry=" + entry + ']');
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
index 365b46b..abeb509 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/colocated/GridDhtColocatedLockFuture.java
@@ -428,25 +428,21 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" +
this + ']');
- for (IgniteInternalFuture<Boolean> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture mini = (MiniFuture)fut;
+ MiniFuture mini = miniFuture(res.miniId());
- if (mini.futureId().equals(res.miniId())) {
- assert mini.node().id().equals(nodeId);
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
- if (log.isDebugEnabled())
- log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
+ if (log.isDebugEnabled())
+ log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
- mini.onResult(res);
+ mini.onResult(res);
- if (log.isDebugEnabled())
- log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini +
- ", res=" + res + ']');
+ if (log.isDebugEnabled())
+ log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini +
+ ", res=" + res + ']');
- return;
- }
- }
+ return;
}
U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res +
@@ -458,6 +454,37 @@ public final class GridDhtColocatedLockFuture extends GridCompoundIdentityFuture
}
/**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<Boolean> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
* @param t Error.
*/
private void onError(Throwable t) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
index c5b55bd..9c3701f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockFuture.java
@@ -478,25 +478,21 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
if (log.isDebugEnabled())
log.debug("Received lock response from node [nodeId=" + nodeId + ", res=" + res + ", fut=" + this + ']');
- for (IgniteInternalFuture<Boolean> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture mini = (MiniFuture)fut;
+ MiniFuture mini = miniFuture(res.miniId());
- if (mini.futureId().equals(res.miniId())) {
- assert mini.node().id().equals(nodeId);
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
- if (log.isDebugEnabled())
- log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
+ if (log.isDebugEnabled())
+ log.debug("Found mini future for response [mini=" + mini + ", res=" + res + ']');
- mini.onResult(res);
+ mini.onResult(res);
- if (log.isDebugEnabled())
- log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini +
- ", res=" + res + ']');
+ if (log.isDebugEnabled())
+ log.debug("Future after processed lock response [fut=" + this + ", mini=" + mini +
+ ", res=" + res + ']');
- return;
- }
- }
+ return;
}
U.warn(log, "Failed to find mini future for response (perhaps due to stale message) [res=" + res +
@@ -508,6 +504,38 @@ public final class GridNearLockFuture extends GridCompoundIdentityFuture<Boolean
}
/**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<Boolean> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
+ }
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
* @param t Error.
*/
private void onError(Throwable t) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
index 165da84..805a6a2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
@@ -20,13 +20,11 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
import java.io.Externalizable;
import java.nio.ByteBuffer;
import java.util.Arrays;
-import java.util.Collection;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.CacheEntryPredicate;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedLockRequest;
@@ -300,7 +298,7 @@ public class GridNearLockRequest extends GridDistributedLockRequest {
dhtVers[idx] = dhtVer;
// Delegate to super.
- addKeyBytes(key, retVal, (Collection<GridCacheMvccCandidate>)null, ctx);
+ addKeyBytes(key, retVal, ctx);
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
index 29774a5..1569b14 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -46,6 +46,7 @@ import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedExceptio
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -210,17 +211,10 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
/** {@inheritDoc} */
@Override public void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
if (!isDone()) {
- for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture f = (MiniFuture)fut;
+ MiniFuture mini = miniFuture(res.miniId());
- if (f.futureId().equals(res.miniId())) {
- assert f.node().id().equals(nodeId);
-
- f.onResult(res);
- }
- }
- }
+ if (mini != null)
+ mini.onResult(res);
}
}
@@ -239,6 +233,37 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
}
/**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<GridNearTxPrepareResponse> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
* @param f Future.
* @return {@code True} if mini-future.
*/
@@ -276,32 +301,27 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
* @param remap Remap flag.
*/
@Override protected void prepare0(boolean remap, boolean topLocked) {
- try {
- boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
-
- if (!txStateCheck) {
- if (tx.setRollbackOnly()) {
- if (tx.timedOut())
- onError(null, new IgniteTxTimeoutCheckedException("Transaction timed out and " +
- "was rolled back: " + this));
- else
- onError(null, new IgniteCheckedException("Invalid transaction state for prepare " +
- "[state=" + tx.state() + ", tx=" + this + ']'));
- }
- else
- onError(null, new IgniteTxRollbackCheckedException("Invalid transaction state for " +
- "prepare [state=" + tx.state() + ", tx=" + this + ']'));
+ boolean txStateCheck = remap ? tx.state() == PREPARING : tx.state(PREPARING);
- return;
+ if (!txStateCheck) {
+ if (tx.setRollbackOnly()) {
+ if (tx.timedOut())
+ onError(null, new IgniteTxTimeoutCheckedException("Transaction timed out and " +
+ "was rolled back: " + this));
+ else
+ onError(null, new IgniteCheckedException("Invalid transaction state for prepare " +
+ "[state=" + tx.state() + ", tx=" + this + ']'));
}
+ else
+ onError(null, new IgniteTxRollbackCheckedException("Invalid transaction state for " +
+ "prepare [state=" + tx.state() + ", tx=" + this + ']'));
- prepare(tx.readEntries(), tx.writeEntries(), remap, topLocked);
-
- markInitialized();
- }
- catch (IgniteCheckedException e) {
- onDone(e);
+ return;
}
+
+ prepare(tx.readEntries(), tx.writeEntries(), remap, topLocked);
+
+ markInitialized();
}
/**
@@ -309,7 +329,6 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
* @param writes Write entries.
* @param remap Remap flag.
* @param topLocked Topology locked flag.
- * @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("unchecked")
private void prepare(
@@ -317,7 +336,7 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
Iterable<IgniteTxEntry> writes,
boolean remap,
boolean topLocked
- ) throws IgniteCheckedException {
+ ) {
AffinityTopologyVersion topVer = tx.topologyVersion();
assert topVer.topologyVersion() > 0;
@@ -355,9 +374,7 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
for (GridDistributedTxMapping m : mappings.values()) {
assert !m.empty();
- MiniFuture fut = new MiniFuture(m);
-
- add(fut);
+ add(new MiniFuture(m));
}
Collection<IgniteInternalFuture<?>> futs = (Collection)futures();
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index 791d2f3..82e3868 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -45,6 +45,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridConcurrentHashSet;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.C1;
@@ -187,18 +188,45 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
/** {@inheritDoc} */
@Override public void onResult(UUID nodeId, GridNearTxPrepareResponse res) {
if (!isDone()) {
- for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
- if (isMini(fut)) {
- MiniFuture f = (MiniFuture)fut;
+ MiniFuture mini = miniFuture(res.miniId());
- if (f.futureId().equals(res.miniId())) {
- assert f.node().id().equals(nodeId);
+ if (mini != null) {
+ assert mini.node().id().equals(nodeId);
- f.onResult(nodeId, res);
- }
+ mini.onResult(nodeId, res);
+ }
+ }
+ }
+
+ /**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<GridNearTxPrepareResponse> fut = futs.get(i);
+
+ if (!isMini(fut))
+ continue;
+
+ MiniFuture mini = (MiniFuture)fut;
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
}
}
}
+
+ return null;
}
/** {@inheritDoc} */
@@ -277,10 +305,7 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
markInitialized();
}
catch (TransactionTimeoutException e) {
- onError( e);
- }
- catch (IgniteCheckedException e) {
- onDone(e);
+ onError(e);
}
}
@@ -327,12 +352,11 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
/**
* @param writes Write entries.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
- * @throws IgniteCheckedException If failed.
*/
private void prepare(
Iterable<IgniteTxEntry> writes,
boolean topLocked
- ) throws IgniteCheckedException {
+ ) {
AffinityTopologyVersion topVer = tx.topologyVersion();
assert topVer.topologyVersion() > 0;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
index 1554a62..103105e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
@@ -103,20 +103,45 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
if (!isDone()) {
assert res.clientRemapVersion() == null : res;
- for (IgniteInternalFuture<GridNearTxPrepareResponse> fut : pending()) {
- MiniFuture f = (MiniFuture)fut;
+ MiniFuture f = miniFuture(res.miniId());
- if (f.futureId().equals(res.miniId())) {
- assert f.node().id().equals(nodeId);
+ if (f != null) {
+ assert f.node().id().equals(nodeId);
- if (log.isDebugEnabled())
- log.debug("Remote node left grid while sending or waiting for reply (will not retry): " + f);
+ if (log.isDebugEnabled())
+ log.debug("Remote node left grid while sending or waiting for reply (will not retry): " + f);
- f.onResult(res);
+ f.onResult(res);
+ }
+ }
+ }
+
+ /**
+ * Finds pending mini future by the given mini ID.
+ *
+ * @param miniId Mini ID to find.
+ * @return Mini future.
+ */
+ @SuppressWarnings("ForLoopReplaceableByForEach")
+ private MiniFuture miniFuture(IgniteUuid miniId) {
+ // We iterate directly over the futs collection here to avoid copy.
+ synchronized (futs) {
+ // Avoid iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ MiniFuture mini = (MiniFuture)futs.get(i);
+
+ if (mini.futureId().equals(miniId)) {
+ if (!mini.isDone())
+ return mini;
+ else
+ return null;
}
}
}
+
+ return null;
}
+
/** {@inheritDoc} */
@Override public void prepare() {
if (!tx.state(PREPARING)) {
[10/51] ignite git commit: Ignite-1093 Backward compatibility
failover.
Posted by vk...@apache.org.
Ignite-1093 Backward compatibility failover.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/efc79fbe
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/efc79fbe
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/efc79fbe
Branch: refs/heads/ignite-direct-marsh-opt
Commit: efc79fbe12f77906ee2ab9266c387bfdc3b887b9
Parents: 44ddf65
Author: Anton Vinogradov <av...@apache.org>
Authored: Mon Nov 9 15:09:36 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Mon Nov 9 15:09:36 2015 +0300
----------------------------------------------------------------------
.../distributed/dht/preloader/GridDhtPartitionDemander.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/efc79fbe/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 35cedf9..29ca5f4 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
@@ -1191,7 +1191,7 @@ public class GridDhtPartitionDemander {
// While.
// =====
- while (!topologyChanged(fut)) {
+ while (!fut.isDone() && !topologyChanged(fut)) {
SupplyMessage s = poll(msgQ, timeout);
// If timed out.
@@ -1350,7 +1350,7 @@ public class GridDhtPartitionDemander {
}
}
}
- while (retry && !topologyChanged(fut));
+ while (retry && !fut.isDone() && !topologyChanged(fut));
}
finally {
cctx.io().removeOrderedHandler(d.topic());
[51/51] ignite git commit: Direct marshalling backward compatibility
Posted by vk...@apache.org.
Direct marshalling backward compatibility
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1c697f35
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1c697f35
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1c697f35
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 1c697f35f2fbac3bbc24c615eb7415eb254cae1b
Parents: 861898e
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Wed Nov 18 20:31:42 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Nov 18 20:31:42 2015 -0800
----------------------------------------------------------------------
.../ignite/internal/managers/communication/GridIoManager.java | 4 ++--
.../plugin/extensions/communication/MessageFormatter.java | 4 +---
.../src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java | 2 +-
.../ignite/spi/communication/tcp/TcpCommunicationSpi.java | 6 ++----
.../org/apache/ignite/testframework/GridSpiTestContext.java | 3 +--
5 files changed, 7 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/1c697f35/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index 3c33e85..d6039b8 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -290,8 +290,8 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
return new DirectMessageWriter(directProtocolVersion(rmtNodeId));
}
- @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory,
- Class<? extends Message> msgCls) throws IgniteCheckedException {
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory)
+ throws IgniteCheckedException {
assert rmtNodeId != null;
return new DirectMessageReader(msgFactory, directProtocolVersion(rmtNodeId));
http://git-wip-us.apache.org/repos/asf/ignite/blob/1c697f35/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
index 111cb55..7bc2a53 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
@@ -46,10 +46,8 @@ public interface MessageFormatter extends Extension {
*
* @param rmtNodeId Remote node ID.
* @param msgFactory Message factory.
- * @param msgCls Message class to read.
* @return Message reader.
* @throws IgniteCheckedException In case of error.
*/
- public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls)
- throws IgniteCheckedException;
+ public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory) throws IgniteCheckedException;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/1c697f35/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
index 0830bad..1cb202c 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
@@ -700,7 +700,7 @@ public abstract class IgniteSpiAdapter implements IgniteSpi, IgniteSpiManagement
throw new IgniteException("Failed to write message, node is not started.");
}
- @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory) {
throw new IgniteException("Failed to read message, node is not started.");
}
};
http://git-wip-us.apache.org/repos/asf/ignite/blob/1c697f35/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 795d168..0c1bd10 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
@@ -1589,8 +1589,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
UUID rmtNodeId = ses.meta(NODE_ID_META);
- // TODO: DIRECT - class is null
- return rmtNodeId != null ? formatter.reader(rmtNodeId, msgFactory, null) : null;
+ return rmtNodeId != null ? formatter.reader(rmtNodeId, msgFactory) : null;
}
};
@@ -2971,8 +2970,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
UUID rmtNodeId = ses.meta(NODE_ID_META);
- // TODO: DIRECT - class is null
- return rmtNodeId != null ? formatter.reader(rmtNodeId, msgFactory, null) : null;
+ return rmtNodeId != null ? formatter.reader(rmtNodeId, msgFactory) : null;
}
};
http://git-wip-us.apache.org/repos/asf/ignite/blob/1c697f35/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
index 4025ddd..e257a97 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
@@ -43,7 +43,6 @@ import org.apache.ignite.internal.managers.communication.GridMessageListener;
import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
@@ -497,7 +496,7 @@ public class GridSpiTestContext implements IgniteSpiContext {
return new DirectMessageWriter(GridIoManager.DIRECT_PROTO_VER);
}
- @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory) {
return new DirectMessageReader(msgFactory, GridIoManager.DIRECT_PROTO_VER);
}
};
[03/51] ignite git commit: Ignite-1093 "Rebalancing with default
parameters is very slow" fixes.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/242d988a/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
new file mode 100644
index 0000000..35cedf9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/preloader/GridDhtPartitionDemander.java
@@ -0,0 +1,1389 @@
+/*
+ * 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.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;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.locks.ReadWriteLock;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cache.CacheRebalanceMode;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.events.DiscoveryEvent;
+import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.processors.cache.CacheEntryInfoCollection;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryInfo;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
+import org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtLocalPartition;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
+import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
+import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter;
+import org.apache.ignite.internal.util.GridLeanSet;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.CI1;
+import org.apache.ignite.internal.util.typedef.CI2;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.LT;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.spi.IgniteSpiException;
+import org.jetbrains.annotations.Nullable;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_OBJECT_LOADED;
+import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_PART_LOADED;
+import static org.apache.ignite.events.EventType.EVT_CACHE_REBALANCE_STOPPED;
+import static org.apache.ignite.internal.GridTopic.TOPIC_CACHE;
+import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.MOVING;
+import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
+import static org.apache.ignite.internal.processors.dr.GridDrType.DR_PRELOAD;
+
+/**
+ * Thread pool for requesting partitions from other nodes and populating local cache.
+ */
+@SuppressWarnings("NonConstantFieldWithUpperCaseName")
+public class GridDhtPartitionDemander {
+ /** */
+ private final GridCacheContext<?, ?> cctx;
+
+ /** */
+ private final IgniteLogger log;
+
+ /** Preload predicate. */
+ private IgnitePredicate<GridCacheEntryInfo> preloadPred;
+
+ /** Future for preload mode {@link CacheRebalanceMode#SYNC}. */
+ @GridToStringInclude
+ private final GridFutureAdapter syncFut = new GridFutureAdapter();
+
+ /** Rebalance future. */
+ @GridToStringInclude
+ private volatile RebalanceFuture rebalanceFut;
+
+ /** Last timeout object. */
+ private AtomicReference<GridTimeoutObject> lastTimeoutObj = new AtomicReference<>();
+
+ /** Last exchange future. */
+ private volatile GridDhtPartitionsExchangeFuture lastExchangeFut;
+
+ /** Demand lock. */
+ @Deprecated//Backward compatibility. To be removed in future.
+ private final ReadWriteLock demandLock;
+
+ /** DemandWorker index. */
+ @Deprecated//Backward compatibility. To be removed in future.
+ private final AtomicInteger dmIdx = new AtomicInteger();
+
+ /** Cached rebalance topics. */
+ private final Map<Integer, Object> rebalanceTopics;
+
+ /**
+ * @param cctx Cctx.
+ * @param demandLock Demand lock.
+ */
+ public GridDhtPartitionDemander(GridCacheContext<?, ?> cctx, ReadWriteLock demandLock) {
+ assert cctx != null;
+
+ this.cctx = cctx;
+ this.demandLock = demandLock;
+
+ log = cctx.logger(getClass());
+
+ boolean enabled = cctx.rebalanceEnabled() && !cctx.kernalContext().clientNode();
+
+ rebalanceFut = new RebalanceFuture();//Dummy.
+
+ if (!enabled) {
+ // Calling onDone() immediately since preloading is disabled.
+ rebalanceFut.onDone(true);
+ syncFut.onDone();
+ }
+
+ Map<Integer, Object> tops = new HashMap<>();
+
+ for (int idx = 0; idx < cctx.gridConfig().getRebalanceThreadPoolSize(); idx++) {
+ tops.put(idx, GridCachePartitionExchangeManager.rebalanceTopic(idx));
+ }
+
+ rebalanceTopics = tops;
+ }
+
+ /**
+ * Start.
+ */
+ void start() {
+ // No-op.
+ }
+
+ /**
+ * Stop.
+ */
+ void stop() {
+ try {
+ rebalanceFut.cancel();
+ }
+ catch (Exception ex) {
+ rebalanceFut.onDone(false);
+ }
+
+ lastExchangeFut = null;
+
+ lastTimeoutObj.set(null);
+ }
+
+ /**
+ * @return Future for {@link CacheRebalanceMode#SYNC} mode.
+ */
+ IgniteInternalFuture<?> syncFuture() {
+ return syncFut;
+ }
+
+ /**
+ * @return Rebalance future.
+ */
+ IgniteInternalFuture<Boolean> rebalanceFuture() {
+ return rebalanceFut;
+ }
+
+ /**
+ * Sets preload predicate for demand pool.
+ *
+ * @param preloadPred Preload predicate.
+ */
+ void preloadPredicate(IgnitePredicate<GridCacheEntryInfo> preloadPred) {
+ this.preloadPred = preloadPred;
+ }
+
+ /**
+ * Force preload.
+ */
+ void forcePreload() {
+ GridTimeoutObject obj = lastTimeoutObj.getAndSet(null);
+
+ if (obj != null)
+ cctx.time().removeTimeoutObject(obj);
+
+ final GridDhtPartitionsExchangeFuture exchFut = lastExchangeFut;
+
+ if (exchFut != null) {
+ if (log.isDebugEnabled())
+ log.debug("Forcing rebalance event for future: " + exchFut);
+
+ exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
+ @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> t) {
+ cctx.shared().exchange().forcePreloadExchange(exchFut);
+ }
+ });
+ }
+ else if (log.isDebugEnabled())
+ log.debug("Ignoring force rebalance request (no topology event happened yet).");
+ }
+
+ /**
+ * @param fut Future.
+ * @return {@code True} if topology changed.
+ */
+ private boolean topologyChanged(RebalanceFuture fut) {
+ return
+ !cctx.affinity().affinityTopologyVersion().equals(fut.topologyVersion()) || // Topology already changed.
+ fut != rebalanceFut; // Same topology, but dummy exchange forced because of missing partitions.
+ }
+
+ /**
+ * @param part Partition.
+ * @param type Type.
+ * @param discoEvt Discovery event.
+ */
+ private void preloadEvent(int part, int type, DiscoveryEvent discoEvt) {
+ assert discoEvt != null;
+
+ cctx.events().addPreloadEvent(part, type, discoEvt.eventNode(), discoEvt.type(), discoEvt.timestamp());
+ }
+
+ /**
+ * @param name Cache name.
+ * @param fut Future.
+ */
+ private boolean waitForCacheRebalancing(String name, RebalanceFuture fut) throws IgniteCheckedException {
+ if (log.isDebugEnabled())
+ log.debug("Waiting for another cache to start rebalancing [cacheName=" + cctx.name() +
+ ", waitCache=" + name + ']');
+
+ RebalanceFuture wFut = (RebalanceFuture)cctx.kernalContext().cache().internalCache(name)
+ .preloader().rebalanceFuture();
+
+ if (!topologyChanged(fut) && wFut.updateSeq == fut.updateSeq) {
+ if (!wFut.get()) {
+ U.log(log, "Skipping waiting of " + name + " cache [top=" + fut.topologyVersion() +
+ "] (cache rebalanced with missed partitions)");
+
+ return false;
+ }
+
+ return true;
+ }
+ else {
+ U.log(log, "Skipping waiting of " + name + " cache [top=" + fut.topologyVersion() +
+ "] (topology already changed)");
+
+ return false;
+ }
+ }
+
+ /**
+ * @param assigns Assignments.
+ * @param force {@code True} if dummy reassign.
+ * @param caches Rebalancing of these caches will be finished before this started.
+ * @param cnt Counter.
+ * @throws IgniteCheckedException Exception
+ */
+ Callable<Boolean> addAssignments(final GridDhtPreloaderAssignments assigns, boolean force,
+ final Collection<String> caches, int cnt) {
+ if (log.isDebugEnabled())
+ log.debug("Adding partition assignments: " + assigns);
+
+ long delay = cctx.config().getRebalanceDelay();
+
+ if (delay == 0 || force) {
+ assert assigns != null;
+
+ final RebalanceFuture oldFut = rebalanceFut;
+
+ final RebalanceFuture fut = new RebalanceFuture(assigns, cctx, log, oldFut.isInitial(), cnt);
+
+ if (!oldFut.isInitial())
+ oldFut.cancel();
+ else
+ fut.listen(new CI1<IgniteInternalFuture<Boolean>>() {
+ @Override public void apply(IgniteInternalFuture<Boolean> future) {
+ oldFut.onDone(fut.result());
+ }
+ });
+
+ rebalanceFut = fut;
+
+ if (assigns.isEmpty()) {
+ fut.doneIfEmpty();
+
+ return null;
+ }
+
+ return new Callable<Boolean>() {
+ @Override public Boolean call() throws Exception {
+ for (String c : caches) {
+ if (!waitForCacheRebalancing(c, fut))
+ return false;
+ }
+
+ return requestPartitions(fut, assigns);
+ }
+ };
+ }
+ else if (delay > 0) {
+ GridTimeoutObject obj = lastTimeoutObj.get();
+
+ if (obj != null)
+ cctx.time().removeTimeoutObject(obj);
+
+ final GridDhtPartitionsExchangeFuture exchFut = lastExchangeFut;
+
+ assert exchFut != null : "Delaying rebalance process without topology event.";
+
+ obj = new GridTimeoutObjectAdapter(delay) {
+ @Override public void onTimeout() {
+ exchFut.listen(new CI1<IgniteInternalFuture<AffinityTopologyVersion>>() {
+ @Override public void apply(IgniteInternalFuture<AffinityTopologyVersion> f) {
+ cctx.shared().exchange().forcePreloadExchange(exchFut);
+ }
+ });
+ }
+ };
+
+ lastTimeoutObj.set(obj);
+
+ cctx.time().addTimeoutObject(obj);
+ }
+
+ return null;
+ }
+
+ /**
+ * @param fut Future.
+ */
+ private boolean requestPartitions(
+ RebalanceFuture fut,
+ GridDhtPreloaderAssignments assigns
+ ) throws IgniteCheckedException {
+ for (Map.Entry<ClusterNode, GridDhtPartitionDemandMessage> e : assigns.entrySet()) {
+ if (topologyChanged(fut))
+ return false;
+
+ final ClusterNode node = e.getKey();
+
+ GridDhtPartitionDemandMessage d = e.getValue();
+
+ fut.appendPartitions(node.id(), d.partitions());//Future preparation.
+ }
+
+ for (Map.Entry<ClusterNode, GridDhtPartitionDemandMessage> e : assigns.entrySet()) {
+ final ClusterNode node = e.getKey();
+
+ final CacheConfiguration cfg = cctx.config();
+
+ final Collection<Integer> parts = fut.remaining.get(node.id()).get2();
+
+ GridDhtPartitionDemandMessage d = e.getValue();
+
+ //Check remote node rebalancing API version.
+ if (node.version().compareTo(GridDhtPreloader.REBALANCING_VER_2_SINCE) >= 0) {
+ U.log(log, "Starting rebalancing [cache=" + cctx.name() + ", mode=" + cfg.getRebalanceMode() +
+ ", fromNode=" + node.id() + ", partitionsCount=" + parts.size() +
+ ", topology=" + fut.topologyVersion() + ", updateSeq=" + fut.updateSeq + "]");
+
+ int lsnrCnt = cctx.gridConfig().getRebalanceThreadPoolSize();
+
+ List<Set<Integer>> sParts = new ArrayList<>(lsnrCnt);
+
+ for (int cnt = 0; cnt < lsnrCnt; cnt++)
+ sParts.add(new HashSet<Integer>());
+
+ Iterator<Integer> it = parts.iterator();
+
+ int cnt = 0;
+
+ while (it.hasNext())
+ sParts.get(cnt++ % lsnrCnt).add(it.next());
+
+ for (cnt = 0; cnt < lsnrCnt; cnt++) {
+ if (!sParts.get(cnt).isEmpty()) {
+
+ // Create copy.
+ GridDhtPartitionDemandMessage initD = new GridDhtPartitionDemandMessage(d, sParts.get(cnt));
+
+ initD.topic(rebalanceTopics.get(cnt));
+ initD.updateSequence(fut.updateSeq);
+ initD.timeout(cctx.config().getRebalanceTimeout());
+
+ synchronized (fut) {
+ if (!fut.isDone())// Future can be already cancelled at this moment and all failovers happened.
+ // New requests will not be covered by failovers.
+ cctx.io().sendOrderedMessage(node,
+ rebalanceTopics.get(cnt), initD, cctx.ioPolicy(), initD.timeout());
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Requested rebalancing [from node=" + node.id() + ", listener index=" +
+ cnt + ", partitions count=" + sParts.get(cnt).size() +
+ " (" + partitionsList(sParts.get(cnt)) + ")]");
+ }
+ }
+ }
+ else {
+ U.log(log, "Starting rebalancing (old api) [cache=" + cctx.name() + ", mode=" + cfg.getRebalanceMode() +
+ ", fromNode=" + node.id() + ", partitionsCount=" + parts.size() +
+ ", topology=" + fut.topologyVersion() + ", updateSeq=" + fut.updateSeq + "]");
+
+ d.timeout(cctx.config().getRebalanceTimeout());
+ d.workerId(0);//old api support.
+
+ DemandWorker dw = new DemandWorker(dmIdx.incrementAndGet(), fut);
+
+ dw.run(node, d);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @param c Partitions.
+ * @return String representation of partitions list.
+ */
+ private String partitionsList(Collection<Integer> c) {
+ List<Integer> s = new ArrayList<>(c);
+
+ Collections.sort(s);
+
+ StringBuilder sb = new StringBuilder();
+
+ int start = -1;
+
+ int prev = -1;
+
+ Iterator<Integer> sit = s.iterator();
+
+ while (sit.hasNext()) {
+ int p = sit.next();
+
+ if (start == -1) {
+ start = p;
+ prev = p;
+ }
+
+ if (prev < p - 1) {
+ sb.append(start);
+
+ if (start != prev)
+ sb.append("-").append(prev);
+
+ sb.append(", ");
+
+ start = p;
+ }
+
+ if (!sit.hasNext()) {
+ sb.append(start);
+
+ if (start != p)
+ sb.append("-").append(p);
+ }
+
+ prev = p;
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * @param idx Index.
+ * @param id Node id.
+ * @param supply Supply.
+ */
+ public void handleSupplyMessage(
+ int idx,
+ final UUID id,
+ final GridDhtPartitionSupplyMessageV2 supply
+ ) {
+ AffinityTopologyVersion topVer = supply.topologyVersion();
+
+ final RebalanceFuture fut = rebalanceFut;
+
+ ClusterNode node = cctx.node(id);
+
+ if (node == null)
+ return;
+
+ if (!fut.isActual(supply.updateSequence())) // Current future have another update sequence.
+ return; // Supple message based on another future.
+
+ if (topologyChanged(fut)) // Topology already changed (for the future that supply message based on).
+ return;
+
+ if (log.isDebugEnabled())
+ log.debug("Received supply message: " + supply);
+
+ // Check whether there were class loading errors on unmarshal
+ if (supply.classError() != null) {
+ U.warn(log, "Rebalancing from node cancelled [node=" + id +
+ "]. Class got undeployed during preloading: " + supply.classError());
+
+ fut.cancel(id);
+
+ return;
+ }
+
+ final GridDhtPartitionTopology top = cctx.dht().topology();
+
+ try {
+ // Preload.
+ for (Map.Entry<Integer, CacheEntryInfoCollection> e : supply.infos().entrySet()) {
+ int p = e.getKey();
+
+ if (cctx.affinity().localNode(p, topVer)) {
+ GridDhtLocalPartition part = top.localPartition(p, topVer, true);
+
+ assert part != null;
+
+ if (part.state() == MOVING) {
+ boolean reserved = part.reserve();
+
+ assert reserved : "Failed to reserve partition [gridName=" +
+ cctx.gridName() + ", cacheName=" + cctx.namex() + ", part=" + part + ']';
+
+ part.lock();
+
+ try {
+ // Loop through all received entries and try to preload them.
+ for (GridCacheEntryInfo entry : e.getValue().infos()) {
+ if (!part.preloadingPermitted(entry.key(), entry.version())) {
+ if (log.isDebugEnabled())
+ log.debug("Preloading is not permitted for entry due to " +
+ "evictions [key=" + entry.key() +
+ ", ver=" + entry.version() + ']');
+
+ continue;
+ }
+
+ if (!preloadEntry(node, p, entry, topVer)) {
+ if (log.isDebugEnabled())
+ log.debug("Got entries for invalid partition during " +
+ "preloading (will skip) [p=" + p + ", entry=" + entry + ']');
+
+ break;
+ }
+ }
+
+ boolean last = supply.last().contains(p);
+
+ // If message was last for this partition,
+ // then we take ownership.
+ if (last) {
+ top.own(part);
+
+ fut.partitionDone(id, p);
+
+ if (log.isDebugEnabled())
+ log.debug("Finished rebalancing partition: " + part);
+ }
+ }
+ finally {
+ part.unlock();
+ part.release();
+ }
+ }
+ else {
+ fut.partitionDone(id, p);
+
+ if (log.isDebugEnabled())
+ log.debug("Skipping rebalancing partition (state is not MOVING): " + part);
+ }
+ }
+ else {
+ fut.partitionDone(id, p);
+
+ if (log.isDebugEnabled())
+ log.debug("Skipping rebalancing partition (it does not belong on current node): " + p);
+ }
+ }
+
+ // Only request partitions based on latest topology version.
+ for (Integer miss : supply.missed()) {
+ if (cctx.affinity().localNode(miss, topVer))
+ fut.partitionMissed(id, miss);
+ }
+
+ for (Integer miss : supply.missed())
+ fut.partitionDone(id, miss);
+
+ GridDhtPartitionDemandMessage d = new GridDhtPartitionDemandMessage(
+ supply.updateSequence(), supply.topologyVersion(), cctx.cacheId());
+
+ d.timeout(cctx.config().getRebalanceTimeout());
+
+ d.topic(rebalanceTopics.get(idx));
+
+ if (!topologyChanged(fut) && !fut.isDone()) {
+ // Send demand message.
+ cctx.io().sendOrderedMessage(node, rebalanceTopics.get(idx),
+ d, cctx.ioPolicy(), cctx.config().getRebalanceTimeout());
+ }
+ }
+ catch (IgniteCheckedException e) {
+ if (log.isDebugEnabled())
+ log.debug("Node left during rebalancing [node=" + node.id() +
+ ", msg=" + e.getMessage() + ']');
+ }
+ catch (IgniteSpiException e) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send message to node (current node is stopping?) [node=" + node.id() +
+ ", msg=" + e.getMessage() + ']');
+ }
+ }
+
+ /**
+ * @param pick Node picked for preloading.
+ * @param p Partition.
+ * @param entry Preloaded entry.
+ * @param topVer Topology version.
+ * @return {@code False} if partition has become invalid during preloading.
+ * @throws IgniteInterruptedCheckedException If interrupted.
+ */
+ private boolean preloadEntry(
+ ClusterNode pick,
+ int p,
+ GridCacheEntryInfo entry,
+ AffinityTopologyVersion topVer
+ ) throws IgniteCheckedException {
+ try {
+ GridCacheEntryEx cached = null;
+
+ try {
+ cached = cctx.dht().entryEx(entry.key());
+
+ if (log.isDebugEnabled())
+ log.debug("Rebalancing key [key=" + entry.key() + ", part=" + p + ", node=" + pick.id() + ']');
+
+ if (cctx.dht().isIgfsDataCache() &&
+ cctx.dht().igfsDataSpaceUsed() > cctx.dht().igfsDataSpaceMax()) {
+ LT.error(log, null, "Failed to rebalance IGFS data cache (IGFS space size exceeded maximum " +
+ "value, will ignore rebalance entries)");
+
+ if (cached.markObsoleteIfEmpty(null))
+ cached.context().cache().removeIfObsolete(cached.key());
+
+ 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
+ )) {
+ 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);
+ }
+ else 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);
+ }
+ catch (GridCacheEntryRemovedException ignored) {
+ if (log.isDebugEnabled())
+ log.debug("Entry has been concurrently removed while rebalancing (will ignore) [key=" +
+ cached.key() + ", part=" + p + ']');
+ }
+ catch (GridDhtInvalidPartitionException ignored) {
+ if (log.isDebugEnabled())
+ log.debug("Partition became invalid during rebalancing (will ignore): " + p);
+
+ return false;
+ }
+ }
+ catch (IgniteInterruptedCheckedException e) {
+ throw e;
+ }
+ catch (IgniteCheckedException e) {
+ throw new IgniteCheckedException("Failed to cache rebalanced entry (will stop rebalancing) [local=" +
+ cctx.nodeId() + ", node=" + pick.id() + ", key=" + entry.key() + ", part=" + p + ']', e);
+ }
+
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(GridDhtPartitionDemander.class, this);
+ }
+
+ /**
+ * Sets last exchange future.
+ *
+ * @param lastFut Last future to set.
+ */
+ void updateLastExchangeFuture(GridDhtPartitionsExchangeFuture lastFut) {
+ lastExchangeFut = lastFut;
+ }
+
+ /**
+ *
+ */
+ public static class RebalanceFuture extends GridFutureAdapter<Boolean> {
+ /** */
+ private static final long serialVersionUID = 1L;
+
+ /** Should EVT_CACHE_REBALANCE_STOPPED event be sent of not. */
+ private final boolean sendStoppedEvnt;
+
+ /** */
+ private final GridCacheContext<?, ?> cctx;
+
+ /** */
+ private final IgniteLogger log;
+
+ /** Remaining. T2: startTime, partitions */
+ private final Map<UUID, T2<Long, Collection<Integer>>> remaining = new HashMap<>();
+
+ /** Missed. */
+ private final Map<UUID, Collection<Integer>> missed = new HashMap<>();
+
+ /** Exchange future. */
+ @GridToStringExclude
+ private final GridDhtPartitionsExchangeFuture exchFut;
+
+ /** Topology version. */
+ private final AffinityTopologyVersion topVer;
+
+ /** Unique (per demander) sequence id. */
+ private final long updateSeq;
+
+ /**
+ * @param assigns Assigns.
+ * @param cctx Context.
+ * @param log Logger.
+ * @param sentStopEvnt Stop event flag.
+ */
+ RebalanceFuture(GridDhtPreloaderAssignments assigns,
+ GridCacheContext<?, ?> cctx,
+ IgniteLogger log,
+ boolean sentStopEvnt,
+ long updateSeq) {
+ assert assigns != null;
+
+ this.exchFut = assigns.exchangeFuture();
+ this.topVer = assigns.topologyVersion();
+ this.cctx = cctx;
+ this.log = log;
+ this.sendStoppedEvnt = sentStopEvnt;
+ this.updateSeq = updateSeq;
+ }
+
+ /**
+ * Dummy future. Will be done by real one.
+ */
+ public RebalanceFuture() {
+ this.exchFut = null;
+ this.topVer = null;
+ this.cctx = null;
+ this.log = null;
+ this.sendStoppedEvnt = false;
+ this.updateSeq = -1;
+ }
+
+ /**
+ * @return Topology version.
+ */
+ public AffinityTopologyVersion topologyVersion() {
+ return topVer;
+ }
+
+ /**
+ * @param updateSeq Update sequence.
+ * @return true in case future created for specified updateSeq, false in other case.
+ */
+ private boolean isActual(long updateSeq) {
+ return this.updateSeq == updateSeq;
+ }
+
+ /**
+ * @return Is initial (created at demander creation).
+ */
+ private boolean isInitial() {
+ return topVer == null;
+ }
+
+ /**
+ * @param nodeId Node id.
+ * @param parts Parts.
+ */
+ private void appendPartitions(UUID nodeId, Collection<Integer> parts) {
+ synchronized (this) {
+ remaining.put(nodeId, new T2<>(U.currentTimeMillis(), parts));
+ }
+ }
+
+ /**
+ *
+ */
+ private void doneIfEmpty() {
+ synchronized (this) {
+ if (isDone())
+ return;
+
+ assert remaining.isEmpty();
+
+ if (log.isDebugEnabled())
+ log.debug("Rebalancing is not required [cache=" + cctx.name() +
+ ", topology=" + topVer + "]");
+
+ checkIsDone();
+ }
+ }
+
+ /**
+ * Cancels this future.
+ *
+ * @return {@code true}.
+ */
+ @Override public boolean cancel() {
+ synchronized (this) {
+ if (isDone())
+ return true;
+
+ U.log(log, "Cancelled rebalancing from all nodes [cache=" + cctx.name()
+ + ", topology=" + topologyVersion());
+
+ for (UUID nodeId : remaining.keySet()) {
+ cleanupRemoteContexts(nodeId);
+ }
+
+ remaining.clear();
+
+ checkIsDone(true /* cancelled */);
+ }
+
+ return true;
+ }
+
+ /**
+ * @param nodeId Node id.
+ */
+ private void cancel(UUID nodeId) {
+ synchronized (this) {
+ if (isDone())
+ return;
+
+ U.log(log, ("Cancelled rebalancing [cache=" + cctx.name() +
+ ", fromNode=" + nodeId + ", topology=" + topologyVersion() +
+ ", time=" + (U.currentTimeMillis() - remaining.get(nodeId).get1()) + " ms]"));
+
+ cleanupRemoteContexts(nodeId);
+
+ remaining.remove(nodeId);
+
+ checkIsDone();
+ }
+
+ }
+
+ /**
+ * @param nodeId Node id.
+ * @param p P.
+ */
+ private void partitionMissed(UUID nodeId, int p) {
+ synchronized (this) {
+ if (isDone())
+ return;
+
+ if (missed.get(nodeId) == null)
+ missed.put(nodeId, new HashSet<Integer>());
+
+ missed.get(nodeId).add(p);
+ }
+ }
+
+ /**
+ * @param nodeId Node id.
+ */
+ private void cleanupRemoteContexts(UUID nodeId) {
+ ClusterNode node = cctx.discovery().node(nodeId);
+
+ if (node == null)
+ return;
+
+ //Check remote node rebalancing API version.
+ if (node.version().compareTo(GridDhtPreloader.REBALANCING_VER_2_SINCE) >= 0) {
+
+ GridDhtPartitionDemandMessage d = new GridDhtPartitionDemandMessage(
+ -1/* remove supply context signal */, this.topologyVersion(), cctx.cacheId());
+
+ d.timeout(cctx.config().getRebalanceTimeout());
+
+ try {
+ for (int idx = 0; idx < cctx.gridConfig().getRebalanceThreadPoolSize(); idx++) {
+ d.topic(GridCachePartitionExchangeManager.rebalanceTopic(idx));
+
+ cctx.io().sendOrderedMessage(node, GridCachePartitionExchangeManager.rebalanceTopic(idx),
+ d, cctx.ioPolicy(), cctx.config().getRebalanceTimeout());
+ }
+ }
+ catch (IgniteCheckedException e) {
+ if (log.isDebugEnabled())
+ log.debug("Failed to send failover context cleanup request to node");
+ }
+ }
+ }
+
+ /**
+ * @param nodeId Node id.
+ * @param p P.
+ */
+ private void partitionDone(UUID nodeId, int p) {
+ synchronized (this) {
+ if (isDone())
+ return;
+
+ if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_PART_LOADED))
+ preloadEvent(p, EVT_CACHE_REBALANCE_PART_LOADED,
+ exchFut.discoveryEvent());
+
+ Collection<Integer> parts = remaining.get(nodeId).get2();
+
+ if (parts != null) {
+ boolean removed = parts.remove(p);
+
+ assert removed;
+
+ if (parts.isEmpty()) {
+ U.log(log, "Completed " + ((remaining.size() == 1 ? "(final) " : "") +
+ "rebalancing [cache=" + cctx.name() +
+ ", fromNode=" + nodeId + ", topology=" + topologyVersion() +
+ ", time=" + (U.currentTimeMillis() - remaining.get(nodeId).get1()) + " ms]"));
+
+ remaining.remove(nodeId);
+ }
+ }
+
+ checkIsDone();
+ }
+ }
+
+ /**
+ * @param part Partition.
+ * @param type Type.
+ * @param discoEvt Discovery event.
+ */
+ private void preloadEvent(int part, int type, DiscoveryEvent discoEvt) {
+ assert discoEvt != null;
+
+ cctx.events().addPreloadEvent(part, type, discoEvt.eventNode(), discoEvt.type(), discoEvt.timestamp());
+ }
+
+ /**
+ * @param type Type.
+ * @param discoEvt Discovery event.
+ */
+ private void preloadEvent(int type, DiscoveryEvent discoEvt) {
+ preloadEvent(-1, type, discoEvt);
+ }
+
+ /**
+ *
+ */
+ private void checkIsDone() {
+ checkIsDone(false);
+ }
+
+ /**
+ * @param cancelled Is cancelled.
+ */
+ private void checkIsDone(boolean cancelled) {
+ if (remaining.isEmpty()) {
+ if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_STOPPED) && (!cctx.isReplicated() || sendStoppedEvnt))
+ preloadEvent(EVT_CACHE_REBALANCE_STOPPED, exchFut.discoveryEvent());
+
+ if (log.isDebugEnabled())
+ log.debug("Completed rebalance future.");
+
+ cctx.shared().exchange().scheduleResendPartitions();
+
+ Collection<Integer> m = new HashSet<>();
+
+ for (Map.Entry<UUID, Collection<Integer>> e : missed.entrySet()) {
+ if (e.getValue() != null && !e.getValue().isEmpty())
+ m.addAll(e.getValue());
+ }
+
+ if (!m.isEmpty()) {
+ U.log(log, ("Reassigning partitions that were missed: " + m));
+
+ onDone(false); //Finished but has missed partitions, will force dummy exchange
+
+ cctx.shared().exchange().forceDummyExchange(true, exchFut);
+
+ return;
+ }
+
+ if (!cancelled && !cctx.preloader().syncFuture().isDone())
+ ((GridFutureAdapter)cctx.preloader().syncFuture()).onDone();
+
+ onDone(!cancelled);
+ }
+ }
+ }
+
+ /**
+ * Supply message wrapper.
+ */
+ @Deprecated//Backward compatibility. To be removed in future.
+ private static class SupplyMessage {
+ /** Sender ID. */
+ private UUID sndId;
+
+ /** Supply message. */
+ private GridDhtPartitionSupplyMessage supply;
+
+ /**
+ * Dummy constructor.
+ */
+ private SupplyMessage() {
+ // No-op.
+ }
+
+ /**
+ * @param sndId Sender ID.
+ * @param supply Supply message.
+ */
+ SupplyMessage(UUID sndId, GridDhtPartitionSupplyMessage supply) {
+ this.sndId = sndId;
+ this.supply = supply;
+ }
+
+ /**
+ * @return Sender ID.
+ */
+ UUID senderId() {
+ return sndId;
+ }
+
+ /**
+ * @return Message.
+ */
+ GridDhtPartitionSupplyMessage supply() {
+ return supply;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(SupplyMessage.class, this);
+ }
+ }
+
+ /**
+ *
+ */
+ @Deprecated//Backward compatibility. To be removed in future.
+ private class DemandWorker {
+ /** Worker ID. */
+ private int id;
+
+ /** Partition-to-node assignments. */
+ private final LinkedBlockingDeque<GridDhtPreloaderAssignments> assignQ = new LinkedBlockingDeque<>();
+
+ /** Message queue. */
+ private final LinkedBlockingDeque<SupplyMessage> msgQ =
+ new LinkedBlockingDeque<>();
+
+ /** Counter. */
+ private long cntr;
+
+ /** Hide worker logger and use cache logger instead. */
+ private IgniteLogger log = GridDhtPartitionDemander.this.log;
+
+ private volatile RebalanceFuture fut;
+
+ /**
+ * @param id Worker ID.
+ */
+ private DemandWorker(int id, RebalanceFuture fut) {
+ assert id >= 0;
+
+ this.id = id;
+ this.fut = fut;
+ }
+
+ /**
+ * @param msg Message.
+ */
+ private void addMessage(SupplyMessage msg) {
+ msgQ.offer(msg);
+ }
+
+ /**
+ * @param deque Deque to poll from.
+ * @param time Time to wait.
+ * @return Polled item.
+ * @throws InterruptedException If interrupted.
+ */
+ @Nullable private <T> T poll(BlockingQueue<T> deque, long time) throws InterruptedException {
+ return deque.poll(time, MILLISECONDS);
+ }
+
+ /**
+ * @param idx Unique index for this topic.
+ * @return Topic for partition.
+ */
+ public Object topic(long idx) {
+ return TOPIC_CACHE.topic(cctx.namexx(), cctx.nodeId(), id, idx);
+ }
+
+ /**
+ * @param node Node to demand from.
+ * @param topVer Topology version.
+ * @param d Demand message.
+ * @param exchFut Exchange future.
+ * @throws InterruptedException If interrupted.
+ * @throws ClusterTopologyCheckedException If node left.
+ * @throws IgniteCheckedException If failed to send message.
+ */
+ private void demandFromNode(
+ ClusterNode node,
+ final AffinityTopologyVersion topVer,
+ GridDhtPartitionDemandMessage d,
+ GridDhtPartitionsExchangeFuture exchFut
+ ) throws InterruptedException, IgniteCheckedException {
+ GridDhtPartitionTopology top = cctx.dht().topology();
+
+ cntr++;
+
+ d.topic(topic(cntr));
+ d.workerId(id);
+
+ if (topologyChanged(fut))
+ return;
+
+ cctx.io().addOrderedHandler(d.topic(), new CI2<UUID, GridDhtPartitionSupplyMessage>() {
+ @Override public void apply(UUID nodeId, GridDhtPartitionSupplyMessage msg) {
+ addMessage(new SupplyMessage(nodeId, msg));
+ }
+ });
+
+ try {
+ boolean retry;
+
+ // DoWhile.
+ // =======
+ do {
+ retry = false;
+
+ // Create copy.
+ d = new GridDhtPartitionDemandMessage(d, fut.remaining.get(node.id()).get2());
+
+ long timeout = cctx.config().getRebalanceTimeout();
+
+ d.timeout(timeout);
+
+ if (log.isDebugEnabled())
+ log.debug("Sending demand message [node=" + node.id() + ", demand=" + d + ']');
+
+ // Send demand message.
+ cctx.io().send(node, d, cctx.ioPolicy());
+
+ // While.
+ // =====
+ while (!topologyChanged(fut)) {
+ SupplyMessage s = poll(msgQ, timeout);
+
+ // If timed out.
+ if (s == null) {
+ if (msgQ.isEmpty()) { // Safety check.
+ U.warn(log, "Timed out waiting for partitions to load, will retry in " + timeout +
+ " ms (you may need to increase 'networkTimeout' or 'rebalanceBatchSize'" +
+ " configuration properties).");
+
+ // Ordered listener was removed if timeout expired.
+ cctx.io().removeOrderedHandler(d.topic());
+
+ // Must create copy to be able to work with IO manager thread local caches.
+ d = new GridDhtPartitionDemandMessage(d, fut.remaining.get(node.id()).get2());
+
+ // Create new topic.
+ d.topic(topic(++cntr));
+
+ // Create new ordered listener.
+ cctx.io().addOrderedHandler(d.topic(),
+ new CI2<UUID, GridDhtPartitionSupplyMessage>() {
+ @Override public void apply(UUID nodeId,
+ GridDhtPartitionSupplyMessage msg) {
+ addMessage(new SupplyMessage(nodeId, msg));
+ }
+ });
+
+ // Resend message with larger timeout.
+ retry = true;
+
+ break; // While.
+ }
+ else
+ continue; // While.
+ }
+
+ // Check that message was received from expected node.
+ if (!s.senderId().equals(node.id())) {
+ U.warn(log, "Received supply message from unexpected node [expectedId=" + node.id() +
+ ", rcvdId=" + s.senderId() + ", msg=" + s + ']');
+
+ continue; // While.
+ }
+
+ if (log.isDebugEnabled())
+ log.debug("Received supply message: " + s);
+
+ GridDhtPartitionSupplyMessage supply = s.supply();
+
+ // Check whether there were class loading errors on unmarshal
+ if (supply.classError() != null) {
+ if (log.isDebugEnabled())
+ log.debug("Class got undeployed during preloading: " + supply.classError());
+
+ retry = true;
+
+ // Quit preloading.
+ break;
+ }
+
+ // Preload.
+ for (Map.Entry<Integer, CacheEntryInfoCollection> e : supply.infos().entrySet()) {
+ int p = e.getKey();
+
+ if (cctx.affinity().localNode(p, topVer)) {
+ GridDhtLocalPartition part = top.localPartition(p, topVer, true);
+
+ assert part != null;
+
+ if (part.state() == MOVING) {
+ boolean reserved = part.reserve();
+
+ assert reserved : "Failed to reserve partition [gridName=" +
+ cctx.gridName() + ", cacheName=" + cctx.namex() + ", part=" + part + ']';
+
+ part.lock();
+
+ try {
+ Collection<Integer> invalidParts = new GridLeanSet<>();
+
+ // Loop through all received entries and try to preload them.
+ for (GridCacheEntryInfo entry : e.getValue().infos()) {
+ if (!invalidParts.contains(p)) {
+ if (!part.preloadingPermitted(entry.key(), entry.version())) {
+ if (log.isDebugEnabled())
+ log.debug("Preloading is not permitted for entry due to " +
+ "evictions [key=" + entry.key() +
+ ", ver=" + entry.version() + ']');
+
+ continue;
+ }
+
+ if (!preloadEntry(node, p, entry, topVer)) {
+ invalidParts.add(p);
+
+ if (log.isDebugEnabled())
+ log.debug("Got entries for invalid partition during " +
+ "preloading (will skip) [p=" + p + ", entry=" + entry + ']');
+ }
+ }
+ }
+
+ boolean last = supply.last().contains(p);
+
+ // If message was last for this partition,
+ // then we take ownership.
+ if (last) {
+ fut.partitionDone(node.id(), p);
+
+ top.own(part);
+
+ if (log.isDebugEnabled())
+ log.debug("Finished rebalancing partition: " + part);
+
+ if (cctx.events().isRecordable(EVT_CACHE_REBALANCE_PART_LOADED))
+ preloadEvent(p, EVT_CACHE_REBALANCE_PART_LOADED,
+ exchFut.discoveryEvent());
+ }
+ }
+ finally {
+ part.unlock();
+ part.release();
+ }
+ }
+ else {
+ fut.partitionDone(node.id(), p);
+
+ if (log.isDebugEnabled())
+ log.debug("Skipping rebalancing partition (state is not MOVING): " + part);
+ }
+ }
+ else {
+ fut.partitionDone(node.id(), p);
+
+ if (log.isDebugEnabled())
+ log.debug("Skipping rebalancing partition (it does not belong on current node): " + p);
+ }
+ }
+
+ // Only request partitions based on latest topology version.
+ for (Integer miss : s.supply().missed()) {
+ if (cctx.affinity().localNode(miss, topVer))
+ fut.partitionMissed(node.id(), miss);
+ }
+
+ for (Integer miss : s.supply().missed())
+ fut.partitionDone(node.id(), miss);
+
+ if (fut.remaining.get(node.id()) == null)
+ break; // While.
+
+ if (s.supply().ack()) {
+ retry = true;
+
+ break;
+ }
+ }
+ }
+ while (retry && !topologyChanged(fut));
+ }
+ finally {
+ cctx.io().removeOrderedHandler(d.topic());
+ }
+ }
+
+ /**
+ * @param node Node.
+ * @param d D.
+ */
+ public void run(ClusterNode node, GridDhtPartitionDemandMessage d) throws IgniteCheckedException {
+ demandLock.readLock().lock();
+
+ try {
+ GridDhtPartitionsExchangeFuture exchFut = fut.exchFut;
+
+ AffinityTopologyVersion topVer = fut.topVer;
+
+ try {
+ demandFromNode(node, topVer, d, exchFut);
+ }
+ catch (InterruptedException e) {
+ throw new IgniteCheckedException(e);
+ }
+ }
+ finally {
+ demandLock.readLock().unlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(DemandWorker.class, this, "assignQ", assignQ, "msgQ", msgQ, "super", super.toString());
+ }
+ }
+}
[30/51] ignite git commit: Added advanced tests for
GridCacheLoadOnlyStoreAdapterSelfTest
Posted by vk...@apache.org.
Added advanced tests for GridCacheLoadOnlyStoreAdapterSelfTest
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d54fcbed
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d54fcbed
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d54fcbed
Branch: refs/heads/ignite-direct-marsh-opt
Commit: d54fcbedf9fdc110de8e73387a6796852b0ff42c
Parents: 8014712
Author: Denis Magda <dm...@gridgain.com>
Authored: Tue Nov 17 11:56:01 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Tue Nov 17 11:56:01 2015 +0300
----------------------------------------------------------------------
.../GridCacheLoadOnlyStoreAdapterSelfTest.java | 145 +++++++++++++++++--
1 file changed, 135 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/d54fcbed/modules/core/src/test/java/org/apache/ignite/cache/store/GridCacheLoadOnlyStoreAdapterSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/cache/store/GridCacheLoadOnlyStoreAdapterSelfTest.java b/modules/core/src/test/java/org/apache/ignite/cache/store/GridCacheLoadOnlyStoreAdapterSelfTest.java
index 70fae9c..461f562 100644
--- a/modules/core/src/test/java/org/apache/ignite/cache/store/GridCacheLoadOnlyStoreAdapterSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/cache/store/GridCacheLoadOnlyStoreAdapterSelfTest.java
@@ -20,6 +20,7 @@ package org.apache.ignite.cache.store;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
+import javax.cache.integration.CacheLoaderException;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.processors.cache.GridCacheAbstractSelfTest;
import org.apache.ignite.internal.util.typedef.T2;
@@ -33,8 +34,8 @@ public class GridCacheLoadOnlyStoreAdapterSelfTest extends GridCacheAbstractSelf
/** Expected loadAll arguments, hardcoded on call site for convenience. */
private static final Integer[] EXP_ARGS = {1, 2, 3};
- /** Test input size. */
- private static final int INPUT_SIZE = 100;
+ /** Store to use. */
+ private CacheLoadOnlyStoreAdapter store;
/** {@inheritDoc} */
@Override protected int gridCount() {
@@ -42,11 +43,33 @@ public class GridCacheLoadOnlyStoreAdapterSelfTest extends GridCacheAbstractSelf
}
/** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTest() throws Exception {
+
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+
+ }
+
+ /** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override protected CacheConfiguration cacheConfiguration(String gridName) throws Exception {
CacheConfiguration cfg = super.cacheConfiguration(gridName);
- cfg.setCacheStoreFactory(singletonFactory(new TestStore()));
+ assertNotNull(store);
+
+ cfg.setCacheStoreFactory(singletonFactory(store));
cfg.setReadThrough(true);
cfg.setWriteThrough(true);
cfg.setLoadPreviousValue(true);
@@ -58,20 +81,74 @@ public class GridCacheLoadOnlyStoreAdapterSelfTest extends GridCacheAbstractSelf
* @throws Exception If failed.
*/
public void testStore() throws Exception {
- jcache().localLoadCache(null, 1, 2, 3);
+ try {
+ int inputSize = 100;
+
+ store = new TestStore(inputSize);
+
+ startGrids(gridCount());
+
+ awaitPartitionMapExchange();
+
+ jcache().localLoadCache(null, 1, 2, 3);
+
+ int cnt = 0;
+
+ for (int i = 0; i < gridCount(); i++)
+ cnt += jcache(i).localSize();
+
+ assertEquals(inputSize - (inputSize / 10), cnt);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testStoreSmallQueueSize() throws Exception {
+ try {
+ int inputSize = 1500;
+
+ store = new ParallelTestStore(inputSize);
+
+ store.setBatchSize(1);
+ store.setBatchQueueSize(1);
+ store.setThreadsCount(2);
+
+ startGrids(gridCount());
+
+ awaitPartitionMapExchange();
+
+ jcache().localLoadCache(null, 1, 2, 3);
- int cnt = 0;
+ int cnt = 0;
- for (int i = 0; i < gridCount(); i++)
- cnt += jcache(i).localSize();
+ for (int i = 0; i < gridCount(); i++)
+ cnt += jcache(i).localSize();
- assertEquals(INPUT_SIZE - (INPUT_SIZE/10), cnt);
+ assertEquals(inputSize, cnt);
+ }
+ finally {
+ stopAllGrids();
+ }
}
/**
*
*/
private static class TestStore extends CacheLoadOnlyStoreAdapter<Integer, String, String> {
+ /** */
+ private final int inputSize;
+
+ /**
+ * @param inputSize Input size.
+ */
+ public TestStore(int inputSize) {
+ this.inputSize = inputSize;
+ }
+
/** {@inheritDoc} */
@Override protected Iterator<String> inputIterator(@Nullable Object... args) {
assertNotNull(args);
@@ -81,7 +158,7 @@ public class GridCacheLoadOnlyStoreAdapterSelfTest extends GridCacheAbstractSelf
private int i = -1;
@Override public boolean hasNext() {
- return i < INPUT_SIZE;
+ return i < inputSize;
}
@Override public String next() {
@@ -111,4 +188,52 @@ public class GridCacheLoadOnlyStoreAdapterSelfTest extends GridCacheAbstractSelf
return i % 10 == 0 ? null : new T2<>(i, p[1]);
}
}
-}
\ No newline at end of file
+
+ /**
+ *
+ */
+ private static class ParallelTestStore extends CacheLoadOnlyStoreAdapter<Integer, String, String> {
+ /** */
+ private final int inputSize;
+
+ /**
+ * @param inputSize Input size.
+ */
+ public ParallelTestStore(int inputSize) {
+ this.inputSize = inputSize;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected Iterator<String> inputIterator(@Nullable Object... args) throws CacheLoaderException {
+ return new Iterator<String>() {
+ private int i;
+
+ @Override public boolean hasNext() {
+ return i < inputSize;
+ }
+
+ @Override public String next() {
+ if (!hasNext())
+ throw new NoSuchElementException();
+
+ String res = i + "=str" + i;
+
+ i++;
+
+ return res;
+ }
+
+ @Override public void remove() {
+ // No-op.
+ }
+ };
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override protected IgniteBiTuple<Integer, String> parse(String rec, @Nullable Object... args) {
+ String[] p = rec.split("=");
+
+ return new T2<>(Integer.parseInt(p[0]), p[1]);
+ }
+ }
+}
[09/51] ignite git commit: Merge branches 'ignite-1.5' and 'master'
of https://git-wip-us.apache.org/repos/asf/ignite
Posted by vk...@apache.org.
Merge branches 'ignite-1.5' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/44ddf657
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/44ddf657
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/44ddf657
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 44ddf657ec153fa5f5e594ea625cc45dda2176fe
Parents: 5d760a8 4ab2bd3
Author: Andrey <an...@gridgain.com>
Authored: Mon Nov 9 17:42:48 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Nov 9 17:42:48 2015 +0700
----------------------------------------------------------------------
.../processors/rest/handlers/query/QueryCommandHandler.java | 4 ----
1 file changed, 4 deletions(-)
----------------------------------------------------------------------
[21/51] ignite git commit: Merge branches 'ignite-1.5' and 'master'
of https://git-wip-us.apache.org/repos/asf/ignite
Posted by vk...@apache.org.
Merge branches 'ignite-1.5' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/440755f0
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/440755f0
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/440755f0
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 440755f070e68c142b68460a4e3dc733edbcd9d6
Parents: 84c88e0 1f5a409
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Nov 12 10:09:07 2015 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Nov 12 10:09:07 2015 +0700
----------------------------------------------------------------------
.../configuration/CacheConfiguration.java | 37 +++++++++
.../cache/CacheStoreBalancingWrapper.java | 5 +-
.../store/GridCacheStoreManagerAdapter.java | 3 +-
.../store/GridCacheBalancingStoreSelfTest.java | 53 ++++++++++--
modules/yardstick/README.txt | 16 ++--
.../config/benchmark-multicast.properties | 5 +-
.../yardstick/config/benchmark-store.properties | 86 ++++++++++++--------
.../ignite/yardstick/IgniteBenchmarkUtils.java | 75 +++++++++++++++++
.../IgniteAccountSerializableTxBenchmark.java | 11 ++-
.../cache/IgniteAccountTxBenchmark.java | 11 ++-
.../cache/IgniteGetAllPutAllTxBenchmark.java | 73 +++++++++++++++++
...IgniteTransactionalWriteInvokeBenchmark.java | 41 +---------
.../IgniteTransactionalWriteReadBenchmark.java | 41 +---------
13 files changed, 313 insertions(+), 144 deletions(-)
----------------------------------------------------------------------
[16/51] ignite git commit: Merge remote-tracking branch
'upstream/master'
Posted by vk...@apache.org.
Merge remote-tracking branch 'upstream/master'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0e1017b3
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0e1017b3
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0e1017b3
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 0e1017b35dd4d1b8e4c2f0c6aeed194e87d89203
Parents: 946360a 57ea0ff
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 10 16:49:21 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 10 16:49:21 2015 -0800
----------------------------------------------------------------------
.../java/org/apache/ignite/IgniteCache.java | 1 +
.../eviction/random/RandomEvictionPolicy.java | 4 +
.../processors/cache/GridCacheAdapter.java | 22 ++-
.../GridCachePartitionExchangeManager.java | 34 ++--
.../processors/cache/IgniteCacheProxy.java | 6 +
.../dht/preloader/GridDhtPartitionDemander.java | 25 ++-
.../GridCacheAtomicReferenceImpl.java | 2 +-
.../processors/igfs/IgfsMetaManager.java | 2 +-
.../org/apache/ignite/stream/StreamAdapter.java | 2 +-
.../store/GridCacheBalancingStoreSelfTest.java | 181 ++++++++++++++++++-
...CacheAtomicReferenceApiSelfAbstractTest.java | 20 +-
modules/rest-http/pom.xml | 11 ++
.../yardstick/config/ignite-store-config.xml | 31 ++--
modules/zookeeper/pom.xml | 2 +-
14 files changed, 294 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
[33/51] ignite git commit: IGNITE-529 Javadoc warning fix
Posted by vk...@apache.org.
IGNITE-529 Javadoc warning fix
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/38e66d93
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/38e66d93
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/38e66d93
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 38e66d93fffce130437355062c5c9d314e48b23b
Parents: 9a5fc05
Author: Anton Vinogradov <av...@apache.org>
Authored: Tue Nov 17 18:39:23 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Tue Nov 17 18:39:23 2015 +0300
----------------------------------------------------------------------
.../java/org/apache/ignite/stream/flume/EventTransformer.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/38e66d93/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
----------------------------------------------------------------------
diff --git a/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java b/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
index e85a98b..913ebb4 100644
--- a/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
+++ b/modules/flume/src/main/java/org/apache/ignite/stream/flume/EventTransformer.java
@@ -22,12 +22,12 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable;
/**
- * Flume event transformer to convert a list of Flume {@link Event} to cache entries.
+ * Flume event transformer to convert a list of Flume Events to cache entries.
*/
public interface EventTransformer<Event, K, V> {
/**
- * Transforms a list of Flume {@link Event} to cache entries.
+ * Transforms a list of Flume Events to cache entries.
*
* @param events List of Flume events to transform.
* @return Cache entries to be written into the grid.
[23/51] ignite git commit: Merge remote-tracking branch
'remotes/origin/ignite-1.5'
Posted by vk...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/af4e9488
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/af4e9488
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/af4e9488
Branch: refs/heads/ignite-direct-marsh-opt
Commit: af4e9488424cfed11b6279bf90e6b6921656f578
Parents: 440755f 5887ae4
Author: Anton Vinogradov <av...@apache.org>
Authored: Fri Nov 13 11:03:07 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Fri Nov 13 11:03:07 2015 +0300
----------------------------------------------------------------------
.../store/jdbc/CacheAbstractJdbcStore.java | 34 +++++++++++---------
1 file changed, 19 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
[46/51] ignite git commit: Direct marshalling backward compatibility
Posted by vk...@apache.org.
Direct marshalling backward compatibility
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e6911884
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e6911884
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e6911884
Branch: refs/heads/ignite-direct-marsh-opt
Commit: e69118848d5e041e01dd83186e3c7fb55f47162a
Parents: a73c67f
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Wed Nov 18 16:42:25 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Nov 18 16:42:25 2015 -0800
----------------------------------------------------------------------
.../managers/communication/GridIoManager.java | 8 +-
.../internal/util/ipc/IpcToNioAdapter.java | 14 ++--
.../util/nio/GridCommunicationClient.java | 4 +-
.../internal/util/nio/GridDirectParser.java | 16 ++--
.../util/nio/GridNioMessageReaderFactory.java | 35 +++++++++
.../util/nio/GridNioMessageWriterFactory.java | 33 ++++++++
.../ignite/internal/util/nio/GridNioServer.java | 31 ++++----
.../util/nio/GridShmemCommunicationClient.java | 6 +-
.../communication/MessageFormatter.java | 11 ++-
.../org/apache/ignite/spi/IgniteSpiAdapter.java | 6 +-
.../communication/tcp/TcpCommunicationSpi.java | 82 ++++++++++++--------
.../testframework/GridSpiTestContext.java | 6 +-
12 files changed, 174 insertions(+), 78 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index 3d4fbef..c3a708c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -276,11 +276,15 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
}
else {
formatter = new MessageFormatter() {
- @Override public MessageWriter writer() {
+ @Override public MessageWriter writer(UUID rmtNodeId) {
+ assert rmtNodeId != null;
+
return new DirectMessageWriter();
}
- @Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
+ assert rmtNodeId != null;
+
return new DirectMessageReader(msgFactory);
}
};
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/ipc/IpcToNioAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/ipc/IpcToNioAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/util/ipc/IpcToNioAdapter.java
index e732a79..6820dc7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/ipc/IpcToNioAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/ipc/IpcToNioAdapter.java
@@ -30,13 +30,13 @@ import org.apache.ignite.internal.util.nio.GridNioFilterAdapter;
import org.apache.ignite.internal.util.nio.GridNioFilterChain;
import org.apache.ignite.internal.util.nio.GridNioFinishedFuture;
import org.apache.ignite.internal.util.nio.GridNioFuture;
+import org.apache.ignite.internal.util.nio.GridNioMessageWriterFactory;
import org.apache.ignite.internal.util.nio.GridNioMetricsListener;
import org.apache.ignite.internal.util.nio.GridNioServerListener;
import org.apache.ignite.internal.util.nio.GridNioSession;
import org.apache.ignite.internal.util.nio.GridNioSessionImpl;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
/**
* Allows to re-use existing {@link GridNioFilter}s on IPC (specifically shared memory IPC)
@@ -65,23 +65,23 @@ public class IpcToNioAdapter<T> {
private final GridNioMetricsListener metricsLsnr;
/** */
- private final MessageFormatter formatter;
+ private final GridNioMessageWriterFactory writerFactory;
/**
* @param metricsLsnr Metrics listener.
* @param log Log.
* @param endp Endpoint.
* @param lsnr Listener.
- * @param formatter Message formatter.
+ * @param writerFactory Writer factory.
* @param filters Filters.
*/
public IpcToNioAdapter(GridNioMetricsListener metricsLsnr, IgniteLogger log, IpcEndpoint endp,
- GridNioServerListener<T> lsnr, MessageFormatter formatter, GridNioFilter... filters) {
+ GridNioServerListener<T> lsnr, GridNioMessageWriterFactory writerFactory, GridNioFilter... filters) {
assert metricsLsnr != null;
this.metricsLsnr = metricsLsnr;
this.endp = endp;
- this.formatter = formatter;
+ this.writerFactory = writerFactory;
chain = new GridNioFilterChain<>(log, lsnr, new HeadFilter(), filters);
ses = new GridNioSessionImpl(chain, null, null, true);
@@ -163,7 +163,7 @@ public class IpcToNioAdapter<T> {
assert writeBuf.hasArray();
try {
- int cnt = U.writeMessageFully(msg, endp.outputStream(), writeBuf, formatter.writer());
+ int cnt = U.writeMessageFully(msg, endp.outputStream(), writeBuf, writerFactory.writer(ses));
metricsLsnr.onBytesSent(cnt);
}
@@ -255,4 +255,4 @@ public class IpcToNioAdapter<T> {
proceedSessionWriteTimeout(ses);
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridCommunicationClient.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridCommunicationClient.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridCommunicationClient.java
index a933916..0de54e9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridCommunicationClient.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridCommunicationClient.java
@@ -94,7 +94,7 @@ public interface GridCommunicationClient {
public void sendMessage(byte[] data, int len) throws IgniteCheckedException;
/**
- * @param nodeId Node ID (provided only if versions of local and remote nodes are different).
+ * @param nodeId Remote node ID. Provided only for sync clients.
* @param msg Message to send.
* @param closure Ack closure.
* @throws IgniteCheckedException If failed.
@@ -107,4 +107,4 @@ public interface GridCommunicationClient {
* @return {@code True} if send is asynchronous.
*/
public boolean async();
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
index 5140cce..a4c9b02 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridDirectParser.java
@@ -23,7 +23,6 @@ import java.nio.ByteBuffer;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
-import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
import org.apache.ignite.plugin.extensions.communication.MessageReader;
import org.jetbrains.annotations.Nullable;
@@ -41,18 +40,18 @@ public class GridDirectParser implements GridNioParser {
private final MessageFactory msgFactory;
/** */
- private final MessageFormatter formatter;
+ private final GridNioMessageReaderFactory readerFactory;
/**
* @param msgFactory Message factory.
- * @param formatter Formatter.
+ * @param readerFactory Message reader factory.
*/
- public GridDirectParser(MessageFactory msgFactory, MessageFormatter formatter) {
+ public GridDirectParser(MessageFactory msgFactory, GridNioMessageReaderFactory readerFactory) {
assert msgFactory != null;
- assert formatter != null;
+ assert readerFactory != null;
this.msgFactory = msgFactory;
- this.formatter = formatter;
+ this.readerFactory = readerFactory;
}
/** {@inheritDoc} */
@@ -61,7 +60,7 @@ public class GridDirectParser implements GridNioParser {
MessageReader reader = ses.meta(READER_META_KEY);
if (reader == null)
- ses.addMeta(READER_META_KEY, reader = formatter.reader(msgFactory, null)); // TODO: class in null
+ ses.addMeta(READER_META_KEY, reader = readerFactory.reader(ses, msgFactory));
Message msg = ses.removeMeta(MSG_META_KEY);
@@ -74,7 +73,8 @@ public class GridDirectParser implements GridNioParser {
finished = msg.readFrom(buf, reader);
if (finished) {
- reader.reset();
+ if (reader != null)
+ reader.reset();
return msg;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
new file mode 100644
index 0000000..68c887f
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageReaderFactory.java
@@ -0,0 +1,35 @@
+/*
+ * 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.nio;
+
+import org.apache.ignite.plugin.extensions.communication.MessageFactory;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+
+/**
+ * Message reader factory.
+ */
+public interface GridNioMessageReaderFactory {
+ /**
+ * Creates new reader.
+ *
+ * @param ses Current session.
+ * @param msgFactory Message factory.
+ * @return Reader.
+ */
+ public MessageReader reader(GridNioSession ses, MessageFactory msgFactory);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.java
new file mode 100644
index 0000000..0c251c2
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioMessageWriterFactory.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.util.nio;
+
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+
+/**
+ * Message writer factory.
+ */
+public interface GridNioMessageWriterFactory {
+ /**
+ * Creates new writer.
+ *
+ * @param ses Current session.
+ * @return Writer.
+ */
+ public MessageWriter writer(GridNioSession ses);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
index 5bd08e7..c4710ad 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
@@ -62,7 +62,6 @@ import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageFormatter;
import org.apache.ignite.plugin.extensions.communication.MessageWriter;
import org.apache.ignite.thread.IgniteThread;
import org.jetbrains.annotations.Nullable;
@@ -176,7 +175,7 @@ public class GridNioServer<T> {
/** */
@GridToStringExclude
- private MessageFormatter formatter;
+ private GridNioMessageWriterFactory writerFactory;
/** */
@GridToStringExclude
@@ -212,7 +211,7 @@ public class GridNioServer<T> {
* @param directMode Whether direct mode is used.
* @param daemon Daemon flag to create threads.
* @param metricsLsnr Metrics listener.
- * @param formatter Message formatter.
+ * @param writerFactory Writer factory.
* @param skipRecoveryPred Skip recovery predicate.
* @param msgQueueLsnr Message queue size listener.
* @param filters Filters for this server.
@@ -234,7 +233,7 @@ public class GridNioServer<T> {
boolean directMode,
boolean daemon,
GridNioMetricsListener metricsLsnr,
- MessageFormatter formatter,
+ GridNioMessageWriterFactory writerFactory,
IgnitePredicate<Message> skipRecoveryPred,
IgniteBiInClosure<GridNioSession, Integer> msgQueueLsnr,
GridNioFilter... filters
@@ -304,7 +303,7 @@ public class GridNioServer<T> {
this.directMode = directMode;
this.metricsLsnr = metricsLsnr;
- this.formatter = formatter;
+ this.writerFactory = writerFactory;
this.skipRecoveryPred = skipRecoveryPred != null ? skipRecoveryPred : F.<Message>alwaysFalse();
}
@@ -935,7 +934,7 @@ public class GridNioServer<T> {
MessageWriter writer = ses.meta(MSG_WRITER.ordinal());
if (writer == null)
- ses.addMeta(MSG_WRITER.ordinal(), writer = formatter.writer());
+ ses.addMeta(MSG_WRITER.ordinal(), writer = writerFactory.writer(ses));
boolean handshakeFinished = sslFilter.lock(ses);
@@ -1130,7 +1129,7 @@ public class GridNioServer<T> {
MessageWriter writer = ses.meta(MSG_WRITER.ordinal());
if (writer == null)
- ses.addMeta(MSG_WRITER.ordinal(), writer = formatter.writer());
+ ses.addMeta(MSG_WRITER.ordinal(), writer = writerFactory.writer(ses));
if (req == null) {
req = (NioOperationFuture<?>)ses.pollFuture();
@@ -1152,7 +1151,7 @@ public class GridNioServer<T> {
finished = msg.writeTo(buf, writer);
- if (finished)
+ if (finished && writer != null)
writer.reset();
}
@@ -1176,7 +1175,7 @@ public class GridNioServer<T> {
finished = msg.writeTo(buf, writer);
- if (finished)
+ if (finished && writer != null)
writer.reset();
}
@@ -2221,8 +2220,8 @@ public class GridNioServer<T> {
/** Daemon flag. */
private boolean daemon;
- /** Message formatter. */
- private MessageFormatter formatter;
+ /** Writer factory. */
+ private GridNioMessageWriterFactory writerFactory;
/** Skip recovery predicate. */
private IgnitePredicate<Message> skipRecoveryPred;
@@ -2253,7 +2252,7 @@ public class GridNioServer<T> {
directMode,
daemon,
metricsLsnr,
- formatter,
+ writerFactory,
skipRecoveryPred,
msgQueueLsnr,
filters != null ? Arrays.copyOf(filters, filters.length) : EMPTY_FILTERS
@@ -2450,11 +2449,11 @@ public class GridNioServer<T> {
}
/**
- * @param formatter Message formatter.
+ * @param writerFactory Writer factory.
* @return This for chaining.
*/
- public Builder<T> messageFormatter(MessageFormatter formatter) {
- this.formatter = formatter;
+ public Builder<T> writerFactory(GridNioMessageWriterFactory writerFactory) {
+ this.writerFactory = writerFactory;
return this;
}
@@ -2479,4 +2478,4 @@ public class GridNioServer<T> {
return this;
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridShmemCommunicationClient.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridShmemCommunicationClient.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridShmemCommunicationClient.java
index 93e789d..0405b61 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridShmemCommunicationClient.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridShmemCommunicationClient.java
@@ -123,13 +123,15 @@ public class GridShmemCommunicationClient extends GridAbstractCommunicationClien
@Override public synchronized boolean sendMessage(@Nullable UUID nodeId, Message msg,
IgniteInClosure<IgniteException> closure)
throws IgniteCheckedException {
+ assert nodeId != null;
+
if (closed())
throw new IgniteCheckedException("Communication client was closed: " + this);
assert writeBuf.hasArray();
try {
- int cnt = U.writeMessageFully(msg, shmem.outputStream(), writeBuf, formatter.writer());
+ int cnt = U.writeMessageFully(msg, shmem.outputStream(), writeBuf, formatter.writer(nodeId));
metricsLsnr.onBytesSent(cnt);
}
@@ -154,4 +156,4 @@ public class GridShmemCommunicationClient extends GridAbstractCommunicationClien
@Override public String toString() {
return S.toString(GridShmemCommunicationClient.class, this, super.toString());
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
index 4c9e0ee..67dd0d3 100644
--- a/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
+++ b/modules/core/src/main/java/org/apache/ignite/plugin/extensions/communication/MessageFormatter.java
@@ -17,6 +17,7 @@
package org.apache.ignite.plugin.extensions.communication;
+import java.util.UUID;
import org.apache.ignite.plugin.Extension;
/**
@@ -33,16 +34,18 @@ public interface MessageFormatter extends Extension {
/**
* Creates new message writer instance.
*
+ * @param rmtNodeId Remote node ID.
* @return Message writer.
*/
- public MessageWriter writer();
+ public MessageWriter writer(UUID rmtNodeId);
/**
* Creates new message reader instance.
*
- * @param factory Message factory.
+ * @param rmtNodeId Remote node ID.
+ * @param msgFactory Message factory.
* @param msgCls Message class to read.
* @return Message reader.
*/
- public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls);
-}
\ No newline at end of file
+ public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
index cd46de4..0830bad 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/IgniteSpiAdapter.java
@@ -696,11 +696,11 @@ public abstract class IgniteSpiAdapter implements IgniteSpi, IgniteSpiManagement
if (msgFormatter0 == null) {
msgFormatter0 = new MessageFormatter() {
- @Override public MessageWriter writer() {
+ @Override public MessageWriter writer(UUID rmtNodeId) {
throw new IgniteException("Failed to write message, node is not started.");
}
- @Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
throw new IgniteException("Failed to read message, node is not started.");
}
};
@@ -880,4 +880,4 @@ public abstract class IgniteSpiAdapter implements IgniteSpi, IgniteSpiManagement
((IgniteKernal)ignite0).context().timeout().removeTimeoutObject(new GridSpiTimeoutObject(obj));
}
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/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 e8bd8a1..116998e 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
@@ -76,7 +76,9 @@ import org.apache.ignite.internal.util.nio.GridConnectionBytesVerifyFilter;
import org.apache.ignite.internal.util.nio.GridDirectParser;
import org.apache.ignite.internal.util.nio.GridNioCodecFilter;
import org.apache.ignite.internal.util.nio.GridNioFilter;
+import org.apache.ignite.internal.util.nio.GridNioMessageReaderFactory;
import org.apache.ignite.internal.util.nio.GridNioMessageTracker;
+import org.apache.ignite.internal.util.nio.GridNioMessageWriterFactory;
import org.apache.ignite.internal.util.nio.GridNioMetricsListener;
import org.apache.ignite.internal.util.nio.GridNioRecoveryDescriptor;
import org.apache.ignite.internal.util.nio.GridNioServer;
@@ -284,7 +286,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
public static final int DFLT_SELECTORS_CNT = Math.min(4, Runtime.getRuntime().availableProcessors());
/** Node ID meta for session. */
- private static final int NODE_ID_META = GridNioSessionMetaKey.nextUniqueKey();
+ public static final int NODE_ID_META = GridNioSessionMetaKey.nextUniqueKey();
/** Message tracker meta for session. */
private static final int TRACKER_META = GridNioSessionMetaKey.nextUniqueKey();
@@ -1575,29 +1577,38 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
}
};
- MessageFormatter msgFormatter = new MessageFormatter() {
- private MessageFormatter impl;
+ GridNioMessageReaderFactory readerFactory = new GridNioMessageReaderFactory() {
+ private MessageFormatter formatter;
- @Override public MessageWriter writer() {
- if (impl == null)
- impl = getSpiContext().messageFormatter();
+ @Override public MessageReader reader(GridNioSession ses, MessageFactory msgFactory) {
+ if (formatter == null)
+ formatter = getSpiContext().messageFormatter();
- assert impl != null;
+ assert formatter != null;
- return impl.writer();
+ UUID rmtNodeId = ses.meta(NODE_ID_META);
+
+ // TODO: DIRECT - class is null
+ return rmtNodeId != null ? formatter.reader(rmtNodeId, msgFactory, null) : null;
}
+ };
- @Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
- if (impl == null)
- impl = getSpiContext().messageFormatter();
+ GridNioMessageWriterFactory writerFactory = new GridNioMessageWriterFactory() {
+ private MessageFormatter formatter;
- assert impl != null;
+ @Override public MessageWriter writer(GridNioSession ses) {
+ if (formatter == null)
+ formatter = getSpiContext().messageFormatter();
+
+ assert formatter != null;
+
+ UUID rmtNodeId = ses.meta(NODE_ID_META);
- return impl.reader(factory, msgCls);
+ return rmtNodeId != null ? formatter.writer(rmtNodeId) : null;
}
};
- GridDirectParser parser = new GridDirectParser(msgFactory, msgFormatter);
+ GridDirectParser parser = new GridDirectParser(msgFactory, readerFactory);
IgnitePredicate<Message> skipRecoveryPred = new IgnitePredicate<Message>() {
@Override public boolean apply(Message msg) {
@@ -1658,7 +1669,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
.metricsListener(metricsLsnr)
.writeTimeout(sockWriteTimeout)
.filters(filters)
- .messageFormatter(msgFormatter)
+ .writerFactory(writerFactory)
.skipRecoveryPredicate(skipRecoveryPred)
.messageQueueSizeListener(queueSizeMonitor)
.build();
@@ -1918,7 +1929,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
UUID nodeId = null;
- if (!client.async() && !locNode.version().equals(node.version()))
+ if (!client.async())
nodeId = node.id();
retry = client.sendMessage(nodeId, msg, ackC);
@@ -2591,7 +2602,7 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
buf.order(ByteOrder.nativeOrder());
- boolean written = msg.writeTo(buf, getSpiContext().messageFormatter().writer());
+ boolean written = msg.writeTo(buf, null);
assert written;
@@ -2932,25 +2943,34 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
}
};
- MessageFormatter msgFormatter = new MessageFormatter() {
- private MessageFormatter impl;
+ GridNioMessageWriterFactory writerFactory = new GridNioMessageWriterFactory() {
+ private MessageFormatter formatter;
- @Override public MessageWriter writer() {
- if (impl == null)
- impl = getSpiContext().messageFormatter();
+ @Override public MessageWriter writer(GridNioSession ses) {
+ if (formatter == null)
+ formatter = getSpiContext().messageFormatter();
- assert impl != null;
+ assert formatter != null;
- return impl.writer();
+ UUID rmtNodeId = ses.meta(NODE_ID_META);
+
+ return rmtNodeId != null ? formatter.writer(rmtNodeId) : null;
}
+ };
- @Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
- if (impl == null)
- impl = getSpiContext().messageFormatter();
+ GridNioMessageReaderFactory readerFactory = new GridNioMessageReaderFactory() {
+ private MessageFormatter formatter;
- assert impl != null;
+ @Override public MessageReader reader(GridNioSession ses, MessageFactory msgFactory) {
+ if (formatter == null)
+ formatter = getSpiContext().messageFormatter();
+
+ assert formatter != null;
+
+ UUID rmtNodeId = ses.meta(NODE_ID_META);
- return impl.reader(factory, msgCls);
+ // TODO: DIRECT - class is null
+ return rmtNodeId != null ? formatter.reader(rmtNodeId, msgFactory, null) : null;
}
};
@@ -2959,8 +2979,8 @@ public class TcpCommunicationSpi extends IgniteSpiAdapter
log,
endpoint,
srvLsnr,
- msgFormatter,
- new GridNioCodecFilter(new GridDirectParser(msgFactory, msgFormatter), log, true),
+ writerFactory,
+ new GridNioCodecFilter(new GridDirectParser(msgFactory, readerFactory), log, true),
new GridConnectionBytesVerifyFilter(log)
);
http://git-wip-us.apache.org/repos/asf/ignite/blob/e6911884/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
index d9334eb..dc1a7e6 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/GridSpiTestContext.java
@@ -492,12 +492,12 @@ public class GridSpiTestContext implements IgniteSpiContext {
@Override public MessageFormatter messageFormatter() {
if (formatter == null) {
formatter = new MessageFormatter() {
- @Override public MessageWriter writer() {
+ @Override public MessageWriter writer(UUID rmtNodeId) {
return new DirectMessageWriter();
}
- @Override public MessageReader reader(MessageFactory factory, Class<? extends Message> msgCls) {
- return new DirectMessageReader(factory);
+ @Override public MessageReader reader(UUID rmtNodeId, MessageFactory msgFactory, Class<? extends Message> msgCls) {
+ return new DirectMessageReader(msgFactory);
}
};
}
[42/51] ignite git commit: Performance optimizations - reviewed by
Yakov.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
index e8546ef..1a26028 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
@@ -273,7 +273,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
* @throws IgniteCheckedException If failed.
* @throws GridDistributedLockCancelledException If lock has been cancelled.
*/
- @SuppressWarnings({"RedundantTypeArguments"})
+ @SuppressWarnings({"RedundantTypeArguments", "ForLoopReplaceableByForEach"})
@Nullable public GridNearTxRemote startRemoteTx(UUID nodeId, GridDhtLockRequest req)
throws IgniteCheckedException, GridDistributedLockCancelledException {
List<KeyCacheObject> nearKeys = req.nearKeys();
@@ -285,6 +285,7 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
if (ldr != null) {
Collection<IgniteTxKey> evicted = null;
+ // Avoid iterator creation.
for (int i = 0; i < nearKeys.size(); i++) {
KeyCacheObject key = nearKeys.get(i);
@@ -293,8 +294,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
IgniteTxKey txKey = ctx.txKey(key);
- Collection<GridCacheMvccCandidate> cands = req.candidatesByIndex(i);
-
if (log.isDebugEnabled())
log.debug("Unmarshalled key: " + key);
@@ -356,8 +355,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
req.owned(entry.key())
);
- assert cands.isEmpty() : "Received non-empty candidates in dht lock request: " + cands;
-
if (!req.inTx())
ctx.evicts().touch(entry, req.topologyVersion());
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index 31aa8c3..9c022b2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@ -40,6 +40,7 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridCompoundIdentityFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -332,6 +333,7 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
/**
* Initializes future.
*/
+ @SuppressWarnings("ForLoopReplaceableByForEach")
void finish() {
if (tx.onNeedCheckBackup()) {
assert tx.onePhaseCommit();
@@ -363,10 +365,18 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
if (!isSync() && !isDone()) {
boolean complete = true;
- for (IgniteInternalFuture<?> f : pending())
- // Mini-future in non-sync mode gets done when message gets sent.
- if (isMini(f) && !f.isDone())
- complete = false;
+ synchronized (futs) {
+ // Avoid collection copy and iterator creation.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<IgniteInternalTx> f = futs.get(i);
+
+ if (isMini(f) && !f.isDone()) {
+ complete = false;
+
+ break;
+ }
+ }
+ }
if (complete)
onComplete();
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 434b6c7..b92be31 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
@@ -461,21 +461,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/**
- * @param nodeId Node ID.
- * @param dhtVer DHT version.
- * @param writeVer Write version.
- */
- void addDhtVersion(UUID nodeId, GridCacheVersion dhtVer, GridCacheVersion writeVer) {
- // This step is very important as near and DHT versions grow separately.
- cctx.versions().onReceived(nodeId, dhtVer);
-
- GridDistributedTxMapping m = mappings.get(nodeId);
-
- if (m != null)
- m.dhtVersion(dhtVer, writeVer);
- }
-
- /**
* @param nodeId Undo mapping.
*/
@Override public boolean removeMapping(UUID nodeId) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
index 45477a0..cfaadc9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareFutureAdapter.java
@@ -172,6 +172,8 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundFuture<
assert res.error() == null : res;
assert F.isEmpty(res.invalidPartitions()) : res;
+ UUID nodeId = m.node().id();
+
for (Map.Entry<IgniteTxKey, CacheVersionedValue> entry : res.ownedValues().entrySet()) {
IgniteTxEntry txEntry = tx.entry(entry.getKey());
@@ -187,7 +189,7 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundFuture<
CacheVersionedValue tup = entry.getValue();
nearEntry.resetFromPrimary(tup.value(), tx.xidVersion(),
- tup.version(), m.node().id(), tx.topologyVersion());
+ tup.version(), nodeId, tx.topologyVersion());
}
else if (txEntry.cached().detached()) {
GridDhtDetachedCacheEntry detachedEntry = (GridDhtDetachedCacheEntry)txEntry.cached();
@@ -229,11 +231,17 @@ public abstract class GridNearTxPrepareFutureAdapter extends GridCompoundFuture<
if (writeVer == null)
writeVer = res.dhtVersion();
- // Register DHT version.
- tx.addDhtVersion(m.node().id(), res.dhtVersion(), writeVer);
+ // This step is very important as near and DHT versions grow separately.
+ cctx.versions().onReceived(nodeId, res.dhtVersion());
+ // Register DHT version.
m.dhtVersion(res.dhtVersion(), writeVer);
+ GridDistributedTxMapping map = tx.mappings().get(nodeId);
+
+ if (map != null)
+ map.dhtVersion(res.dhtVersion(), writeVer);
+
if (m.near())
tx.readyNearLocks(m, res.pending(), res.committedVersions(), res.rolledbackVersions());
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
index 798635a..9dfdb43 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
@@ -71,7 +71,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
/** Implicit single flag. */
private boolean implicitSingle;
- /** Explicit lock flag. Set to true if at leat one entry was explicitly locked. */
+ /** Explicit lock flag. Set to true if at least one entry was explicitly locked. */
private boolean explicitLock;
/** Subject ID. */
@@ -282,73 +282,73 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
}
switch (writer.state()) {
- case 22:
+ case 23:
if (!writer.writeBoolean("explicitLock", explicitLock))
return false;
writer.incrementState();
- case 23:
+ case 24:
if (!writer.writeBoolean("firstClientReq", firstClientReq))
return false;
writer.incrementState();
- case 24:
+ case 25:
if (!writer.writeIgniteUuid("futId", futId))
return false;
writer.incrementState();
- case 25:
+ case 26:
if (!writer.writeBoolean("implicitSingle", implicitSingle))
return false;
writer.incrementState();
- case 26:
+ case 27:
if (!writer.writeBoolean("last", last))
return false;
writer.incrementState();
- case 27:
+ case 28:
if (!writer.writeCollection("lastBackups", lastBackups, MessageCollectionItemType.UUID))
return false;
writer.incrementState();
- case 28:
+ case 29:
if (!writer.writeIgniteUuid("miniId", miniId))
return false;
writer.incrementState();
- case 29:
+ case 30:
if (!writer.writeBoolean("near", near))
return false;
writer.incrementState();
- case 30:
+ case 31:
if (!writer.writeBoolean("retVal", retVal))
return false;
writer.incrementState();
- case 31:
+ case 32:
if (!writer.writeUuid("subjId", subjId))
return false;
writer.incrementState();
- case 32:
+ case 33:
if (!writer.writeInt("taskNameHash", taskNameHash))
return false;
writer.incrementState();
- case 33:
+ case 34:
if (!writer.writeMessage("topVer", topVer))
return false;
@@ -370,7 +370,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
return false;
switch (reader.state()) {
- case 22:
+ case 23:
explicitLock = reader.readBoolean("explicitLock");
if (!reader.isLastRead())
@@ -378,7 +378,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 23:
+ case 24:
firstClientReq = reader.readBoolean("firstClientReq");
if (!reader.isLastRead())
@@ -386,7 +386,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 24:
+ case 25:
futId = reader.readIgniteUuid("futId");
if (!reader.isLastRead())
@@ -394,7 +394,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 25:
+ case 26:
implicitSingle = reader.readBoolean("implicitSingle");
if (!reader.isLastRead())
@@ -402,7 +402,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 26:
+ case 27:
last = reader.readBoolean("last");
if (!reader.isLastRead())
@@ -410,7 +410,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 27:
+ case 28:
lastBackups = reader.readCollection("lastBackups", MessageCollectionItemType.UUID);
if (!reader.isLastRead())
@@ -418,7 +418,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 28:
+ case 29:
miniId = reader.readIgniteUuid("miniId");
if (!reader.isLastRead())
@@ -426,7 +426,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 29:
+ case 30:
near = reader.readBoolean("near");
if (!reader.isLastRead())
@@ -434,7 +434,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 30:
+ case 31:
retVal = reader.readBoolean("retVal");
if (!reader.isLastRead())
@@ -442,7 +442,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 31:
+ case 32:
subjId = reader.readUuid("subjId");
if (!reader.isLastRead())
@@ -450,7 +450,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 32:
+ case 33:
taskNameHash = reader.readInt("taskNameHash");
if (!reader.isLastRead())
@@ -458,7 +458,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
reader.incrementState();
- case 33:
+ case 34:
topVer = reader.readMessage("topVer");
if (!reader.isLastRead())
@@ -478,7 +478,7 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
/** {@inheritDoc} */
@Override public byte fieldsCount() {
- return 34;
+ return 35;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
index f5f99f5..eb0db4a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.timeout.GridTimeoutObject;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.lang.GridTuple;
import org.apache.ignite.lang.IgniteAsyncSupported;
import org.apache.ignite.lang.IgniteUuid;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 6a0f8ab..3ddd909 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -54,6 +54,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEntryEx;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter;
import org.apache.ignite.internal.util.lang.GridTuple;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
index 9eb2808..23f83be 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxEntry.java
@@ -599,20 +599,20 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
*/
@SuppressWarnings("unchecked")
public CacheObject applyEntryProcessors(CacheObject cacheVal) {
- Object val = null;
- Object keyVal = null;
-
GridCacheVersion ver;
try {
ver = entry.version();
}
- catch (GridCacheEntryRemovedException e) {
+ catch (GridCacheEntryRemovedException ignore) {
assert tx == null || tx.optimistic() : tx;
ver = null;
}
+ Object val = null;
+ Object keyVal = null;
+
for (T2<EntryProcessor<Object, Object, Object>, Object[]> t : entryProcessors()) {
try {
CacheInvokeEntry<Object, Object> invokeEntry = new CacheInvokeEntry(ctx, key, keyVal, cacheVal, val,
@@ -1078,5 +1078,4 @@ public class IgniteTxEntry implements GridPeerDeployAware, Message {
@Override public String toString() {
return GridToStringBuilder.toString(IgniteTxEntry.class, this, "xidVer", tx == null ? "null" : tx.xidVersion());
}
-
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
index 5f48469..c75a8f38 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
@@ -147,6 +147,13 @@ public class IgniteTxImplicitSingleStateImpl extends IgniteTxLocalStateAdapter {
}
/** {@inheritDoc} */
+ @Override public boolean hasInterceptor(GridCacheSharedContext cctx) {
+ GridCacheContext ctx0 = cacheCtx;
+
+ return ctx0 != null && ctx0.config().getInterceptor() != null;
+ }
+
+ /** {@inheritDoc} */
@Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
if (cacheCtx == null)
return null;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index 758f82c..9e44b10 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -67,6 +67,7 @@ import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridLeanMap;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -74,7 +75,6 @@ import org.apache.ignite.internal.util.lang.GridClosureException;
import org.apache.ignite.internal.util.lang.GridInClosure3;
import org.apache.ignite.internal.util.lang.GridTuple;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
-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.C2;
@@ -358,6 +358,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @return {@code True} if transaction participates in a cache that has an interceptor configured.
+ */
+ public boolean hasInterceptor() {
+ return txState().hasInterceptor(cctx);
+ }
+
+ /**
* @param needRetVal Need return value flag.
*/
public void needReturnValue(boolean needRetVal) {
@@ -3045,7 +3052,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
try {
Set<?> keySet = map0 != null ? map0.keySet() : invokeMap0.keySet();
- final Collection<KeyCacheObject> enlisted = new ArrayList<>();
+ final Collection<KeyCacheObject> enlisted = new ArrayList<>(keySet.size());
CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
@@ -3434,7 +3441,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
*/
public boolean init() {
return !txState.init(txSize) || cctx.tm().onStarted(this);
-
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index ccccca0..67bca51 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -59,6 +59,7 @@ import org.apache.ignite.internal.processors.timeout.GridTimeoutObjectAdapter;
import org.apache.ignite.internal.transactions.IgniteTxOptimisticCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
import org.apache.ignite.internal.util.GridBoundedConcurrentOrderedMap;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridCompoundFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.lang.IgnitePair;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
index e7c4c96..3e5034b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
@@ -92,6 +92,11 @@ public abstract class IgniteTxRemoteStateAdapter implements IgniteTxRemoteState
}
/** {@inheritDoc} */
+ @Override public boolean hasInterceptor(GridCacheSharedContext cctx) {
+ return false;
+ }
+
+ /** {@inheritDoc} */
@Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
assert false;
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
index 81707ba..18fce8d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
@@ -101,6 +101,12 @@ public interface IgniteTxState {
/**
* @param cctx Context.
+ * @return {@code True} if transaction spans one or more caches with configured interceptor.
+ */
+ public boolean hasInterceptor(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
* @return Configured stores for active caches.
*/
public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx);
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 c95fb19..213c5e6 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
@@ -24,11 +24,13 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cache.CacheInterceptor;
import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.GridLongList;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.tostring.GridToStringInclude;
@@ -45,7 +47,7 @@ import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
*/
public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** Active cache IDs. */
- private Set<Integer> activeCacheIds = new HashSet<>();
+ private GridLongList activeCacheIds = new GridLongList();
/** Per-transaction read map. */
@GridToStringInclude
@@ -66,13 +68,13 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** {@inheritDoc} */
@Nullable @Override public Integer firstCacheId() {
- return F.first(activeCacheIds);
+ return activeCacheIds.isEmpty() ? null : (int)activeCacheIds.get(0);
}
/** {@inheritDoc} */
@Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
if (activeCacheIds.size() == 1) {
- int cacheId = F.first(activeCacheIds);
+ int cacheId = (int)activeCacheIds.get(0);
return cctx.cacheContext(cacheId);
}
@@ -82,8 +84,11 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** {@inheritDoc} */
@Override public void awaitLastFut(GridCacheSharedContext cctx) {
- for (Integer cacheId : activeCacheIds)
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
cctx.cacheContext(cacheId).cache().awaitLastFut();
+ }
}
/** {@inheritDoc} */
@@ -91,7 +96,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
GridDhtTopologyFuture topFut) {
StringBuilder invalidCaches = null;
- for (Integer cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext ctx = cctx.cacheContext(cacheId);
assert ctx != null : cacheId;
@@ -113,7 +120,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
invalidCaches.toString());
}
- for (int cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
if (CU.affinityNodes(cacheCtx, topFut.topologyVersion()).isEmpty()) {
@@ -127,7 +136,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** {@inheritDoc} */
@Override public boolean sync(GridCacheSharedContext cctx) {
- for (int cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
if (cctx.cacheContext(cacheId).config().getWriteSynchronizationMode() == FULL_SYNC)
return true;
}
@@ -137,7 +148,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** {@inheritDoc} */
@Override public boolean hasNearCache(GridCacheSharedContext cctx) {
- for (Integer cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
if (cacheCtx.isNear())
@@ -163,7 +176,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
int idx = 0;
- for (Integer activeCacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int activeCacheId = (int)activeCacheIds.get(i);
+
cacheNames.append(cctx.cacheContext(activeCacheId).name());
if (idx++ < activeCacheIds.size() - 1)
@@ -192,7 +207,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
GridCacheContext<?, ?> nonLocCtx = null;
- for (int cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
if (!cacheCtx.isLocal()) {
@@ -222,7 +239,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
if (!activeCacheIds.isEmpty()) {
GridCacheContext<?, ?> nonLocCtx = null;
- for (int cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
if (!cacheCtx.isLocal()) {
@@ -240,7 +259,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** {@inheritDoc} */
@Override public boolean storeUsed(GridCacheSharedContext cctx) {
if (!activeCacheIds.isEmpty()) {
- for (int cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
CacheStoreManager store = cctx.cacheContext(cacheId).store();
if (store.configured())
@@ -252,13 +273,29 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
}
/** {@inheritDoc} */
+ @Override public boolean hasInterceptor(GridCacheSharedContext cctx) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
+ CacheInterceptor interceptor = cctx.cacheContext(cacheId).config().getInterceptor();
+
+ if (interceptor != null)
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
@Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
- Collection<Integer> cacheIds = activeCacheIds;
+ GridLongList cacheIds = activeCacheIds;
if (!cacheIds.isEmpty()) {
Collection<CacheStoreManager> stores = new ArrayList<>(cacheIds.size());
- for (int cacheId : cacheIds) {
+ for (int i = 0; i < cacheIds.size(); i++) {
+ int cacheId = (int)cacheIds.get(i);
+
CacheStoreManager store = cctx.cacheContext(cacheId).store();
if (store.configured())
@@ -273,7 +310,9 @@ public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
/** {@inheritDoc} */
@Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
- for (int cacheId : activeCacheIds) {
+ for (int i = 0; i < activeCacheIds.size(); i++) {
+ int cacheId = (int)activeCacheIds.get(i);
+
GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
onTxEnd(cacheCtx, tx, commit);
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/processors/clock/GridClockSyncProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/clock/GridClockSyncProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/clock/GridClockSyncProcessor.java
index 21d3fb6..b5c89cf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/clock/GridClockSyncProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/clock/GridClockSyncProcessor.java
@@ -35,6 +35,7 @@ import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
import org.apache.ignite.internal.processors.GridProcessorAdapter;
import org.apache.ignite.internal.util.GridBoundedConcurrentOrderedMap;
import org.apache.ignite.internal.util.GridSpinReadWriteLock;
+import org.apache.ignite.internal.util.typedef.T2;
import org.apache.ignite.internal.util.typedef.internal.LT;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.util.worker.GridWorker;
@@ -71,6 +72,9 @@ public class GridClockSyncProcessor extends GridProcessorAdapter {
private NavigableMap<GridClockDeltaVersion, GridClockDeltaSnapshot> timeSyncHist =
new GridBoundedConcurrentOrderedMap<>(MAX_TIME_SYNC_HISTORY);
+ /** Last recorded. */
+ private volatile T2<GridClockDeltaVersion, GridClockDeltaSnapshot> lastSnapshot;
+
/** Time source. */
private GridClockSource clockSrc;
@@ -99,7 +103,11 @@ public class GridClockSyncProcessor extends GridProcessorAdapter {
GridClockDeltaVersion ver = msg0.snapshotVersion();
- timeSyncHist.put(ver, new GridClockDeltaSnapshot(ver, msg0.deltas()));
+ GridClockDeltaSnapshot snap = new GridClockDeltaSnapshot(ver, msg0.deltas());
+
+ lastSnapshot = new T2<>(ver, snap);
+
+ timeSyncHist.put(ver, snap);
}
});
@@ -265,11 +273,19 @@ public class GridClockSyncProcessor extends GridProcessorAdapter {
* @return Adjusted time.
*/
public long adjustedTime(long topVer) {
- // Get last synchronized time on given topology version.
- Map.Entry<GridClockDeltaVersion, GridClockDeltaSnapshot> entry = timeSyncHistory().lowerEntry(
- new GridClockDeltaVersion(0, topVer + 1));
+ T2<GridClockDeltaVersion, GridClockDeltaSnapshot> fastSnap = lastSnapshot;
+
+ GridClockDeltaSnapshot snap;
- GridClockDeltaSnapshot snap = entry == null ? null : entry.getValue();
+ if (fastSnap != null && fastSnap.get1().topologyVersion() == topVer)
+ snap = fastSnap.get2();
+ else {
+ // Get last synchronized time on given topology version.
+ Map.Entry<GridClockDeltaVersion, GridClockDeltaSnapshot> entry = timeSyncHistory().lowerEntry(
+ new GridClockDeltaVersion(0, topVer + 1));
+
+ snap = entry == null ? null : entry.getValue();
+ }
long now = clockSrc.currentTimeMillis();
@@ -295,6 +311,8 @@ public class GridClockSyncProcessor extends GridProcessorAdapter {
return;
try {
+ lastSnapshot = new T2<>(snapshot.version(), snapshot);
+
timeSyncHist.put(snapshot.version(), snapshot);
for (ClusterNode n : top.topologyNodes()) {
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/util/UUIDCollectionMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/UUIDCollectionMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/util/UUIDCollectionMessage.java
new file mode 100644
index 0000000..25e3376
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/UUIDCollectionMessage.java
@@ -0,0 +1,114 @@
+/*
+ * 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.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.UUID;
+import org.apache.ignite.internal.GridDirectCollection;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+
+/**
+ *
+ */
+public class UUIDCollectionMessage implements Message {
+ /** */
+ private static final long serialVersionUID = 0L;
+
+ /** */
+ @GridDirectCollection(UUID.class)
+ private Collection<UUID> uuids;
+
+ /**
+ * Empty constructor required for direct marshalling.
+ */
+ public UUIDCollectionMessage() {
+ // No-op.
+ }
+
+ /**
+ * @param uuids UUIDs to wrap.
+ */
+ public UUIDCollectionMessage(Collection<UUID> uuids) {
+ this.uuids = uuids;
+ }
+
+ /**
+ * @return The collection of UUIDs that was wrapped.
+ */
+ public Collection<UUID> uuids() {
+ return uuids;
+ }
+
+ /** {@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.writeCollection("uuids", uuids, MessageCollectionItemType.UUID))
+ 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:
+ uuids = reader.readCollection("uuids", MessageCollectionItemType.UUID);
+
+ if (!reader.isLastRead())
+ return false;
+
+ reader.incrementState();
+
+ }
+
+ return reader.afterMessageRead(UUIDCollectionMessage.class);
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte directType() {
+ return 115;
+ }
+
+ /** {@inheritDoc} */
+ @Override public byte fieldsCount() {
+ return 1;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java
index 31674f1..5f0d411 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/future/GridCompoundFuture.java
@@ -53,7 +53,7 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> {
AtomicIntegerFieldUpdater.newUpdater(GridCompoundFuture.class, "lsnrCalls");
/** Futures. */
- private final Collection<IgniteInternalFuture<T>> futs = new ArrayList<>();
+ protected final ArrayList<IgniteInternalFuture<T>> futs = new ArrayList<>();
/** Reducer. */
@GridToStringInclude
@@ -166,8 +166,19 @@ public class GridCompoundFuture<T, R> extends GridFutureAdapter<R> {
*
* @return {@code True} if there are pending futures.
*/
+ @SuppressWarnings("ForLoopReplaceableByForEach")
public boolean hasPending() {
- return !pending().isEmpty();
+ synchronized (futs) {
+ // Avoid iterator creation and collection copy.
+ for (int i = 0; i < futs.size(); i++) {
+ IgniteInternalFuture<T> fut = futs.get(i);
+
+ if (!fut.isDone())
+ return true;
+ }
+ }
+
+ return false;
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/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 c1d91a8..8d5a8e7 100644
--- 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
@@ -1866,6 +1866,8 @@ public class GridFunc {
assert m != null;
+ final boolean hasPred = p != null && p.length > 0;
+
return new GridSerializableMap<K, V1>() {
/** Entry predicate. */
private IgnitePredicate<Entry<K, V>> ep = new P1<Map.Entry<K, V>>() {
@@ -1911,7 +1913,7 @@ public class GridFunc {
}
@Override public int size() {
- return F.size(m.keySet(), p);
+ return hasPred ? F.size(m.keySet(), p) : m.size();
}
@SuppressWarnings({"unchecked"})
@@ -1925,13 +1927,13 @@ public class GridFunc {
}
@Override public boolean isEmpty() {
- return !iterator().hasNext();
+ return hasPred ? !iterator().hasNext() : m.isEmpty();
}
};
}
@Override public boolean isEmpty() {
- return entrySet().isEmpty();
+ return hasPred ? entrySet().isEmpty() : m.isEmpty();
}
@SuppressWarnings({"unchecked"})
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
index 1824339..5bd08e7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/nio/GridNioServer.java
@@ -1301,6 +1301,8 @@ public class GridNioServer<T> {
@SuppressWarnings("unchecked")
private void bodyInternal() throws IgniteCheckedException {
try {
+ long lastIdleCheck = U.currentTimeMillis();
+
while (!closed && selector.isOpen()) {
NioOperationFuture req;
@@ -1374,11 +1376,18 @@ public class GridNioServer<T> {
}
// Wake up every 2 seconds to check if closed.
- if (selector.select(2000) > 0)
+ if (selector.select(2000) > 0) {
// Walk through the ready keys collection and process network events.
processSelectedKeys(selector.selectedKeys());
+ }
- checkIdle(selector.keys());
+ long now = U.currentTimeMillis();
+
+ if (now - lastIdleCheck > 2000) {
+ lastIdleCheck = now;
+
+ checkIdle(selector.keys());
+ }
}
}
// Ignore this exception as thread interruption is equal to 'close' call.
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/integration/IgniteCacheTxStoreSessionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/integration/IgniteCacheTxStoreSessionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/integration/IgniteCacheTxStoreSessionTest.java
index 8957c5d..6424b8b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/integration/IgniteCacheTxStoreSessionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/integration/IgniteCacheTxStoreSessionTest.java
@@ -285,7 +285,7 @@ public class IgniteCacheTxStoreSessionTest extends IgniteCacheStoreSessionAbstra
expData.add(new ExpectedData(true, "write", new HashMap<>(), CACHE_NAME1));
expData.add(new ExpectedData(true, "write", F.<Object, Object>asMap(0, "write"), null));
- expData.add(new ExpectedData(true, "sessionEnd", F.<Object, Object>asMap(0, "write", 1, "write"), null));
+ expData.add(new ExpectedData(true, "sessionEnd", F.<Object, Object>asMap(0, "write", 1, "write"), CACHE_NAME1));
tx.commit();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/175b7f24/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
index c3c3659..ea13cdd 100644
--- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
+++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite3.java
@@ -51,6 +51,7 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridCachePut
import org.apache.ignite.internal.processors.cache.distributed.near.IgniteTxReentryNearSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingAsyncSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingSyncSelfTest;
+import org.apache.ignite.internal.processors.cache.distributed.rebalancing.GridCacheRebalancingUnmarshallingFailedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheDaemonNodeReplicatedSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedAtomicGetAndTransformStoreSelfTest;
import org.apache.ignite.internal.processors.cache.distributed.replicated.GridCacheReplicatedBasicApiTest;
@@ -138,6 +139,7 @@ public class IgniteCacheTestSuite3 extends TestSuite {
suite.addTestSuite(GridCacheOrderedPreloadingSelfTest.class);
suite.addTestSuite(GridCacheRebalancingSyncSelfTest.class);
+ suite.addTestSuite(GridCacheRebalancingUnmarshallingFailedSelfTest.class);
suite.addTestSuite(GridCacheRebalancingAsyncSelfTest.class);
// Test for byte array value special case.
[35/51] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index 2c7bf8a..758f82c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -66,9 +66,7 @@ import org.apache.ignite.internal.processors.dr.GridDrType;
import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
-import org.apache.ignite.internal.util.F0;
import org.apache.ignite.internal.util.GridLeanMap;
-import org.apache.ignite.internal.util.GridLeanSet;
import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -123,18 +121,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** */
private static final long serialVersionUID = 0L;
- /** Per-transaction read map. */
- @GridToStringInclude
- protected Map<IgniteTxKey, IgniteTxEntry> txMap;
-
- /** Read view on transaction map. */
- @GridToStringExclude
- protected IgniteTxMap readView;
-
- /** Write view on transaction map. */
- @GridToStringExclude
- protected IgniteTxMap writeView;
-
/** Minimal version encountered (either explicit lock or XID of this transaction). */
protected GridCacheVersion minVer;
@@ -156,9 +142,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** Commit error. */
protected AtomicReference<Throwable> commitErr = new AtomicReference<>();
- /** Active cache IDs. */
- protected Set<Integer> activeCacheIds = new HashSet<>();
-
/** Need return value. */
protected boolean needRetVal;
@@ -168,6 +151,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** Flag indicating whether deployment is enabled for caches from this transaction or not. */
private boolean depEnabled;
+ /** */
+ @GridToStringInclude
+ protected IgniteTxLocalState txState;
+
/**
* Empty constructor required for {@link Externalizable}.
*/
@@ -209,7 +196,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cctx,
xidVer,
implicit,
- implicitSingle,
/*local*/true,
sys,
plc,
@@ -225,6 +211,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
);
minVer = xidVer;
+
+ txState = implicitSingle ? new IgniteTxImplicitSingleStateImpl() : new IgniteTxStateImpl();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxState txState() {
+ return txState;
}
/**
@@ -246,7 +239,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public boolean empty() {
- return txMap.isEmpty();
+ return txState.empty();
}
/** {@inheritDoc} */
@@ -267,16 +260,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
assert false;
- return false;
- }
- /**
- * Gets collection of active cache IDs for this transaction.
- *
- * @return Collection of active cache IDs.
- */
- @Override public Collection<Integer> activeCacheIds() {
- return activeCacheIds;
+ return false;
}
/** {@inheritDoc} */
@@ -284,77 +269,70 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
return depEnabled;
}
+ /**
+ * @param depEnabled Flag indicating whether deployment is enabled for caches from this transaction or not.
+ */
+ public void activeCachesDeploymentEnabled(boolean depEnabled) {
+ this.depEnabled = depEnabled;
+ }
+
/** {@inheritDoc} */
@Override public boolean isStarted() {
- return txMap != null;
+ return txState.initialized();
}
/** {@inheritDoc} */
@Override public boolean hasWriteKey(IgniteTxKey key) {
- return writeView.containsKey(key);
+ return txState.hasWriteKey(key);
}
/**
* @return Transaction read set.
*/
@Override public Set<IgniteTxKey> readSet() {
- return txMap == null ? Collections.<IgniteTxKey>emptySet() : readView.keySet();
+ return txState.readSet();
}
/**
* @return Transaction write set.
*/
@Override public Set<IgniteTxKey> writeSet() {
- return txMap == null ? Collections.<IgniteTxKey>emptySet() : writeView.keySet();
- }
-
- /** {@inheritDoc} */
- @Override public boolean removed(IgniteTxKey key) {
- if (txMap == null)
- return false;
-
- IgniteTxEntry e = txMap.get(key);
-
- return e != null && e.op() == DELETE;
+ return txState.writeSet();
}
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
- return readView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : readView;
+ return txState.readMap();
}
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
- return writeView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : writeView;
+ return txState.writeMap();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> allEntries() {
- return txMap == null ? Collections.<IgniteTxEntry>emptySet() : txMap.values();
+ return txState.allEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> readEntries() {
- return readView == null ? Collections.<IgniteTxEntry>emptyList() : readView.values();
+ return txState.readEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> writeEntries() {
- return writeView == null ? Collections.<IgniteTxEntry>emptyList() : writeView.values();
+ return txState.writeEntries();
}
/** {@inheritDoc} */
@Nullable @Override public IgniteTxEntry entry(IgniteTxKey key) {
- return txMap == null ? null : txMap.get(key);
+ return txState.entry(key);
}
/** {@inheritDoc} */
@Override public void seal() {
- if (readView != null)
- readView.seal();
-
- if (writeView != null)
- writeView.seal();
+ txState.seal();
}
/** {@inheritDoc} */
@@ -409,7 +387,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
KeyCacheObject key,
CacheEntryPredicate[] filter
) throws GridCacheFilterFailedException {
- IgniteTxEntry e = txMap == null ? null : txMap.get(cacheCtx.txKey(key));
+ IgniteTxEntry e = entry(cacheCtx.txKey(key));
if (e != null) {
// We should look at tx entry previous value. If this is a user peek then previous
@@ -652,7 +630,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (!storeEnabled() || internal())
return;
- Collection<CacheStoreManager> stores = stores();
+ Collection<CacheStoreManager> stores = txState.stores(cctx);
if (stores == null || stores.isEmpty())
return;
@@ -854,7 +832,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
checkValid();
- boolean empty = F.isEmpty(near() ? txMap : writeMap());
+ Collection<IgniteTxEntry> commitEntries = near() ? allEntries() : writeEntries();
+
+ boolean empty = F.isEmpty(commitEntries);
// Register this transaction as completed prior to write-phase to
// ensure proper lock ordering for removed entries.
@@ -874,7 +854,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/*
* Commit to cache. Note that for 'near' transaction we loop through all the entries.
*/
- for (IgniteTxEntry txEntry : (near() ? allEntries() : writeEntries())) {
+ for (IgniteTxEntry txEntry : commitEntries) {
GridCacheContext cacheCtx = txEntry.context();
GridDrType drType = cacheCtx.isDrEnabled() ? DR_PRIMARY : DR_NONE;
@@ -1282,7 +1262,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cctx.tm().rollbackTx(this);
if (!internal()) {
- Collection<CacheStoreManager> stores = stores();
+ Collection<CacheStoreManager> stores = txState.stores(cctx);
if (stores != null && !stores.isEmpty()) {
assert isWriteToStoreFromDhtValid(stores) :
@@ -1582,25 +1562,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
- * Adds skipped key.
- *
- * @param skipped Skipped set (possibly {@code null}).
- * @param key Key to add.
- * @return Skipped set.
- */
- private Set<KeyCacheObject> skip(Set<KeyCacheObject> skipped, KeyCacheObject key) {
- if (skipped == null)
- skipped = new GridLeanSet<>();
-
- skipped.add(key);
-
- if (log.isDebugEnabled())
- log.debug("Added key to skipped set: " + key);
-
- return skipped;
- }
-
- /**
* Loads all missed keys for
* {@link #getAllAsync(GridCacheContext, Collection, boolean, boolean, boolean, boolean)} method.
*
@@ -1954,6 +1915,24 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
+ @Override public <K, V> IgniteInternalFuture<GridCacheReturn> putAsync(
+ GridCacheContext cacheCtx,
+ K key,
+ V val,
+ boolean retval,
+ CacheEntryPredicate[] filter) {
+ return putAsync0(cacheCtx, key, val, null, null, retval, filter);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <K, V> IgniteInternalFuture<GridCacheReturn> invokeAsync(GridCacheContext cacheCtx,
+ K key,
+ EntryProcessor<K, V, Object> entryProcessor,
+ Object... invokeArgs) {
+ return (IgniteInternalFuture)putAsync0(cacheCtx, key, null, entryProcessor, invokeArgs, true, null);
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteInternalFuture<?> putAllDrAsync(
GridCacheContext cacheCtx,
Map<KeyCacheObject, GridCacheDrInfo> drMap
@@ -2009,12 +1988,88 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param cacheCtx Cache context.
+ * @param cacheKey Key to enlist.
+ * @param val Value.
+ * @param expiryPlc Explicitly specified expiry policy for entry.
+ * @param entryProcessor Entry processor (for invoke operation).
+ * @param invokeArgs Optional arguments for EntryProcessor.
+ * @param retval Flag indicating whether a value should be returned.
+ * @param lockOnly If {@code true}, then entry will be enlisted as noop.
+ * @param filter User filters.
+ * @param ret Return value.
+ * @param skipStore Skip store flag.
+ * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
+ * @return Future for entry values loading.
+ */
+ private <K, V> IgniteInternalFuture<Void> enlistWrite(
+ final GridCacheContext cacheCtx,
+ KeyCacheObject cacheKey,
+ Object val,
+ @Nullable ExpiryPolicy expiryPlc,
+ @Nullable EntryProcessor<K, V, Object> entryProcessor,
+ @Nullable Object[] invokeArgs,
+ final boolean retval,
+ boolean lockOnly,
+ final CacheEntryPredicate[] filter,
+ final GridCacheReturn ret,
+ boolean skipStore,
+ final boolean singleRmv) {
+ try {
+ addActiveCache(cacheCtx);
+
+ final boolean hasFilters = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
+ final boolean needVal = singleRmv || retval || hasFilters;
+ final boolean needReadVer = needVal && (serializable() && optimistic());
+
+ if (entryProcessor != null)
+ transform = true;
+
+ boolean loadMissed = enlistWriteEntry(cacheCtx,
+ cacheKey,
+ val,
+ entryProcessor,
+ invokeArgs,
+ expiryPlc,
+ retval,
+ lockOnly,
+ filter,
+ /*drVer*/null,
+ /*drTtl*/-1L,
+ /*drExpireTime*/-1L,
+ ret,
+ /*enlisted*/null,
+ skipStore,
+ singleRmv,
+ hasFilters,
+ needVal,
+ needReadVer);
+
+ if (loadMissed) {
+ return loadMissing(cacheCtx,
+ Collections.singleton(cacheKey),
+ filter,
+ ret,
+ needReadVer,
+ singleRmv,
+ hasFilters,
+ skipStore,
+ retval);
+ }
+
+ return new GridFinishedFuture<>();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
+ }
+ }
+
+ /**
* Internal routine for <tt>putAll(..)</tt>
*
* @param cacheCtx Cache context.
* @param keys Keys to enlist.
* @param expiryPlc Explicitly specified expiry policy for entry.
- * @param implicit Implicit flag.
* @param lookup Value lookup map ({@code null} for remove).
* @param invokeMap Map with entry processors for invoke operation.
* @param invokeArgs Optional arguments for EntryProcessor.
@@ -2027,13 +2082,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @param drRmvMap DR remove map (optional).
* @param skipStore Skip store flag.
* @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
- * @return Future with skipped keys (the ones that didn't pass filter for pessimistic transactions).
+ * @return Future for missing values loading.
*/
- private <K, V> IgniteInternalFuture<Set<KeyCacheObject>> enlistWrite(
+ private <K, V> IgniteInternalFuture<Void> enlistWrite(
final GridCacheContext cacheCtx,
Collection<?> keys,
@Nullable ExpiryPolicy expiryPlc,
- boolean implicit,
@Nullable Map<?, ?> lookup,
@Nullable Map<?, EntryProcessor<K, V, Object>> invokeMap,
@Nullable Object[] invokeArgs,
@@ -2056,8 +2110,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
return new GridFinishedFuture<>(e);
}
- Set<KeyCacheObject> skipped = null;
-
boolean rmv = lookup == null && invokeMap == null;
Set<KeyCacheObject> missedForLoad = null;
@@ -2115,345 +2167,441 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
- IgniteTxKey txKey = cacheCtx.txKey(cacheKey);
-
- IgniteTxEntry txEntry = entry(txKey);
-
- // First time access.
- if (txEntry == null) {
- while (true) {
- GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topologyVersion());
-
- try {
- entry.unswap(false);
-
- // Check if lock is being explicitly acquired by the same thread.
- if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() &&
- entry.lockedByThread(threadId, xidVer))
- throw new IgniteCheckedException("Cannot access key within transaction if lock is " +
- "externally held [key=" + key + ", entry=" + entry + ", xidVer=" + xidVer +
- ", threadId=" + threadId +
- ", locNodeId=" + cctx.localNodeId() + ']');
-
- CacheObject old = null;
- GridCacheVersion readVer = null;
+ boolean loadMissed = enlistWriteEntry(cacheCtx,
+ cacheKey,
+ val,
+ entryProcessor,
+ invokeArgs,
+ expiryPlc,
+ retval,
+ lockOnly,
+ filter,
+ drVer,
+ drTtl,
+ drExpireTime,
+ ret,
+ enlisted,
+ skipStore,
+ singleRmv,
+ hasFilters,
+ needVal,
+ needReadVer);
+
+ if (loadMissed) {
+ if (missedForLoad == null)
+ missedForLoad = new HashSet<>();
+
+ missedForLoad.add(cacheKey);
+ }
+ }
- if (optimistic() && !implicit()) {
- try {
- if (needReadVer) {
- T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
- entry.innerGetVersioned(this,
- /*swap*/false,
- /*unmarshal*/retval,
- /*metrics*/retval,
- /*events*/retval,
- CU.subjectId(this, cctx),
- entryProcessor,
- resolveTaskName(),
- null) : null;
+ if (missedForLoad != null) {
+ return loadMissing(cacheCtx,
+ missedForLoad,
+ filter,
+ ret,
+ needReadVer,
+ singleRmv,
+ hasFilters,
+ skipStore,
+ retval);
+ }
- if (res != null) {
- old = res.get1();
- readVer = res.get2();
- }
- }
- else {
- old = entry.innerGet(this,
- /*swap*/false,
- /*read-through*/false,
- /*fail-fast*/false,
- /*unmarshal*/retval,
- /*metrics*/retval,
- /*events*/retval,
- /*temporary*/false,
- CU.subjectId(this, cctx),
- entryProcessor,
- resolveTaskName(),
- null);
- }
- }
- catch (ClusterTopologyCheckedException e) {
- entry.context().evicts().touch(entry, topologyVersion());
+ return new GridFinishedFuture<>();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
+ }
+ }
- throw e;
- }
- }
- else
- old = retval ? entry.rawGetOrUnmarshal(false) : entry.rawGet();
+ /**
+ * @param cacheCtx Cache context.
+ * @param keys Keys to load.
+ * @param ret Return value.
+ * @param needReadVer Read version flag.
+ * @param singleRmv {@code True} for single remove operation.
+ * @param hasFilters {@code True} if filters not empty.
+ * @param skipStore Skip store flag.
+ * @param retval Return value flag.
+ * @return Load future.
+ */
+ private IgniteInternalFuture<Void> loadMissing(
+ final GridCacheContext cacheCtx,
+ final Set<KeyCacheObject> keys,
+ final CacheEntryPredicate[] filter,
+ final GridCacheReturn ret,
+ final boolean needReadVer,
+ final boolean singleRmv,
+ final boolean hasFilters,
+ final boolean skipStore,
+ final boolean retval) {
+ GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c =
+ new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
+ @Override public void apply(KeyCacheObject key,
+ @Nullable Object val,
+ @Nullable GridCacheVersion loadVer) {
+ if (log.isDebugEnabled())
+ log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
- if (old != null && hasFilters && !filter(entry.context(), cacheKey, old, filter)) {
- skipped = skip(skipped, cacheKey);
+ IgniteTxEntry e = entry(new IgniteTxKey(key, cacheCtx.cacheId()));
- ret.set(cacheCtx, old, false);
+ assert e != null;
- if (!readCommitted()) {
- // Enlist failed filters as reads for non-read-committed mode,
- // so future ops will get the same values.
- txEntry = addEntry(READ,
- old,
- null,
- null,
- entry,
- null,
- CU.empty0(),
- false,
- -1L,
- -1L,
- null,
- skipStore);
+ if (needReadVer) {
+ assert loadVer != null;
- txEntry.markValid();
+ e.serializableReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
+ }
- if (needReadVer) {
- assert readVer != null;
+ if (singleRmv) {
+ assert !hasFilters && !retval;
+ assert val == null || Boolean.TRUE.equals(val) : val;
- txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
- }
- }
+ ret.set(cacheCtx, null, val != null);
+ }
+ else {
+ CacheObject cacheVal = cacheCtx.toCacheObject(val);
- if (readCommitted())
- cacheCtx.evicts().touch(entry, topologyVersion());
+ if (e.op() == TRANSFORM) {
+ GridCacheVersion ver;
- break; // While.
+ try {
+ ver = e.cached().version();
}
+ catch (GridCacheEntryRemovedException ex) {
+ assert optimistic() : e;
- final GridCacheOperation op = lockOnly ? NOOP : rmv ? DELETE :
- entryProcessor != null ? TRANSFORM : old != null ? UPDATE : CREATE;
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
- txEntry = addEntry(op,
- cacheCtx.toCacheObject(val),
- entryProcessor,
- invokeArgs,
- entry,
- expiryPlc,
- filter,
- true,
- drTtl,
- drExpireTime,
- drVer,
- skipStore);
+ ver = null;
+ }
- if (!implicit() && readCommitted() && !cacheCtx.offheapTiered())
- cacheCtx.evicts().touch(entry, topologyVersion());
+ addInvokeResult(e, cacheVal, ret, ver);
+ }
+ else {
+ boolean success = !hasFilters || isAll(e.context(), key, cacheVal, filter);
- enlisted.add(cacheKey);
+ ret.set(cacheCtx, cacheVal, success);
+ }
+ }
+ }
+ };
- if (!pessimistic() && !implicit()) {
- txEntry.markValid();
+ return loadMissing(
+ cacheCtx,
+ /*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore,
+ /*async*/true,
+ keys,
+ /*skipVals*/singleRmv,
+ needReadVer,
+ c);
+ }
- if (old == null) {
- if (needVal) {
- if (missedForLoad == null)
- missedForLoad = new HashSet<>();
+ /**
+ * @param cacheCtx Cache context.
+ * @param cacheKey Key.
+ * @param val Value.
+ * @param entryProcessor Entry processor.
+ * @param invokeArgs Optional arguments for EntryProcessor.
+ * @param expiryPlc Explicitly specified expiry policy for entry.
+ * @param retval Return value flag.
+ * @param lockOnly
+ * @param filter Filter.
+ * @param drVer DR version.
+ * @param drTtl DR ttl.
+ * @param drExpireTime DR expire time.
+ * @param ret Return value.
+ * @param enlisted Enlisted keys collection.
+ * @param skipStore Skip store flag.
+ * @param singleRmv {@code True} for single remove operation.
+ * @param hasFilters {@code True} if filters not empty.
+ * @param needVal {@code True} if value is needed.
+ * @param needReadVer {@code True} if need read entry version.
+ * @return {@code True} if entry value should be loaded.
+ * @throws IgniteCheckedException If failed.
+ */
+ private boolean enlistWriteEntry(GridCacheContext cacheCtx,
+ final KeyCacheObject cacheKey,
+ final @Nullable Object val,
+ final @Nullable EntryProcessor<?, ?, ?> entryProcessor,
+ final @Nullable Object[] invokeArgs,
+ final @Nullable ExpiryPolicy expiryPlc,
+ final boolean retval,
+ final boolean lockOnly,
+ final CacheEntryPredicate[] filter,
+ final GridCacheVersion drVer,
+ final long drTtl,
+ long drExpireTime,
+ final GridCacheReturn ret,
+ @Nullable final Collection<KeyCacheObject> enlisted,
+ boolean skipStore,
+ boolean singleRmv,
+ boolean hasFilters,
+ final boolean needVal,
+ boolean needReadVer
+ ) throws IgniteCheckedException {
+ boolean loadMissed = false;
- missedForLoad.add(cacheKey);
- }
- else {
- assert !implicit() || !transform : this;
- assert txEntry.op() != TRANSFORM : txEntry;
+ final boolean rmv = val == null && entryProcessor == null;
- if (retval)
- ret.set(cacheCtx, null, true);
- else
- ret.success(true);
- }
- }
- else {
- if (needReadVer) {
- assert readVer != null;
+ IgniteTxKey txKey = cacheCtx.txKey(cacheKey);
- txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
- }
+ IgniteTxEntry txEntry = entry(txKey);
- if (retval && !transform)
- ret.set(cacheCtx, old, true);
- else {
- if (txEntry.op() == TRANSFORM) {
- GridCacheVersion ver;
+ // First time access.
+ if (txEntry == null) {
+ while (true) {
+ GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topologyVersion());
- try {
- ver = entry.version();
- }
- catch (GridCacheEntryRemovedException ex) {
- assert optimistic() : txEntry;
+ try {
+ entry.unswap(false);
+
+ // Check if lock is being explicitly acquired by the same thread.
+ if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() &&
+ entry.lockedByThread(threadId, xidVer)) {
+ throw new IgniteCheckedException("Cannot access key within transaction if lock is " +
+ "externally held [key=" + CU.value(cacheKey, cacheCtx, false) +
+ ", entry=" + entry +
+ ", xidVer=" + xidVer +
+ ", threadId=" + threadId +
+ ", locNodeId=" + cctx.localNodeId() + ']');
+ }
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version " +
- "[err=" + ex.getMessage() + ']');
+ CacheObject old = null;
+ GridCacheVersion readVer = null;
- ver = null;
- }
+ if (optimistic() && !implicit()) {
+ try {
+ if (needReadVer) {
+ T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
+ entry.innerGetVersioned(this,
+ /*swap*/false,
+ /*unmarshal*/retval,
+ /*metrics*/retval,
+ /*events*/retval,
+ CU.subjectId(this, cctx),
+ entryProcessor,
+ resolveTaskName(),
+ null) : null;
- addInvokeResult(txEntry, old, ret, ver);
- }
- else
- ret.success(true);
- }
+ if (res != null) {
+ old = res.get1();
+ readVer = res.get2();
}
}
- // Pessimistic.
else {
- if (retval && !transform)
- ret.set(cacheCtx, old, true);
- else
- ret.success(true);
+ old = entry.innerGet(this,
+ /*swap*/false,
+ /*read-through*/false,
+ /*fail-fast*/false,
+ /*unmarshal*/retval,
+ /*metrics*/retval,
+ /*events*/retval,
+ /*temporary*/false,
+ CU.subjectId(this, cctx),
+ entryProcessor,
+ resolveTaskName(),
+ null);
}
-
- break; // While.
}
- catch (GridCacheEntryRemovedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Got removed entry in transaction putAll0 method: " + entry);
+ catch (ClusterTopologyCheckedException e) {
+ entry.context().evicts().touch(entry, topologyVersion());
+
+ throw e;
}
}
- }
- else {
- if (entryProcessor == null && txEntry.op() == TRANSFORM)
- throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " +
- "transaction after EntryProcessor is applied): " + key);
+ else
+ old = retval ? entry.rawGetOrUnmarshal(false) : entry.rawGet();
- GridCacheEntryEx entry = txEntry.cached();
+ if (old != null && hasFilters && !filter(entry.context(), cacheKey, old, filter)) {
+ ret.set(cacheCtx, old, false);
- CacheObject v = txEntry.value();
-
- boolean del = txEntry.op() == DELETE && rmv;
+ if (!readCommitted()) {
+ // Enlist failed filters as reads for non-read-committed mode,
+ // so future ops will get the same values.
+ txEntry = addEntry(READ,
+ old,
+ null,
+ null,
+ entry,
+ null,
+ CU.empty0(),
+ false,
+ -1L,
+ -1L,
+ null,
+ skipStore);
- if (!del) {
- if (hasFilters && !filter(entry.context(), cacheKey, v, filter)) {
- skipped = skip(skipped, cacheKey);
+ txEntry.markValid();
- ret.set(cacheCtx, v, false);
+ if (needReadVer) {
+ assert readVer != null;
- continue;
+ txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
+ }
}
- GridCacheOperation op = rmv ? DELETE : entryProcessor != null ? TRANSFORM :
- v != null ? UPDATE : CREATE;
+ if (readCommitted())
+ cacheCtx.evicts().touch(entry, topologyVersion());
- txEntry = addEntry(op,
- cacheCtx.toCacheObject(val),
- entryProcessor,
- invokeArgs,
- entry,
- expiryPlc,
- filter,
- true,
- drTtl,
- drExpireTime,
- drVer,
- skipStore);
+ break; // While.
+ }
+
+ final GridCacheOperation op = lockOnly ? NOOP : rmv ? DELETE :
+ entryProcessor != null ? TRANSFORM : old != null ? UPDATE : CREATE;
+
+ txEntry = addEntry(op,
+ cacheCtx.toCacheObject(val),
+ entryProcessor,
+ invokeArgs,
+ entry,
+ expiryPlc,
+ filter,
+ true,
+ drTtl,
+ drExpireTime,
+ drVer,
+ skipStore);
+ if (!implicit() && readCommitted() && !cacheCtx.offheapTiered())
+ cacheCtx.evicts().touch(entry, topologyVersion());
+
+ if (enlisted != null)
enlisted.add(cacheKey);
- if (txEntry.op() == TRANSFORM) {
- GridCacheVersion ver;
+ if (!pessimistic() && !implicit()) {
+ txEntry.markValid();
- try {
- ver = entry.version();
- }
- catch (GridCacheEntryRemovedException e) {
- assert optimistic() : txEntry;
+ if (old == null) {
+ if (needVal)
+ loadMissed = true;
+ else {
+ assert !implicit() || !transform : this;
+ assert txEntry.op() != TRANSFORM : txEntry;
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
+ if (retval)
+ ret.set(cacheCtx, null, true);
+ else
+ ret.success(true);
+ }
+ }
+ else {
+ if (needReadVer) {
+ assert readVer != null;
- ver = null;
+ txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
}
- addInvokeResult(txEntry, txEntry.value(), ret, ver);
- }
- }
+ if (retval && !transform)
+ ret.set(cacheCtx, old, true);
+ else {
+ if (txEntry.op() == TRANSFORM) {
+ GridCacheVersion ver;
- if (!pessimistic()) {
- txEntry.markValid();
+ try {
+ ver = entry.version();
+ }
+ catch (GridCacheEntryRemovedException ex) {
+ assert optimistic() : txEntry;
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version " +
+ "[err=" + ex.getMessage() + ']');
+
+ ver = null;
+ }
+ addInvokeResult(txEntry, old, ret, ver);
+ }
+ else
+ ret.success(true);
+ }
+ }
+ }
+ // Pessimistic.
+ else {
if (retval && !transform)
- ret.set(cacheCtx, v, true);
+ ret.set(cacheCtx, old, true);
else
ret.success(true);
}
- }
+
+ break; // While.
+ }
+ catch (GridCacheEntryRemovedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Got removed entry in transaction putAll0 method: " + entry);
+ }
}
}
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
-
- if (missedForLoad != null) {
- final boolean skipVals = singleRmv;
-
- IgniteInternalFuture<Void> fut = loadMissing(
- cacheCtx,
- /*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore,
- /*async*/true,
- missedForLoad,
- skipVals,
- needReadVer,
- new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
- @Override public void apply(KeyCacheObject key,
- @Nullable Object val,
- @Nullable GridCacheVersion loadVer) {
- if (log.isDebugEnabled())
- log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
+ else {
+ if (entryProcessor == null && txEntry.op() == TRANSFORM)
+ throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " +
+ "transaction after EntryProcessor is applied): " + CU.value(cacheKey, cacheCtx, false));
- IgniteTxEntry e = entry(new IgniteTxKey(key, cacheCtx.cacheId()));
+ GridCacheEntryEx entry = txEntry.cached();
- assert e != null;
+ CacheObject v = txEntry.value();
- if (needReadVer) {
- assert loadVer != null;
+ boolean del = txEntry.op() == DELETE && rmv;
- e.serializableReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
- }
+ if (!del) {
+ if (hasFilters && !filter(entry.context(), cacheKey, v, filter)) {
+ ret.set(cacheCtx, v, false);
- if (singleRmv) {
- assert !hasFilters && !retval;
- assert val == null || Boolean.TRUE.equals(val) : val;
+ return loadMissed;
+ }
- ret.set(cacheCtx, null, val != null);
- }
- else {
- CacheObject cacheVal = cacheCtx.toCacheObject(val);
+ GridCacheOperation op = rmv ? DELETE : entryProcessor != null ? TRANSFORM :
+ v != null ? UPDATE : CREATE;
- if (e.op() == TRANSFORM) {
- GridCacheVersion ver;
+ txEntry = addEntry(op,
+ cacheCtx.toCacheObject(val),
+ entryProcessor,
+ invokeArgs,
+ entry,
+ expiryPlc,
+ filter,
+ true,
+ drTtl,
+ drExpireTime,
+ drVer,
+ skipStore);
- try {
- ver = e.cached().version();
- }
- catch (GridCacheEntryRemovedException ex) {
- assert optimistic() : e;
+ if (enlisted != null)
+ enlisted.add(cacheKey);
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
+ if (txEntry.op() == TRANSFORM) {
+ GridCacheVersion ver;
- ver = null;
- }
+ try {
+ ver = entry.version();
+ }
+ catch (GridCacheEntryRemovedException e) {
+ assert optimistic() : txEntry;
- addInvokeResult(e, cacheVal, ret, ver);
- }
- else {
- boolean success = !hasFilters || isAll(e.context(), key, cacheVal, filter);
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
- ret.set(cacheCtx, cacheVal, success);
- }
- }
+ ver = null;
}
- });
- return new GridEmbeddedFuture<>(
- new C2<Void, Exception, Set<KeyCacheObject>>() {
- @Override public Set<KeyCacheObject> apply(Void b, Exception e) {
- if (e != null)
- throw new GridClosureException(e);
+ addInvokeResult(txEntry, txEntry.value(), ret, ver);
+ }
+ }
- return Collections.emptySet();
- }
- }, fut
- );
+ if (!pessimistic()) {
+ txEntry.markValid();
+
+ if (retval && !transform)
+ ret.set(cacheCtx, v, true);
+ else
+ ret.success(true);
+ }
}
- return new GridFinishedFuture<>(skipped);
+ return loadMissed;
}
/**
@@ -2486,22 +2634,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
*
* @param cacheCtx Context.
* @param keys Keys.
- * @param failed Collection of potentially failed keys (need to populate in this method).
* @param ret Return value.
* @param rmv {@code True} if remove.
* @param retval Flag to return value or not.
* @param read {@code True} if read.
* @param accessTtl TTL for read operation.
* @param filter Filter to check entries.
- * @return Failed keys.
* @throws IgniteCheckedException If error.
* @param computeInvoke If {@code true} computes return value for invoke operation.
*/
@SuppressWarnings("unchecked")
- protected Set<KeyCacheObject> postLockWrite(
+ protected final void postLockWrite(
GridCacheContext cacheCtx,
Iterable<KeyCacheObject> keys,
- Set<KeyCacheObject> failed,
GridCacheReturn ret,
boolean rmv,
boolean retval,
@@ -2606,8 +2751,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
log.debug("Filter passed in post lock for key: " + k);
}
else {
- failed = skip(failed, k);
-
// Revert operation to previous. (if no - NOOP, so entry will be unlocked).
txEntry.setAndMarkValid(txEntry.previousOperation(), cacheCtx.toCacheObject(ret.value()));
txEntry.filters(CU.empty0());
@@ -2638,11 +2781,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
}
}
-
- if (log.isDebugEnabled())
- log.debug("Entries that failed after lock filter check: " + failed);
-
- return failed;
}
/**
@@ -2696,6 +2834,144 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param cacheCtx Cache context.
+ * @param retval Return value flag.
+ * @throws IgniteCheckedException If failed.
+ */
+ private void beforePut(GridCacheContext cacheCtx, boolean retval) throws IgniteCheckedException {
+ checkUpdatesAllowed(cacheCtx);
+
+ cacheCtx.checkSecurity(SecurityPermission.CACHE_PUT);
+
+ if (retval)
+ needReturnValue(true);
+
+ checkValid();
+
+ init();
+ }
+
+ /**
+ * Internal method for single update operation.
+ *
+ * @param cacheCtx Cache context.
+ * @param key Key.
+ * @param val Value.
+ * @param entryProcessor Entry processor.
+ * @param invokeArgs Optional arguments for EntryProcessor.
+ * @param retval Return value flag.
+ * @param filter Filter.
+ * @return Operation future.
+ */
+ private <K, V> IgniteInternalFuture putAsync0(
+ final GridCacheContext cacheCtx,
+ K key,
+ @Nullable V val,
+ @Nullable EntryProcessor entryProcessor,
+ @Nullable final Object[] invokeArgs,
+ final boolean retval,
+ @Nullable final CacheEntryPredicate[] filter
+ ) {
+ assert key != null;
+
+ try {
+ beforePut(cacheCtx, retval);
+
+ final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
+
+ CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
+
+ KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
+
+ final IgniteInternalFuture<Void> loadFut = enlistWrite(
+ cacheCtx,
+ cacheKey,
+ val,
+ opCtx != null ? opCtx.expiry() : null,
+ entryProcessor,
+ invokeArgs,
+ retval,
+ /*lockOnly*/false,
+ filter,
+ ret,
+ opCtx != null && opCtx.skipStore(),
+ /*singleRmv*/false);
+
+ if (pessimistic()) {
+ assert loadFut == null || loadFut.isDone() : loadFut;
+
+ final Collection<KeyCacheObject> enlisted = Collections.singleton(cacheKey);
+
+ if (log.isDebugEnabled())
+ log.debug("Before acquiring transaction lock for put on key: " + enlisted);
+
+ IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted,
+ lockTimeout(),
+ this,
+ false,
+ retval,
+ isolation,
+ isInvalidate(),
+ -1L);
+
+ PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
+ @Override public GridCacheReturn postLock(GridCacheReturn ret)
+ throws IgniteCheckedException
+ {
+ if (log.isDebugEnabled())
+ log.debug("Acquired transaction lock for put on keys: " + enlisted);
+
+ postLockWrite(cacheCtx,
+ enlisted,
+ ret,
+ /*remove*/false,
+ retval,
+ /*read*/false,
+ -1L,
+ filter,
+ /*computeInvoke*/true);
+
+ return ret;
+ }
+ };
+
+ if (fut.isDone()) {
+ try {
+ return nonInterruptable(plc1.apply(fut.get(), null));
+ }
+ catch (GridClosureException e) {
+ return new GridFinishedFuture<>(e.unwrap());
+ }
+ catch (IgniteCheckedException e) {
+ try {
+ return nonInterruptable(plc1.apply(false, e));
+ }
+ catch (Exception e1) {
+ return new GridFinishedFuture<>(e1);
+ }
+ }
+ }
+ else {
+ return nonInterruptable(new GridEmbeddedFuture<>(
+ fut,
+ plc1
+ ));
+ }
+ }
+ else
+ return optimisticPutFuture(loadFut, ret);
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture(e);
+ }
+ catch (RuntimeException e) {
+ onException();
+
+ throw e;
+ }
+ }
+
+ /**
* Internal method for all put and transform operations. Only one of {@code map}, {@code transformMap}
* maps must be non-null.
*
@@ -2721,17 +2997,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert filter == null || invokeMap == null;
try {
- checkUpdatesAllowed(cacheCtx);
+ beforePut(cacheCtx, retval);
}
catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
- cacheCtx.checkSecurity(SecurityPermission.CACHE_PUT);
-
- if (retval)
- needReturnValue(true);
-
// Cached entry may be passed only from entry wrapper.
final Map<?, ?> map0;
final Map<?, EntryProcessor<K, V, Object>> invokeMap0;
@@ -2757,15 +3028,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert map0 != null || invokeMap0 != null;
- try {
- checkValid();
- }
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
-
- init();
-
final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
if (F.isEmpty(map0) && F.isEmpty(invokeMap0)) {
@@ -2783,15 +3045,14 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
try {
Set<?> keySet = map0 != null ? map0.keySet() : invokeMap0.keySet();
- Collection<KeyCacheObject> enlisted = new ArrayList<>();
+ final Collection<KeyCacheObject> enlisted = new ArrayList<>();
CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
- final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
+ final IgniteInternalFuture<Void> loadFut = enlistWrite(
cacheCtx,
keySet,
opCtx != null ? opCtx.expiry() : null,
- implicit,
map0,
invokeMap0,
invokeArgs,
@@ -2806,15 +3067,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
false);
if (pessimistic()) {
- // Loose all skipped.
- final Set<KeyCacheObject> loaded = loadFut.get();
-
- final Collection<KeyCacheObject> keys = F.view(enlisted, F0.notIn(loaded));
+ assert loadFut == null || loadFut.isDone() : loadFut;
if (log.isDebugEnabled())
- log.debug("Before acquiring transaction lock for put on keys: " + keys);
+ log.debug("Before acquiring transaction lock for put on keys: " + enlisted);
- IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(keys,
+ IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted,
lockTimeout(),
this,
false,
@@ -2828,11 +3086,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
throws IgniteCheckedException
{
if (log.isDebugEnabled())
- log.debug("Acquired transaction lock for put on keys: " + keys);
+ log.debug("Acquired transaction lock for put on keys: " + enlisted);
postLockWrite(cacheCtx,
- keys,
- loaded,
+ enlisted,
ret,
/*remove*/false,
retval,
@@ -2861,64 +3118,79 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
}
}
- else
+ else {
return nonInterruptable(new GridEmbeddedFuture<>(
fut,
plc1
));
+ }
}
- else {
- if (implicit()) {
- // Should never load missing values for implicit transaction as values will be returned
- // with prepare response, if required.
- assert loadFut.isDone();
+ else
+ return optimisticPutFuture(loadFut, ret);
+ }
+ catch (RuntimeException e) {
+ onException();
- try {
- loadFut.get();
- }
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
+ throw e;
+ }
+ }
- return nonInterruptable(commitAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut) throws IgniteCheckedException {
- try {
- txFut.get();
+ /**
+ * @param loadFut Missing keys load future.
+ * @param ret Future result.
+ * @return Future.
+ */
+ private IgniteInternalFuture optimisticPutFuture(IgniteInternalFuture<Void> loadFut, final GridCacheReturn ret) {
+ if (implicit()) {
+ // Should never load missing values for implicit transaction as values will be returned
+ // with prepare response, if required.
+ assert loadFut.isDone();
- return implicitRes;
- }
- catch (IgniteCheckedException | RuntimeException e) {
- rollbackAsync();
+ try {
+ loadFut.get();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
+ }
- throw e;
- }
+ return nonInterruptable(commitAsync().chain(
+ new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut)
+ throws IgniteCheckedException {
+ try {
+ txFut.get();
+
+ return implicitRes;
}
- }));
- }
- else
- return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Set<KeyCacheObject>>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f) throws IgniteCheckedException {
- f.get();
+ catch (IgniteCheckedException | RuntimeException e) {
+ rollbackAsync();
- return ret;
+ throw e;
}
- }));
- }
+ }
+ }
+ ));
}
- catch (RuntimeException e) {
- for (IgniteTxEntry txEntry : txMap.values()) {
- GridCacheEntryEx cached0 = txEntry.cached();
-
- if (cached0 != null)
- txEntry.context().evicts().touch(cached0, topologyVersion());
- }
+ else {
+ return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Void>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<Void> f) throws IgniteCheckedException {
+ f.get();
- throw e;
+ return ret;
+ }
+ }));
}
- catch (IgniteCheckedException e) {
- setRollbackOnly();
+ }
- return new GridFinishedFuture<>(e);
+ /**
+ *
+ */
+ private void onException() {
+ for (IgniteTxEntry txEntry : allEntries()) {
+ GridCacheEntryEx cached0 = txEntry.cached();
+
+ if (cached0 != null)
+ txEntry.context().evicts().touch(cached0, topologyVersion());
}
}
@@ -2974,9 +3246,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert keys0 != null;
- if (log.isDebugEnabled())
+ if (log.isDebugEnabled()) {
log.debug("Called removeAllAsync(...) [tx=" + this + ", keys=" + keys0 + ", implicit=" + implicit +
", retval=" + retval + "]");
+ }
try {
checkValid();
@@ -3002,140 +3275,131 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
init();
- try {
- Collection<KeyCacheObject> enlisted = new ArrayList<>();
-
- CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
+ final Collection<KeyCacheObject> enlisted = new ArrayList<>();
- ExpiryPolicy plc;
+ CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
- if (!F.isEmpty(filter))
- plc = opCtx != null ? opCtx.expiry() : null;
- else
- plc = null;
+ ExpiryPolicy plc;
- final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
- cacheCtx,
- keys0,
- plc,
- implicit,
- /** lookup map */null,
- /** invoke map */null,
- /** invoke arguments */null,
- retval,
- /** lock only */false,
- filter,
- ret,
- enlisted,
- null,
- drMap,
- opCtx != null && opCtx.skipStore(),
- singleRmv
- );
+ if (!F.isEmpty(filter))
+ plc = opCtx != null ? opCtx.expiry() : null;
+ else
+ plc = null;
- if (log.isDebugEnabled())
- log.debug("Remove keys: " + enlisted);
+ final IgniteInternalFuture<Void> loadFut = enlistWrite(
+ cacheCtx,
+ keys0,
+ plc,
+ /** lookup map */null,
+ /** invoke map */null,
+ /** invoke arguments */null,
+ retval,
+ /** lock only */false,
+ filter,
+ ret,
+ enlisted,
+ null,
+ drMap,
+ opCtx != null && opCtx.skipStore(),
+ singleRmv
+ );
- // Acquire locks only after having added operation to the write set.
- // Otherwise, during rollback we will not know whether locks need
- // to be rolled back.
- if (pessimistic()) {
- // Loose all skipped.
- final Collection<KeyCacheObject> passedKeys = F.view(enlisted, F0.notIn(loadFut.get()));
+ if (log.isDebugEnabled())
+ log.debug("Remove keys: " + enlisted);
- if (log.isDebugEnabled())
- log.debug("Before acquiring transaction lock for remove on keys: " + passedKeys);
+ // Acquire locks only after having added operation to the write set.
+ // Otherwise, during rollback we will not know whether locks need
+ // to be rolled back.
+ if (pessimistic()) {
+ assert loadFut.isDone() : loadFut;
- IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(passedKeys,
- lockTimeout(),
- this,
- false,
- retval,
- isolation,
- isInvalidate(),
- -1L);
+ if (log.isDebugEnabled())
+ log.debug("Before acquiring transaction lock for remove on keys: " + enlisted);
- PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
- @Override protected GridCacheReturn postLock(GridCacheReturn ret)
- throws IgniteCheckedException
- {
- if (log.isDebugEnabled())
- log.debug("Acquired transaction lock for remove on keys: " + passedKeys);
+ IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted,
+ lockTimeout(),
+ this,
+ false,
+ retval,
+ isolation,
+ isInvalidate(),
+ -1L);
+
+ PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
+ @Override protected GridCacheReturn postLock(GridCacheReturn ret)
+ throws IgniteCheckedException
+ {
+ if (log.isDebugEnabled())
+ log.debug("Acquired transaction lock for remove on keys: " + enlisted);
- postLockWrite(cacheCtx,
- passedKeys,
- loadFut.get(),
- ret,
+ postLockWrite(cacheCtx,
+ enlisted,
+ ret,
/*remove*/true,
- retval,
+ retval,
/*read*/false,
- -1L,
- filter,
+ -1L,
+ filter,
/*computeInvoke*/false);
- return ret;
- }
- };
+ return ret;
+ }
+ };
- if (fut.isDone()) {
+ if (fut.isDone()) {
+ try {
+ return nonInterruptable(plc1.apply(fut.get(), null));
+ }
+ catch (GridClosureException e) {
+ return new GridFinishedFuture<>(e.unwrap());
+ }
+ catch (IgniteCheckedException e) {
try {
- return nonInterruptable(plc1.apply(fut.get(), null));
+ return nonInterruptable(plc1.apply(false, e));
}
- catch (GridClosureException e) {
- return new GridFinishedFuture<>(e.unwrap());
- }
- catch (IgniteCheckedException e) {
- try {
- return nonInterruptable(plc1.apply(false, e));
- }
- catch (Exception e1) {
- return new GridFinishedFuture<>(e1);
- }
+ catch (Exception e1) {
+ return new GridFinishedFuture<>(e1);
}
}
- else
- return nonInterruptable(new GridEmbeddedFuture<>(
- fut,
- plc1
- ));
}
- else {
- if (implicit()) {
- // Should never load missing values for implicit transaction as values will be returned
- // with prepare response, if required.
- assert loadFut.isDone();
-
- return nonInterruptable(commitAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut)
- throws IgniteCheckedException {
- try {
- txFut.get();
+ else
+ return nonInterruptable(new GridEmbeddedFuture<>(
+ fut,
+ plc1
+ ));
+ }
+ else {
+ if (implicit()) {
+ // Should never load missing values for implicit transaction as values will be returned
+ // with prepare response, if required.
+ assert loadFut.isDone();
- return implicitRes;
- }
- catch (IgniteCheckedException | RuntimeException e) {
- rollbackAsync();
+ return nonInterruptable(commitAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut)
+ throws IgniteCheckedException {
+ try {
+ txFut.get();
- throw e;
- }
+ return implicitRes;
}
- }));
- }
- else
- return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Set<KeyCacheObject>>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f)
- throws IgniteCheckedException {
- f.get();
+ catch (IgniteCheckedException | RuntimeException e) {
+ rollbackAsync();
- return ret;
+ throw e;
}
- }));
+ }
+ }));
}
- }
- catch (IgniteCheckedException e) {
- setRollbackOnly();
+ else {
+ return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Void>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<Void> f)
+ throws IgniteCheckedException {
+ f.get();
- return new GridFinishedFuture<>(e);
+ return ret;
+ }
+ }));
+ }
}
}
@@ -3169,16 +3433,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @return {@code True} if transaction was successfully started.
*/
public boolean init() {
- if (txMap == null) {
- txMap = new LinkedHashMap<>(txSize > 0 ? txSize : 16, 1.0f);
+ return !txState.init(txSize) || cctx.tm().onStarted(this);
- readView = new IgniteTxMap(txMap, CU.reads());
- writeView = new IgniteTxMap(txMap, CU.writes());
-
- return cctx.tm().onStarted(this);
- }
-
- return true;
}
/**
@@ -3188,38 +3444,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @throws IgniteCheckedException If caches already enlisted in this transaction are not compatible with given
* cache (e.g. they have different stores).
*/
- protected void addActiveCache(GridCacheContext cacheCtx) throws IgniteCheckedException {
- int cacheId = cacheCtx.cacheId();
-
- // Check if we can enlist new cache to transaction.
- if (!activeCacheIds.contains(cacheId)) {
- String err = cctx.verifyTxCompatibility(this, activeCacheIds, cacheCtx);
-
- if (err != null) {
- StringBuilder cacheNames = new StringBuilder();
-
- int idx = 0;
-
- for (Integer activeCacheId : activeCacheIds) {
- cacheNames.append(cctx.cacheContext(activeCacheId).name());
-
- if (idx++ < activeCacheIds.size() - 1)
- cacheNames.append(", ");
- }
-
- throw new IgniteCheckedException("Failed to enlist new cache to existing transaction (" +
- err +
- ") [activeCaches=[" + cacheNames + "]" +
- ", cacheName=" + cacheCtx.name() +
- ", cacheSystem=" + cacheCtx.systemTx() +
- ", txSystem=" + system() + ']');
- }
- else
- activeCacheIds.add(cacheId);
-
- if (activeCacheIds.size() == 1)
- depEnabled = cacheCtx.deploymentEnabled();
- }
+ protected final void addActiveCache(GridCacheContext cacheCtx) throws IgniteCheckedException {
+ txState.addActiveCache(cacheCtx, this);
}
/**
@@ -3294,7 +3520,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
"Invalid tx state for adding entry [op=" + op + ", val=" + val + ", entry=" + entry + ", filter=" +
Arrays.toString(filter) + ", txCtx=" + cctx.tm().txContextVersion() + ", tx=" + this + ']';
- IgniteTxEntry old = txMap.get(key);
+ IgniteTxEntry old = entry(key);
// Keep old filter if already have one (empty filter is always overridden).
if (!filtersSet || !F.isEmptyOrNulls(filter)) {
@@ -3358,7 +3584,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (!hasDrTtl)
txEntry.expiry(expiryPlc);
- txMap.put(key, txEntry);
+ txState.addEntry(txEntry);
if (log.isDebugEnabled())
log.debug("Created transaction entry: " + txEntry);
@@ -3420,7 +3646,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public String toString() {
return GridToStringBuilder.toString(IgniteTxLocalAdapter.class, this, "super", super.toString(),
- "size", (txMap == null ? 0 : txMap.size()));
+ "size", allEntries().size());
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
index 0d83338..5dc3338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
@@ -93,9 +93,37 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
/**
* @param cacheCtx Cache context.
+ * @param key Key.
+ * @param val Value.
+ * @param retval Return value flag.
+ * @param filter Filter.
+ * @return Future for put operation.
+ */
+ public <K, V> IgniteInternalFuture<GridCacheReturn> putAsync(
+ GridCacheContext cacheCtx,
+ K key,
+ V val,
+ boolean retval,
+ CacheEntryPredicate[] filter);
+
+ /**
+ * @param cacheCtx Cache context.
+ * @param key Key.
+ * @param entryProcessor Entry processor.
+ * @param invokeArgs Optional arguments for entry processor.
+ * @return Operation future.
+ */
+ public <K, V> IgniteInternalFuture<GridCacheReturn> invokeAsync(
+ GridCacheContext cacheCtx,
+ K key,
+ EntryProcessor<K, V, Object> entryProcessor,
+ Object... invokeArgs);
+
+ /**
+ * @param cacheCtx Cache context.
* @param map Entry processors map.
* @param invokeArgs Optional arguments for entry processor.
- * @return Transform operation future.
+ * @return Operation future.
*/
public <K, V, T> IgniteInternalFuture<GridCacheReturn> invokeAsync(
GridCacheContext cacheCtx,
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
new file mode 100644
index 0000000..123d396
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.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.cache.transactions;
+
+/**
+ *
+ */
+public interface IgniteTxLocalState extends IgniteTxState {
+ /**
+ * @param entry Entry.
+ */
+ public void addEntry(IgniteTxEntry entry);
+
+ /**
+ * @param txSize Transaction size.
+ * @return {@code True} if transaction was successfully started.
+ */
+ public boolean init(int txSize);
+
+ /**
+ * @return {@code True} if init method was called.
+ */
+ public boolean initialized();
+
+ /**
+ *
+ */
+ public void seal();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java
new file mode 100644
index 0000000..cde5203
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.transactions;
+
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ *
+ */
+public abstract class IgniteTxLocalStateAdapter implements IgniteTxLocalState {
+ /**
+ * @param cacheCtx Cache context.
+ * @param tx Transaction.
+ * @param commit {@code False} if transaction rolled back.
+ */
+ protected final void onTxEnd(GridCacheContext cacheCtx, IgniteInternalTx tx, boolean commit) {
+ if (cacheCtx.cache().configuration().isStatisticsEnabled()) {
+ // Convert start time from ms to ns.
+ if (commit)
+ cacheCtx.cache().metrics0().onTxCommit((U.currentTimeMillis() - tx.startTime()) * 1000);
+ else
+ cacheCtx.cache().metrics0().onTxRollback((U.currentTimeMillis() - tx.startTime()) * 1000);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index c2e7dea..ccccca0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -1092,13 +1092,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (!tx.system())
cctx.txMetrics().onTxCommit();
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
-
- if (cacheCtx.cache().configuration().isStatisticsEnabled())
- // Convert start time from ms to ns.
- cacheCtx.cache().metrics0().onTxCommit((U.currentTimeMillis() - tx.startTime()) * 1000);
- }
+ tx.txState().onTxEnd(cctx, tx, true);
}
if (slowTxWarnTimeout > 0 && tx.local() &&
@@ -1163,13 +1157,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (!tx.system())
cctx.txMetrics().onTxRollback();
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
-
- if (cacheCtx.cache().configuration().isStatisticsEnabled())
- // Convert start time from ms to ns.
- cacheCtx.cache().metrics0().onTxRollback((U.currentTimeMillis() - tx.startTime()) * 1000);
- }
+ tx.txState().onTxEnd(cctx, tx, false);
}
if (log.isDebugEnabled())
@@ -1233,7 +1221,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (!tx.system())
threadMap.remove(tx.threadId(), tx);
else {
- Integer cacheId = F.first(tx.activeCacheIds());
+ Integer cacheId = tx.txState().firstCacheId();
if (cacheId != null)
sysThreadMap.remove(new TxThreadKey(tx.threadId(), cacheId), tx);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
index 6408573..429c995 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
@@ -170,8 +170,7 @@ public class IgniteTxMap extends AbstractMap<IgniteTxKey, IgniteTxEntry> impleme
}
/** {@inheritDoc} */
- @Nullable
- @Override public IgniteTxEntry get(Object key) {
+ @Nullable @Override public IgniteTxEntry get(Object key) {
IgniteTxEntry e = txMap.get(key);
return e == null ? null : filter.apply(e) ? e : null;
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
index 9660e4e..b80909f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
@@ -25,22 +25,13 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
*/
public interface IgniteTxRemoteEx extends IgniteInternalTx {
/**
- * @return Remote thread ID.
- */
- public long remoteThreadId();
-
- /**
* @param baseVer Base version.
* @param committedVers Committed version.
* @param rolledbackVers Rolled back version.
* @param pendingVers Pending versions.
*/
- public void doneRemote(GridCacheVersion baseVer, Collection<GridCacheVersion> committedVers,
- Collection<GridCacheVersion> rolledbackVers, Collection<GridCacheVersion> pendingVers);
-
- /**
- * @param e Sets write value for pessimistic transactions.
- * @return {@code True} if entry was found.
- */
- public boolean setWriteValue(IgniteTxEntry e);
+ public void doneRemote(GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
+ Collection<GridCacheVersion> pendingVers);
}
\ No newline at end of file
[06/51] ignite git commit: Merge branches 'ignite-1.5' and 'master'
of https://git-wip-us.apache.org/repos/asf/ignite
Posted by vk...@apache.org.
Merge branches 'ignite-1.5' and 'master' of https://git-wip-us.apache.org/repos/asf/ignite
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8b99f658
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8b99f658
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8b99f658
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 8b99f658dcf8f37e0785621d7028ebeb1ebe3768
Parents: 242d988 7393227
Author: Andrey <an...@gridgain.com>
Authored: Mon Nov 9 11:05:44 2015 +0700
Committer: Andrey <an...@gridgain.com>
Committed: Mon Nov 9 11:05:44 2015 +0700
----------------------------------------------------------------------
.../rest/AbstractRestProcessorSelfTest.java | 5 +-
.../JettyRestProcessorAbstractSelfTest.java | 142 ++++++----
.../configuration/ConnectorConfiguration.java | 61 ++++-
.../discovery/GridDiscoveryManager.java | 5 +-
.../handlers/cache/GridCacheCommandHandler.java | 128 +++++++--
.../handlers/query/QueryCommandHandler.java | 258 +++++++++++++++----
.../top/GridTopologyCommandHandler.java | 4 -
.../visor/commands/open/VisorOpenCommand.scala | 14 +-
8 files changed, 477 insertions(+), 140 deletions(-)
----------------------------------------------------------------------
[31/51] ignite git commit: Merge remote-tracking branch
'remotes/apache-main/ignite-cont-merge' into ignite-1.5
Posted by vk...@apache.org.
Merge remote-tracking branch 'remotes/apache-main/ignite-cont-merge' into ignite-1.5
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b382062e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b382062e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b382062e
Branch: refs/heads/ignite-direct-marsh-opt
Commit: b382062e02d7e3effca38d5181c47c76c16e24aa
Parents: d54fcbe db221f5
Author: Denis Magda <dm...@gridgain.com>
Authored: Tue Nov 17 16:36:48 2015 +0300
Committer: Denis Magda <dm...@gridgain.com>
Committed: Tue Nov 17 16:36:48 2015 +0300
----------------------------------------------------------------------
.../apache/ignite/internal/IgniteKernal.java | 9 +-
.../org/apache/ignite/mxbean/IgniteMXBean.java | 8 +-
.../ignite/util/mbeans/GridMBeanSelfTest.java | 33 ++++-
.../GridSpringResourceInjectionSelfTest.java | 143 +++++++++++++++++++
.../processors/resource/spring-resource.xml | 27 ++++
.../testsuites/IgniteResourceSelfTestSuite.java | 2 +
6 files changed, 209 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
[24/51] ignite git commit: Merge remote-tracking branch
'remotes/origin/ignite-1.5'
Posted by vk...@apache.org.
Merge remote-tracking branch 'remotes/origin/ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3a8c19ed
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3a8c19ed
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3a8c19ed
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 3a8c19ed14d92bfda161ddf2d5a783ad34ace665
Parents: af4e948 c9cea76
Author: Anton Vinogradov <av...@apache.org>
Authored: Fri Nov 13 14:21:52 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Fri Nov 13 14:21:52 2015 +0300
----------------------------------------------------------------------
.../cache/distributed/dht/preloader/GridDhtPartitionSupplier.java | 3 +++
.../src/main/scala/org/apache/ignite/visor/visor.scala | 3 +--
2 files changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
[41/51] ignite git commit: IGNITE-529 Rat fail fix
Posted by vk...@apache.org.
IGNITE-529 Rat fail fix
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/4c9ea586
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/4c9ea586
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/4c9ea586
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 4c9ea5864e731a876673d6d3cda3639ef4d421fa
Parents: 3ff71fd
Author: Anton Vinogradov <av...@apache.org>
Authored: Wed Nov 18 11:16:47 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Wed Nov 18 11:16:47 2015 +0300
----------------------------------------------------------------------
parent/pom.xml | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/4c9ea586/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 765ecf1..cb7c533 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -680,6 +680,7 @@
<exclude>**/licenses/*.txt</exclude><!--files of licenses-->
<exclude>**/*readme*.txt</exclude><!--readme files-->
<exclude>**/*README*.txt</exclude><!--readme files-->
+ <exclude>**/*README*.md</exclude><!--readme files-->
<exclude>**/*.timestamp</exclude><!--tmp-files-->
<exclude>**/*.iml</exclude><!--IDEA files-->
<exclude>**/pom-installed.xml</exclude><!--tmp-files-->
[26/51] ignite git commit: Optimizations for direct marshalling
Posted by vk...@apache.org.
Optimizations for direct marshalling
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d7747d81
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d7747d81
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d7747d81
Branch: refs/heads/ignite-direct-marsh-opt
Commit: d7747d816fc6d330759e0a1780188d4b2ef24a6d
Parents: 4cc5c9f
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Sun Nov 15 22:30:23 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Sun Nov 15 22:30:23 2015 -0800
----------------------------------------------------------------------
.../internal/direct/DirectByteBufferStream.java | 152 +++++++++++--------
1 file changed, 92 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/d7747d81/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
index dc6e419..ef9168c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
@@ -282,6 +282,9 @@ public class DirectByteBufferStream {
private Map<Object, Object> map;
/** */
+ private long prim;
+
+ /** */
private boolean lastFinished;
/**
@@ -353,14 +356,27 @@ public class DirectByteBufferStream {
* @param val Value.
*/
public void writeInt(int val) {
- lastFinished = buf.remaining() >= 4;
+ if (val == Integer.MAX_VALUE)
+ val = Integer.MIN_VALUE;
+ else
+ val++;
+
+ lastFinished = buf.remaining() >= 5;
if (lastFinished) {
int pos = buf.position();
- UNSAFE.putInt(heapArr, baseOff + pos, val);
+ while ((val & 0xFFFFFF80) != 0) {
+ byte b = (byte)(val | 0x80);
- buf.position(pos + 4);
+ UNSAFE.putByte(heapArr, baseOff + pos++, b);
+
+ val >>>= 7;
+ }
+
+ UNSAFE.putByte(heapArr, baseOff + pos++, (byte) val);
+
+ buf.position(pos);
}
}
@@ -368,14 +384,22 @@ public class DirectByteBufferStream {
* @param val Value.
*/
public void writeLong(long val) {
- lastFinished = buf.remaining() >= 8;
+ lastFinished = buf.remaining() >= 10;
if (lastFinished) {
int pos = buf.position();
- UNSAFE.putLong(heapArr, baseOff + pos, val);
+ while ((val & 0xFFFFFFFFFFFFFF80L) != 0) {
+ byte b = (byte)(val | 0x80);
- buf.position(pos + 8);
+ UNSAFE.putByte(heapArr, baseOff + pos++, b);
+
+ val >>>= 7;
+ }
+
+ UNSAFE.putByte(heapArr, baseOff + pos++, (byte) val);
+
+ buf.position(pos);
}
}
@@ -738,34 +762,73 @@ public class DirectByteBufferStream {
* @return Value.
*/
public int readInt() {
- lastFinished = buf.remaining() >= 4;
+ lastFinished = false;
- if (lastFinished) {
- int pos = buf.position();
+ int val = 0;
- buf.position(pos + 4);
+ int initPos = buf.position();
+ int shift = 0;
+
+ while (buf.hasRemaining()) {
+ byte b = UNSAFE.getByte(heapArr, baseOff + initPos + shift);
+
+ prim |= ((long)b & 0x7F) << (7 * shift);
+
+ shift++;
- return UNSAFE.getInt(heapArr, baseOff + pos);
+ if ((b & 0x80) == 0) {
+ lastFinished = true;
+
+ val = (int)prim;
+
+ if (val == Integer.MIN_VALUE)
+ val = Integer.MAX_VALUE;
+ else
+ val--;
+
+ prim = 0;
+
+ break;
+ }
}
- else
- return 0;
+
+ buf.position(initPos + shift);
+
+ return val;
}
/**
* @return Value.
*/
public long readLong() {
- lastFinished = buf.remaining() >= 8;
+ lastFinished = false;
- if (lastFinished) {
- int pos = buf.position();
+ long val = 0;
- buf.position(pos + 8);
+ int initPos = buf.position();
+ int shift = 0;
- return UNSAFE.getLong(heapArr, baseOff + pos);
+ while (buf.hasRemaining()) {
+ byte b = UNSAFE.getByte(heapArr, baseOff + initPos + shift);
+
+ prim |= ((long)b & 0x7F) << (7 * shift);
+
+ shift++;
+
+ if ((b & 0x80) == 0) {
+ lastFinished = true;
+
+ val = prim;
+
+ prim = 0;
+
+ break;
+ }
}
- else
- return 0;
+
+ buf.position(initPos + shift);
+
+ return val;
}
/**
@@ -1123,35 +1186,20 @@ public class DirectByteBufferStream {
* @param off Offset.
* @param len Length.
* @param bytes Length in bytes.
- * @return Whether array was fully written
+ * @return Whether array was fully written.
*/
private boolean writeArray(Object arr, long off, int len, int bytes) {
- return writeArray(arr, off, len, bytes, false);
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param len Length.
- * @param bytes Length in bytes.
- * @param skipLen {@code true} if length should not be written.
- * @return Whether array was fully written
- */
- private boolean writeArray(Object arr, long off, int len, int bytes, boolean skipLen) {
- assert arr != null;
- assert arr.getClass().isArray() && arr.getClass().getComponentType().isPrimitive();
+ assert arr == null || (arr.getClass().isArray() && arr.getClass().getComponentType().isPrimitive());
assert off > 0;
assert len >= 0;
assert bytes >= 0;
assert bytes >= arrOff;
if (arrOff == -1) {
- if (!skipLen) {
- if (buf.remaining() < 4)
- return false;
+ writeInt(len);
- writeInt(len);
- }
+ if (!lastFinished)
+ return false;
arrOff = 0;
}
@@ -1190,31 +1238,15 @@ public class DirectByteBufferStream {
* @param off Base offset.
* @return Array or special value if it was not fully read.
*/
- private <T> T readArray(ArrayCreator<T> creator, int lenShift, long off) {
- return readArray(creator, lenShift, off, -1);
- }
-
- /**
- * @param creator Array creator.
- * @param lenShift Array length shift size.
- * @param off Base offset.
- * @param len Length.
- * @return Array or special value if it was not fully read.
- */
@SuppressWarnings("unchecked")
- private <T> T readArray(ArrayCreator<T> creator, int lenShift, long off, int len) {
+ private <T> T readArray(ArrayCreator<T> creator, int lenShift, long off) {
assert creator != null;
if (tmpArr == null) {
- if (len == -1) {
- if (buf.remaining() < 4) {
- lastFinished = false;
+ int len = readInt();
- return null;
- }
-
- len = readInt();
- }
+ if (!lastFinished)
+ return null;
switch (len) {
case -1:
[14/51] ignite git commit: Merge branch 'ignite-1.5'
Posted by vk...@apache.org.
Merge branch 'ignite-1.5'
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/57ea0ff5
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/57ea0ff5
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/57ea0ff5
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 57ea0ff5417518590d723678eaedd85ee1d7e077
Parents: 4e45b98 cb28819
Author: Raul Kripalani <ra...@apache.org>
Authored: Tue Nov 10 21:14:01 2015 +0000
Committer: Raul Kripalani <ra...@apache.org>
Committed: Tue Nov 10 21:14:01 2015 +0000
----------------------------------------------------------------------
.../apache/ignite/internal/processors/igfs/IgfsMetaManager.java | 2 +-
.../core/src/main/java/org/apache/ignite/stream/StreamAdapter.java | 2 +-
modules/zookeeper/pom.xml | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
[11/51] ignite git commit: Ignite-1093 Backward compatibility fix.
Posted by vk...@apache.org.
Ignite-1093 Backward compatibility fix.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ee5a50f4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ee5a50f4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ee5a50f4
Branch: refs/heads/ignite-direct-marsh-opt
Commit: ee5a50f4b3124219f3fe2700cccaf64c6d031eb1
Parents: efc79fb
Author: Anton Vinogradov <av...@apache.org>
Authored: Mon Nov 9 18:11:43 2015 +0300
Committer: Anton Vinogradov <av...@apache.org>
Committed: Mon Nov 9 18:11:43 2015 +0300
----------------------------------------------------------------------
.../cache/distributed/dht/preloader/GridDhtPreloader.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/ee5a50f4/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 c634ff5..8e56c2d 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
@@ -207,7 +207,7 @@ public class GridDhtPreloader extends GridCachePreloaderAdapter {
});
supplier = new GridDhtPartitionSupplier(cctx);
- demander = new GridDhtPartitionDemander(cctx, busyLock);
+ demander = new GridDhtPartitionDemander(cctx, demandLock);
supplier.start();
demander.start();
[48/51] ignite git commit: Direct marshalling backward compatibility
Posted by vk...@apache.org.
Direct marshalling backward compatibility
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/00986d45
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/00986d45
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/00986d45
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 00986d459494658b33e820064569d61a6dc5f9d3
Parents: e691188
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Wed Nov 18 20:10:56 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Nov 18 20:10:56 2015 -0800
----------------------------------------------------------------------
.../internal/direct/DirectByteBufferStream.java | 1700 ------------------
.../internal/direct/DirectMessageReader.java | 6 +-
.../direct/DirectMessageReaderState.java | 32 +-
.../internal/direct/DirectMessageWriter.java | 33 +-
.../direct/stream/DirectByteBufferStream.java | 316 ++++
.../stream/v1/DirectByteBufferStreamImplV1.java | 1347 ++++++++++++++
.../stream/v2/DirectByteBufferStreamImplV2.java | 1580 ++++++++++++++++
.../managers/communication/GridIoManager.java | 39 +-
.../testframework/GridSpiTestContext.java | 5 +-
9 files changed, 3341 insertions(+), 1717 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
deleted file mode 100644
index c55eaac..0000000
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectByteBufferStream.java
+++ /dev/null
@@ -1,1700 +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.direct;
-
-import java.lang.reflect.Array;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.RandomAccess;
-import java.util.UUID;
-import org.apache.ignite.internal.util.GridUnsafe;
-import org.apache.ignite.internal.util.typedef.internal.U;
-import org.apache.ignite.lang.IgniteUuid;
-import org.apache.ignite.plugin.extensions.communication.Message;
-import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
-import org.apache.ignite.plugin.extensions.communication.MessageFactory;
-import org.apache.ignite.plugin.extensions.communication.MessageReader;
-import org.apache.ignite.plugin.extensions.communication.MessageWriter;
-import sun.misc.Unsafe;
-import sun.nio.ch.DirectBuffer;
-
-/**
- * Portable stream based on {@link ByteBuffer}.
- */
-public class DirectByteBufferStream {
- /** */
- private static final Unsafe UNSAFE = GridUnsafe.unsafe();
-
- /** */
- private static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class);
-
- /** */
- private static final long SHORT_ARR_OFF = UNSAFE.arrayBaseOffset(short[].class);
-
- /** */
- private static final long INT_ARR_OFF = UNSAFE.arrayBaseOffset(int[].class);
-
- /** */
- private static final long LONG_ARR_OFF = UNSAFE.arrayBaseOffset(long[].class);
-
- /** */
- private static final long FLOAT_ARR_OFF = UNSAFE.arrayBaseOffset(float[].class);
-
- /** */
- private static final long DOUBLE_ARR_OFF = UNSAFE.arrayBaseOffset(double[].class);
-
- /** */
- private static final long CHAR_ARR_OFF = UNSAFE.arrayBaseOffset(char[].class);
-
- /** */
- private static final long BOOLEAN_ARR_OFF = UNSAFE.arrayBaseOffset(boolean[].class);
-
- /** */
- private static final byte[] BYTE_ARR_EMPTY = new byte[0];
-
- /** */
- private static final short[] SHORT_ARR_EMPTY = new short[0];
-
- /** */
- private static final int[] INT_ARR_EMPTY = U.EMPTY_INTS;
-
- /** */
- private static final long[] LONG_ARR_EMPTY = U.EMPTY_LONGS;
-
- /** */
- private static final float[] FLOAT_ARR_EMPTY = new float[0];
-
- /** */
- private static final double[] DOUBLE_ARR_EMPTY = new double[0];
-
- /** */
- private static final char[] CHAR_ARR_EMPTY = new char[0];
-
- /** */
- private static final boolean[] BOOLEAN_ARR_EMPTY = new boolean[0];
-
- /** */
- private static final ArrayCreator<byte[]> BYTE_ARR_CREATOR = new ArrayCreator<byte[]>() {
- @Override public byte[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return BYTE_ARR_EMPTY;
-
- default:
- return new byte[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<short[]> SHORT_ARR_CREATOR = new ArrayCreator<short[]>() {
- @Override public short[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return SHORT_ARR_EMPTY;
-
- default:
- return new short[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<int[]> INT_ARR_CREATOR = new ArrayCreator<int[]>() {
- @Override public int[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return INT_ARR_EMPTY;
-
- default:
- return new int[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<long[]> LONG_ARR_CREATOR = new ArrayCreator<long[]>() {
- @Override public long[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return LONG_ARR_EMPTY;
-
- default:
- return new long[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<float[]> FLOAT_ARR_CREATOR = new ArrayCreator<float[]>() {
- @Override public float[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return FLOAT_ARR_EMPTY;
-
- default:
- return new float[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<double[]> DOUBLE_ARR_CREATOR = new ArrayCreator<double[]>() {
- @Override public double[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return DOUBLE_ARR_EMPTY;
-
- default:
- return new double[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<char[]> CHAR_ARR_CREATOR = new ArrayCreator<char[]>() {
- @Override public char[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return CHAR_ARR_EMPTY;
-
- default:
- return new char[len];
- }
- }
- };
-
- /** */
- private static final ArrayCreator<boolean[]> BOOLEAN_ARR_CREATOR = new ArrayCreator<boolean[]>() {
- @Override public boolean[] create(int len) {
- assert len >= 0;
-
- switch (len) {
- case 0:
- return BOOLEAN_ARR_EMPTY;
-
- default:
- return new boolean[len];
- }
- }
- };
-
- /** */
- private static final Object NULL = new Object();
-
- /** */
- private final MessageFactory msgFactory;
-
- /** */
- private ByteBuffer buf;
-
- /** */
- private byte[] heapArr;
-
- /** */
- private long baseOff;
-
- /** */
- private int arrOff = -1;
-
- /** */
- private Object tmpArr;
-
- /** */
- private int tmpArrOff;
-
- /** */
- private int tmpArrBytes;
-
- /** */
- private boolean msgTypeDone;
-
- /** */
- private Message msg;
-
- /** */
- private Iterator<?> mapIt;
-
- /** */
- private Iterator<?> it;
-
- /** */
- private int arrPos = -1;
-
- /** */
- private Object arrCur = NULL;
-
- /** */
- private Object mapCur = NULL;
-
- /** */
- private Object cur = NULL;
-
- /** */
- private boolean keyDone;
-
- /** */
- private int readSize = -1;
-
- /** */
- private int readItems;
-
- /** */
- private Object[] objArr;
-
- /** */
- private Collection<Object> col;
-
- /** */
- private Map<Object, Object> map;
-
- /** */
- private long prim;
-
- /** */
- private int primShift;
-
- /** */
- private int uuidState;
-
- /** */
- private long uuidMost;
-
- /** */
- private long uuidLeast;
-
- /** */
- private long uuidLocId;
-
- /** */
- private boolean lastFinished;
-
- /**
- * @param msgFactory Message factory.
- */
- public DirectByteBufferStream(MessageFactory msgFactory) {
- this.msgFactory = msgFactory;
- }
-
- /**
- * @param buf Buffer.
- */
- public void setBuffer(ByteBuffer buf) {
- assert buf != null;
-
- if (this.buf != buf) {
- this.buf = buf;
-
- heapArr = buf.isDirect() ? null : buf.array();
- baseOff = buf.isDirect() ? ((DirectBuffer)buf).address() : BYTE_ARR_OFF;
- }
- }
-
- /**
- * @return Number of remaining bytes.
- */
- public int remaining() {
- return buf.remaining();
- }
-
- /**
- * @return Whether last object was fully written or read.
- */
- public boolean lastFinished() {
- return lastFinished;
- }
-
- /**
- * @param val Value.
- */
- public void writeByte(byte val) {
- lastFinished = buf.remaining() >= 1;
-
- if (lastFinished) {
- int pos = buf.position();
-
- UNSAFE.putByte(heapArr, baseOff + pos, val);
-
- buf.position(pos + 1);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeShort(short val) {
- lastFinished = buf.remaining() >= 2;
-
- if (lastFinished) {
- int pos = buf.position();
-
- UNSAFE.putShort(heapArr, baseOff + pos, val);
-
- buf.position(pos + 2);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeInt(int val) {
- lastFinished = buf.remaining() >= 5;
-
- lastFinished = buf.remaining() >= 5;
-
- if (lastFinished) {
- if (val == Integer.MAX_VALUE)
- val = Integer.MIN_VALUE;
- else
- val++;
-
- int pos = buf.position();
-
- while ((val & 0xFFFF_FF80) != 0) {
- byte b = (byte)(val | 0x80);
-
- UNSAFE.putByte(heapArr, baseOff + pos++, b);
-
- val >>>= 7;
- }
-
- UNSAFE.putByte(heapArr, baseOff + pos++, (byte)val);
-
- buf.position(pos);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeLong(long val) {
- lastFinished = buf.remaining() >= 10;
-
- if (lastFinished) {
- if (val == Long.MAX_VALUE)
- val = Long.MIN_VALUE;
- else
- val++;
-
- int pos = buf.position();
-
- while ((val & 0xFFFF_FFFF_FFFF_FF80L) != 0) {
- byte b = (byte)(val | 0x80);
-
- UNSAFE.putByte(heapArr, baseOff + pos++, b);
-
- val >>>= 7;
- }
-
- UNSAFE.putByte(heapArr, baseOff + pos++, (byte)val);
-
- buf.position(pos);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeFloat(float val) {
- lastFinished = buf.remaining() >= 4;
-
- if (lastFinished) {
- int pos = buf.position();
-
- UNSAFE.putFloat(heapArr, baseOff + pos, val);
-
- buf.position(pos + 4);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeDouble(double val) {
- lastFinished = buf.remaining() >= 8;
-
- if (lastFinished) {
- int pos = buf.position();
-
- UNSAFE.putDouble(heapArr, baseOff + pos, val);
-
- buf.position(pos + 8);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeChar(char val) {
- lastFinished = buf.remaining() >= 2;
-
- if (lastFinished) {
- int pos = buf.position();
-
- UNSAFE.putChar(heapArr, baseOff + pos, val);
-
- buf.position(pos + 2);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeBoolean(boolean val) {
- lastFinished = buf.remaining() >= 1;
-
- if (lastFinished) {
- int pos = buf.position();
-
- UNSAFE.putBoolean(heapArr, baseOff + pos, val);
-
- buf.position(pos + 1);
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeByteArray(byte[] val) {
- if (val != null)
- lastFinished = writeArray(val, BYTE_ARR_OFF, val.length, val.length);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- * @param off Offset.
- * @param len Length.
- */
- public void writeByteArray(byte[] val, long off, int len) {
- if (val != null)
- lastFinished = writeArray(val, BYTE_ARR_OFF + off, len, len);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeShortArray(short[] val) {
- if (val != null)
- lastFinished = writeArray(val, SHORT_ARR_OFF, val.length, val.length << 1);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeIntArray(int[] val) {
- if (val != null)
- lastFinished = writeArray(val, INT_ARR_OFF, val.length, val.length << 2);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeLongArray(long[] val) {
- if (val != null)
- lastFinished = writeArray(val, LONG_ARR_OFF, val.length, val.length << 3);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeFloatArray(float[] val) {
- if (val != null)
- lastFinished = writeArray(val, FLOAT_ARR_OFF, val.length, val.length << 2);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeDoubleArray(double[] val) {
- if (val != null)
- lastFinished = writeArray(val, DOUBLE_ARR_OFF, val.length, val.length << 3);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeCharArray(char[] val) {
- if (val != null)
- lastFinished = writeArray(val, CHAR_ARR_OFF, val.length, val.length << 1);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeBooleanArray(boolean[] val) {
- if (val != null)
- lastFinished = writeArray(val, BOOLEAN_ARR_OFF, val.length, val.length);
- else
- writeInt(-1);
- }
-
- /**
- * @param val Value.
- */
- public void writeString(String val) {
- writeByteArray(val != null ? val.getBytes() : null);
- }
-
- /**
- * @param val Value.
- */
- public void writeBitSet(BitSet val) {
- writeLongArray(val != null ? val.toLongArray() : null);
- }
-
- /**
- * @param val Value.
- */
- public void writeUuid(UUID val) {
- switch (uuidState) {
- case 0:
- writeBoolean(val == null);
-
- if (!lastFinished || val == null)
- return;
-
- uuidState++;
-
- case 1:
- writeLong(val.getMostSignificantBits());
-
- if (!lastFinished)
- return;
-
- uuidState++;
-
- case 2:
- writeLong(val.getLeastSignificantBits());
-
- if (!lastFinished)
- return;
-
- uuidState = 0;
- }
- }
-
- /**
- * @param val Value.
- */
- public void writeIgniteUuid(IgniteUuid val) {
- switch (uuidState) {
- case 0:
- writeBoolean(val == null);
-
- if (!lastFinished || val == null)
- return;
-
- uuidState++;
-
- case 1:
- writeLong(val.globalId().getMostSignificantBits());
-
- if (!lastFinished)
- return;
-
- uuidState++;
-
- case 2:
- writeLong(val.globalId().getLeastSignificantBits());
-
- if (!lastFinished)
- return;
-
- uuidState++;
-
- case 3:
- writeLong(val.localId());
-
- if (!lastFinished)
- return;
-
- uuidState = 0;
- }
- }
-
- /**
- * @param msg Message.
- */
- public void writeMessage(Message msg, MessageWriter writer) {
- if (msg != null) {
- if (buf.hasRemaining()) {
- try {
- writer.beforeInnerMessageWrite();
-
- lastFinished = msg.writeTo(buf, writer);
- }
- finally {
- writer.afterInnerMessageWrite(lastFinished);
- }
- }
- else
- lastFinished = false;
- }
- else
- writeByte(Byte.MIN_VALUE);
- }
-
- /**
- * @param arr Array.
- * @param itemType Component type.
- * @param writer Writer.
- */
- public <T> void writeObjectArray(T[] arr, MessageCollectionItemType itemType, MessageWriter writer) {
- if (arr != null) {
- int len = arr.length;
-
- if (arrPos == -1) {
- writeInt(len);
-
- if (!lastFinished)
- return;
-
- arrPos = 0;
- }
-
- while (arrPos < len || arrCur != NULL) {
- if (arrCur == NULL)
- arrCur = arr[arrPos++];
-
- write(itemType, arrCur, writer);
-
- if (!lastFinished)
- return;
-
- arrCur = NULL;
- }
-
- arrPos = -1;
- }
- else
- writeInt(-1);
- }
-
- /**
- * @param col Collection.
- * @param itemType Item type.
- * @param writer Writer.
- */
- public <T> void writeCollection(Collection<T> col, MessageCollectionItemType itemType, MessageWriter writer) {
- if (col != null) {
- if (it == null) {
- writeInt(col.size());
-
- if (!lastFinished)
- return;
-
- it = col.iterator();
- }
-
- while (it.hasNext() || cur != NULL) {
- if (cur == NULL)
- cur = it.next();
-
- write(itemType, cur, writer);
-
- if (!lastFinished)
- return;
-
- cur = NULL;
- }
-
- it = null;
- }
- else
- writeInt(-1);
- }
-
- /**
- * @param list List.
- * @param itemType Component type.
- * @param writer Writer.
- */
- public <T> void writeRandomAccessList(List<T> list, MessageCollectionItemType itemType, MessageWriter writer) {
- if (list != null) {
- assert list instanceof RandomAccess;
-
- int size = list.size();
-
- if (arrPos == -1) {
- writeInt(size);
-
- if (!lastFinished)
- return;
-
- arrPos = 0;
- }
-
- while (arrPos < size || arrCur != NULL) {
- if (arrCur == NULL)
- arrCur = list.get(arrPos++);
-
- write(itemType, arrCur, writer);
-
- if (!lastFinished)
- return;
-
- arrCur = NULL;
- }
-
- arrPos = -1;
- }
- else
- writeInt(-1);
- }
-
- /**
- * @param map Map.
- * @param keyType Key type.
- * @param valType Value type.
- * @param writer Writer.
- */
- @SuppressWarnings("unchecked")
- public <K, V> void writeMap(Map<K, V> map, MessageCollectionItemType keyType, MessageCollectionItemType valType,
- MessageWriter writer) {
- if (map != null) {
- if (mapIt == null) {
- writeInt(map.size());
-
- if (!lastFinished)
- return;
-
- mapIt = map.entrySet().iterator();
- }
-
- while (mapIt.hasNext() || mapCur != NULL) {
- Map.Entry<K, V> e;
-
- if (mapCur == NULL)
- mapCur = mapIt.next();
-
- e = (Map.Entry<K, V>)mapCur;
-
- if (!keyDone) {
- write(keyType, e.getKey(), writer);
-
- if (!lastFinished)
- return;
-
- keyDone = true;
- }
-
- write(valType, e.getValue(), writer);
-
- if (!lastFinished)
- return;
-
- mapCur = NULL;
- keyDone = false;
- }
-
- mapIt = null;
- }
- else
- writeInt(-1);
- }
-
- /**
- * @return Value.
- */
- public byte readByte() {
- lastFinished = buf.remaining() >= 1;
-
- if (lastFinished) {
- int pos = buf.position();
-
- buf.position(pos + 1);
-
- return UNSAFE.getByte(heapArr, baseOff + pos);
- }
- else
- return 0;
- }
-
- /**
- * @return Value.
- */
- public short readShort() {
- lastFinished = buf.remaining() >= 2;
-
- if (lastFinished) {
- int pos = buf.position();
-
- buf.position(pos + 2);
-
- return UNSAFE.getShort(heapArr, baseOff + pos);
- }
- else
- return 0;
- }
-
- /**
- * @return Value.
- */
- public int readInt() {
- lastFinished = false;
-
- int val = 0;
-
- while (buf.hasRemaining()) {
- int pos = buf.position();
-
- byte b = UNSAFE.getByte(heapArr, baseOff + pos);
-
- buf.position(pos + 1);
-
- prim |= ((long)b & 0x7F) << (7 * primShift);
-
- if ((b & 0x80) == 0) {
- lastFinished = true;
-
- val = (int)prim;
-
- if (val == Integer.MIN_VALUE)
- val = Integer.MAX_VALUE;
- else
- val--;
-
- prim = 0;
- primShift = 0;
-
- break;
- }
- else
- primShift++;
- }
-
- return val;
- }
-
- /**
- * @return Value.
- */
- public long readLong() {
- lastFinished = false;
-
- long val = 0;
-
- while (buf.hasRemaining()) {
- int pos = buf.position();
-
- byte b = UNSAFE.getByte(heapArr, baseOff + pos);
-
- buf.position(pos + 1);
-
- prim |= ((long)b & 0x7F) << (7 * primShift);
-
- if ((b & 0x80) == 0) {
- lastFinished = true;
-
- val = prim;
-
- if (val == Long.MIN_VALUE)
- val = Long.MAX_VALUE;
- else
- val--;
-
- prim = 0;
- primShift = 0;
-
- break;
- }
- else
- primShift++;
- }
-
- return val;
- }
-
- /**
- * @return Value.
- */
- public float readFloat() {
- lastFinished = buf.remaining() >= 4;
-
- if (lastFinished) {
- int pos = buf.position();
-
- buf.position(pos + 4);
-
- return UNSAFE.getFloat(heapArr, baseOff + pos);
- }
- else
- return 0;
- }
-
- /**
- * @return Value.
- */
- public double readDouble() {
- lastFinished = buf.remaining() >= 8;
-
- if (lastFinished) {
- int pos = buf.position();
-
- buf.position(pos + 8);
-
- return UNSAFE.getDouble(heapArr, baseOff + pos);
- }
- else
- return 0;
- }
-
- /**
- * @return Value.
- */
- public char readChar() {
- lastFinished = buf.remaining() >= 2;
-
- if (lastFinished) {
- int pos = buf.position();
-
- buf.position(pos + 2);
-
- return UNSAFE.getChar(heapArr, baseOff + pos);
- }
- else
- return 0;
- }
-
- /**
- * @return Value.
- */
- public boolean readBoolean() {
- lastFinished = buf.hasRemaining();
-
- if (lastFinished) {
- int pos = buf.position();
-
- buf.position(pos + 1);
-
- return UNSAFE.getBoolean(heapArr, baseOff + pos);
- }
- else
- return false;
- }
-
- /**
- * @return Value.
- */
- public byte[] readByteArray() {
- return readArray(BYTE_ARR_CREATOR, 0, BYTE_ARR_OFF);
- }
-
- /**
- /**
- * @return Value.
- */
- public short[] readShortArray() {
- return readArray(SHORT_ARR_CREATOR, 1, SHORT_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public int[] readIntArray() {
- return readArray(INT_ARR_CREATOR, 2, INT_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public long[] readLongArray() {
- return readArray(LONG_ARR_CREATOR, 3, LONG_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public float[] readFloatArray() {
- return readArray(FLOAT_ARR_CREATOR, 2, FLOAT_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public double[] readDoubleArray() {
- return readArray(DOUBLE_ARR_CREATOR, 3, DOUBLE_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public char[] readCharArray() {
- return readArray(CHAR_ARR_CREATOR, 1, CHAR_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public boolean[] readBooleanArray() {
- return readArray(BOOLEAN_ARR_CREATOR, 0, BOOLEAN_ARR_OFF);
- }
-
- /**
- * @return Value.
- */
- public String readString() {
- byte[] arr = readByteArray();
-
- return arr != null ? new String(arr) : null;
- }
-
- /**
- * @return Value.
- */
- public BitSet readBitSet() {
- long[] arr = readLongArray();
-
- return arr != null ? BitSet.valueOf(arr) : null;
- }
-
- /**
- * @return Value.
- */
- public UUID readUuid() {
- switch (uuidState) {
- case 0:
- boolean isNull = readBoolean();
-
- if (!lastFinished || isNull)
- return null;
-
- uuidState++;
-
- case 1:
- uuidMost = readLong();
-
- if (!lastFinished)
- return null;
-
- uuidState++;
-
- case 2:
- uuidLeast = readLong();
-
- if (!lastFinished)
- return null;
-
- uuidState = 0;
- }
-
- UUID val = new UUID(uuidMost, uuidLeast);
-
- uuidMost = 0;
- uuidLeast = 0;
-
- return val;
- }
-
- /**
- * @return Value.
- */
- public IgniteUuid readIgniteUuid() {
- switch (uuidState) {
- case 0:
- boolean isNull = readBoolean();
-
- if (!lastFinished || isNull)
- return null;
-
- uuidState++;
-
- case 1:
- uuidMost = readLong();
-
- if (!lastFinished)
- return null;
-
- uuidState++;
-
- case 2:
- uuidLeast = readLong();
-
- if (!lastFinished)
- return null;
-
- uuidState++;
-
- case 3:
- uuidLocId = readLong();
-
- if (!lastFinished)
- return null;
-
- uuidState = 0;
- }
-
- IgniteUuid val = new IgniteUuid(new UUID(uuidMost, uuidLeast), uuidLocId);
-
- uuidMost = 0;
- uuidLeast = 0;
-
- return val;
- }
-
- /**
- * @return Message.
- */
- @SuppressWarnings("unchecked")
- public <T extends Message> T readMessage(MessageReader reader) {
- if (!msgTypeDone) {
- if (!buf.hasRemaining()) {
- lastFinished = false;
-
- return null;
- }
-
- byte type = readByte();
-
- msg = type == Byte.MIN_VALUE ? null : msgFactory.create(type);
-
- msgTypeDone = true;
- }
-
- if (msg != null) {
- try {
- reader.beforeInnerMessageRead();
-
- lastFinished = msg.readFrom(buf, reader);
- }
- finally {
- reader.afterInnerMessageRead(lastFinished);
- }
- }
- else
- lastFinished = true;
-
- if (lastFinished) {
- Message msg0 = msg;
-
- msgTypeDone = false;
- msg = null;
-
- return (T)msg0;
- }
- else
- return null;
- }
-
- /**
- * @param itemType Component type.
- * @param itemCls Component class.
- * @param reader Reader.
- * @return Array.
- */
- @SuppressWarnings("unchecked")
- public <T> T[] readObjectArray(MessageCollectionItemType itemType, Class<T> itemCls, MessageReader reader) {
- if (readSize == -1) {
- int size = readInt();
-
- if (!lastFinished)
- return null;
-
- readSize = size;
- }
-
- if (readSize >= 0) {
- if (objArr == null)
- objArr = itemCls != null ? (Object[])Array.newInstance(itemCls, readSize) : new Object[readSize];
-
- for (int i = readItems; i < readSize; i++) {
- Object item = read(itemType, reader);
-
- if (!lastFinished)
- return null;
-
- objArr[i] = item;
-
- readItems++;
- }
- }
-
- readSize = -1;
- readItems = 0;
- cur = null;
-
- T[] objArr0 = (T[])objArr;
-
- objArr = null;
-
- return objArr0;
- }
-
- /**
- * @param itemType Item type.
- * @param reader Reader.
- * @return Collection.
- */
- @SuppressWarnings("unchecked")
- public <C extends Collection<?>> C readCollection(MessageCollectionItemType itemType, MessageReader reader) {
- if (readSize == -1) {
- int size = readInt();
-
- if (!lastFinished)
- return null;
-
- readSize = size;
- }
-
- if (readSize >= 0) {
- if (col == null)
- col = new ArrayList<>(readSize);
-
- for (int i = readItems; i < readSize; i++) {
- Object item = read(itemType, reader);
-
- if (!lastFinished)
- return null;
-
- col.add(item);
-
- readItems++;
- }
- }
-
- readSize = -1;
- readItems = 0;
- cur = null;
-
- C col0 = (C)col;
-
- col = null;
-
- return col0;
- }
-
- /**
- * @param keyType Key type.
- * @param valType Value type.
- * @param linked Whether linked map should be created.
- * @param reader Reader.
- * @return Map.
- */
- @SuppressWarnings("unchecked")
- public <M extends Map<?, ?>> M readMap(MessageCollectionItemType keyType, MessageCollectionItemType valType,
- boolean linked, MessageReader reader) {
- if (readSize == -1) {
- int size = readInt();
-
- if (!lastFinished)
- return null;
-
- readSize = size;
- }
-
- if (readSize >= 0) {
- if (map == null)
- map = linked ? U.newLinkedHashMap(readSize) : U.newHashMap(readSize);
-
- for (int i = readItems; i < readSize; i++) {
- if (!keyDone) {
- Object key = read(keyType, reader);
-
- if (!lastFinished)
- return null;
-
- mapCur = key;
- keyDone = true;
- }
-
- Object val = read(valType, reader);
-
- if (!lastFinished)
- return null;
-
- map.put(mapCur, val);
-
- keyDone = false;
-
- readItems++;
- }
- }
-
- readSize = -1;
- readItems = 0;
- mapCur = null;
-
- M map0 = (M)map;
-
- map = null;
-
- return map0;
- }
-
- /**
- * @param arr Array.
- * @param off Offset.
- * @param len Length.
- * @param bytes Length in bytes.
- * @return Whether array was fully written.
- */
- private boolean writeArray(Object arr, long off, int len, int bytes) {
- assert arr != null;
- assert arr.getClass().isArray() && arr.getClass().getComponentType().isPrimitive();
- assert off > 0;
- assert len >= 0;
- assert bytes >= 0;
- assert bytes >= arrOff;
-
- if (arrOff == -1) {
- writeInt(len);
-
- if (!lastFinished)
- return false;
-
- arrOff = 0;
- }
-
- int toWrite = bytes - arrOff;
- int pos = buf.position();
- int remaining = buf.remaining();
-
- if (toWrite <= remaining) {
- if (toWrite > 0) {
- UNSAFE.copyMemory(arr, off + arrOff, heapArr, baseOff + pos, toWrite);
-
- buf.position(pos + toWrite);
- }
-
- arrOff = -1;
-
- return true;
- }
- else {
- if (remaining > 0) {
- UNSAFE.copyMemory(arr, off + arrOff, heapArr, baseOff + pos, remaining);
-
- buf.position(pos + remaining);
-
- arrOff += remaining;
- }
-
- return false;
- }
- }
-
- /**
- * @param creator Array creator.
- * @param lenShift Array length shift size.
- * @param off Base offset.
- * @return Array or special value if it was not fully read.
- */
- @SuppressWarnings("unchecked")
- private <T> T readArray(ArrayCreator<T> creator, int lenShift, long off) {
- assert creator != null;
-
- if (tmpArr == null) {
- int len = readInt();
-
- if (!lastFinished)
- return null;
-
- switch (len) {
- case -1:
- lastFinished = true;
-
- return null;
-
- case 0:
- lastFinished = true;
-
- return creator.create(0);
-
- default:
- tmpArr = creator.create(len);
- tmpArrBytes = len << lenShift;
- }
- }
-
- int toRead = tmpArrBytes - tmpArrOff;
- int remaining = buf.remaining();
- int pos = buf.position();
-
- lastFinished = toRead <= remaining;
-
- if (lastFinished) {
- UNSAFE.copyMemory(heapArr, baseOff + pos, tmpArr, off + tmpArrOff, toRead);
-
- buf.position(pos + toRead);
-
- T arr = (T)tmpArr;
-
- tmpArr = null;
- tmpArrBytes = 0;
- tmpArrOff = 0;
-
- return arr;
- }
- else {
- UNSAFE.copyMemory(heapArr, baseOff + pos, tmpArr, off + tmpArrOff, remaining);
-
- buf.position(pos + remaining);
-
- tmpArrOff += remaining;
-
- return null;
- }
- }
-
- /**
- * @param type Type.
- * @param val Value.
- * @param writer Writer.
- */
- private void write(MessageCollectionItemType type, Object val, MessageWriter writer) {
- switch (type) {
- case BYTE:
- writeByte((Byte)val);
-
- break;
-
- case SHORT:
- writeShort((Short)val);
-
- break;
-
- case INT:
- writeInt((Integer)val);
-
- break;
-
- case LONG:
- writeLong((Long)val);
-
- break;
-
- case FLOAT:
- writeFloat((Float)val);
-
- break;
-
- case DOUBLE:
- writeDouble((Double)val);
-
- break;
-
- case CHAR:
- writeChar((Character)val);
-
- break;
-
- case BOOLEAN:
- writeBoolean((Boolean)val);
-
- break;
-
- case BYTE_ARR:
- writeByteArray((byte[])val);
-
- break;
-
- case SHORT_ARR:
- writeShortArray((short[])val);
-
- break;
-
- case INT_ARR:
- writeIntArray((int[])val);
-
- break;
-
- case LONG_ARR:
- writeLongArray((long[])val);
-
- break;
-
- case FLOAT_ARR:
- writeFloatArray((float[])val);
-
- break;
-
- case DOUBLE_ARR:
- writeDoubleArray((double[])val);
-
- break;
-
- case CHAR_ARR:
- writeCharArray((char[])val);
-
- break;
-
- case BOOLEAN_ARR:
- writeBooleanArray((boolean[])val);
-
- break;
-
- case STRING:
- writeString((String)val);
-
- break;
-
- case BIT_SET:
- writeBitSet((BitSet)val);
-
- break;
-
- case UUID:
- writeUuid((UUID)val);
-
- break;
-
- case IGNITE_UUID:
- writeIgniteUuid((IgniteUuid)val);
-
- break;
-
- case MSG:
- try {
- if (val != null)
- writer.beforeInnerMessageWrite();
-
- writeMessage((Message)val, writer);
- }
- finally {
- if (val != null)
- writer.afterInnerMessageWrite(lastFinished);
- }
-
- break;
-
- default:
- throw new IllegalArgumentException("Unknown type: " + type);
- }
- }
-
- /**
- * @param type Type.
- * @param reader Reader.
- * @return Value.
- */
- private Object read(MessageCollectionItemType type, MessageReader reader) {
- switch (type) {
- case BYTE:
- return readByte();
-
- case SHORT:
- return readShort();
-
- case INT:
- return readInt();
-
- case LONG:
- return readLong();
-
- case FLOAT:
- return readFloat();
-
- case DOUBLE:
- return readDouble();
-
- case CHAR:
- return readChar();
-
- case BOOLEAN:
- return readBoolean();
-
- case BYTE_ARR:
- return readByteArray();
-
- case SHORT_ARR:
- return readShortArray();
-
- case INT_ARR:
- return readIntArray();
-
- case LONG_ARR:
- return readLongArray();
-
- case FLOAT_ARR:
- return readFloatArray();
-
- case DOUBLE_ARR:
- return readDoubleArray();
-
- case CHAR_ARR:
- return readCharArray();
-
- case BOOLEAN_ARR:
- return readBooleanArray();
-
- case STRING:
- return readString();
-
- case BIT_SET:
- return readBitSet();
-
- case UUID:
- return readUuid();
-
- case IGNITE_UUID:
- return readIgniteUuid();
-
- case MSG:
- return readMessage(reader);
-
- default:
- throw new IllegalArgumentException("Unknown type: " + type);
- }
- }
-
- /**
- * Array creator.
- */
- private static interface ArrayCreator<T> {
- /**
- * @param len Array length or {@code -1} if array was not fully read.
- * @return New array.
- */
- public T create(int len);
- }
-}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
index 2f91fbd..297d3e1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReader.java
@@ -22,6 +22,7 @@ import java.util.BitSet;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
+import org.apache.ignite.internal.direct.stream.DirectByteBufferStream;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
@@ -41,9 +42,10 @@ public class DirectMessageReader implements MessageReader {
/**
* @param msgFactory Message factory.
+ * @param protoVer Protocol version.
*/
- public DirectMessageReader(MessageFactory msgFactory) {
- state = new DirectMessageReaderState(msgFactory);
+ public DirectMessageReader(MessageFactory msgFactory, byte protoVer) {
+ state = new DirectMessageReaderState(msgFactory, protoVer);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
index d423052..1b02213 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageReaderState.java
@@ -17,6 +17,9 @@
package org.apache.ignite.internal.direct;
+import org.apache.ignite.internal.direct.stream.DirectByteBufferStream;
+import org.apache.ignite.internal.direct.stream.v1.DirectByteBufferStreamImplV1;
+import org.apache.ignite.internal.direct.stream.v2.DirectByteBufferStreamImplV2;
import org.apache.ignite.plugin.extensions.communication.MessageFactory;
/**
@@ -29,6 +32,9 @@ public class DirectMessageReaderState {
/** Message factory. */
private final MessageFactory msgFactory;
+ /** Protocol version. */
+ private final byte protoVer;
+
/** Stack array. */
private StateItem[] stack;
@@ -37,13 +43,15 @@ public class DirectMessageReaderState {
/**
* @param msgFactory Message factory.
+ * @param protoVer Protocol version.
*/
- public DirectMessageReaderState(MessageFactory msgFactory) {
+ public DirectMessageReaderState(MessageFactory msgFactory, byte protoVer) {
this.msgFactory = msgFactory;
+ this.protoVer = protoVer;
stack = new StateItem[INIT_SIZE];
- stack[0] = new StateItem(msgFactory);
+ stack[0] = new StateItem(msgFactory, protoVer);
}
/**
@@ -84,7 +92,7 @@ public class DirectMessageReaderState {
}
if (stack[pos] == null)
- stack[pos] = new StateItem(msgFactory);
+ stack[pos] = new StateItem(msgFactory, protoVer);
}
/**
@@ -120,9 +128,23 @@ public class DirectMessageReaderState {
/**
* @param msgFactory Message factory.
+ * @param protoVer Protocol version.
*/
- public StateItem(MessageFactory msgFactory) {
- stream = new DirectByteBufferStream(msgFactory);
+ public StateItem(MessageFactory msgFactory, byte protoVer) {
+ switch (protoVer) {
+ case 1:
+ stream = new DirectByteBufferStreamImplV1(msgFactory);
+
+ break;
+
+ case 2:
+ stream = new DirectByteBufferStreamImplV2(msgFactory);
+
+ break;
+
+ default:
+ throw new IllegalStateException("Invalid protocol version: " + protoVer);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
index 3f2866f..07a037e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/DirectMessageWriter.java
@@ -20,10 +20,11 @@ package org.apache.ignite.internal.direct;
import java.nio.ByteBuffer;
import java.util.BitSet;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
-import java.util.RandomAccess;
import java.util.UUID;
+import org.apache.ignite.internal.direct.stream.DirectByteBufferStream;
+import org.apache.ignite.internal.direct.stream.v1.DirectByteBufferStreamImplV1;
+import org.apache.ignite.internal.direct.stream.v2.DirectByteBufferStreamImplV2;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.plugin.extensions.communication.Message;
import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
@@ -35,11 +36,31 @@ import org.jetbrains.annotations.Nullable;
*/
public class DirectMessageWriter implements MessageWriter {
/** Stream. */
- private final DirectByteBufferStream stream = new DirectByteBufferStream(null);
+ private final DirectByteBufferStream stream;
/** State. */
private final DirectMessageWriterState state = new DirectMessageWriterState();
+ /**
+ * @param protoVer Protocol version.
+ */
+ public DirectMessageWriter(byte protoVer) {
+ switch (protoVer) {
+ case 1:
+ stream = new DirectByteBufferStreamImplV1(null);
+
+ break;
+
+ case 2:
+ stream = new DirectByteBufferStreamImplV2(null);
+
+ break;
+
+ default:
+ throw new IllegalStateException("Invalid protocol version: " + protoVer);
+ }
+ }
+
/** {@inheritDoc} */
@Override public void setBuffer(ByteBuffer buf) {
stream.setBuffer(buf);
@@ -215,9 +236,9 @@ public class DirectMessageWriter implements MessageWriter {
/** {@inheritDoc} */
@Override public <T> boolean writeCollection(String name, Collection<T> col, MessageCollectionItemType itemType) {
- if (col instanceof List && col instanceof RandomAccess)
- stream.writeRandomAccessList((List<T>)col, itemType, this);
- else
+// if (col instanceof List && col instanceof RandomAccess)
+// stream.writeRandomAccessList((List<T>)col, itemType, this);
+// else
stream.writeCollection(col, itemType, this);
return stream.lastFinished();
http://git-wip-us.apache.org/repos/asf/ignite/blob/00986d45/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java
new file mode 100644
index 0000000..bc9de5a
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/direct/stream/DirectByteBufferStream.java
@@ -0,0 +1,316 @@
+/*
+ * 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.direct.stream;
+
+import java.nio.ByteBuffer;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.plugin.extensions.communication.Message;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+import org.apache.ignite.plugin.extensions.communication.MessageReader;
+import org.apache.ignite.plugin.extensions.communication.MessageWriter;
+
+/**
+ * Direct marshalling I/O stream.
+ */
+public interface DirectByteBufferStream {
+ /**
+ * @param buf Buffer.
+ */
+ public void setBuffer(ByteBuffer buf);
+
+ /**
+ * @return Number of remaining bytes.
+ */
+ public int remaining();
+
+ /**
+ * @return Whether last object was fully written or read.
+ */
+ public boolean lastFinished();
+
+ /**
+ * @param val Value.
+ */
+ public void writeByte(byte val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeShort(short val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeInt(int val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeLong(long val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeFloat(float val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeDouble(double val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeChar(char val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeBoolean(boolean val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeByteArray(byte[] val);
+
+ /**
+ * @param val Value.
+ * @param off Offset.
+ * @param len Length.
+ */
+ public void writeByteArray(byte[] val, long off, int len);
+
+ /**
+ * @param val Value.
+ */
+ public void writeShortArray(short[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeIntArray(int[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeLongArray(long[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeFloatArray(float[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeDoubleArray(double[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeCharArray(char[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeBooleanArray(boolean[] val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeString(String val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeBitSet(BitSet val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeUuid(UUID val);
+
+ /**
+ * @param val Value.
+ */
+ public void writeIgniteUuid(IgniteUuid val);
+
+ /**
+ * @param msg Message.
+ * @param writer Writer.
+ */
+ public void writeMessage(Message msg, MessageWriter writer);
+
+ /**
+ * @param arr Array.
+ * @param itemType Component type.
+ * @param writer Writer.
+ */
+ public <T> void writeObjectArray(T[] arr, MessageCollectionItemType itemType, MessageWriter writer);
+
+ /**
+ * @param col Collection.
+ * @param itemType Component type.
+ * @param writer Writer.
+ */
+ public <T> void writeCollection(Collection<T> col, MessageCollectionItemType itemType, MessageWriter writer);
+
+ /**
+ * @param map Map.
+ * @param keyType Key type.
+ * @param valType Value type.
+ * @param writer Writer.
+ */
+ public <K, V> void writeMap(Map<K, V> map, MessageCollectionItemType keyType, MessageCollectionItemType valType,
+ MessageWriter writer);
+
+ /**
+ * @return Value.
+ */
+ public byte readByte();
+
+ /**
+ * @return Value.
+ */
+ public short readShort();
+
+ /**
+ * @return Value.
+ */
+ public int readInt();
+
+ /**
+ * @return Value.
+ */
+ public long readLong();
+
+ /**
+ * @return Value.
+ */
+ public float readFloat();
+
+ /**
+ * @return Value.
+ */
+ public double readDouble();
+
+ /**
+ * @return Value.
+ */
+ public char readChar();
+
+ /**
+ * @return Value.
+ */
+ public boolean readBoolean();
+
+ /**
+ * @return Value.
+ */
+ public byte[] readByteArray();
+
+ /**
+ * @return Value.
+ */
+ public short[] readShortArray();
+
+ /**
+ * @return Value.
+ */
+ public int[] readIntArray();
+
+ /**
+ * @return Value.
+ */
+ public long[] readLongArray();
+
+ /**
+ * @return Value.
+ */
+ public float[] readFloatArray();
+
+ /**
+ * @return Value.
+ */
+ public double[] readDoubleArray();
+
+ /**
+ * @return Value.
+ */
+ public char[] readCharArray();
+
+ /**
+ * @return Value.
+ */
+ public boolean[] readBooleanArray();
+
+ /**
+ * @return Value.
+ */
+ public String readString();
+
+ /**
+ * @return Value.
+ */
+ public BitSet readBitSet();
+
+ /**
+ * @return Value.
+ */
+ public UUID readUuid();
+
+ /**
+ * @return Value.
+ */
+ public IgniteUuid readIgniteUuid();
+
+ /**
+ * @param reader Reader.
+ * @return Message.
+ */
+ public <T extends Message> T readMessage(MessageReader reader);
+
+ /**
+ * @param itemType Item type.
+ * @param itemCls Item class.
+ * @param reader Reader.
+ * @return Array.
+ */
+ public <T> T[] readObjectArray(MessageCollectionItemType itemType, Class<T> itemCls, MessageReader reader);
+
+ /**
+ * @param itemType Item type.
+ * @param reader Reader.
+ * @return Collection.
+ */
+ public <C extends Collection<?>> C readCollection(MessageCollectionItemType itemType, MessageReader reader);
+
+ /**
+ * @param keyType Key type.
+ * @param valType Value type.
+ * @param linked Whether linked map should be created.
+ * @param reader Reader.
+ * @return Map.
+ */
+ public <M extends Map<?, ?>> M readMap(MessageCollectionItemType keyType, MessageCollectionItemType valType,
+ boolean linked, MessageReader reader);
+}
[29/51] ignite git commit: ignite-1758 Discovery fixes
Posted by vk...@apache.org.
ignite-1758 Discovery fixes
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/80147128
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/80147128
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/80147128
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 80147128a3b07f927dec65f0a6934f6782efab5c
Parents: 5a116cb
Author: sboikov <sb...@gridgain.com>
Authored: Tue Nov 17 09:48:58 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Nov 17 09:48:58 2015 +0300
----------------------------------------------------------------------
.../ignite/spi/discovery/tcp/ServerImpl.java | 360 +++++++++++----
.../spi/discovery/tcp/TcpDiscoveryImpl.java | 4 +-
.../tcp/internal/TcpDiscoveryNodesRing.java | 95 ++--
.../messages/TcpDiscoveryAbstractMessage.java | 37 ++
.../TcpDiscoveryStatusCheckMessage.java | 11 +
.../tcp/TcpDiscoveryMultiThreadedTest.java | 158 ++++---
.../discovery/tcp/TcpDiscoveryRestartTest.java | 10 +-
.../spi/discovery/tcp/TcpDiscoverySelfTest.java | 459 ++++++++++++++++++-
.../TcpDiscoveryMulticastIpFinderSelfTest.java | 28 +-
.../testframework/junits/GridAbstractTest.java | 29 +-
10 files changed, 942 insertions(+), 249 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
index 0fe2881..ae23d0e 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/ServerImpl.java
@@ -159,6 +159,10 @@ class ServerImpl extends TcpDiscoveryImpl {
private static final int ENSURED_MSG_HIST_SIZE = getInteger(IGNITE_DISCOVERY_HISTORY_SIZE, 1024 * 10);
/** */
+ private static final IgniteProductVersion CUSTOM_MSG_ALLOW_JOINING_FOR_VERIFIED_SINCE =
+ IgniteProductVersion.fromString("1.5.0");
+
+ /** */
private final ThreadPoolExecutor utilityPool = new ThreadPoolExecutor(0, 1, 2000, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
@@ -191,10 +195,10 @@ class ServerImpl extends TcpDiscoveryImpl {
private StatisticsPrinter statsPrinter;
/** Failed nodes (but still in topology). */
- private Collection<TcpDiscoveryNode> failedNodes = new HashSet<>();
+ private final Collection<TcpDiscoveryNode> failedNodes = new HashSet<>();
/** Leaving nodes (but still in topology). */
- private Collection<TcpDiscoveryNode> leavingNodes = new HashSet<>();
+ private final Collection<TcpDiscoveryNode> leavingNodes = new HashSet<>();
/** If non-shared IP finder is used this flag shows whether IP finder contains local address. */
private boolean ipFinderHasLocAddr;
@@ -1080,13 +1084,34 @@ class ServerImpl extends TcpDiscoveryImpl {
openSock = true;
+ TcpDiscoveryHandshakeRequest req = new TcpDiscoveryHandshakeRequest(locNodeId);
+
// Handshake.
- spi.writeToSocket(sock, new TcpDiscoveryHandshakeRequest(locNodeId), timeoutHelper.nextTimeoutChunk(
- spi.getSocketTimeout()));
+ spi.writeToSocket(sock, req, timeoutHelper.nextTimeoutChunk(spi.getSocketTimeout()));
TcpDiscoveryHandshakeResponse res = spi.readMessage(sock, null, timeoutHelper.nextTimeoutChunk(
ackTimeout0));
+ if (msg instanceof TcpDiscoveryJoinRequestMessage) {
+ boolean ignore = false;
+
+ synchronized (failedNodes) {
+ for (TcpDiscoveryNode failedNode : failedNodes) {
+ if (failedNode.id().equals(res.creatorNodeId())) {
+ if (log.isDebugEnabled())
+ log.debug("Ignore response from node from failed list: " + res);
+
+ ignore = true;
+
+ break;
+ }
+ }
+ }
+
+ if (ignore)
+ break;
+ }
+
if (locNodeId.equals(res.creatorNodeId())) {
if (log.isDebugEnabled())
log.debug("Handshake response from local node: " + res);
@@ -1104,7 +1129,7 @@ class ServerImpl extends TcpDiscoveryImpl {
spi.stats.onMessageSent(msg, U.currentTimeMillis() - tstamp);
if (debugMode)
- debugLog("Message has been sent directly to address [msg=" + msg + ", addr=" + addr +
+ debugLog(msg, "Message has been sent directly to address [msg=" + msg + ", addr=" + addr +
", rmtNodeId=" + res.creatorNodeId() + ']');
if (log.isDebugEnabled())
@@ -1754,6 +1779,32 @@ class ServerImpl extends TcpDiscoveryImpl {
}
/**
+ * Adds failed nodes specified in the received message to the local failed nodes list.
+ *
+ * @param msg Message.
+ */
+ private void processMessageFailedNodes(TcpDiscoveryAbstractMessage msg) {
+ if (msg.failedNodes() != null) {
+ for (UUID nodeId : msg.failedNodes()) {
+ TcpDiscoveryNode failedNode = ring.node(nodeId);
+
+ if (failedNode != null) {
+ if (!failedNode.isLocal()) {
+ boolean added;
+
+ synchronized (mux) {
+ added = failedNodes.add(failedNode);
+ }
+
+ if (added && log.isDebugEnabled())
+ log.debug("Added node to failed nodes list [node=" + failedNode + ", msg=" + msg + ']');
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Discovery messages history used for client reconnect.
*/
private class EnsuredMessageHistory {
@@ -2131,10 +2182,28 @@ class ServerImpl extends TcpDiscoveryImpl {
log.debug("Processing message [cls=" + msg.getClass().getSimpleName() + ", id=" + msg.id() + ']');
if (debugMode)
- debugLog("Processing message [cls=" + msg.getClass().getSimpleName() + ", id=" + msg.id() + ']');
+ debugLog(msg, "Processing message [cls=" + msg.getClass().getSimpleName() + ", id=" + msg.id() + ']');
+
+ if (locNode.internalOrder() == 0) {
+ boolean process = false;
+
+ if (msg instanceof TcpDiscoveryNodeAddedMessage)
+ process = ((TcpDiscoveryNodeAddedMessage)msg).node().equals(locNode);
+
+ if (!process) {
+ if (log.isDebugEnabled()) {
+ log.debug("Ignore message, local node order is not initialized [msg=" + msg +
+ ", locNode=" + locNode + ']');
+ }
+
+ return;
+ }
+ }
spi.stats.onMessageProcessingStarted(msg);
+ processMessageFailedNodes(msg);
+
if (msg instanceof TcpDiscoveryJoinRequestMessage)
processJoinRequestMessage((TcpDiscoveryJoinRequestMessage)msg);
@@ -2200,6 +2269,8 @@ class ServerImpl extends TcpDiscoveryImpl {
checkHeartbeatsReceiving();
checkPendingCustomMessages();
+
+ checkFailedNodesList();
}
/**
@@ -2262,50 +2333,50 @@ class ServerImpl extends TcpDiscoveryImpl {
boolean sent = false;
- boolean searchNext = true;
+ boolean newNextNode = false;
UUID locNodeId = getLocalNodeId();
while (true) {
- if (searchNext) {
- TcpDiscoveryNode newNext = ring.nextNode(failedNodes);
-
- if (newNext == null) {
- if (log.isDebugEnabled())
- log.debug("No next node in topology.");
+ TcpDiscoveryNode newNext = ring.nextNode(failedNodes);
- if (debugMode)
- debugLog("No next node in topology.");
+ if (newNext == null) {
+ if (log.isDebugEnabled())
+ log.debug("No next node in topology.");
- if (ring.hasRemoteNodes() && !(msg instanceof TcpDiscoveryConnectionCheckMessage) &&
- !(msg instanceof TcpDiscoveryStatusCheckMessage && msg.creatorNodeId().equals(locNodeId))) {
- msg.senderNodeId(locNodeId);
+ if (debugMode)
+ debugLog(msg, "No next node in topology.");
- addMessage(msg);
- }
+ if (ring.hasRemoteNodes() && !(msg instanceof TcpDiscoveryConnectionCheckMessage) &&
+ !(msg instanceof TcpDiscoveryStatusCheckMessage && msg.creatorNodeId().equals(locNodeId))) {
+ msg.senderNodeId(locNodeId);
- break;
+ addMessage(msg);
}
- if (!newNext.equals(next)) {
- if (log.isDebugEnabled())
- log.debug("New next node [newNext=" + newNext + ", formerNext=" + next +
- ", ring=" + ring + ", failedNodes=" + failedNodes + ']');
+ break;
+ }
- if (debugMode)
- debugLog("New next node [newNext=" + newNext + ", formerNext=" + next +
- ", ring=" + ring + ", failedNodes=" + failedNodes + ']');
+ if (!newNext.equals(next)) {
+ if (log.isDebugEnabled())
+ log.debug("New next node [newNext=" + newNext + ", formerNext=" + next +
+ ", ring=" + ring + ", failedNodes=" + failedNodes + ']');
- U.closeQuiet(sock);
+ if (debugMode)
+ debugLog(msg, "New next node [newNext=" + newNext + ", formerNext=" + next +
+ ", ring=" + ring + ", failedNodes=" + failedNodes + ']');
- sock = null;
+ U.closeQuiet(sock);
- next = newNext;
- }
- else if (log.isDebugEnabled())
- log.debug("Next node remains the same [nextId=" + next.id() +
- ", nextOrder=" + next.internalOrder() + ']');
+ sock = null;
+
+ next = newNext;
+
+ newNextNode = true;
}
+ else if (log.isDebugEnabled())
+ log.debug("Next node remains the same [nextId=" + next.id() +
+ ", nextOrder=" + next.internalOrder() + ']');
// Flag that shows whether next node exists and accepts incoming connections.
boolean nextNodeExists = sock != null;
@@ -2379,8 +2450,8 @@ class ServerImpl extends TcpDiscoveryImpl {
"expected [expectedId=" + next.id() + ", rcvdId=" + nextId + ']');
if (debugMode)
- debugLog("Failed to restore ring because next node ID received is not as " +
- "expected [expectedId=" + next.id() + ", rcvdId=" + nextId + ']');
+ debugLog(msg, "Failed to restore ring because next node ID received is not " +
+ "as expected [expectedId=" + next.id() + ", rcvdId=" + nextId + ']');
break;
}
@@ -2401,8 +2472,8 @@ class ServerImpl extends TcpDiscoveryImpl {
", rcvd=" + nextOrder + ", id=" + next.id() + ']');
if (debugMode)
- debugLog("Failed to restore ring because next node order received " +
- "is not as expected [expected=" + next.internalOrder() +
+ debugLog(msg, "Failed to restore ring because next node order " +
+ "received is not as expected [expected=" + next.internalOrder() +
", rcvd=" + nextOrder + ", id=" + next.id() + ']');
break;
@@ -2413,7 +2484,7 @@ class ServerImpl extends TcpDiscoveryImpl {
log.debug("Initialized connection with next node: " + next.id());
if (debugMode)
- debugLog("Initialized connection with next node: " + next.id());
+ debugLog(msg, "Initialized connection with next node: " + next.id());
errs = null;
@@ -2477,13 +2548,20 @@ class ServerImpl extends TcpDiscoveryImpl {
assert !forceSndPending || msg instanceof TcpDiscoveryNodeLeftMessage;
- if (failure || forceSndPending) {
+ boolean sndPending=
+ (newNextNode && ring.minimumNodeVersion().compareTo(CUSTOM_MSG_ALLOW_JOINING_FOR_VERIFIED_SINCE) >= 0) ||
+ failure ||
+ forceSndPending;
+
+ if (sndPending) {
if (log.isDebugEnabled())
log.debug("Pending messages will be sent [failure=" + failure +
+ ", newNextNode=" + newNextNode +
", forceSndPending=" + forceSndPending + ']');
if (debugMode)
- debugLog("Pending messages will be sent [failure=" + failure +
+ debugLog(msg, "Pending messages will be sent [failure=" + failure +
+ ", newNextNode=" + newNextNode +
", forceSndPending=" + forceSndPending + ']');
for (TcpDiscoveryAbstractMessage pendingMsg : pendingMsgs) {
@@ -2513,7 +2591,7 @@ class ServerImpl extends TcpDiscoveryImpl {
", res=" + res + ']');
if (debugMode)
- debugLog("Pending message has been sent to next node [msgId=" + msg.id() +
+ debugLog(msg, "Pending message has been sent to next node [msgId=" + msg.id() +
", pendingMsgId=" + pendingMsg.id() + ", next=" + next.id() +
", res=" + res + ']');
@@ -2540,6 +2618,14 @@ class ServerImpl extends TcpDiscoveryImpl {
if (timeoutHelper == null)
timeoutHelper = new IgniteSpiOperationTimeoutHelper(spi);
+ if (!failedNodes.isEmpty()) {
+ for (TcpDiscoveryNode failedNode : failedNodes) {
+ assert !failedNode.equals(next) : failedNode;
+
+ msg.addFailedNode(failedNode.id());
+ }
+ }
+
writeToSocket(sock, msg, timeoutHelper.nextTimeoutChunk(spi.getSocketTimeout()));
spi.stats.onMessageSent(msg, U.currentTimeMillis() - tstamp);
@@ -2548,15 +2634,17 @@ class ServerImpl extends TcpDiscoveryImpl {
onMessageExchanged();
- if (log.isDebugEnabled())
+ if (log.isDebugEnabled()) {
log.debug("Message has been sent to next node [msg=" + msg +
", next=" + next.id() +
", res=" + res + ']');
+ }
- if (debugMode)
- debugLog("Message has been sent to next node [msg=" + msg +
+ if (debugMode) {
+ debugLog(msg, "Message has been sent to next node [msg=" + msg +
", next=" + next.id() +
", res=" + res + ']');
+ }
}
finally {
clearNodeAddedMessage(msg);
@@ -2635,8 +2723,6 @@ class ServerImpl extends TcpDiscoveryImpl {
next = null;
- searchNext = true;
-
errs = null;
}
else
@@ -2665,25 +2751,30 @@ class ServerImpl extends TcpDiscoveryImpl {
msgWorker.addMessage(new TcpDiscoveryNodeFailedMessage(locNodeId, n.id(), n.internalOrder()));
if (!sent) {
+ assert next == null : next;
+
if (log.isDebugEnabled())
log.debug("Pending messages will be resent to local node");
if (debugMode)
- log.debug("Pending messages will be resent to local node");
+ debugLog(msg, "Pending messages will be resent to local node");
for (TcpDiscoveryAbstractMessage pendingMsg : pendingMsgs) {
prepareNodeAddedMessage(pendingMsg, locNodeId, pendingMsgs.msgs, pendingMsgs.discardId,
pendingMsgs.customDiscardId);
+ pendingMsg.senderNodeId(locNodeId);
+
msgWorker.addMessage(pendingMsg);
if (log.isDebugEnabled())
log.debug("Pending message has been sent to local node [msg=" + msg.id() +
- ", pendingMsgId=" + pendingMsg + ", next=" + next.id() + ']');
+ ", pendingMsgId=" + pendingMsg + ']');
- if (debugMode)
- debugLog("Pending message has been sent to local node [msg=" + msg.id() +
- ", pendingMsgId=" + pendingMsg + ", next=" + next.id() + ']');
+ if (debugMode) {
+ debugLog(msg, "Pending message has been sent to local node [msg=" + msg.id() +
+ ", pendingMsgId=" + pendingMsg + ']');
+ }
}
}
@@ -3317,15 +3408,17 @@ class ServerImpl extends TcpDiscoveryImpl {
if (sendMessageToRemotes(msg))
sendMessageAcrossRing(msg);
- if (log.isDebugEnabled())
+ if (log.isDebugEnabled()) {
log.debug("Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " +
- "coordinator for final processing [ring=" + ring + ", node=" + node + ", locNode="
- + locNode + ", msg=" + msg + ']');
+ "coordinator for final processing [ring=" + ring + ", node=" + node + ", locNode="
+ + locNode + ", msg=" + msg + ']');
+ }
- if (debugMode)
- debugLog("Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " +
- "coordinator for final processing [ring=" + ring + ", node=" + node + ", locNode="
- + locNode + ", msg=" + msg + ']');
+ if (debugMode) {
+ debugLog(msg, "Local node already has node being added. Passing TcpDiscoveryNodeAddedMessage to " +
+ "coordinator for final processing [ring=" + ring + ", node=" + node + ", locNode="
+ + locNode + ", msg=" + msg + ']');
+ }
return;
}
@@ -3338,7 +3431,7 @@ class ServerImpl extends TcpDiscoveryImpl {
", msg=" + msg + ']');
if (debugMode)
- debugLog("Discarding node added message since new node's order is less than " +
+ debugLog(msg, "Discarding node added message since new node's order is less than " +
"max order in ring [ring=" + ring + ", node=" + node + ", locNode=" + locNode +
", msg=" + msg + ']');
@@ -3427,6 +3520,8 @@ class ServerImpl extends TcpDiscoveryImpl {
spi.onExchange(node.id(), node.id(), data, U.gridClassLoader());
msg.addDiscoveryData(locNodeId, spi.collectExchangeData(node.id()));
+
+ processMessageFailedNodes(msg);
}
if (log.isDebugEnabled())
@@ -3447,6 +3542,9 @@ class ServerImpl extends TcpDiscoveryImpl {
spi.gridStartTime = msg.gridStartTime();
for (TcpDiscoveryNode n : top) {
+ assert n.internalOrder() < node.internalOrder() :
+ "Invalid node [topNode=" + n + ", added=" + node + ']';
+
// Make all preceding nodes and local node visible.
n.visible(true);
}
@@ -3500,6 +3598,8 @@ class ServerImpl extends TcpDiscoveryImpl {
for (Map.Entry<UUID, Map<Integer, byte[]>> entry : dataMap.entrySet())
spi.onExchange(node.id(), entry.getKey(), entry.getValue(), U.gridClassLoader());
}
+
+ processMessageFailedNodes(msg);
}
if (sendMessageToRemotes(msg))
@@ -3733,7 +3833,7 @@ class ServerImpl extends TcpDiscoveryImpl {
interruptPing(leavingNode);
- assert leftNode != null;
+ assert leftNode != null : msg;
if (log.isDebugEnabled())
log.debug("Removed node from topology: " + leftNode);
@@ -3887,6 +3987,8 @@ class ServerImpl extends TcpDiscoveryImpl {
}
if (node != null) {
+ assert !node.isLocal() : msg;
+
synchronized (mux) {
failedNodes.add(node);
}
@@ -4036,32 +4138,46 @@ class ServerImpl extends TcpDiscoveryImpl {
return;
}
+ TcpDiscoveryStatusCheckMessage msg0 = msg;
+
+ if (F.contains(msg.failedNodes(), msg.creatorNodeId())) {
+ msg0 = new TcpDiscoveryStatusCheckMessage(msg);
+
+ msg0.failedNodes(null);
+
+ for (UUID failedNodeId : msg.failedNodes()) {
+ if (!failedNodeId.equals(msg.creatorNodeId()))
+ msg0.addFailedNode(failedNodeId);
+ }
+ }
+
try {
- trySendMessageDirectly(msg.creatorNode(), msg);
+ trySendMessageDirectly(msg0.creatorNode(), msg0);
if (log.isDebugEnabled())
log.debug("Responded to status check message " +
- "[recipient=" + msg.creatorNodeId() + ", status=" + msg.status() + ']');
+ "[recipient=" + msg0.creatorNodeId() + ", status=" + msg0.status() + ']');
}
catch (IgniteSpiException e) {
if (e.hasCause(SocketException.class)) {
if (log.isDebugEnabled())
log.debug("Failed to respond to status check message (connection " +
- "refused) [recipient=" + msg.creatorNodeId() + ", status=" +
- msg.status() + ']');
+ "refused) [recipient=" + msg0.creatorNodeId() + ", status=" +
+ msg0.status() + ']');
onException("Failed to respond to status check message (connection refused) " +
- "[recipient=" + msg.creatorNodeId() + ", status=" + msg.status() + ']', e);
+ "[recipient=" + msg0.creatorNodeId() + ", status=" + msg0.status() + ']', e);
}
- else {
- if (pingNode(msg.creatorNode()))
+ else if (!spi.isNodeStopping0()) {
+ if (pingNode(msg0.creatorNode()))
// Node exists and accepts incoming connections.
U.error(log, "Failed to respond to status check message [recipient=" +
- msg.creatorNodeId() + ", status=" + msg.status() + ']', e);
- else if (log.isDebugEnabled())
- log.debug("Failed to respond to status check message (did the node " +
- "stop?) [recipient=" + msg.creatorNodeId() + ", status=" + msg.status()
- + ']');
+ msg0.creatorNodeId() + ", status=" + msg0.status() + ']', e);
+ else if (log.isDebugEnabled()) {
+ log.debug("Failed to respond to status check message (did the node stop?)" +
+ "[recipient=" + msg0.creatorNodeId() +
+ ", status=" + msg0.status() + ']');
+ }
}
}
}
@@ -4364,27 +4480,42 @@ class ServerImpl extends TcpDiscoveryImpl {
*/
private void processCustomMessage(TcpDiscoveryCustomEventMessage msg) {
if (isLocalNodeCoordinator()) {
- if (!joiningNodes.isEmpty()) {
+ boolean delayMsg;
+
+ assert ring.minimumNodeVersion() != null : ring;
+
+ if (ring.minimumNodeVersion().compareTo(CUSTOM_MSG_ALLOW_JOINING_FOR_VERIFIED_SINCE) >= 0)
+ delayMsg = msg.topologyVersion() == 0L && !joiningNodes.isEmpty();
+ else
+ delayMsg = !joiningNodes.isEmpty();
+
+ if (delayMsg) {
+ if (log.isDebugEnabled()) {
+ log.debug("Delay custom message processing, there are joining nodes [msg=" + msg +
+ ", joiningNodes=" + joiningNodes + ']');
+ }
+
pendingCustomMsgs.add(msg);
return;
}
- boolean sndNext = !msg.verified();
-
- if (sndNext) {
+ if (!msg.verified()) {
msg.verify(getLocalNodeId());
msg.topologyVersion(ring.topologyVersion());
- if (pendingMsgs.procCustomMsgs.add(msg.id()))
+ if (pendingMsgs.procCustomMsgs.add(msg.id())) {
notifyDiscoveryListener(msg);
- else
- sndNext = false;
- }
- if (sndNext && ring.hasRemoteNodes())
- sendMessageAcrossRing(msg);
+ if (sendMessageToRemotes(msg))
+ sendMessageAcrossRing(msg);
+ else
+ processCustomMessage(msg);
+ }
+ }
else {
+ addMessage(new TcpDiscoveryDiscardMessage(getLocalNodeId(), msg.id(), true));
+
spi.stats.onRingMessageReceived(msg);
DiscoverySpiCustomMessage msgObj = null;
@@ -4401,16 +4532,21 @@ class ServerImpl extends TcpDiscoveryImpl {
if (nextMsg != null) {
try {
- addMessage(new TcpDiscoveryCustomEventMessage(getLocalNodeId(), nextMsg,
- spi.marsh.marshal(nextMsg)));
+ TcpDiscoveryCustomEventMessage ackMsg = new TcpDiscoveryCustomEventMessage(
+ getLocalNodeId(), nextMsg, spi.marsh.marshal(nextMsg));
+
+ ackMsg.topologyVersion(msg.topologyVersion());
+
+ processCustomMessage(ackMsg);
+
+ if (ackMsg.verified())
+ msgHist.add(ackMsg);
}
catch (IgniteCheckedException e) {
U.error(log, "Failed to marshal discovery custom message.", e);
}
}
}
-
- addMessage(new TcpDiscoveryDiscardMessage(getLocalNodeId(), msg.id(), true));
}
}
else {
@@ -4428,9 +4564,8 @@ class ServerImpl extends TcpDiscoveryImpl {
}
if (msg.verified() && state0 == CONNECTED && pendingMsgs.procCustomMsgs.add(msg.id())) {
- assert joiningNodes.isEmpty() : "Joining nodes: " + joiningNodes + ", msg=" + msg + ", loc=" + locNode.id() +
- ", topver=" + ring.topologyVersion();
- assert msg.topologyVersion() == ring.topologyVersion() : "msg: " + msg + ", topver=" + ring.topologyVersion();
+ assert msg.topologyVersion() == ring.topologyVersion() :
+ "msg: " + msg + ", topVer=" + ring.topologyVersion();
notifyDiscoveryListener(msg);
}
@@ -4441,6 +4576,38 @@ class ServerImpl extends TcpDiscoveryImpl {
}
/**
+ * Checks failed nodes list and sends {@link TcpDiscoveryNodeFailedMessage} if failed node
+ * is still in the ring.
+ */
+ private void checkFailedNodesList() {
+ List<TcpDiscoveryNodeFailedMessage> msgs = null;
+
+ synchronized (mux) {
+ for (Iterator<TcpDiscoveryNode> it = failedNodes.iterator(); it.hasNext();) {
+ TcpDiscoveryNode node = it.next();
+
+ if (ring.node(node.id()) != null) {
+ if (msgs == null)
+ msgs = new ArrayList<>(failedNodes.size());
+
+ msgs.add(new TcpDiscoveryNodeFailedMessage(getLocalNodeId(), node.id(), node.internalOrder()));
+ }
+ else
+ it.remove();
+ }
+ }
+
+ if (msgs != null) {
+ for (TcpDiscoveryNodeFailedMessage msg : msgs) {
+ if (log.isDebugEnabled())
+ log.debug("Add node failed message for node from failed nodes list: " + msg);
+
+ addMessage(msg);
+ }
+ }
+ }
+
+ /**
* Checks and flushes custom event messages if no nodes are attempting to join the grid.
*/
private void checkPendingCustomMessages() {
@@ -4640,10 +4807,10 @@ class ServerImpl extends TcpDiscoveryImpl {
synchronized (mux) {
readers.add(reader);
-
- reader.start();
}
+ reader.start();
+
spi.stats.onServerSocketInitialized(U.currentTimeMillis() - tstamp);
}
}
@@ -4861,9 +5028,10 @@ class ServerImpl extends TcpDiscoveryImpl {
log.debug("Initialized connection with remote node [nodeId=" + nodeId +
", client=" + req.client() + ']');
- if (debugMode)
- debugLog("Initialized connection with remote node [nodeId=" + nodeId +
+ if (debugMode) {
+ debugLog(msg, "Initialized connection with remote node [nodeId=" + nodeId +
", client=" + req.client() + ']');
+ }
}
catch (IOException e) {
if (log.isDebugEnabled())
@@ -4932,7 +5100,7 @@ class ServerImpl extends TcpDiscoveryImpl {
spi.stats.onMessageReceived(msg);
if (debugMode && recordable(msg))
- debugLog("Message has been received: " + msg);
+ debugLog(msg, "Message has been received: " + msg);
if (msg instanceof TcpDiscoveryConnectionCheckMessage) {
spi.writeToSocket(msg, sock, RES_OK, socketTimeout);
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
index 2786d0b..1aef728 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryImpl.java
@@ -37,6 +37,7 @@ import org.apache.ignite.spi.IgniteSpiException;
import org.apache.ignite.spi.IgniteSpiThread;
import org.apache.ignite.spi.discovery.DiscoverySpiCustomMessage;
import org.apache.ignite.spi.discovery.tcp.internal.TcpDiscoveryNode;
+import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage;
import org.jetbrains.annotations.Nullable;
/**
@@ -99,9 +100,10 @@ abstract class TcpDiscoveryImpl {
}
/**
+ * @param discoMsg Discovery message.
* @param msg Message.
*/
- protected void debugLog(String msg) {
+ protected void debugLog(@Nullable TcpDiscoveryAbstractMessage discoMsg, String msg) {
assert debugMode;
String msg0 = new SimpleDateFormat("[HH:mm:ss,SSS]").format(new Date(System.currentTimeMillis())) +
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java
index 7ca092c..eb0f74a 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/internal/TcpDiscoveryNodesRing.java
@@ -26,6 +26,7 @@ import org.apache.ignite.internal.util.typedef.PN;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgnitePredicate;
+import org.apache.ignite.lang.IgniteProductVersion;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -88,6 +89,23 @@ public class TcpDiscoveryNodesRing {
@GridToStringExclude
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
+ /** */
+ private IgniteProductVersion minNodeVer;
+
+ /**
+ * @return Minimum node version.
+ */
+ public IgniteProductVersion minimumNodeVersion() {
+ rwLock.readLock().lock();
+
+ try {
+ return minNodeVer;
+ }
+ finally {
+ rwLock.readLock().unlock();
+ }
+ }
+
/**
* Sets local node.
*
@@ -225,6 +243,8 @@ public class TcpDiscoveryNodesRing {
nodeOrder = node.internalOrder();
maxInternalOrder = node.internalOrder();
+
+ initializeMinimumVersion();
}
finally {
rwLock.writeLock().unlock();
@@ -295,6 +315,8 @@ public class TcpDiscoveryNodesRing {
}
nodeOrder = topVer;
+
+ initializeMinimumVersion();
}
finally {
rwLock.writeLock().unlock();
@@ -341,6 +363,8 @@ public class TcpDiscoveryNodesRing {
nodes.remove(rmv);
}
+ initializeMinimumVersion();
+
return rmv;
}
finally {
@@ -372,6 +396,8 @@ public class TcpDiscoveryNodesRing {
maxInternalOrder = 0;
topVer = 0;
+
+ minNodeVer = locNode.version();
}
finally {
rwLock.writeLock().unlock();
@@ -451,61 +477,8 @@ public class TcpDiscoveryNodesRing {
* topology contains less than two nodes.
*/
@Nullable public TcpDiscoveryNode nextNode(@Nullable Collection<TcpDiscoveryNode> excluded) {
- assert excluded == null || excluded.isEmpty() || !excluded.contains(locNode);
-
- rwLock.readLock().lock();
-
- try {
- Collection<TcpDiscoveryNode> filtered = serverNodes(excluded);
-
- if (filtered.size() < 2)
- return null;
-
- Iterator<TcpDiscoveryNode> iter = filtered.iterator();
-
- while (iter.hasNext()) {
- TcpDiscoveryNode node = iter.next();
-
- if (locNode.equals(node))
- break;
- }
-
- return iter.hasNext() ? iter.next() : F.first(filtered);
- }
- finally {
- rwLock.readLock().unlock();
- }
- }
-
- /**
- * Finds previous node in the topology.
- *
- * @return Previous node.
- */
- @Nullable public TcpDiscoveryNode previousNode() {
- rwLock.readLock().lock();
-
- try {
- if (nodes.size() < 2)
- return null;
-
- return previousNode(null);
- }
- finally {
- rwLock.readLock().unlock();
- }
- }
-
- /**
- * Finds previous node in the topology filtering excluded nodes from search.
- *
- * @param excluded Nodes to exclude from the search (optional). If provided,
- * cannot contain local node.
- * @return Previous node or {@code null} if all nodes were filtered out or
- * topology contains less than two nodes.
- */
- @Nullable public TcpDiscoveryNode previousNode(@Nullable Collection<TcpDiscoveryNode> excluded) {
- assert excluded == null || excluded.isEmpty() || !excluded.contains(locNode);
+ assert locNode.internalOrder() > 0 : locNode;
+ assert excluded == null || excluded.isEmpty() || !excluded.contains(locNode) : excluded;
rwLock.readLock().lock();
@@ -638,6 +611,18 @@ public class TcpDiscoveryNodesRing {
});
}
+ /**
+ *
+ */
+ private void initializeMinimumVersion() {
+ minNodeVer = null;
+
+ for (TcpDiscoveryNode node : nodes) {
+ if (minNodeVer == null || node.version().compareTo(minNodeVer) < 0)
+ minNodeVer = node.version();
+ }
+ }
+
/** {@inheritDoc} */
@Override public String toString() {
rwLock.readLock().lock();
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java
index 875d18e..9cb47af 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryAbstractMessage.java
@@ -19,10 +19,15 @@ package org.apache.ignite.spi.discovery.tcp.messages;
import java.io.Externalizable;
import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
import java.util.UUID;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteUuid;
+import org.jetbrains.annotations.Nullable;
/**
* Base class to implement discovery messages.
@@ -62,6 +67,10 @@ public abstract class TcpDiscoveryAbstractMessage implements Serializable {
/** Pending message index. */
private short pendingIdx;
+ /** */
+ @GridToStringInclude
+ private Set<UUID> failedNodes;
+
/**
* Default no-arg constructor for {@link Externalizable} interface.
*/
@@ -236,6 +245,34 @@ public abstract class TcpDiscoveryAbstractMessage implements Serializable {
return false;
}
+ /**
+ * Adds node ID to the failed nodes list.
+ *
+ * @param nodeId Node ID.
+ */
+ public void addFailedNode(UUID nodeId) {
+ assert nodeId != null;
+
+ if (failedNodes == null)
+ failedNodes = new HashSet<>();
+
+ failedNodes.add(nodeId);
+ }
+
+ /**
+ * @param failedNodes Failed nodes.
+ */
+ public void failedNodes(@Nullable Set<UUID> failedNodes) {
+ this.failedNodes = failedNodes;
+ }
+
+ /**
+ * @return Failed nodes IDs.
+ */
+ @Nullable public Collection<UUID> failedNodes() {
+ return failedNodes;
+ }
+
/** {@inheritDoc} */
@Override public final boolean equals(Object obj) {
if (this == obj)
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryStatusCheckMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryStatusCheckMessage.java b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryStatusCheckMessage.java
index 6118f4d..70b0080 100644
--- a/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryStatusCheckMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/spi/discovery/tcp/messages/TcpDiscoveryStatusCheckMessage.java
@@ -62,6 +62,17 @@ public class TcpDiscoveryStatusCheckMessage extends TcpDiscoveryAbstractMessage
}
/**
+ * @param msg Message to copy.
+ */
+ public TcpDiscoveryStatusCheckMessage(TcpDiscoveryStatusCheckMessage msg) {
+ super(msg);
+
+ this.creatorNode = msg.creatorNode;
+ this.failedNodeId = msg.failedNodeId;
+ this.status = msg.status;
+ }
+
+ /**
* Gets creator node.
*
* @return Creator node.
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryMultiThreadedTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryMultiThreadedTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryMultiThreadedTest.java
index 55474dc..5053c2d 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryMultiThreadedTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryMultiThreadedTest.java
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteClientDisconnectedException;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.DiscoveryEvent;
@@ -212,6 +213,22 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
public void testMultiThreadedClientsServersRestart() throws Throwable {
fail("https://issues.apache.org/jira/browse/IGNITE-1123");
+ multiThreadedClientsServersRestart(GRID_CNT, CLIENT_GRID_CNT);
+ }
+
+ /**
+ * @throws Exception If any error occurs.
+ */
+ public void _testMultiThreadedServersRestart() throws Throwable {
+ multiThreadedClientsServersRestart(GRID_CNT * 2, 0);
+ }
+
+ /**
+ * @param srvs Number of servers.
+ * @param clients Number of clients.
+ * @throws Exception If any error occurs.
+ */
+ private void multiThreadedClientsServersRestart(int srvs, int clients) throws Throwable {
final AtomicBoolean done = new AtomicBoolean();
try {
@@ -219,91 +236,95 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
info("Test timeout: " + (getTestTimeout() / (60 * 1000)) + " min.");
- startGridsMultiThreaded(GRID_CNT);
-
- clientFlagGlobal = true;
+ startGridsMultiThreaded(srvs);
- startGridsMultiThreaded(GRID_CNT, CLIENT_GRID_CNT);
+ IgniteInternalFuture<?> clientFut = null;
final AtomicReference<Throwable> error = new AtomicReference<>();
- final BlockingQueue<Integer> clientStopIdxs = new LinkedBlockingQueue<>();
-
- for (int i = GRID_CNT; i < GRID_CNT + CLIENT_GRID_CNT; i++)
- clientStopIdxs.add(i);
+ if (clients > 0) {
+ clientFlagGlobal = true;
- final AtomicInteger clientStartIdx = new AtomicInteger(9000);
+ startGridsMultiThreaded(srvs, clients);
- IgniteInternalFuture<?> fut1 = multithreadedAsync(
- new Callable<Object>() {
- @Override public Object call() throws Exception {
- try {
- clientFlagPerThread.set(true);
+ final BlockingQueue<Integer> clientStopIdxs = new LinkedBlockingQueue<>();
- while (!done.get() && error.get() == null) {
- Integer stopIdx = clientStopIdxs.take();
+ for (int i = srvs; i < srvs + clients; i++)
+ clientStopIdxs.add(i);
- log.info("Stop client: " + stopIdx);
+ final AtomicInteger clientStartIdx = new AtomicInteger(9000);
- stopGrid(stopIdx);
+ clientFut = multithreadedAsync(
+ new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ try {
+ clientFlagPerThread.set(true);
while (!done.get() && error.get() == null) {
- // Generate unique name to simplify debugging.
- int startIdx = clientStartIdx.getAndIncrement();
+ Integer stopIdx = clientStopIdxs.take();
- log.info("Start client: " + startIdx);
+ log.info("Stop client: " + stopIdx);
- UUID id = UUID.randomUUID();
+ stopGrid(stopIdx);
- nodeId.set(id);
+ while (!done.get() && error.get() == null) {
+ // Generate unique name to simplify debugging.
+ int startIdx = clientStartIdx.getAndIncrement();
- try {
- Ignite ignite = startGrid(startIdx);
+ log.info("Start client: " + startIdx);
- assertTrue(ignite.configuration().isClientMode());
+ UUID id = UUID.randomUUID();
- clientStopIdxs.add(startIdx);
+ nodeId.set(id);
- break;
- }
- catch (Exception e) {
- if (X.hasCause(e, IgniteClientDisconnectedCheckedException.class) ||
- X.hasCause(e, IgniteClientDisconnectedException.class))
- log.info("Client disconnected: " + e);
- else if (X.hasCause(e, ClusterTopologyCheckedException.class))
- log.info("Client failed to start: " + e);
- else {
- if (failedNodes.contains(id) && X.hasCause(e, IgniteSpiException.class))
- log.info("Client failed: " + e);
- else
- throw e;
+ try {
+ Ignite ignite = startGrid(startIdx);
+
+ assertTrue(ignite.configuration().isClientMode());
+
+ clientStopIdxs.add(startIdx);
+
+ break;
+ }
+ catch (Exception e) {
+ if (X.hasCause(e, IgniteClientDisconnectedCheckedException.class) ||
+ X.hasCause(e, IgniteClientDisconnectedException.class))
+ log.info("Client disconnected: " + e);
+ else if (X.hasCause(e, ClusterTopologyCheckedException.class))
+ log.info("Client failed to start: " + e);
+ else {
+ if (failedNodes.contains(id) && X.hasCause(e, IgniteSpiException.class))
+ log.info("Client failed: " + e);
+ else
+ throw e;
+ }
}
}
}
}
- }
- catch (Throwable e) {
- log.error("Unexpected error: " + e, e);
+ catch (Throwable e) {
+ log.error("Unexpected error: " + e, e);
- error.compareAndSet(null, e);
+ error.compareAndSet(null, e);
+
+ return null;
+ }
return null;
}
-
- return null;
- }
- },
- CLIENT_GRID_CNT,
- "client-restart");
+ },
+ clients,
+ "client-restart");
+ }
final BlockingQueue<Integer> srvStopIdxs = new LinkedBlockingQueue<>();
- for (int i = 0; i < GRID_CNT; i++)
+ for (int i = 0; i < srvs; i++)
srvStopIdxs.add(i);
- final AtomicInteger srvStartIdx = new AtomicInteger(GRID_CNT + CLIENT_GRID_CNT);
+ final AtomicInteger srvStartIdx = new AtomicInteger(srvs + clients);
- IgniteInternalFuture<?> fut2 = multithreadedAsync(
+ IgniteInternalFuture<?> srvFut = multithreadedAsync(
new Callable<Object>() {
@Override public Object call() throws Exception {
try {
@@ -312,6 +333,10 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
while (!done.get() && error.get() == null) {
int stopIdx = srvStopIdxs.take();
+ U.sleep(50);
+
+ Thread.currentThread().setName("stop-server-" + getTestGridName(stopIdx));
+
log.info("Stop server: " + stopIdx);
stopGrid(stopIdx);
@@ -319,13 +344,20 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
// Generate unique name to simplify debugging.
int startIdx = srvStartIdx.getAndIncrement();
+ Thread.currentThread().setName("start-server-" + getTestGridName(startIdx));
+
log.info("Start server: " + startIdx);
- Ignite ignite = startGrid(startIdx);
+ try {
+ Ignite ignite = startGrid(startIdx);
- assertFalse(ignite.configuration().isClientMode());
+ assertFalse(ignite.configuration().isClientMode());
- srvStopIdxs.add(startIdx);
+ srvStopIdxs.add(startIdx);
+ }
+ catch (IgniteCheckedException e) {
+ log.info("Failed to start: " + e);
+ }
}
}
catch (Throwable e) {
@@ -339,7 +371,7 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
return null;
}
},
- GRID_CNT - 1,
+ srvs - 1,
"server-restart");
final long timeToExec = getTestTimeout() - 60_000;
@@ -356,8 +388,10 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
done.set(true);
- fut1.cancel();
- fut2.cancel();
+ if (clientFut != null)
+ clientFut.cancel();
+
+ srvFut.cancel();
throw err;
}
@@ -367,8 +401,10 @@ public class TcpDiscoveryMultiThreadedTest extends GridCommonAbstractTest {
done.set(true);
- fut1.get();
- fut2.get();
+ if (clientFut != null)
+ clientFut.get();
+
+ srvFut.get();
}
finally {
done.set(true);
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryRestartTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryRestartTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryRestartTest.java
index 8b94f54..7beeb41 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryRestartTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoveryRestartTest.java
@@ -30,6 +30,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.DiscoveryEvent;
import org.apache.ignite.events.Event;
import org.apache.ignite.internal.IgniteInternalFuture;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
@@ -196,8 +197,15 @@ public class TcpDiscoveryRestartTest extends GridCommonAbstractTest {
/**
* @param nodeId Node ID.
+ * @throws Exception If failed.
*/
- void checkEvents(UUID nodeId) {
+ void checkEvents(final UUID nodeId) throws Exception {
+ GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ return joinIds.contains(nodeId) && leftIds.contains(nodeId);
+ }
+ }, 5000);
+
assertTrue("No join event: " + nodeId, joinIds.contains(nodeId));
assertTrue("No left event: " + nodeId, leftIds.contains(nodeId));
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
index 51d8a2d..379a3a6 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/TcpDiscoverySelfTest.java
@@ -21,16 +21,19 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -38,6 +41,8 @@ import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteException;
+import org.apache.ignite.IgniteIllegalStateException;
+import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.DiscoveryEvent;
@@ -46,12 +51,16 @@ import org.apache.ignite.events.EventType;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.IgniteKernal;
+import org.apache.ignite.internal.managers.discovery.DiscoveryCustomMessage;
+import org.apache.ignite.internal.processors.continuous.StartRoutineAckDiscoveryMessage;
import org.apache.ignite.internal.processors.port.GridPortRecord;
import org.apache.ignite.internal.util.io.GridByteArrayOutputStream;
+import org.apache.ignite.internal.util.lang.GridAbsPredicate;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteBiPredicate;
import org.apache.ignite.lang.IgniteInClosure;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.spi.IgniteSpiException;
@@ -64,8 +73,8 @@ import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryAbstractMessage;
import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryCustomEventMessage;
import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddFinishedMessage;
import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeAddedMessage;
+import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeFailedMessage;
import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryNodeLeftMessage;
-import org.apache.ignite.spi.discovery.tcp.messages.TcpDiscoveryPingResponse;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.jetbrains.annotations.Nullable;
@@ -94,7 +103,7 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
private UUID nodeId;
/** */
- private TcpDiscoverySpi nodeSpi;
+ private static ThreadLocal<TcpDiscoverySpi> nodeSpi = new ThreadLocal<>();
/**
* @throws Exception If fails.
@@ -104,15 +113,17 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
}
/** {@inheritDoc} */
- @SuppressWarnings({"IfMayBeConditional", "deprecation"})
@Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
IgniteConfiguration cfg = super.getConfiguration(gridName);
- TcpDiscoverySpi spi = nodeSpi;
+ TcpDiscoverySpi spi = nodeSpi.get();
- if (spi == null)
+ if (spi == null) {
spi = gridName.contains("testPingInterruptedOnNodeFailedFailingNode") ?
new TestTcpDiscoverySpi() : new TcpDiscoverySpi();
+ }
+ else
+ nodeSpi.set(null);
discoMap.put(gridName, spi);
@@ -176,6 +187,13 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
return cfg;
}
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ discoMap = null;
+
+ super.afterTest();
+ }
+
/**
* @throws Exception If any error occurs.
*/
@@ -1202,11 +1220,11 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
private void customEventRace1(final boolean cacheStartFrom1, boolean stopCrd) throws Exception {
TestCustomEventRaceSpi spi0 = new TestCustomEventRaceSpi();
- nodeSpi = spi0;
+ nodeSpi.set(spi0);
final Ignite ignite0 = startGrid(0);
- nodeSpi = new TestCustomEventRaceSpi();
+ nodeSpi.set(new TestCustomEventRaceSpi());
final Ignite ignite1 = startGrid(1);
@@ -1221,7 +1239,7 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
@Override public Void call() throws Exception {
log.info("Start 2");
- nodeSpi = new TestCustomEventRaceSpi();
+ nodeSpi.set(new TestCustomEventRaceSpi());
Ignite ignite2 = startGrid(2);
@@ -1271,7 +1289,7 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
assertEquals(1, cache.get(1));
- nodeSpi = new TestCustomEventRaceSpi();
+ nodeSpi.set(new TestCustomEventRaceSpi());
Ignite ignite = startGrid(3);
@@ -1314,15 +1332,15 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
private void customEventCoordinatorFailure(boolean twoNodes) throws Exception {
TestCustomEventCoordinatorFailureSpi spi0 = new TestCustomEventCoordinatorFailureSpi();
- nodeSpi = spi0;
+ nodeSpi.set(spi0);
Ignite ignite0 = startGrid(0);
- nodeSpi = new TestCustomEventCoordinatorFailureSpi();
+ nodeSpi.set(new TestCustomEventCoordinatorFailureSpi());
Ignite ignite1 = startGrid(1);
- nodeSpi = new TestCustomEventCoordinatorFailureSpi();
+ nodeSpi.set(new TestCustomEventCoordinatorFailureSpi());
Ignite ignite2 = twoNodes ? null : startGrid(2);
@@ -1366,7 +1384,7 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
log.info("Try start one more node.");
- nodeSpi = new TestCustomEventCoordinatorFailureSpi();
+ nodeSpi.set(new TestCustomEventCoordinatorFailureSpi());
Ignite ignite = startGrid(twoNodes ? 2 : 3);
@@ -1381,6 +1399,421 @@ public class TcpDiscoverySelfTest extends GridCommonAbstractTest {
}
/**
+ * Coordinator is added in failed list during node start.
+ *
+ * @throws Exception If failed.
+ */
+ public void testFailedNodes1() throws Exception {
+ try {
+ final int FAIL_ORDER = 3;
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ final Ignite ignite0 = startGrid(0);
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ startGrid(1);
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ Ignite ignite2 = startGrid(2);
+
+ assertEquals(2, ignite2.cluster().nodes().size());
+
+ waitNodeStop(ignite0.name());
+
+ tryCreateCache(2);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * Coordinator is added in failed list, concurrent nodes start.
+ *
+ * @throws Exception If failed.
+ */
+ public void testFailedNodes2() throws Exception {
+ try {
+ final int FAIL_ORDER = 3;
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ Ignite ignite0 = startGrid(0);
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ startGrid(1);
+
+ final AtomicInteger nodeIdx = new AtomicInteger(1);
+
+ GridTestUtils.runMultiThreaded(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ int idx = nodeIdx.incrementAndGet();
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ startGrid(idx);
+
+ return null;
+ }
+ }, 3, "start-node");
+
+ Ignite ignite2 = ignite(2);
+
+ waitForRemoteNodes(ignite2, 3);
+
+ waitNodeStop(ignite0.name());
+
+ tryCreateCache(4);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * Coordinator is added in failed list during node start, test with two nodes.
+ *
+ * @throws Exception If failed.
+ */
+ public void testFailedNodes3() throws Exception {
+ try {
+ nodeSpi.set(new TestFailedNodesSpi(-1));
+
+ Ignite ignite0 = startGrid(0);
+
+ nodeSpi.set(new TestFailedNodesSpi(2));
+
+ Ignite ignite1 = startGrid(1);
+
+ assertEquals(1, ignite1.cluster().nodes().size());
+
+ waitNodeStop(ignite0.name());
+
+ ignite1.getOrCreateCache(new CacheConfiguration<>()).put(1, 1);
+
+ startGrid(2);
+
+ assertEquals(2, ignite1.cluster().nodes().size());
+
+ tryCreateCache(2);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * Coordinator is added in failed list during node start, but node detected failure dies before
+ * sending {@link TcpDiscoveryNodeFailedMessage}.
+ *
+ * @throws Exception If failed.
+ */
+ public void testFailedNodes4() throws Exception {
+ try {
+ final int FAIL_ORDER = 3;
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ final Ignite ignite0 = startGrid(0);
+
+ nodeSpi.set(new TestFailedNodesSpi(FAIL_ORDER));
+
+ Ignite ignite1 = startGrid(1);
+
+ TestFailedNodesSpi spi = new TestFailedNodesSpi(FAIL_ORDER);
+
+ spi.stopBeforeSndFail = true;
+
+ nodeSpi.set(spi);
+
+ Ignite ignite2 = startGrid(2);
+
+ waitNodeStop(ignite2.name());
+
+ log.info("Try start new node.");
+
+ Ignite ignite3 = startGrid(3);
+
+ waitNodeStop(ignite0.name());
+
+ assertEquals(2, ignite1.cluster().nodes().size());
+ assertEquals(2, ignite3.cluster().nodes().size());
+
+ tryCreateCache(2);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * Adds some node in failed list after join process finished.
+ *
+ * @throws Exception If failed.
+ */
+ public void testFailedNodes5() throws Exception {
+ try {
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ for (int iter = 0; iter < 3; iter++) {
+ final int NODES = iter == 0 ? 2 : rnd.nextInt(3, 6);
+
+ for (int i = 0; i < NODES; i++) {
+ nodeSpi.set(new TestFailedNodesSpi(-1));
+
+ startGrid(i);
+ }
+
+ Map<Long, Ignite> nodes = new HashMap<>();
+
+ for (int i = 0; i < NODES; i++) {
+ Ignite ignite = ignite(i);
+
+ nodes.put(ignite.cluster().localNode().order(), ignite);
+ }
+
+ Ignite ignite = ignite(rnd.nextInt(NODES));
+
+ log.info("Iteration [iter=" + iter + ", nodes=" + NODES + ", failFrom=" + ignite.name() + ']');
+
+ TestFailedNodesSpi spi = (TestFailedNodesSpi)ignite.configuration().getDiscoverySpi();
+
+ spi.failSingleMsg = true;
+
+ long order = ignite.cluster().localNode().order();
+
+ long nextOrder = order == NODES ? 1 : order + 1;
+
+ Ignite failingNode = nodes.get(nextOrder);
+
+ assertNotNull(failingNode);
+
+ waitNodeStop(failingNode.name());
+
+ Ignite newNode = startGrid(NODES);
+
+ assertEquals(NODES, newNode.cluster().nodes().size());
+
+ tryCreateCache(NODES);
+
+ stopAllGrids();
+ }
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * @throws Exception If failed.
+ */
+ public void testCustomEventAckNotSend() throws Exception {
+ try {
+ TestCustomerEventAckSpi spi0 = new TestCustomerEventAckSpi();
+
+ nodeSpi.set(spi0);
+
+ Ignite ignite0 = startGrid(0);
+
+ nodeSpi.set(new TestCustomerEventAckSpi());
+
+ Ignite ignite1 = startGrid(1);
+
+ spi0.stopBeforeSndAck = true;
+
+ ignite1.message().remoteListen("test", new DummyPredicate());
+
+ waitNodeStop(ignite0.name());
+
+ startGrid(2);
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
+ * @param nodeName Node name.
+ * @throws Exception If failed.
+ */
+ private void waitNodeStop(final String nodeName) throws Exception {
+ boolean wait = GridTestUtils.waitForCondition(new GridAbsPredicate() {
+ @Override public boolean apply() {
+ try {
+ Ignition.ignite(nodeName);
+
+ return false;
+ }
+ catch (IgniteIllegalStateException e) {
+ return true;
+ }
+ }
+ }, 10_000);
+
+ if (!wait)
+ U.dumpThreads(log);
+
+ assertTrue("Failed to wait for node stop.", wait);
+ }
+
+ /**
+ * @param expNodes Expected nodes number.
+ */
+ private void tryCreateCache(int expNodes) {
+ List<Ignite> allNodes = G.allGrids();
+
+ assertEquals(expNodes, allNodes.size());
+
+ int cntr = 0;
+
+ for (Ignite ignite : allNodes) {
+ CacheConfiguration<Object, Object> ccfg = new CacheConfiguration<>();
+
+ ccfg.setName("cache-" + cntr++);
+
+ log.info("Try create cache [node=" + ignite.name() + ", cache=" + ccfg.getName() + ']');
+
+ ignite.getOrCreateCache(ccfg).put(1, 1);
+ }
+ }
+
+ /**
+ *
+ */
+ static class DummyPredicate implements IgniteBiPredicate<UUID, Object> {
+ /** {@inheritDoc} */
+ @Override public boolean apply(UUID uuid, Object o) {
+ return true;
+ }
+ }
+
+ /**
+ *
+ */
+ private static class TestCustomerEventAckSpi extends TcpDiscoverySpi {
+ /** */
+ private volatile boolean stopBeforeSndAck;
+
+ /** {@inheritDoc} */
+ @Override protected void writeToSocket(Socket sock,
+ TcpDiscoveryAbstractMessage msg,
+ GridByteArrayOutputStream bout,
+ long timeout) throws IOException, IgniteCheckedException {
+ if (stopBeforeSndAck) {
+ if (msg instanceof TcpDiscoveryCustomEventMessage) {
+ try {
+ DiscoveryCustomMessage custMsg = GridTestUtils.getFieldValue(
+ ((TcpDiscoveryCustomEventMessage)msg).message(marsh), "delegate");
+
+ if (custMsg instanceof StartRoutineAckDiscoveryMessage) {
+ log.info("Skip message send and stop node: " + msg);
+
+ sock.close();
+
+ GridTestUtils.runAsync(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ ignite.close();
+
+ return null;
+ }
+ }, "stop-node");
+
+ return;
+ }
+ }
+ catch (Throwable e) {
+ fail("Unexpected error: " + e);
+ }
+ }
+ }
+
+ super.writeToSocket(sock, msg, bout, timeout);
+ }
+ }
+
+ /**
+ * Simulate scenario when node detects node failure trying to send message, but node still alive.
+ */
+ private static class TestFailedNodesSpi extends TcpDiscoverySpi {
+ /** */
+ private AtomicBoolean failMsg = new AtomicBoolean();
+
+ /** */
+ private int failOrder;
+
+ /** */
+ private boolean stopBeforeSndFail;
+
+ /** */
+ private boolean stop;
+
+ /** */
+ private volatile boolean failSingleMsg;
+
+ /**
+ * @param failOrder Spi fails connection if local node order equals to this order.
+ */
+ TestFailedNodesSpi(int failOrder) {
+ this.failOrder = failOrder;
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void writeToSocket(Socket sock,
+ TcpDiscoveryAbstractMessage msg,
+ GridByteArrayOutputStream bout,
+ long timeout) throws IOException, IgniteCheckedException {
+ if (stop)
+ return;
+
+ if (failSingleMsg) {
+ failSingleMsg = false;
+
+ log.info("IO error on message send [locNode=" + locNode + ", msg=" + msg + ']');
+
+ sock.close();
+
+ throw new SocketTimeoutException();
+ }
+
+ if (locNode.internalOrder() == failOrder &&
+ (msg instanceof TcpDiscoveryNodeAddedMessage) &&
+ failMsg.compareAndSet(false, true)) {
+ log.info("IO error on message send [locNode=" + locNode + ", msg=" + msg + ']');
+
+ sock.close();
+
+ throw new SocketTimeoutException();
+ }
+
+ if (stopBeforeSndFail &&
+ locNode.internalOrder() == failOrder &&
+ (msg instanceof TcpDiscoveryNodeFailedMessage)) {
+ stop = true;
+
+ log.info("Skip messages send and stop node [locNode=" + locNode + ", msg=" + msg + ']');
+
+ sock.close();
+
+ GridTestUtils.runAsync(new Callable<Object>() {
+ @Override public Object call() throws Exception {
+ ignite.close();
+
+ return null;
+ }
+ }, "stop-node");
+
+ return;
+ }
+
+ super.writeToSocket(sock, msg, bout, timeout);
+ }
+ }
+
+ /**
*
*/
private static class TestCustomEventCoordinatorFailureSpi extends TcpDiscoverySpi {
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/multicast/TcpDiscoveryMulticastIpFinderSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/multicast/TcpDiscoveryMulticastIpFinderSelfTest.java b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/multicast/TcpDiscoveryMulticastIpFinderSelfTest.java
index 97ba5cf..1e710ee 100644
--- a/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/multicast/TcpDiscoveryMulticastIpFinderSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/spi/discovery/tcp/ipfinder/multicast/TcpDiscoveryMulticastIpFinderSelfTest.java
@@ -58,14 +58,20 @@ public class TcpDiscoveryMulticastIpFinderSelfTest
try {
ipFinder1 = ipFinder();
+ ipFinder1.setResponseWaitTime(1000);
+ ipFinder1.setAddressRequestAttempts(10);
ipFinder2 = new TcpDiscoveryMulticastIpFinder();
+ ipFinder2.setResponseWaitTime(1000);
+ ipFinder2.setAddressRequestAttempts(10);
ipFinder2.setMulticastGroup(ipFinder1.getMulticastGroup());
ipFinder2.setMulticastPort(ipFinder1.getMulticastPort());
ipFinder3 = new TcpDiscoveryMulticastIpFinder();
+ ipFinder3.setResponseWaitTime(1000);
+ ipFinder3.setAddressRequestAttempts(10);
ipFinder3.setMulticastGroup(ipFinder1.getMulticastGroup());
ipFinder3.setMulticastPort(ipFinder1.getMulticastPort());
@@ -81,21 +87,13 @@ public class TcpDiscoveryMulticastIpFinderSelfTest
ipFinder2.initializeLocalAddresses(Collections.singleton(new InetSocketAddress("host2", 1002)));
ipFinder3.initializeLocalAddresses(Collections.singleton(new InetSocketAddress("host3", 1003)));
- for (int i = 0; i < 5; i++) {
- Collection<InetSocketAddress> addrs1 = ipFinder1.getRegisteredAddresses();
- Collection<InetSocketAddress> addrs2 = ipFinder2.getRegisteredAddresses();
- Collection<InetSocketAddress> addrs3 = ipFinder3.getRegisteredAddresses();
-
- if (addrs1.size() != 1 || addrs2.size() != 2 || addrs3.size() != 3) {
- info("Addrs1: " + addrs1);
- info("Addrs2: " + addrs2);
- info("Addrs2: " + addrs3);
-
- Thread.sleep(1000);
- }
- else
- break;
- }
+ Collection<InetSocketAddress> addrs1 = ipFinder1.getRegisteredAddresses();
+ Collection<InetSocketAddress> addrs2 = ipFinder2.getRegisteredAddresses();
+ Collection<InetSocketAddress> addrs3 = ipFinder3.getRegisteredAddresses();
+
+ info("Addrs1: " + addrs1);
+ info("Addrs2: " + addrs2);
+ info("Addrs2: " + addrs3);
assertEquals(1, ipFinder1.getRegisteredAddresses().size());
assertEquals(2, ipFinder2.getRegisteredAddresses().size());
http://git-wip-us.apache.org/repos/asf/ignite/blob/80147128/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index 41d4b4a..3e41979 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -1120,16 +1120,31 @@ public abstract class GridAbstractTest extends TestCase {
if (gridName != null && gridName.matches(".*\\d")) {
String idStr = UUID.randomUUID().toString();
- char[] chars = idStr.toCharArray();
+ if (gridName.startsWith(getTestGridName())) {
+ String idxStr = String.valueOf(getTestGridIndex(gridName));
- chars[0] = gridName.charAt(gridName.length() - 1);
- chars[1] = '0';
+ while (idxStr.length() < 5)
+ idxStr = '0' + idxStr;
- chars[chars.length - 3] = '0';
- chars[chars.length - 2] = '0';
- chars[chars.length - 1] = gridName.charAt(gridName.length() - 1);
+ char[] chars = idStr.toCharArray();
- cfg.setNodeId(UUID.fromString(new String(chars)));
+ for (int i = 0; i < idxStr.length(); i++)
+ chars[chars.length - idxStr.length() + i] = idxStr.charAt(i);
+
+ cfg.setNodeId(UUID.fromString(new String(chars)));
+ }
+ else {
+ char[] chars = idStr.toCharArray();
+
+ chars[0] = gridName.charAt(gridName.length() - 1);
+ chars[1] = '0';
+
+ chars[chars.length - 3] = '0';
+ chars[chars.length - 2] = '0';
+ chars[chars.length - 1] = gridName.charAt(gridName.length() - 1);
+
+ cfg.setNodeId(UUID.fromString(new String(chars)));
+ }
}
if (isMultiJvm())
[36/51] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by vk...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/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 db4a4b8..434b6c7 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
@@ -68,9 +68,7 @@ import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionState;
import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentHashMap8;
-import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
import static org.apache.ignite.transactions.TransactionState.COMMITTED;
import static org.apache.ignite.transactions.TransactionState.COMMITTING;
import static org.apache.ignite.transactions.TransactionState.PREPARING;
@@ -87,7 +85,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
private static final long serialVersionUID = 0L;
/** DHT mappings. */
- private Map<UUID, GridDistributedTxMapping> mappings = new ConcurrentHashMap8<>();
+ private IgniteTxMappings mappings;
/** Future. */
@GridToStringExclude
@@ -172,6 +170,8 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
subjId,
taskNameHash);
+ mappings = implicitSingle ? new IgniteTxMappingsSingleImpl() : new IgniteTxMappingsImpl();
+
initResult();
}
@@ -208,13 +208,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/** {@inheritDoc} */
- @Override protected IgniteUuid nearMiniId() {
- assert false : "nearMiniId should not be called for colocated transactions.";
-
- return null;
- }
-
- /** {@inheritDoc} */
@Override protected IgniteInternalFuture<Boolean> addReader(
long msgId,
GridDhtCacheEntry cached,
@@ -280,15 +273,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
* @return {@code True} if transaction is fully synchronous.
*/
private boolean sync() {
- if (super.syncCommit())
- return true;
-
- for (int cacheId : activeCacheIds()) {
- if (cctx.cacheContext(cacheId).config().getWriteSynchronizationMode() == FULL_SYNC)
- return true;
- }
-
- return false;
+ return super.syncCommit() || txState().sync(cctx);
}
/**
@@ -471,7 +456,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
/**
* @return DHT map.
*/
- Map<UUID, GridDistributedTxMapping> mappings() {
+ IgniteTxMappings mappings() {
return mappings;
}
@@ -518,9 +503,9 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
GridDistributedTxMapping m = mappings.get(node.id());
if (m == null)
- mappings.put(node.id(), m = new GridDistributedTxMapping(node));
+ mappings.put(m = new GridDistributedTxMapping(node));
- IgniteTxEntry txEntry = txMap.get(key);
+ IgniteTxEntry txEntry = entry(key);
assert txEntry != null;
@@ -534,26 +519,10 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/**
- * Adds keys mapping.
- *
- * @param n Mapped node.
- * @param mappedKeys Mapped keys.
+ * @return Non-null entry if tx has only one write entry.
*/
- private void addKeyMapping(ClusterNode n, Iterable<IgniteTxKey> mappedKeys) {
- GridDistributedTxMapping m = mappings.get(n.id());
-
- if (m == null)
- mappings.put(n.id(), m = new GridDistributedTxMapping(n));
-
- for (IgniteTxKey key : mappedKeys) {
- IgniteTxEntry txEntry = txMap.get(key);
-
- assert txEntry != null;
-
- txEntry.nodeId(n.id());
-
- m.add(txEntry);
- }
+ @Nullable IgniteTxEntry singleWrite() {
+ return txState.singleWrite();
}
/**
@@ -567,7 +536,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
GridDistributedTxMapping m = mappings.get(n.id());
if (m == null) {
- m = F.addIfAbsent(mappings, n.id(), new GridDistributedTxMapping(n));
+ mappings.put(m = new GridDistributedTxMapping(n));
m.near(map.near());
@@ -575,8 +544,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
m.markExplicitLock();
}
- assert m != null;
-
for (IgniteTxEntry entry : map.entries())
m.add(entry);
}
@@ -588,6 +555,25 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/**
+ * @param map Mapping.
+ * @param entry Entry.
+ */
+ void addSingleEntryMapping(GridDistributedTxMapping map, IgniteTxEntry entry) {
+ ClusterNode n = map.node();
+
+ GridDistributedTxMapping m = new GridDistributedTxMapping(n);
+
+ mappings.put(m);
+
+ m.near(map.near());
+
+ if (map.explicitLock())
+ m.markExplicitLock();
+
+ m.add(entry);
+ }
+
+ /**
* @param nodeId Node ID to mark with explicit lock.
* @return {@code True} if mapping was found.
*/
@@ -623,8 +609,23 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
Collection<GridCacheVersion> committedVers,
Collection<GridCacheVersion> rolledbackVers)
{
- Collection<IgniteTxEntry> entries = F.concat(false, mapping.writes(), mapping.reads());
+ readyNearLocks(mapping.writes(), mapping.dhtVersion(), pendingVers, committedVers, rolledbackVers);
+ readyNearLocks(mapping.reads(), mapping.dhtVersion(), pendingVers, committedVers, rolledbackVers);
+ }
+ /**
+ * @param entries Entries.
+ * @param dhtVer DHT version.
+ * @param pendingVers Pending versions.
+ * @param committedVers Committed versions.
+ * @param rolledbackVers Rolled back versions.
+ */
+ void readyNearLocks(Collection<IgniteTxEntry> entries,
+ GridCacheVersion dhtVer,
+ Collection<GridCacheVersion> pendingVers,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers)
+ {
for (IgniteTxEntry txEntry : entries) {
while (true) {
GridCacheContext cacheCtx = txEntry.cached().context();
@@ -637,8 +638,13 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
// Handle explicit locks.
GridCacheVersion explicit = txEntry.explicitVersion();
- if (explicit == null)
- entry.readyNearLock(xidVer, mapping.dhtVersion(), committedVers, rolledbackVers, pendingVers);
+ if (explicit == null) {
+ entry.readyNearLock(xidVer,
+ dhtVer,
+ committedVers,
+ rolledbackVers,
+ pendingVers);
+ }
break;
}
@@ -871,7 +877,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
* @param writes Write entries.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this is last prepare request.
- * @param lastBackups IDs of backup nodes receiving last prepare request.
* @return Future that will be completed when locks are acquired.
*/
@SuppressWarnings("TypeMayBeWeakened")
@@ -879,8 +884,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
@Nullable Collection<IgniteTxEntry> reads,
@Nullable Collection<IgniteTxEntry> writes,
Map<UUID, Collection<UUID>> txNodes,
- boolean last,
- Collection<UUID> lastBackups
+ boolean last
) {
if (state() != PREPARING) {
if (timedOut())
@@ -901,8 +905,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
IgniteUuid.randomUuid(),
Collections.<IgniteTxKey, GridCacheVersion>emptyMap(),
last,
- needReturnValue() && implicit(),
- lastBackups);
+ needReturnValue() && implicit());
try {
// At this point all the entries passed in must be enlisted in transaction because this is an
@@ -1274,6 +1277,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
/** {@inheritDoc} */
@Override public String toString() {
- return S.toString(GridNearTxLocal.class, this, "mappings", mappings.keySet(), "super", super.toString());
+ return S.toString(GridNearTxLocal.class, this, "mappings", mappings, "super", super.toString());
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
index 456d726..798635a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
@@ -99,7 +99,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
* @param near {@code True} if mapping is for near caches.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this last prepare request for node.
- * @param lastBackups IDs of backup nodes receiving last prepare request during this prepare.
* @param onePhaseCommit One phase commit flag.
* @param retVal Return value flag.
* @param implicitSingle Implicit single flag.
@@ -118,7 +117,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
boolean near,
Map<UUID, Collection<UUID>> txNodes,
boolean last,
- Collection<UUID> lastBackups,
boolean onePhaseCommit,
boolean retVal,
boolean implicitSingle,
@@ -137,7 +135,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
this.topVer = topVer;
this.near = near;
this.last = last;
- this.lastBackups = lastBackups;
this.retVal = retVal;
this.implicitSingle = implicitSingle;
this.explicitLock = explicitLock;
@@ -153,12 +150,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
return firstClientReq;
}
- /**
- * @return IDs of backup nodes receiving last prepare request during this prepare.
- */
- public Collection<UUID> lastBackups() {
- return lastBackups;
- }
/**
* @return {@code True} if this last prepare request for node.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
index 87c68b2..d078df4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
@@ -34,10 +34,12 @@ import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxRemoteAdapter;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteStateImpl;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.GridLeanMap;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
import org.jetbrains.annotations.Nullable;
@@ -74,7 +76,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
* @param ldr Class loader.
* @param nodeId Node ID.
* @param nearNodeId Near node ID.
- * @param rmtThreadId Remote thread ID.
* @param xidVer XID version.
* @param commitVer Commit version.
* @param sys System flag.
@@ -92,7 +93,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
ClassLoader ldr,
UUID nodeId,
UUID nearNodeId,
- long rmtThreadId,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
boolean sys,
@@ -109,8 +109,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
super(
ctx,
nodeId,
- rmtThreadId,
- xidVer,
+ xidVer,
commitVer,
sys,
plc,
@@ -127,10 +126,10 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
this.nearNodeId = nearNodeId;
- readMap = Collections.emptyMap();
+ int writeSize = writeEntries != null ? Math.max(txSize, writeEntries.size()) : txSize;
- writeMap = new LinkedHashMap<>(
- writeEntries != null ? Math.max(txSize, writeEntries.size()) : txSize, 1.0f);
+ txState = new IgniteTxRemoteStateImpl(Collections.<IgniteTxKey, IgniteTxEntry>emptyMap(),
+ U.<IgniteTxKey, IgniteTxEntry>newLinkedHashMap(writeSize));
if (writeEntries != null) {
for (IgniteTxEntry entry : writeEntries) {
@@ -147,7 +146,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
* @param nodeId Node ID.
* @param nearNodeId Near node ID.
* @param nearXidVer Near transaction ID.
- * @param rmtThreadId Remote thread ID.
* @param xidVer XID version.
* @param commitVer Commit version.
* @param sys System flag.
@@ -163,7 +161,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
UUID nodeId,
UUID nearNodeId,
GridCacheVersion nearXidVer,
- long rmtThreadId,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
boolean sys,
@@ -179,8 +176,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
super(
ctx,
nodeId,
- rmtThreadId,
- xidVer,
+ xidVer,
commitVer,
sys,
plc,
@@ -198,8 +194,8 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
this.nearXidVer = nearXidVer;
this.nearNodeId = nearNodeId;
- readMap = new LinkedHashMap<>(1, 1.0f);
- writeMap = new LinkedHashMap<>(txSize, 1.0f);
+ txState = new IgniteTxRemoteStateImpl(U.<IgniteTxKey, IgniteTxEntry>newLinkedHashMap(1),
+ U.<IgniteTxKey, IgniteTxEntry>newLinkedHashMap(txSize));
}
/** {@inheritDoc} */
@@ -322,7 +318,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
// Initialize cache entry.
entry.cached(cached);
- writeMap.put(entry.txKey(), entry);
+ txState.addWriteEntry(entry.txKey(), entry);
addExplicit(entry);
@@ -391,7 +387,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
drVer,
skipStore);
- writeMap.put(key, txEntry);
+ txState.addWriteEntry(key, txEntry);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java
new file mode 100644
index 0000000..0465510
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java
@@ -0,0 +1,75 @@
+/*
+ * 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.near;
+
+import java.util.Collection;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public interface IgniteTxMappings {
+ /**
+ * Clears this mappings.
+ */
+ public void clear();
+
+ /**
+ * @return {@code True} if there are no mappings.
+ */
+ public boolean empty();
+
+ /**
+ * @param nodeId Node ID.
+ * @return Node mapping.
+ */
+ @Nullable public GridDistributedTxMapping get(UUID nodeId);
+
+ /**
+ * @param mapping Mapping.
+ */
+ public void put(GridDistributedTxMapping mapping);
+
+ /**
+ * @param nodeId Node ID.
+ * @return Removed mapping.
+ */
+ @Nullable public GridDistributedTxMapping remove(UUID nodeId);
+
+ /**
+ * @return Mapping for local node.
+ */
+ @Nullable public GridDistributedTxMapping localMapping();
+
+ /**
+ * @return Non null instance if this mappings contain only one mapping.
+ */
+ @Nullable public GridDistributedTxMapping singleMapping();
+
+ /**
+ * @return All mappings.
+ */
+ public Collection<GridDistributedTxMapping> mappings();
+
+ /**
+ * @return {@code True} if this is single mapping.
+ */
+ public boolean single();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java
new file mode 100644
index 0000000..7dec7af
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java
@@ -0,0 +1,92 @@
+/*
+ * 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.near;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentHashMap8;
+
+/**
+ *
+ */
+public class IgniteTxMappingsImpl implements IgniteTxMappings {
+ /** */
+ private final Map<UUID, GridDistributedTxMapping> mappings = new ConcurrentHashMap8<>();
+
+ /** {@inheritDoc} */
+ @Override public void clear() {
+ mappings.clear();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return mappings.isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping get(UUID nodeId) {
+ return mappings.get(nodeId);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void put(GridDistributedTxMapping mapping) {
+ mappings.put(mapping.node().id(), mapping);
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping remove(UUID nodeId) {
+ return mappings.remove(nodeId);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping localMapping() {
+ for (GridDistributedTxMapping m : mappings.values()) {
+ if (m.node().isLocal())
+ return m;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean single() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping singleMapping() {
+ assert mappings.size() == 1 : mappings;
+
+ return F.firstValue(mappings);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridDistributedTxMapping> mappings() {
+ return mappings.values();
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxMappingsImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java
new file mode 100644
index 0000000..fc15592
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.near;
+
+import java.util.Collection;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class IgniteTxMappingsSingleImpl implements IgniteTxMappings {
+ /** */
+ private volatile GridDistributedTxMapping mapping;
+
+ /** {@inheritDoc} */
+ @Override public void clear() {
+ mapping = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return mapping == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping get(UUID nodeId) {
+ GridDistributedTxMapping mapping0 = mapping;
+
+ return (mapping0 != null && mapping0.node().id().equals(nodeId)) ? mapping0 : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void put(GridDistributedTxMapping mapping) {
+ assert this.mapping == null;
+
+ this.mapping = mapping;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping remove(UUID nodeId) {
+ GridDistributedTxMapping mapping0 = mapping;
+
+ if (mapping0 != null && mapping0.node().id().equals(nodeId)) {
+ this.mapping = null;
+
+ return mapping0;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping localMapping() {
+ GridDistributedTxMapping mapping0 = mapping;
+
+ if (mapping0 != null && mapping0.node().isLocal())
+ return mapping0;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean single() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping singleMapping() {
+ return mapping;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridDistributedTxMapping> mappings() {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxMappingsSingleImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
index 94af6bb..f5f99f5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
@@ -275,9 +275,9 @@ public interface IgniteInternalTx extends AutoCloseable, GridTimeoutObject {
public boolean implicitSingle();
/**
- * @return Collection of cache IDs involved in this transaction.
+ * @return Transaction state.
*/
- public Collection<Integer> activeCacheIds();
+ public IgniteTxState txState();
/**
* @return {@code true} or {@code false} if the deployment is enabled or disabled for all active caches involved
@@ -669,14 +669,6 @@ public interface IgniteInternalTx extends AutoCloseable, GridTimeoutObject {
public boolean serializable();
/**
- * Checks whether given key has been removed within transaction.
- *
- * @param key Key to check.
- * @return {@code True} if key has been removed.
- */
- public boolean removed(IgniteTxKey key);
-
- /**
* Gets allowed remaining time for this transaction.
*
* @return Remaining time.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index eb2ca2c..6a0f8ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -22,7 +22,6 @@ import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.ObjectStreamException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -50,7 +49,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheOperation;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
-import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
import org.apache.ignite.internal.processors.cache.version.GridCachePlainVersionedEntry;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
@@ -120,10 +118,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
@GridToStringInclude
protected boolean implicit;
- /** Implicit with one key flag. */
- @GridToStringInclude
- protected boolean implicitSingle;
-
/** Local flag. */
@GridToStringInclude
protected boolean loc;
@@ -262,7 +256,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
* @param cctx Cache registry.
* @param xidVer Transaction ID.
* @param implicit Implicit flag.
- * @param implicitSingle Implicit with one key flag.
* @param loc Local flag.
* @param sys System transaction flag.
* @param plc IO policy.
@@ -275,7 +268,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
GridCacheSharedContext<?, ?> cctx,
GridCacheVersion xidVer,
boolean implicit,
- boolean implicitSingle,
boolean loc,
boolean sys,
byte plc,
@@ -295,7 +287,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
this.cctx = cctx;
this.xidVer = xidVer;
this.implicit = implicit;
- this.implicitSingle = implicitSingle;
this.loc = loc;
this.sys = sys;
this.plc = plc;
@@ -362,7 +353,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
this.taskNameHash = taskNameHash;
implicit = false;
- implicitSingle = false;
loc = false;
if (log == null)
@@ -421,45 +411,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
/** {@inheritDoc} */
@Override public boolean storeUsed() {
- if (!storeEnabled())
- return false;
-
- Collection<Integer> cacheIds = activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- for (int cacheId : cacheIds) {
- CacheStoreManager store = cctx.cacheContext(cacheId).store();
-
- if (store.configured())
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Store manager for current transaction.
- *
- * @return Store manager.
- */
- protected Collection<CacheStoreManager> stores() {
- Collection<Integer> cacheIds = activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- Collection<CacheStoreManager> stores = new ArrayList<>(cacheIds.size());
-
- for (int cacheId : cacheIds) {
- CacheStoreManager store = cctx.cacheContext(cacheId).store();
-
- if (store.configured())
- stores.add(store);
- }
-
- return stores;
- }
-
- return null;
+ return storeEnabled() && txState().storeUsed(cctx);
}
/**
@@ -645,7 +597,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
/** {@inheritDoc} */
@Override public boolean implicitSingle() {
- return implicitSingle;
+ return txState().implicitSingle();
}
/** {@inheritDoc} */
@@ -1758,11 +1710,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
}
/** {@inheritDoc} */
- @Override public Collection<Integer> activeCacheIds() {
- throw new IllegalStateException("Deserialized transaction can only be used as read-only.");
- }
-
- /** {@inheritDoc} */
@Override public boolean activeCachesDeploymentEnabled() {
return false;
}
@@ -1877,6 +1824,11 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
}
/** {@inheritDoc} */
+ @Override public IgniteTxState txState() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
@Override public Collection<UUID> masterNodeIds() {
return null;
}
@@ -2150,11 +2102,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
}
/** {@inheritDoc} */
- @Override public boolean removed(IgniteTxKey key) {
- return false;
- }
-
- /** {@inheritDoc} */
@Override public long remainingTime() throws IgniteTxTimeoutCheckedException {
return 0;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index 570aa48..0e5657b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -216,8 +216,7 @@ public class IgniteTxHandler {
req.reads(),
req.writes(),
req.transactionNodes(),
- req.last(),
- req.lastBackups());
+ req.last());
if (locTx.isRollbackOnly())
locTx.rollbackAsync();
@@ -398,7 +397,6 @@ public class IgniteTxHandler {
if (req.onePhaseCommit()) {
assert req.last();
- assert F.isEmpty(req.lastBackups()) || req.lastBackups().size() <= 1;
tx.onePhaseCommit(true);
}
@@ -413,8 +411,7 @@ public class IgniteTxHandler {
req.messageId(),
req.miniId(),
req.transactionNodes(),
- req.last(),
- req.lastBackups());
+ req.last());
if (tx.isRollbackOnly()) {
try {
@@ -1091,12 +1088,13 @@ public class IgniteTxHandler {
GridDhtTxRemote tx = ctx.tm().tx(req.version());
if (tx == null) {
+ boolean single = req.last() && req.writes().size() == 1;
+
tx = new GridDhtTxRemote(
ctx,
req.nearNodeId(),
req.futureId(),
nodeId,
- req.threadId(),
req.topologyVersion(),
req.version(),
null,
@@ -1110,7 +1108,8 @@ public class IgniteTxHandler {
req.nearXidVersion(),
req.transactionNodes(),
req.subjectId(),
- req.taskNameHash());
+ req.taskNameHash(),
+ single);
tx.writeVersion(req.writeVersion());
@@ -1138,7 +1137,7 @@ public class IgniteTxHandler {
tx.transactionNodes(req.transactionNodes());
}
- if (!tx.isSystemInvalidate() && !F.isEmpty(req.writes())) {
+ if (!tx.isSystemInvalidate()) {
int idx = 0;
for (IgniteTxEntry entry : req.writes()) {
@@ -1236,7 +1235,6 @@ public class IgniteTxHandler {
ldr,
nodeId,
req.nearNodeId(),
- req.threadId(),
req.version(),
null,
req.system(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
new file mode 100644
index 0000000..5f48469
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
@@ -0,0 +1,259 @@
+/*
+ * 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.transactions;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+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.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class IgniteTxImplicitSingleStateImpl extends IgniteTxLocalStateAdapter {
+ /** */
+ private GridCacheContext cacheCtx;
+
+ /** */
+ private IgniteTxEntry entry;
+
+ /** */
+ private boolean init;
+
+ /** {@inheritDoc} */
+ @Override public void addActiveCache(GridCacheContext ctx, IgniteTxLocalAdapter tx)
+ throws IgniteCheckedException {
+ assert cacheCtx == null : "Cache already set [cur=" + cacheCtx.name() + ", new=" + ctx.name() + ']';
+
+ this.cacheCtx = ctx;
+
+ tx.activeCachesDeploymentEnabled(cacheCtx.deploymentEnabled());
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
+ return cacheCtx;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public Integer firstCacheId() {
+ return cacheCtx != null ? cacheCtx.cacheId() : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void awaitLastFut(GridCacheSharedContext ctx) {
+ if (cacheCtx == null)
+ return;
+
+ cacheCtx.cache().awaitLastFut();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean implicitSingle() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException validateTopology(GridCacheSharedContext cctx, GridDhtTopologyFuture topFut) {
+ if (cacheCtx == null)
+ return null;
+
+ Throwable err = topFut.validateCache(cacheCtx);
+
+ if (err != null) {
+ return new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
+ U.maskName(cacheCtx.name()));
+ }
+
+ if (CU.affinityNodes(cacheCtx, topFut.topologyVersion()).isEmpty()) {
+ return new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
+ "partition nodes left the grid): " + cacheCtx.name());
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sync(GridCacheSharedContext cctx) {
+ return cacheCtx != null && cacheCtx.config().getWriteSynchronizationMode() == FULL_SYNC;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNearCache(GridCacheSharedContext cctx) {
+ return cacheCtx != null && cacheCtx.isNear();
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
+ if (cacheCtx == null || cacheCtx.isLocal())
+ return cctx.exchange().lastTopologyFuture();
+
+ cacheCtx.topology().readLock();
+
+ if (cacheCtx.topology().stopping()) {
+ fut.onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
+ cacheCtx.name()));
+
+ return null;
+ }
+
+ return cacheCtx.topology().topologyVersionFuture();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
+ if (cacheCtx == null || cacheCtx.isLocal())
+ return;
+
+ cacheCtx.topology().readUnlock();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean storeUsed(GridCacheSharedContext cctx) {
+ if (cacheCtx == null)
+ return false;
+
+ CacheStoreManager store = cacheCtx.store();
+
+ return store.configured();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
+ if (cacheCtx == null)
+ return null;
+
+ CacheStoreManager store = cacheCtx.store();
+
+ if (store.configured())
+ return Collections.singleton(store);
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
+ if (cacheCtx != null)
+ onTxEnd(cacheCtx, tx, commit);
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ if (entry != null && entry.txKey().equals(key))
+ return entry;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return entry != null && entry.txKey().equals(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return Collections.emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return entry != null ? Collections.singleton(entry.txKey()) : Collections.<IgniteTxKey>emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return Collections.emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return entry != null ? Collections.singletonMap(entry.txKey(), entry) :
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return Collections.emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return entry == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean init(int txSize) {
+ if (!init) {
+ init = true;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean initialized() {
+ return init;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addEntry(IgniteTxEntry entry) {
+ assert this.entry == null : "Entry already set [cur=" + this.entry + ", new=" + entry + ']';
+
+ this.entry = entry;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void seal() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry singleWrite() {
+ return entry;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxImplicitSingleStateImpl.class, this);
+ }
+}
[27/51] ignite git commit: IGNITE-1900: Ignite JXM problem with
Spring Boot. This closes #227.
Posted by vk...@apache.org.
IGNITE-1900: Ignite JXM problem with Spring Boot. This closes #227.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/dc32789c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/dc32789c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/dc32789c
Branch: refs/heads/ignite-direct-marsh-opt
Commit: dc32789c270c7d4661178539957b2e27d5dcb91b
Parents: 5a116cb
Author: wmz7year <yd...@gmail.com>
Authored: Mon Nov 16 13:43:23 2015 +0300
Committer: dmagda <ma...@gmail.com>
Committed: Mon Nov 16 13:43:23 2015 +0300
----------------------------------------------------------------------
.../apache/ignite/internal/IgniteKernal.java | 9 +++---
.../org/apache/ignite/mxbean/IgniteMXBean.java | 8 ++---
.../ignite/util/mbeans/GridMBeanSelfTest.java | 33 +++++++++++++++++---
3 files changed, 37 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/dc32789c/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index dd129da..f1d67af 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -564,10 +564,10 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
- @Override public Collection<String> getUserAttributesFormatted() {
+ @Override public List<String> getUserAttributesFormatted() {
assert cfg != null;
- return F.transform(cfg.getUserAttributes().entrySet(), new C1<Map.Entry<String, ?>, String>() {
+ return (List<String>)F.transform(cfg.getUserAttributes().entrySet(), new C1<Map.Entry<String, ?>, String>() {
@Override public String apply(Map.Entry<String, ?> e) {
return e.getKey() + ", " + e.getValue().toString();
}
@@ -582,10 +582,11 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
}
/** {@inheritDoc} */
- @Override public Collection<String> getLifecycleBeansFormatted() {
+ @Override public List<String> getLifecycleBeansFormatted() {
LifecycleBean[] beans = cfg.getLifecycleBeans();
- return F.isEmpty(beans) ? Collections.<String>emptyList() : F.transform(beans, F.<LifecycleBean>string());
+ return F.isEmpty(beans) ? Collections.<String>emptyList() :
+ (List<String>)F.transform(beans, F.<LifecycleBean>string());
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/dc32789c/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java b/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
index c30e0e5..0754c27 100644
--- a/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
+++ b/modules/core/src/main/java/org/apache/ignite/mxbean/IgniteMXBean.java
@@ -17,7 +17,7 @@
package org.apache.ignite.mxbean;
-import java.util.Collection;
+import java.util.List;
import java.util.UUID;
import javax.management.JMException;
@@ -75,7 +75,7 @@ public interface IgniteMXBean {
public long getUpTime();
/**
- * Gets a collection of formatted user-defined attributes added to this node.
+ * Gets a list of formatted user-defined attributes added to this node.
* <p>
* Note that grid will add all System properties and environment properties
* to grid node attributes also. SPIs may also add node attributes that are
@@ -84,7 +84,7 @@ public interface IgniteMXBean {
* @return User defined attributes for this node.
*/
@MXBeanDescription("Collection of formatted user-defined attributes added to this node.")
- public Collection<String> getUserAttributesFormatted();
+ public List<String> getUserAttributesFormatted();
/**
* Gets a formatted instance of logger that is in grid.
@@ -149,7 +149,7 @@ public interface IgniteMXBean {
* with Ignite.
*/
@MXBeanDescription("String representation of lifecycle beans.")
- public Collection<String> getLifecycleBeansFormatted();
+ public List<String> getLifecycleBeansFormatted();
/**
* This method allows manually remove the checkpoint with given {@code key}.
http://git-wip-us.apache.org/repos/asf/ignite/blob/dc32789c/modules/core/src/test/java/org/apache/ignite/util/mbeans/GridMBeanSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/util/mbeans/GridMBeanSelfTest.java b/modules/core/src/test/java/org/apache/ignite/util/mbeans/GridMBeanSelfTest.java
index da31742..58be549 100644
--- a/modules/core/src/test/java/org/apache/ignite/util/mbeans/GridMBeanSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/util/mbeans/GridMBeanSelfTest.java
@@ -23,6 +23,7 @@ import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.StandardMBean;
import org.apache.ignite.internal.mxbean.IgniteStandardMXBean;
+import org.apache.ignite.mxbean.IgniteMXBean;
import org.apache.ignite.mxbean.MXBeanDescription;
import org.apache.ignite.mxbean.MXBeanParametersDescriptions;
import org.apache.ignite.mxbean.MXBeanParametersNames;
@@ -40,13 +41,13 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
public void testCorrectMBeanInfo() throws Exception {
StandardMBean mbean = new IgniteStandardMXBean(new GridMBeanImplementation(), GridMBeanInterface.class);
- MBeanInfo info = mbean.getMBeanInfo();
+ MBeanInfo info = mbean.getMBeanInfo();
assert info.getDescription().equals("MBeanDescription.") == true;
assert info.getOperations().length == 2;
- for (MBeanOperationInfo opInfo: info.getOperations()) {
+ for (MBeanOperationInfo opInfo : info.getOperations()) {
if (opInfo.getDescription().equals("MBeanOperation."))
assert opInfo.getSignature().length == 2;
else {
@@ -55,7 +56,7 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
}
}
- for (MBeanParameterInfo paramInfo: info.getOperations()[0].getSignature()) {
+ for (MBeanParameterInfo paramInfo : info.getOperations()[0].getSignature()) {
if (paramInfo.getName().equals("ignored"))
assert paramInfo.getDescription().equals("MBeanOperationParameter1.") == true;
else {
@@ -64,9 +65,9 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
}
}
- assert info.getAttributes().length == 4: "Expected 4 attributes but got " + info.getAttributes().length;
+ assert info.getAttributes().length == 4 : "Expected 4 attributes but got " + info.getAttributes().length;
- for (MBeanAttributeInfo attrInfo: info.getAttributes()) {
+ for (MBeanAttributeInfo attrInfo : info.getAttributes()) {
if (attrInfo.isWritable() == false) {
assert (attrInfo.getDescription().equals("MBeanReadonlyGetter.") == true ||
attrInfo.getDescription().equals("MBeanROGetter."));
@@ -80,6 +81,7 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
/**
* Tests correct MBean interface.
+ *
* @throws Exception Thrown if test fails.
*/
public void testMissedNameMBeanInfo() throws Exception {
@@ -97,6 +99,7 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
/**
* Tests correct MBean interface.
+ *
* @throws Exception Thrown if test fails.
*/
public void testMissedDescriptionMBeanInfo() throws Exception {
@@ -115,6 +118,7 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
/**
* Tests correct MBean interface.
+ *
* @throws Exception Thrown if test fails.
*/
public void testEmptyDescriptionMBeanInfo() throws Exception {
@@ -133,6 +137,7 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
/**
* Tests correct MBean interface.
+ *
* @throws Exception Thrown if test fails.
*/
public void testEmptyNameMBeanInfo() throws Exception {
@@ -150,6 +155,23 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
}
/**
+ * Tests correct MBean interface.
+ *
+ * @throws Exception Thrown if test fails.
+ */
+ public void testIgniteKernalReturnsValidMBeanInfo() throws Exception {
+ try {
+ IgniteMXBean ignite = (IgniteMXBean)startGrid();
+
+ assertNotNull(ignite.getUserAttributesFormatted());
+ assertNotNull(ignite.getLifecycleBeansFormatted());
+ }
+ finally {
+ stopAllGrids();
+ }
+ }
+
+ /**
* Super interface for {@link GridMBeanInterface}.
*/
public static interface GridMBeanSuperInterface {
@@ -211,6 +233,7 @@ public class GridMBeanSelfTest extends GridCommonAbstractTest {
/**
* Test boolean setter.
+ *
* @param isWritable Just a boolean.
*/
public void setWritable(boolean isWritable);
[45/51] ignite git commit: Merge branch 'ignite-1.5' of
https://git-wip-us.apache.org/repos/asf/ignite into ignite-direct-marsh-opt
Posted by vk...@apache.org.
Merge branch 'ignite-1.5' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-direct-marsh-opt
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a73c67ff
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a73c67ff
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a73c67ff
Branch: refs/heads/ignite-direct-marsh-opt
Commit: a73c67ff897ff6056e81e517f6d4b3d223f4b268
Parents: 0bb3566 c490de3
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Wed Nov 18 15:20:51 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Wed Nov 18 15:20:51 2015 -0800
----------------------------------------------------------------------
modules/camel/pom.xml | 102 +++++
.../ignite/stream/camel/CamelStreamer.java | 237 +++++++++++
.../stream/camel/IgniteCamelStreamerTest.java | 420 +++++++++++++++++++
.../camel/IgniteCamelStreamerTestSuite.java | 48 +++
.../src/test/resources/camel.test.properties | 18 +
.../ignite/codegen/MessageCodeGenerator.java | 11 +-
.../communication/GridIoMessageFactory.java | 6 +
.../discovery/GridDiscoveryManager.java | 2 +-
.../cache/GridCacheDeploymentManager.java | 2 +-
.../processors/cache/GridCacheGateway.java | 1 -
.../processors/cache/GridCacheMvcc.java | 7 -
.../processors/cache/GridCacheMvccManager.java | 42 --
.../GridCachePartitionExchangeManager.java | 55 ++-
.../cache/GridCacheSharedContext.java | 7 +-
.../distributed/GridCacheTxRecoveryFuture.java | 41 +-
.../distributed/GridDistributedBaseMessage.java | 56 ---
.../distributed/GridDistributedLockRequest.java | 6 -
.../GridDistributedLockResponse.java | 32 +-
.../GridDistributedTxPrepareRequest.java | 67 ++-
.../distributed/dht/GridDhtLockFuture.java | 63 ++-
.../distributed/dht/GridDhtLockRequest.java | 2 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 5 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 9 +
.../distributed/dht/GridDhtTxPrepareFuture.java | 60 ++-
.../dht/GridDhtTxPrepareRequest.java | 54 +--
.../dht/colocated/GridDhtColocatedCache.java | 2 +-
.../colocated/GridDhtColocatedLockFuture.java | 55 ++-
.../distributed/near/GridNearLockFuture.java | 56 ++-
.../distributed/near/GridNearLockRequest.java | 4 +-
...arOptimisticSerializableTxPrepareFuture.java | 91 ++--
.../near/GridNearOptimisticTxPrepareFuture.java | 50 ++-
.../GridNearPessimisticTxPrepareFuture.java | 39 +-
.../near/GridNearTransactionalCache.java | 7 +-
.../near/GridNearTxFinishFuture.java | 18 +-
.../cache/distributed/near/GridNearTxLocal.java | 15 -
.../near/GridNearTxPrepareFutureAdapter.java | 14 +-
.../near/GridNearTxPrepareRequest.java | 52 +--
.../cache/transactions/IgniteInternalTx.java | 1 +
.../cache/transactions/IgniteTxAdapter.java | 1 +
.../cache/transactions/IgniteTxEntry.java | 9 +-
.../IgniteTxImplicitSingleStateImpl.java | 7 +
.../transactions/IgniteTxLocalAdapter.java | 12 +-
.../cache/transactions/IgniteTxManager.java | 1 +
.../IgniteTxRemoteStateAdapter.java | 5 +
.../cache/transactions/IgniteTxState.java | 6 +
.../cache/transactions/IgniteTxStateImpl.java | 69 ++-
.../clock/GridClockSyncProcessor.java | 28 +-
.../internal/util/UUIDCollectionMessage.java | 114 +++++
.../util/future/GridCompoundFuture.java | 15 +-
.../ignite/internal/util/lang/GridFunc.java | 8 +-
.../ignite/internal/util/nio/GridNioServer.java | 13 +-
.../org/apache/ignite/stream/StreamAdapter.java | 19 +-
.../IgniteCacheTxStoreSessionTest.java | 2 +-
parent/pom.xml | 1 +
pom.xml | 1 +
55 files changed, 1639 insertions(+), 429 deletions(-)
----------------------------------------------------------------------
[18/51] ignite git commit: Minor fix for StreamTransformer
Posted by vk...@apache.org.
Minor fix for StreamTransformer
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/569dd21f
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/569dd21f
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/569dd21f
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 569dd21fc049be6cd89df0f24551818ba88f0329
Parents: 6a7d079
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 10 17:45:10 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 10 17:45:10 2015 -0800
----------------------------------------------------------------------
.../main/java/org/apache/ignite/stream/StreamTransformer.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/569dd21f/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java b/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
index f0f41bf..4435c0a 100644
--- a/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
+++ b/modules/core/src/main/java/org/apache/ignite/stream/StreamTransformer.java
@@ -37,7 +37,7 @@ public abstract class StreamTransformer<K, V> implements StreamReceiver<K, V>, E
/** {@inheritDoc} */
@Override public void receive(IgniteCache<K, V> cache, Collection<Map.Entry<K, V>> entries) throws IgniteException {
for (Map.Entry<K, V> entry : entries)
- cache.invoke(entry.getKey(), this);
+ cache.invoke(entry.getKey(), this, entry.getValue());
}
/**
@@ -53,4 +53,4 @@ public abstract class StreamTransformer<K, V> implements StreamReceiver<K, V>, E
}
};
}
-}
\ No newline at end of file
+}
[40/51] ignite git commit: Merge branch 'ignite-1.5' of
https://git-wip-us.apache.org/repos/asf/ignite into ignite-direct-marsh-opt
Posted by vk...@apache.org.
Merge branch 'ignite-1.5' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-direct-marsh-opt
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0bb35667
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0bb35667
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0bb35667
Branch: refs/heads/ignite-direct-marsh-opt
Commit: 0bb35667bacaa9090599e624ad15327b01eacd08
Parents: 6bf335c 3ff71fd
Author: Valentin Kulichenko <va...@gmail.com>
Authored: Tue Nov 17 17:38:28 2015 -0800
Committer: Valentin Kulichenko <va...@gmail.com>
Committed: Tue Nov 17 17:38:28 2015 -0800
----------------------------------------------------------------------
.../apache/ignite/internal/IgniteKernal.java | 9 +-
.../processors/cache/GridCacheAdapter.java | 48 +-
.../processors/cache/GridCacheMapEntry.java | 11 +-
.../cache/GridCacheSharedContext.java | 31 +-
.../distributed/GridDistributedTxMapping.java | 78 -
.../GridDistributedTxRemoteAdapter.java | 136 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 1 -
.../cache/distributed/dht/GridDhtTxLocal.java | 24 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 80 +-
.../cache/distributed/dht/GridDhtTxMapping.java | 134 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 59 +-
.../cache/distributed/dht/GridDhtTxRemote.java | 29 +-
...arOptimisticSerializableTxPrepareFuture.java | 16 -
.../near/GridNearOptimisticTxPrepareFuture.java | 103 +-
...ridNearOptimisticTxPrepareFutureAdapter.java | 72 +-
.../GridNearPessimisticTxPrepareFuture.java | 1 -
.../near/GridNearTransactionalCache.java | 1 -
.../near/GridNearTxFinishFuture.java | 61 +-
.../cache/distributed/near/GridNearTxLocal.java | 109 +-
.../near/GridNearTxPrepareRequest.java | 9 -
.../distributed/near/GridNearTxRemote.java | 26 +-
.../distributed/near/IgniteTxMappings.java | 75 +
.../distributed/near/IgniteTxMappingsImpl.java | 92 ++
.../near/IgniteTxMappingsSingleImpl.java | 101 ++
.../cache/transactions/IgniteInternalTx.java | 12 +-
.../cache/transactions/IgniteTxAdapter.java | 67 +-
.../cache/transactions/IgniteTxHandler.java | 16 +-
.../IgniteTxImplicitSingleStateImpl.java | 259 ++++
.../transactions/IgniteTxLocalAdapter.java | 1388 ++++++++++--------
.../cache/transactions/IgniteTxLocalEx.java | 30 +-
.../cache/transactions/IgniteTxLocalState.java | 44 +
.../transactions/IgniteTxLocalStateAdapter.java | 41 +
.../cache/transactions/IgniteTxManager.java | 18 +-
.../cache/transactions/IgniteTxMap.java | 3 +-
.../cache/transactions/IgniteTxRemoteEx.java | 17 +-
.../IgniteTxRemoteSingleStateImpl.java | 108 ++
.../cache/transactions/IgniteTxRemoteState.java | 34 +
.../IgniteTxRemoteStateAdapter.java | 110 ++
.../transactions/IgniteTxRemoteStateImpl.java | 124 ++
.../cache/transactions/IgniteTxState.java | 171 +++
.../cache/transactions/IgniteTxStateImpl.java | 375 +++++
.../org/apache/ignite/mxbean/IgniteMXBean.java | 8 +-
.../ignite/spi/discovery/tcp/ServerImpl.java | 360 +++--
.../spi/discovery/tcp/TcpDiscoveryImpl.java | 4 +-
.../tcp/internal/TcpDiscoveryNodesRing.java | 95 +-
.../messages/TcpDiscoveryAbstractMessage.java | 37 +
.../TcpDiscoveryStatusCheckMessage.java | 11 +
.../GridCacheLoadOnlyStoreAdapterSelfTest.java | 145 +-
.../tcp/TcpDiscoveryMultiThreadedTest.java | 158 +-
.../discovery/tcp/TcpDiscoveryRestartTest.java | 10 +-
.../spi/discovery/tcp/TcpDiscoverySelfTest.java | 459 +++++-
.../TcpDiscoveryMulticastIpFinderSelfTest.java | 28 +-
.../testframework/junits/GridAbstractTest.java | 29 +-
.../ignite/util/mbeans/GridMBeanSelfTest.java | 33 +-
modules/flume/README.md | 40 +
modules/flume/pom.xml | 77 +
.../ignite/stream/flume/EventTransformer.java | 36 +
.../apache/ignite/stream/flume/IgniteSink.java | 186 +++
.../stream/flume/IgniteSinkConstants.java | 35 +
.../ignite/stream/flume/IgniteSinkTest.java | 142 ++
.../stream/flume/IgniteSinkTestSuite.java | 37 +
.../stream/flume/TestEventTransformer.java | 66 +
.../flume/src/test/resources/example-ignite.xml | 71 +
.../GridSpringResourceInjectionSelfTest.java | 143 ++
.../processors/resource/spring-resource.xml | 27 +
.../testsuites/IgniteResourceSelfTestSuite.java | 2 +
pom.xml | 1 +
67 files changed, 4686 insertions(+), 1677 deletions(-)
----------------------------------------------------------------------